mirror of
https://github.com/markuryy/shark.git
synced 2025-12-12 11:41:02 +00:00
149 lines
3.9 KiB
TypeScript
149 lines
3.9 KiB
TypeScript
import { LazyStore } from '@tauri-apps/plugin-store';
|
|
import { writable, type Writable } from 'svelte/store';
|
|
|
|
// Spotify User interface
|
|
export interface SpotifyUser {
|
|
id: string;
|
|
display_name: string;
|
|
email?: string;
|
|
country?: string;
|
|
product?: string; // premium, free, etc.
|
|
images?: Array<{ url: string }>;
|
|
}
|
|
|
|
// Spotify auth state
|
|
export interface SpotifyAuthState {
|
|
// Developer credentials
|
|
clientId: string | null;
|
|
clientSecret: string | null;
|
|
// OAuth tokens
|
|
accessToken: string | null;
|
|
refreshToken: string | null;
|
|
expiresAt: number | null; // Unix timestamp in milliseconds
|
|
// User data
|
|
user: SpotifyUser | null;
|
|
loggedIn: boolean;
|
|
cacheTimestamp: number | null; // Unix timestamp in seconds
|
|
}
|
|
|
|
// Initialize the store with spotify.json
|
|
const store = new LazyStore('spotify.json');
|
|
|
|
// Default state
|
|
const defaultState: SpotifyAuthState = {
|
|
clientId: null,
|
|
clientSecret: null,
|
|
accessToken: null,
|
|
refreshToken: null,
|
|
expiresAt: null,
|
|
user: null,
|
|
loggedIn: false,
|
|
cacheTimestamp: null
|
|
};
|
|
|
|
// Create a writable store for reactive UI updates
|
|
export const spotifyAuth: Writable<SpotifyAuthState> = writable(defaultState);
|
|
|
|
// Load Spotify auth state from store
|
|
export async function loadSpotifyAuth(): Promise<void> {
|
|
const clientId = await store.get<string>('clientId');
|
|
const clientSecret = await store.get<string>('clientSecret');
|
|
const accessToken = await store.get<string>('accessToken');
|
|
const refreshToken = await store.get<string>('refreshToken');
|
|
const expiresAt = await store.get<number>('expiresAt');
|
|
const user = await store.get<SpotifyUser>('user');
|
|
const cacheTimestamp = await store.get<number>('cacheTimestamp');
|
|
|
|
spotifyAuth.set({
|
|
clientId: clientId ?? null,
|
|
clientSecret: clientSecret ?? null,
|
|
accessToken: accessToken ?? null,
|
|
refreshToken: refreshToken ?? null,
|
|
expiresAt: expiresAt ?? null,
|
|
user: user ?? null,
|
|
loggedIn: !!(accessToken && user),
|
|
cacheTimestamp: cacheTimestamp ?? null
|
|
});
|
|
}
|
|
|
|
// Save client credentials (developer app credentials)
|
|
export async function saveClientCredentials(clientId: string, clientSecret: string): Promise<void> {
|
|
await store.set('clientId', clientId);
|
|
await store.set('clientSecret', clientSecret);
|
|
await store.save();
|
|
|
|
spotifyAuth.update(s => ({
|
|
...s,
|
|
clientId,
|
|
clientSecret
|
|
}));
|
|
}
|
|
|
|
// Save OAuth tokens
|
|
export async function saveTokens(accessToken: string, refreshToken: string, expiresIn: number): Promise<void> {
|
|
const expiresAt = Date.now() + (expiresIn * 1000);
|
|
|
|
await store.set('accessToken', accessToken);
|
|
await store.set('refreshToken', refreshToken);
|
|
await store.set('expiresAt', expiresAt);
|
|
await store.save();
|
|
|
|
spotifyAuth.update(s => ({
|
|
...s,
|
|
accessToken,
|
|
refreshToken,
|
|
expiresAt
|
|
}));
|
|
}
|
|
|
|
// Save user data
|
|
export async function saveUser(user: SpotifyUser): Promise<void> {
|
|
await store.set('user', user);
|
|
await store.save();
|
|
|
|
spotifyAuth.update(s => ({
|
|
...s,
|
|
user,
|
|
loggedIn: true
|
|
}));
|
|
}
|
|
|
|
// Clear auth (logout)
|
|
export async function clearSpotifyAuth(): Promise<void> {
|
|
await store.delete('accessToken');
|
|
await store.delete('refreshToken');
|
|
await store.delete('expiresAt');
|
|
await store.delete('user');
|
|
await store.save();
|
|
|
|
spotifyAuth.update(s => ({
|
|
...s,
|
|
accessToken: null,
|
|
refreshToken: null,
|
|
expiresAt: null,
|
|
user: null,
|
|
loggedIn: false
|
|
}));
|
|
}
|
|
|
|
// Check if token is expired or about to expire (within 5 minutes)
|
|
export function isTokenExpired(expiresAt: number | null): boolean {
|
|
if (!expiresAt) return true;
|
|
const bufferTime = 5 * 60 * 1000; // 5 minutes in milliseconds
|
|
return Date.now() >= (expiresAt - bufferTime);
|
|
}
|
|
|
|
// Save cache timestamp
|
|
export async function saveCacheTimestamp(timestamp: number): Promise<void> {
|
|
await store.set('cacheTimestamp', timestamp);
|
|
await store.save();
|
|
|
|
spotifyAuth.update(s => ({
|
|
...s,
|
|
cacheTimestamp: timestamp
|
|
}));
|
|
}
|
|
|
|
// Initialize on module load
|
|
loadSpotifyAuth();
|