| | |
| |
|
| | const STORAGE_KEY = 'hf_oauth_token'; |
| | const USER_INFO_KEY = 'hf_user_info'; |
| | const DEV_MODE_KEY = 'hf_dev_mode'; |
| | const API_BASE = '/api'; |
| |
|
| | |
| | const isDevelopment = typeof window !== 'undefined' && |
| | (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'); |
| |
|
| | export interface OAuthUserInfo { |
| | id?: string; |
| | sub?: string; |
| | name: string; |
| | preferred_username?: string; |
| | preferredUsername?: string; |
| | picture?: string; |
| | avatarUrl?: string; |
| | } |
| |
|
| | export interface OAuthResult { |
| | accessToken: string; |
| | accessTokenExpiresAt: Date; |
| | userInfo: OAuthUserInfo; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | export async function initializeOAuth(): Promise<OAuthResult | null> { |
| | try { |
| | |
| | if (isDevelopment && isDevModeEnabled()) { |
| | const storedToken = getStoredToken(); |
| | const storedUserInfo = getStoredUserInfo(); |
| | |
| | if (storedToken && storedUserInfo) { |
| | return { |
| | accessToken: storedToken, |
| | accessTokenExpiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000), |
| | userInfo: storedUserInfo, |
| | }; |
| | } |
| | return null; |
| | } |
| | |
| | |
| | const urlParams = new URLSearchParams(window.location.search); |
| | const sessionToken = urlParams.get('session'); |
| | |
| | if (sessionToken) { |
| | |
| | try { |
| | const response = await fetch(`${API_BASE}/auth/session?session=${sessionToken}`); |
| | if (response.ok) { |
| | const data = await response.json(); |
| | |
| | |
| | const userInfo: OAuthUserInfo = { |
| | id: data.user_info.sub || data.user_info.id, |
| | name: data.user_info.name, |
| | preferredUsername: data.user_info.preferred_username || data.user_info.preferredUsername, |
| | avatarUrl: data.user_info.picture || data.user_info.avatarUrl, |
| | }; |
| | |
| | const oauthResult: OAuthResult = { |
| | accessToken: data.access_token, |
| | accessTokenExpiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000), |
| | userInfo, |
| | }; |
| | |
| | |
| | storeOAuthData(oauthResult); |
| | |
| | |
| | window.history.replaceState({}, document.title, window.location.pathname); |
| | |
| | return oauthResult; |
| | } |
| | } catch (error) { |
| | console.error('Failed to fetch session:', error); |
| | } |
| | } |
| | |
| | |
| | const storedToken = getStoredToken(); |
| | const storedUserInfo = getStoredUserInfo(); |
| | |
| | if (storedToken && storedUserInfo) { |
| | return { |
| | accessToken: storedToken, |
| | accessTokenExpiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000), |
| | userInfo: storedUserInfo, |
| | }; |
| | } |
| | |
| | return null; |
| | } catch (error) { |
| | console.error('OAuth initialization error:', error); |
| | return null; |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | export async function loginWithHuggingFace(): Promise<void> { |
| | try { |
| | |
| | const response = await fetch(`${API_BASE}/auth/login`); |
| | if (!response.ok) { |
| | throw new Error('Failed to get login URL'); |
| | } |
| | |
| | const data = await response.json(); |
| | |
| | window.location.href = data.login_url; |
| | } catch (error) { |
| | console.error('Failed to initiate OAuth login:', error); |
| | throw new Error('Failed to start login process'); |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | export function logout(): void { |
| | if (typeof window !== 'undefined') { |
| | localStorage.removeItem(STORAGE_KEY); |
| | localStorage.removeItem(USER_INFO_KEY); |
| | localStorage.removeItem(DEV_MODE_KEY); |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | function storeOAuthData(result: OAuthResult): void { |
| | if (typeof window !== 'undefined') { |
| | localStorage.setItem(STORAGE_KEY, result.accessToken); |
| | localStorage.setItem(USER_INFO_KEY, JSON.stringify(result.userInfo)); |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | export function getStoredToken(): string | null { |
| | if (typeof window !== 'undefined') { |
| | return localStorage.getItem(STORAGE_KEY); |
| | } |
| | return null; |
| | } |
| |
|
| | |
| | |
| | |
| | export function getStoredUserInfo(): OAuthUserInfo | null { |
| | if (typeof window !== 'undefined') { |
| | const userInfoStr = localStorage.getItem(USER_INFO_KEY); |
| | if (userInfoStr) { |
| | try { |
| | return JSON.parse(userInfoStr); |
| | } catch { |
| | return null; |
| | } |
| | } |
| | } |
| | return null; |
| | } |
| |
|
| | |
| | |
| | |
| | export function isAuthenticated(): boolean { |
| | return getStoredToken() !== null; |
| | } |
| |
|
| | |
| | |
| | |
| | export function loginDevMode(username: string): OAuthResult { |
| | const mockToken = `dev_token_${username}_${Date.now()}`; |
| | const mockUserInfo: OAuthUserInfo = { |
| | id: `dev_${Date.now()}`, |
| | name: username, |
| | preferredUsername: username.toLowerCase().replace(/\s+/g, '_'), |
| | avatarUrl: `https://ui-avatars.com/api/?name=${encodeURIComponent(username)}&background=random&size=128`, |
| | }; |
| | |
| | const result: OAuthResult = { |
| | accessToken: mockToken, |
| | accessTokenExpiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000), |
| | userInfo: mockUserInfo, |
| | }; |
| | |
| | |
| | storeOAuthData(result); |
| | |
| | if (typeof window !== 'undefined') { |
| | localStorage.setItem(DEV_MODE_KEY, 'true'); |
| | } |
| | |
| | return result; |
| | } |
| |
|
| | |
| | |
| | |
| | export function isDevModeEnabled(): boolean { |
| | if (typeof window !== 'undefined') { |
| | return localStorage.getItem(DEV_MODE_KEY) === 'true'; |
| | } |
| | return false; |
| | } |
| |
|
| | |
| | |
| | |
| | export function isDevelopmentMode(): boolean { |
| | return isDevelopment; |
| | } |
| |
|
| |
|