import { writable, get } from "svelte/store"; import { oauthLoginUrl, oauthHandleRedirectIfPresent, type UserInfo, } from "@huggingface/hub"; export interface AuthState { isAuthenticated: boolean; user: UserInfo | null; accessToken: string | null; expiresAt: number | null; loading: boolean; error: string | null; } function createAuthStore() { const { subscribe, set, update } = writable({ isAuthenticated: false, user: null, accessToken: null, expiresAt: null, loading: true, error: null, }); const getOAuthConfig = () => { const isProduction = window.location.hostname.includes("hf.space"); const clientId = "87f5f1d1-6e9e-4962-98f0-e5f3831ec988"; let redirectUrl: string; if (isProduction) { redirectUrl = `https://${window.location.hostname}/auth/callback`; } else { redirectUrl = `http://localhost:7860/auth/callback`; } return { clientId, redirectUrl, scopes: "openid profile inference-api", }; }; return { subscribe, async init() { update((state) => ({ ...state, loading: true })); try { const oauthResult = await oauthHandleRedirectIfPresent(); if (oauthResult) { const { accessToken, accessTokenExpiresAt, userInfo } = oauthResult; set({ isAuthenticated: true, user: userInfo, accessToken, expiresAt: accessTokenExpiresAt ? accessTokenExpiresAt.getTime() : null, loading: false, error: null, }); sessionStorage.setItem( "hf_auth", JSON.stringify({ accessToken, expiresAt: accessTokenExpiresAt ? accessTokenExpiresAt.getTime() : null, user: userInfo, }), ); return true; } const stored = sessionStorage.getItem("hf_auth"); if (stored) { const authData = JSON.parse(stored); if (!authData.expiresAt || authData.expiresAt > Date.now()) { set({ isAuthenticated: true, user: authData.user, accessToken: authData.accessToken, expiresAt: authData.expiresAt, loading: false, error: null, }); return true; } else { sessionStorage.removeItem("hf_auth"); } } set({ isAuthenticated: false, user: null, accessToken: null, expiresAt: null, loading: false, error: null, }); return false; } catch (error) { console.error("Auth initialization error:", error); set({ isAuthenticated: false, user: null, accessToken: null, expiresAt: null, loading: false, error: error instanceof Error ? error.message : "Authentication failed", }); return false; } }, async login() { const config = getOAuthConfig(); try { const url = await oauthLoginUrl({ clientId: config.clientId, redirectUrl: config.redirectUrl, scopes: config.scopes, }); window.location.href = url; } catch (error) { console.error("Login error:", error); update((state) => ({ ...state, error: error instanceof Error ? error.message : "Login failed", })); } }, logout() { sessionStorage.removeItem("hf_auth"); set({ isAuthenticated: false, user: null, accessToken: null, expiresAt: null, loading: false, error: null, }); }, getToken(): string | null { const state = get({ subscribe }); return state.accessToken; }, isTokenValid(): boolean { const state = get({ subscribe }); if (!state.accessToken) return false; if (!state.expiresAt) return true; return state.expiresAt > Date.now(); }, }; } export const authStore = createAuthStore();