godgpt-web-auth 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +7 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -649,8 +649,12 @@ async function signInWithApple(config) {
|
|
|
649
649
|
const isLocalhost = window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1";
|
|
650
650
|
if (isLocalhost) {
|
|
651
651
|
console.warn("[Auth Apple] Running on localhost - Apple Sign In requires:");
|
|
652
|
-
console.warn(
|
|
653
|
-
|
|
652
|
+
console.warn(
|
|
653
|
+
" 1. Your Service ID (com.gpt.godweb) must have localhost configured in Apple Developer Portal"
|
|
654
|
+
);
|
|
655
|
+
console.warn(
|
|
656
|
+
" 2. Return URL must include: http://localhost:5173 (or your port)"
|
|
657
|
+
);
|
|
654
658
|
}
|
|
655
659
|
try {
|
|
656
660
|
console.log("[Auth Apple] Loading SDK...");
|
|
@@ -666,7 +670,7 @@ async function signInWithApple(config) {
|
|
|
666
670
|
const code = response.authorization?.code;
|
|
667
671
|
const idToken = response.authorization?.id_token;
|
|
668
672
|
if (code) {
|
|
669
|
-
console.log("[Auth Apple] Exchanging authorization code");
|
|
673
|
+
console.log("[Auth Apple] Exchanging authorization code", code);
|
|
670
674
|
return await exchangeToken({ code }, "apple", config);
|
|
671
675
|
} else if (idToken) {
|
|
672
676
|
console.log("[Auth Apple] Exchanging id_token");
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/auth/config.ts","../src/auth/services/storageService.ts","../src/auth/components/AuthProvider.tsx","../src/auth/hooks/useAuth.ts","../src/auth/services/tokenService.ts","../src/auth/strategies/google.ts","../src/auth/strategies/apple.ts","../src/auth/strategies/email.ts","../src/auth/components/LoginPage.tsx"],"names":["createContext","useState","useRef","useEffect","useCallback","useMemo","useContext","jsxs","jsx","Fragment"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { AuthConfig } from \"./types\";\n\n// ============================================\n// CONFIGURATION VALIDATION\n// ============================================\n\n/**\n * Validate auth configuration.\n * Called by AuthProvider on mount.\n */\nexport function validateConfig(config: AuthConfig): void {\n if (!config.backendUrl) {\n throw new Error(\"[Auth] backendUrl is required in AuthConfig\");\n }\n\n if (!config.google && !config.apple && !config.email?.enabled) {\n console.warn(\n \"[Auth] No auth strategies configured. Enable at least one: google, apple, or email.\"\n );\n }\n\n // Validate Google config\n if (config.google && !config.google.clientId) {\n throw new Error(\"[Auth] google.clientId is required when google is enabled\");\n }\n\n // Validate Apple config\n if (config.apple && !config.apple.clientId) {\n throw new Error(\"[Auth] apple.clientId is required when apple is enabled\");\n }\n\n console.log(\"[Auth] Config validated:\", {\n backendUrl: config.backendUrl,\n hasGoogle: !!config.google,\n hasApple: !!config.apple,\n hasEmail: !!config.email?.enabled,\n });\n}\n","import type { JWTData } from \"../types\";\n\n// ============================================\n// STORAGE ADAPTER INTERFACE\n// ============================================\n\n/**\n * Interface for custom storage adapters.\n * Implement this to use your own storage (Redux, Zustand, AsyncStorage, etc.)\n */\nexport interface StorageAdapter {\n getItem: (key: string) => Promise<string | null> | string | null;\n setItem: (key: string, value: string) => Promise<void> | void;\n removeItem: (key: string) => Promise<void> | void;\n}\n\n// ============================================\n// DEFAULT ADAPTERS\n// ============================================\n\n/**\n * Default localStorage adapter for web\n * Includes SSR safety checks for Next.js and other SSR frameworks\n */\nexport const localStorageAdapter: StorageAdapter = {\n getItem: (key) => {\n if (typeof window === \"undefined\") return null;\n return localStorage.getItem(key);\n },\n setItem: (key, value) => {\n if (typeof window === \"undefined\") return;\n localStorage.setItem(key, value);\n },\n removeItem: (key) => {\n if (typeof window === \"undefined\") return;\n localStorage.removeItem(key);\n },\n};\n\n/**\n * Memory adapter for SSR or testing\n */\nexport const memoryStorageAdapter = (): StorageAdapter => {\n const store = new Map<string, string>();\n return {\n getItem: (key) => store.get(key) ?? null,\n setItem: (key, value) => {\n store.set(key, value);\n },\n removeItem: (key) => {\n store.delete(key);\n },\n };\n};\n\n// ============================================\n// STORAGE SERVICE FACTORY\n// ============================================\n\nconst TOKEN_KEY = \"auth_token_data\";\n\n/**\n * Creates a storage service with the provided adapter.\n * Reusable token logic with pluggable storage backend.\n */\nexport function createStorageService(adapter: StorageAdapter) {\n return {\n /**\n * Save tokens to storage\n */\n async saveTokens(tokens: JWTData): Promise<void> {\n try {\n const dataToStore = {\n ...tokens,\n stored_at: Date.now(),\n };\n await adapter.setItem(TOKEN_KEY, JSON.stringify(dataToStore));\n console.log(\"[Auth Storage] Tokens saved successfully\");\n } catch (error) {\n console.error(\"[Auth Storage] Failed to save tokens:\", error);\n throw error;\n }\n },\n\n /**\n * Get tokens from storage\n * Returns null if no tokens exist or if they're invalid\n */\n async getTokens(): Promise<JWTData | null> {\n try {\n const data = await adapter.getItem(TOKEN_KEY);\n if (!data) {\n return null;\n }\n\n const parsed = JSON.parse(data);\n\n // Return tokens without the stored_at metadata\n const { stored_at: _storedAt, ...tokens } = parsed;\n\n return tokens as JWTData;\n } catch (error) {\n console.error(\"[Auth Storage] Failed to get tokens:\", error);\n // Clear corrupted data\n await this.clearTokens();\n return null;\n }\n },\n\n /**\n * Get raw stored data (including metadata like stored_at)\n */\n async getRawData(): Promise<{ tokens: JWTData; stored_at: number } | null> {\n try {\n const data = await adapter.getItem(TOKEN_KEY);\n if (!data) {\n return null;\n }\n const parsed = JSON.parse(data);\n\n // Data is stored as flat object: { ...tokens, stored_at }\n // Extract stored_at and return in expected format\n const { stored_at, ...tokens } = parsed;\n\n return { tokens: tokens as JWTData, stored_at };\n } catch (error) {\n console.error(\"[Auth Storage] Failed to get raw data:\", error);\n return null;\n }\n },\n\n /**\n * Clear tokens from storage\n */\n async clearTokens(): Promise<void> {\n try {\n await adapter.removeItem(TOKEN_KEY);\n console.log(\"[Auth Storage] Tokens cleared\");\n } catch (error) {\n console.error(\"[Auth Storage] Failed to clear tokens:\", error);\n }\n },\n\n /**\n * Check if tokens exist in storage\n */\n async hasTokens(): Promise<boolean> {\n const data = await adapter.getItem(TOKEN_KEY);\n return data !== null;\n },\n\n /**\n * Check if stored tokens are expired\n * Uses expires_in from the token data\n */\n async isTokenExpired(): Promise<boolean> {\n try {\n const rawData = await this.getRawData();\n if (!rawData) {\n return true;\n }\n\n const { stored_at, tokens } = rawData;\n const expiresIn = tokens.expires_in;\n\n if (!stored_at || !expiresIn) {\n return true;\n }\n\n // Check if current time is past expiration\n // expires_in is in seconds, so convert to milliseconds\n const expirationTime = stored_at + expiresIn * 1000;\n const isExpired = Date.now() >= expirationTime;\n\n if (isExpired) {\n console.log(\"[Auth Storage] Token is expired\");\n }\n\n return isExpired;\n } catch (error) {\n console.error(\n \"[Auth Storage] Failed to check token expiration:\",\n error\n );\n return true;\n }\n },\n\n /**\n * Get the time until token expires (in milliseconds)\n * Returns 0 if token is expired or doesn't exist\n */\n async getTimeUntilExpiry(): Promise<number> {\n try {\n const rawData = await this.getRawData();\n if (!rawData) {\n return 0;\n }\n\n const { stored_at, tokens } = rawData;\n const expiresIn = tokens.expires_in;\n\n if (!stored_at || !expiresIn) {\n return 0;\n }\n\n const expirationTime = stored_at + expiresIn * 1000;\n const timeRemaining = expirationTime - Date.now();\n\n return Math.max(0, timeRemaining);\n } catch (error) {\n console.error(\"[Auth Storage] Failed to get time until expiry:\", error);\n return 0;\n }\n },\n };\n}\n\n// ============================================\n// STORAGE SERVICE TYPE\n// ============================================\n\nexport type StorageService = ReturnType<typeof createStorageService>;\n\n// ============================================\n// DEFAULT INSTANCE (backwards compatible)\n// ============================================\n\n/**\n * Default storage service using localStorage.\n * For custom storage, use createStorageService(yourAdapter) instead.\n */\nexport const storageService = createStorageService(localStorageAdapter);\n","import React, {\n createContext,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n AuthConfig,\n AuthInternalContextValue,\n JWTData,\n} from \"../types\";\nimport { validateConfig } from \"../config\";\nimport { storageService } from \"../services/storageService\";\n\n// ============================================\n// CONTEXT\n// ============================================\n\n/**\n * Internal context - includes config and _setTokens for LoginPage\n */\nexport const AuthInternalContext =\n createContext<AuthInternalContextValue | null>(null);\n\n// ============================================\n// PROVIDER PROPS\n// ============================================\n\ninterface AuthProviderProps {\n children: React.ReactNode;\n /** Auth configuration with backend URL and provider settings */\n config: AuthConfig;\n /**\n * Called when user logs out or tokens are invalid on mount.\n * Use this to redirect, clear app state, etc.\n */\n onLogout?: () => void;\n}\n\n// ============================================\n// AUTH PROVIDER COMPONENT\n// ============================================\n\n/**\n * AuthProvider - Wraps your app to provide authentication state.\n *\n * @example\n * ```tsx\n * <AuthProvider\n * config={{\n * backendUrl: import.meta.env.VITE_AUTH_BACKEND_URL,\n * google: { clientId: import.meta.env.VITE_GOOGLE_CLIENT_ID },\n * apple: { clientId: import.meta.env.VITE_APPLE_CLIENT_ID },\n * }}\n * onLogout={() => router.push('/')}\n * >\n * <App />\n * </AuthProvider>\n * ```\n */\nexport function AuthProvider({\n children,\n config,\n onLogout,\n}: AuthProviderProps) {\n // ============================================\n // STATE\n // ============================================\n\n const [tokens, setTokens] = useState<JWTData | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [isAuthLoaded, setIsAuthLoaded] = useState(false);\n\n // Use ref for callback to avoid re-running effect when callback changes\n const onLogoutRef = useRef(onLogout);\n onLogoutRef.current = onLogout;\n\n // Track if initialization has run\n const hasInitialized = useRef(false);\n\n // ============================================\n // INITIALIZATION\n // ============================================\n\n useEffect(() => {\n // Only run initialization once\n if (hasInitialized.current) {\n return;\n }\n hasInitialized.current = true;\n\n // Validate config on mount\n validateConfig(config);\n\n // Load tokens from storage\n const initializeAuth = async () => {\n console.log(\"[AuthProvider] Initializing auth state\");\n\n try {\n // Check if we have stored tokens\n const storedTokens = await storageService.getTokens();\n\n if (storedTokens) {\n // Check if tokens are expired\n const isExpired = await storageService.isTokenExpired();\n\n if (isExpired) {\n console.log(\"[AuthProvider] Stored tokens are expired, clearing\");\n await storageService.clearTokens();\n onLogoutRef.current?.();\n } else {\n console.log(\"[AuthProvider] Valid tokens found, restoring session\");\n setTokens(storedTokens);\n }\n } else {\n console.log(\"[AuthProvider] No stored tokens found\");\n }\n } catch (error) {\n console.error(\"[AuthProvider] Error initializing auth:\", error);\n // Clear any corrupted data\n await storageService.clearTokens();\n } finally {\n setIsAuthLoaded(true);\n }\n };\n\n initializeAuth();\n }, [config]);\n\n // ============================================\n // INTERNAL: SET TOKENS (for LoginPage)\n // ============================================\n\n const _setTokens = useCallback(async (newTokens: JWTData) => {\n console.log(\"[AuthProvider] Setting tokens\");\n\n // Save to storage\n await storageService.saveTokens(newTokens);\n\n // Update state\n setTokens(newTokens);\n }, []);\n\n // ============================================\n // INTERNAL: SET LOADING (for LoginPage)\n // ============================================\n\n const _setLoading = useCallback((loading: boolean) => {\n setIsLoading(loading);\n }, []);\n\n // ============================================\n // LOGOUT\n // ============================================\n\n const logout = useCallback(async () => {\n console.log(\"[AuthProvider] Logging out\");\n\n // Clear storage\n await storageService.clearTokens();\n\n // Clear state\n setTokens(null);\n\n // Call callback\n onLogoutRef.current?.();\n }, []);\n\n // ============================================\n // CONTEXT VALUE\n // ============================================\n\n const contextValue = useMemo<AuthInternalContextValue>(\n () => ({\n // Public API\n tokens,\n logout,\n isLoading,\n isAuthLoaded,\n\n // Internal API (for LoginPage)\n config,\n _setTokens,\n _setLoading,\n }),\n [tokens, logout, isLoading, isAuthLoaded, config, _setTokens, _setLoading]\n );\n\n return (\n <AuthInternalContext.Provider value={contextValue}>\n {children}\n </AuthInternalContext.Provider>\n );\n}\n\n\n\n","import { useContext } from \"react\";\nimport { AuthInternalContext } from \"../components/AuthProvider\";\nimport type { AuthContextValue, AuthInternalContextValue } from \"../types\";\n\n// ============================================\n// PUBLIC HOOK\n// ============================================\n\n/**\n * useAuth - Public hook for consumers.\n * Returns only the public API (tokens, logout, isLoading, isAuthLoaded).\n *\n * @example\n * ```tsx\n * function App() {\n * const { tokens, logout, isLoading, isAuthLoaded } = useAuth();\n *\n * if (!isAuthLoaded) return <SplashScreen />;\n * if (!tokens) return <LoginPage />;\n * return <MainApp onLogout={logout} />;\n * }\n * ```\n */\nexport function useAuth(): AuthContextValue {\n const context = useContext(AuthInternalContext);\n\n if (!context) {\n throw new Error(\"useAuth must be used within an AuthProvider\");\n }\n\n // Return only public API\n return {\n tokens: context.tokens,\n logout: context.logout,\n isLoading: context.isLoading,\n isAuthLoaded: context.isAuthLoaded,\n };\n}\n\n// ============================================\n// INTERNAL HOOK (for LoginPage)\n// ============================================\n\n/**\n * useAuthInternal - Internal hook for LoginPage.\n * Returns the full internal API including config, _setTokens, _setLoading.\n *\n * @internal\n */\nexport function useAuthInternal(): AuthInternalContextValue {\n const context = useContext(AuthInternalContext);\n\n if (!context) {\n throw new Error(\"useAuthInternal must be used within an AuthProvider\");\n }\n\n return context;\n}\n\n\n\n","import type {\n AuthConfig,\n AuthProviderType,\n AuthResult,\n JWTData,\n TokenRequestParams,\n} from \"../types\";\n\n// ============================================\n// TOKEN EXCHANGE SERVICE\n// ============================================\n\n/**\n * Exchange provider credentials for JWT tokens from the backend.\n * @param params - Auth parameters (id_token, code, username/password)\n * @param provider - The auth provider type\n * @param config - Auth configuration with backendUrl\n */\nexport async function exchangeToken(\n params: TokenRequestParams,\n provider: AuthProviderType,\n config: AuthConfig\n): Promise<AuthResult> {\n console.log(`[Auth Token] Exchanging ${provider} credentials for tokens`);\n\n try {\n const bodyParams: Record<string, string> = {\n grant_type: provider,\n client_id: \"AevatarAuthServer\", // TODO: Make configurable via config\n scope: \"Aevatar offline_access\",\n };\n\n // Add source only for non-password providers (OAuth flows)\n if (provider == \"google\") {\n bodyParams.source = \"web\"; // works for google web.\n } else if (provider == \"apple\") {\n bodyParams.source = \"ios\";\n }\n\n // Add provider-specific app IDs (only for the active provider)\n if (provider === \"google\" && config.appId) {\n bodyParams.google_app_id = config.appId;\n }\n if (provider === \"apple\" && config.apple) {\n // Use apple.appId if set, otherwise fall back to clientId\n bodyParams.apple_app_id = config.apple.appId || config.apple.clientId;\n }\n\n // Add auth params (id_token, code, username, password, etc.)\n if (params.id_token) {\n bodyParams.id_token = params.id_token;\n }\n if (params.code) {\n bodyParams.code = params.code;\n }\n if (params.username) {\n bodyParams.username = params.username;\n }\n if (params.password) {\n bodyParams.password = params.password;\n }\n\n // Encode as form data\n const body = Object.entries(bodyParams)\n .map(([k, v]) => `${k}=${encodeURIComponent(v)}`)\n .join(\"&\");\n\n // Add timeout to prevent hanging requests\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 15000);\n\n const response = await fetch(`${config.backendUrl}/connect/token`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n // Handle error responses\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error(\n `[Auth Token] Exchange failed (${provider}):`,\n response.status,\n errorData\n );\n\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message:\n errorData.error_description ||\n errorData.error ||\n `HTTP ${response.status}: ${response.statusText}`,\n provider,\n };\n }\n\n // Parse successful response\n const tokens = (await response.json()) as JWTData;\n\n console.log(`[Auth Token] Exchange successful for ${provider}`);\n\n return {\n success: true,\n state: \"success\",\n tokens: {\n access_token: tokens.access_token,\n refresh_token: tokens.refresh_token,\n expires_in: tokens.expires_in,\n token_type: tokens.token_type,\n },\n message: \"Login successful\",\n provider,\n };\n } catch (error) {\n // Handle timeout\n const isTimeout = error instanceof Error && error.name === \"AbortError\";\n const errorMessage = isTimeout\n ? \"Request timed out. Please check your connection.\"\n : error instanceof Error\n ? error.message\n : \"Login failed\";\n\n console.error(`[Auth Token] Exchange error (${provider}):`, error);\n\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: errorMessage,\n provider,\n };\n }\n}\n\n// ============================================\n// TOKEN REFRESH SERVICE\n// ============================================\n\n/**\n * Refresh an expired access token using the refresh token.\n * @param refresh_token - The refresh token\n * @param backendUrl - The backend API URL\n */\nexport async function refreshToken(\n refresh_token: string,\n backendUrl: string\n): Promise<JWTData | null> {\n console.log(\"[Auth Token] Refreshing access token\");\n\n try {\n const body = new URLSearchParams({\n grant_type: \"refresh_token\",\n client_id: \"AevatarAuthServer\", // TODO: Make configurable\n refresh_token,\n }).toString();\n\n // Add timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 15000);\n\n const response = await fetch(`${backendUrl}/connect/token`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error(\"[Auth Token] Refresh failed:\", response.status, errorData);\n throw new Error(\n errorData.error_description || `Refresh failed: ${response.status}`\n );\n }\n\n const tokens = (await response.json()) as JWTData;\n\n console.log(\"[Auth Token] Refresh successful\");\n\n return {\n access_token: tokens.access_token,\n refresh_token: tokens.refresh_token,\n expires_in: tokens.expires_in,\n token_type: tokens.token_type,\n };\n } catch (error) {\n const isTimeout = error instanceof Error && error.name === \"AbortError\";\n console.error(\n \"[Auth Token] Refresh error:\",\n isTimeout ? \"Request timed out\" : error\n );\n return null;\n }\n}\n","import type { AuthConfig, AuthResult } from \"../types\";\nimport { exchangeToken } from \"../services/tokenService\";\n\n// ============================================\n// GOOGLE IDENTITY SERVICES TYPES\n// ============================================\n\ndeclare global {\n interface Window {\n google?: {\n accounts: {\n id: {\n initialize: (config: GoogleInitConfig) => void;\n prompt: (callback?: (notification: PromptNotification) => void) => void;\n renderButton: (element: HTMLElement, config: ButtonConfig) => void;\n revoke: (hint: string, callback: () => void) => void;\n cancel: () => void;\n };\n };\n };\n }\n}\n\ninterface GoogleInitConfig {\n client_id: string;\n callback: (response: GoogleCredentialResponse) => void;\n auto_select?: boolean;\n cancel_on_tap_outside?: boolean;\n context?: \"signin\" | \"signup\" | \"use\";\n ux_mode?: \"popup\" | \"redirect\";\n login_uri?: string;\n nonce?: string;\n use_fedcm_for_prompt?: boolean;\n}\n\ninterface GoogleCredentialResponse {\n credential: string; // JWT id_token\n select_by?: string;\n clientId?: string;\n}\n\ninterface PromptNotification {\n isNotDisplayed: () => boolean;\n isSkippedMoment: () => boolean;\n isDismissedMoment: () => boolean;\n getNotDisplayedReason: () => string;\n getSkippedReason: () => string;\n getDismissedReason: () => string;\n}\n\ninterface ButtonConfig {\n type?: \"standard\" | \"icon\";\n theme?: \"outline\" | \"filled_blue\" | \"filled_black\";\n size?: \"large\" | \"medium\" | \"small\";\n text?: \"signin_with\" | \"signup_with\" | \"continue_with\" | \"signin\";\n shape?: \"rectangular\" | \"pill\" | \"circle\" | \"square\";\n logo_alignment?: \"left\" | \"center\";\n width?: number;\n locale?: string;\n}\n\n// ============================================\n// STATE\n// ============================================\n\nlet googleSDKLoaded = false;\nlet googleSDKLoading: Promise<void> | null = null;\n\n// ============================================\n// SDK LOADER\n// ============================================\n\n/**\n * Load Google Identity Services SDK\n */\nexport function loadGoogleSDK(): Promise<void> {\n // Already loaded\n if (googleSDKLoaded && window.google?.accounts) {\n return Promise.resolve();\n }\n\n // Already loading\n if (googleSDKLoading) {\n return googleSDKLoading;\n }\n\n googleSDKLoading = new Promise((resolve, reject) => {\n // Check if already in DOM\n if (window.google?.accounts) {\n googleSDKLoaded = true;\n resolve();\n return;\n }\n\n console.log(\"[Auth Google] Loading Google Identity Services SDK\");\n\n const script = document.createElement(\"script\");\n script.src = \"https://accounts.google.com/gsi/client\";\n script.async = true;\n script.defer = true;\n\n script.onload = () => {\n console.log(\"[Auth Google] SDK loaded successfully\");\n googleSDKLoaded = true;\n resolve();\n };\n\n script.onerror = () => {\n console.error(\"[Auth Google] Failed to load SDK\");\n googleSDKLoading = null;\n reject(new Error(\"Failed to load Google Identity Services SDK\"));\n };\n\n document.head.appendChild(script);\n });\n\n return googleSDKLoading;\n}\n\n// ============================================\n// SIGN IN\n// ============================================\n\n/**\n * Sign in with Google using Google Identity Services.\n * Uses One Tap flow with popup fallback.\n *\n * @param config - Auth configuration with Google client ID\n * @returns AuthResult with tokens on success\n */\nexport async function signInWithGoogle(config: AuthConfig): Promise<AuthResult> {\n console.log(\"[Auth Google] Starting Google sign-in\");\n console.log(\"[Auth Google] Current origin:\", window.location.origin);\n\n // Validate config\n if (!config.google?.clientId) {\n console.error(\"[Auth Google] No client ID configured\");\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Google client ID not configured\",\n provider: \"google\",\n };\n }\n\n console.log(\"[Auth Google] Client ID:\", config.google.clientId.substring(0, 20) + \"...\");\n\n try {\n // Load SDK if not loaded\n console.log(\"[Auth Google] Loading SDK...\");\n await loadGoogleSDK();\n\n if (!window.google?.accounts) {\n throw new Error(\"Google SDK not available after loading\");\n }\n\n console.log(\"[Auth Google] SDK loaded, starting OAuth flow...\");\n\n // Use direct OAuth popup flow (more reliable than One Tap)\n return await signInWithGoogleRedirect(config);\n } catch (error) {\n console.error(\"[Auth Google] Sign-in error:\", error);\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: error instanceof Error ? error.message : \"Google login failed\",\n provider: \"google\",\n };\n }\n}\n\n/**\n * Sign in using OAuth popup flow\n */\nasync function signInWithGooglePopup(config: AuthConfig): Promise<AuthResult> {\n return new Promise((resolve) => {\n console.log(\"[Auth Google] Using popup flow\");\n\n // Generate nonce for security\n const nonce = Math.random().toString(36).substring(2, 15);\n\n // Initialize Google Sign-In\n window.google!.accounts.id.initialize({\n client_id: config.google!.clientId,\n callback: async (response: GoogleCredentialResponse) => {\n console.log(\"[Auth Google] Received credential response\");\n\n if (response.credential) {\n // Exchange id_token for our backend tokens\n const result = await exchangeToken(\n { id_token: response.credential },\n \"google\",\n config\n );\n resolve(result);\n } else {\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: \"No credential received from Google\",\n provider: \"google\",\n });\n }\n },\n auto_select: false,\n cancel_on_tap_outside: true,\n context: \"signin\",\n nonce,\n });\n\n // Show the One Tap prompt\n window.google!.accounts.id.prompt((notification: PromptNotification) => {\n if (notification.isNotDisplayed()) {\n const reason = notification.getNotDisplayedReason();\n console.log(\"[Auth Google] Prompt not displayed:\", reason);\n\n // Fall back to OAuth redirect if One Tap fails\n if (reason === \"opt_out_or_no_session\" || reason === \"suppressed_by_user\") {\n console.log(\"[Auth Google] Falling back to OAuth redirect\");\n signInWithGoogleRedirect(config).then(resolve);\n } else {\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: `Google Sign-In not available: ${reason}`,\n provider: \"google\",\n });\n }\n } else if (notification.isSkippedMoment()) {\n const reason = notification.getSkippedReason();\n console.log(\"[Auth Google] Prompt skipped:\", reason);\n resolve({\n success: false,\n state: \"cancelled\",\n tokens: null,\n message: \"Google Sign-In was skipped\",\n provider: \"google\",\n });\n } else if (notification.isDismissedMoment()) {\n const reason = notification.getDismissedReason();\n console.log(\"[Auth Google] Prompt dismissed:\", reason);\n\n if (reason === \"credential_returned\") {\n // Success - callback will handle this\n return;\n }\n\n resolve({\n success: false,\n state: \"cancelled\",\n tokens: null,\n message: \"Google Sign-In was cancelled\",\n provider: \"google\",\n });\n }\n });\n });\n}\n\n/**\n * Fallback: Sign in using OAuth redirect flow\n */\nasync function signInWithGoogleRedirect(config: AuthConfig): Promise<AuthResult> {\n return new Promise((resolve) => {\n const clientId = config.google!.clientId;\n const redirectUri = window.location.origin;\n const nonce = Math.random().toString(36).substring(2, 15);\n\n console.log(\"[Auth Google] OAuth redirect flow:\");\n console.log(\" - Client ID:\", clientId);\n console.log(\" - Redirect URI:\", redirectUri);\n console.log(\" ⚠️ Make sure this redirect URI is added to Google Cloud Console!\");\n\n const params = new URLSearchParams({\n client_id: clientId,\n redirect_uri: redirectUri,\n response_type: \"id_token\",\n scope: \"openid email profile\",\n nonce,\n prompt: \"select_account\",\n });\n\n const authUrl = `https://accounts.google.com/o/oauth2/v2/auth?${params}`;\n console.log(\"[Auth Google] Auth URL:\", authUrl);\n\n // Open popup\n const width = 500;\n const height = 600;\n const left = window.screenX + (window.outerWidth - width) / 2;\n const top = window.screenY + (window.outerHeight - height) / 2;\n\n const popup = window.open(\n authUrl,\n \"google-auth\",\n `width=${width},height=${height},left=${left},top=${top}`\n );\n\n if (!popup) {\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Popup was blocked. Please allow popups for this site.\",\n provider: \"google\",\n });\n return;\n }\n\n // Poll for popup close or redirect\n const pollInterval = setInterval(() => {\n try {\n // Check if popup was closed\n if (popup.closed) {\n clearInterval(pollInterval);\n resolve({\n success: false,\n state: \"cancelled\",\n tokens: null,\n message: \"Google Sign-In was cancelled\",\n provider: \"google\",\n });\n return;\n }\n\n // Try to read URL (will fail while on Google's domain)\n const url = popup.location.href;\n\n // Check if redirected back to our origin\n if (url.startsWith(redirectUri)) {\n clearInterval(pollInterval);\n popup.close();\n\n // Parse the hash fragment\n const hash = new URL(url.replace(\"#\", \"?\")).searchParams;\n const idToken = hash.get(\"id_token\");\n const error = hash.get(\"error\");\n\n if (error) {\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: hash.get(\"error_description\") || error,\n provider: \"google\",\n });\n return;\n }\n\n if (idToken) {\n // Exchange id_token for our backend tokens\n exchangeToken({ id_token: idToken }, \"google\", config).then(resolve);\n } else {\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: \"No token received from Google\",\n provider: \"google\",\n });\n }\n }\n } catch {\n // Cross-origin error - popup still on Google's domain, keep polling\n }\n }, 500);\n\n // Timeout after 5 minutes\n setTimeout(() => {\n clearInterval(pollInterval);\n if (!popup.closed) {\n popup.close();\n }\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Google Sign-In timed out\",\n provider: \"google\",\n });\n }, 5 * 60 * 1000);\n });\n}\n\n","import type { AuthConfig, AuthResult } from \"../types\";\nimport { exchangeToken } from \"../services/tokenService\";\n\n// ============================================\n// APPLE SIGN IN JS TYPES\n// ============================================\n\ndeclare global {\n interface Window {\n AppleID?: {\n auth: {\n init: (config: AppleInitConfig) => void;\n signIn: (config?: AppleSignInConfig) => Promise<AppleSignInResponse>;\n };\n };\n }\n}\n\ninterface AppleInitConfig {\n clientId: string;\n scope?: string;\n redirectURI: string;\n state?: string;\n nonce?: string;\n usePopup?: boolean;\n}\n\ninterface AppleSignInConfig {\n scope?: string;\n state?: string;\n nonce?: string;\n}\n\ninterface AppleSignInResponse {\n authorization: {\n code: string;\n id_token?: string;\n state?: string;\n };\n user?: {\n email?: string;\n name?: {\n firstName?: string;\n lastName?: string;\n };\n };\n}\n\ninterface AppleSignInError {\n error: string;\n}\n\n// ============================================\n// STATE\n// ============================================\n\nlet appleSDKLoaded = false;\nlet appleSDKLoading: Promise<void> | null = null;\nlet appleInitialized = false;\n\n// ============================================\n// SDK LOADER\n// ============================================\n\n/**\n * Load Apple Sign In JS SDK\n */\nexport function loadAppleSDK(): Promise<void> {\n // Already loaded\n if (appleSDKLoaded && window.AppleID) {\n return Promise.resolve();\n }\n\n // Already loading\n if (appleSDKLoading) {\n return appleSDKLoading;\n }\n\n appleSDKLoading = new Promise((resolve, reject) => {\n // Check if already in DOM\n if (window.AppleID) {\n appleSDKLoaded = true;\n resolve();\n return;\n }\n\n console.log(\"[Auth Apple] Loading Apple Sign In JS SDK\");\n\n const script = document.createElement(\"script\");\n script.src =\n \"https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js\";\n script.async = true;\n\n script.onload = () => {\n console.log(\"[Auth Apple] SDK loaded successfully\");\n appleSDKLoaded = true;\n resolve();\n };\n\n script.onerror = () => {\n console.error(\"[Auth Apple] Failed to load SDK\");\n appleSDKLoading = null;\n reject(new Error(\"Failed to load Apple Sign In JS SDK\"));\n };\n\n document.head.appendChild(script);\n });\n\n return appleSDKLoading;\n}\n\n// ============================================\n// INITIALIZE\n// ============================================\n\n/**\n * Initialize Apple Sign In with configuration\n */\nfunction initializeApple(config: AuthConfig): void {\n if (appleInitialized || !window.AppleID || !config.apple) {\n return;\n }\n\n // For localhost testing, always use current origin\n // Apple requires exact domain matching\n const isLocalhost = window.location.hostname === \"localhost\" || \n window.location.hostname === \"127.0.0.1\";\n const redirectUri = isLocalhost \n ? window.location.origin \n : (config.apple.redirectUri || window.location.origin);\n\n console.log(\"[Auth Apple] Initializing with config:\", {\n clientId: config.apple.clientId,\n redirectUri,\n isLocalhost,\n currentOrigin: window.location.origin,\n });\n\n window.AppleID.auth.init({\n clientId: config.apple.clientId,\n scope: \"name email\",\n redirectURI: redirectUri,\n usePopup: true,\n });\n\n appleInitialized = true;\n}\n\n// ============================================\n// SIGN IN\n// ============================================\n\n/**\n * Sign in with Apple using Apple Sign In JS.\n *\n * @param config - Auth configuration with Apple client ID\n * @returns AuthResult with tokens on success\n */\nexport async function signInWithApple(config: AuthConfig): Promise<AuthResult> {\n console.log(\"[Auth Apple] Starting Apple sign-in\");\n\n // Validate config\n if (!config.apple?.clientId) {\n console.error(\"[Auth Apple] No client ID configured\");\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Apple client ID not configured\",\n provider: \"apple\",\n };\n }\n\n // Check if running on localhost - warn about Apple limitations\n const isLocalhost = window.location.hostname === \"localhost\" || \n window.location.hostname === \"127.0.0.1\";\n if (isLocalhost) {\n console.warn(\"[Auth Apple] Running on localhost - Apple Sign In requires:\");\n console.warn(\" 1. Your Service ID (com.gpt.godweb) must have localhost configured in Apple Developer Portal\");\n console.warn(\" 2. Return URL must include: http://localhost:5173 (or your port)\");\n }\n\n try {\n // Load SDK if not loaded\n console.log(\"[Auth Apple] Loading SDK...\");\n await loadAppleSDK();\n\n if (!window.AppleID) {\n throw new Error(\"Apple SDK not available after loading\");\n }\n\n // Reset initialization to ensure fresh config\n appleInitialized = false;\n \n // Initialize Apple Sign In\n initializeApple(config);\n\n console.log(\"[Auth Apple] Calling Apple signIn...\");\n\n // Attempt sign in\n const response = await window.AppleID.auth.signIn();\n\n console.log(\"[Auth Apple] Received response\");\n\n // Apple returns authorization.code for web\n const code = response.authorization?.code;\n const idToken = response.authorization?.id_token;\n\n if (code) {\n console.log(\"[Auth Apple] Exchanging authorization code\");\n return await exchangeToken({ code }, \"apple\", config);\n } else if (idToken) {\n console.log(\"[Auth Apple] Exchanging id_token\");\n return await exchangeToken({ id_token: idToken }, \"apple\", config);\n } else {\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"No authorization code or token received from Apple\",\n provider: \"apple\",\n };\n }\n } catch (error) {\n // Apple throws specific errors\n const appleError = error as AppleSignInError;\n\n // User cancelled\n if (\n appleError?.error === \"popup_closed_by_user\" ||\n appleError?.error === \"user_cancelled_authorize\"\n ) {\n console.log(\"[Auth Apple] Sign-in cancelled by user\");\n return {\n success: false,\n state: \"cancelled\",\n tokens: null,\n message: \"Apple Sign-In was cancelled\",\n provider: \"apple\",\n };\n }\n\n console.error(\"[Auth Apple] Sign-in error:\", error);\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message:\n appleError?.error ||\n (error instanceof Error ? error.message : \"Apple login failed\"),\n provider: \"apple\",\n };\n }\n}\n\n","import type { AuthConfig, AuthResult } from \"../types\";\nimport { exchangeToken } from \"../services/tokenService\";\n\n// ============================================\n// EMAIL SIGN-IN STRATEGY\n// ============================================\n\n/**\n * Sign in with email and password.\n * Sends credentials to backend for authentication.\n *\n * @param email - User's email address\n * @param password - User's password\n * @param config - Auth configuration with backendUrl\n * @returns AuthResult with tokens on success\n */\nexport async function signInWithEmail(\n email: string,\n password: string,\n config: AuthConfig\n): Promise<AuthResult> {\n console.log(\"[Auth Email] Starting email sign-in\");\n\n // Validate inputs\n if (!email || !email.trim()) {\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Email is required\",\n provider: \"password\",\n };\n }\n\n if (!password) {\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Password is required\",\n provider: \"password\",\n };\n }\n\n // Basic email format validation\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(email.trim())) {\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Please enter a valid email address\",\n provider: \"password\",\n };\n }\n\n try {\n // Exchange credentials for tokens\n // Note: grant_type is \"password\" for email/password auth (OAuth2 standard)\n const result = await exchangeToken(\n {\n username: email.trim(),\n password,\n },\n \"password\",\n config\n );\n\n if (result.success) {\n console.log(\"[Auth Email] Sign-in successful\");\n } else {\n console.log(\"[Auth Email] Sign-in failed:\", result.message);\n }\n\n return result;\n } catch (error) {\n console.error(\"[Auth Email] Sign-in error:\", error);\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: error instanceof Error ? error.message : \"Email login failed\",\n provider: \"password\",\n };\n }\n}\n\n","import React, { useState } from \"react\";\nimport { useAuthInternal } from \"../hooks/useAuth\";\nimport { signInWithGoogle } from \"../strategies/google\";\nimport { signInWithApple } from \"../strategies/apple\";\nimport { signInWithEmail } from \"../strategies/email\";\n\n// ============================================\n// ICONS\n// ============================================\n\nconst GoogleIcon = () => (\n <svg className=\"w-5 h-5\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z\"\n fill=\"#4285F4\"\n />\n <path\n d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"\n fill=\"#34A853\"\n />\n <path\n d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\"\n fill=\"#FBBC05\"\n />\n <path\n d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"\n fill=\"#EA4335\"\n />\n </svg>\n);\n\nconst AppleIcon = () => (\n <svg className=\"w-5 h-5\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.48-3.24 0-1.44.62-2.2.44-3.06-.4C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09l.01-.01zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z\" />\n </svg>\n);\n\nconst LoadingSpinner = () => (\n <svg\n className=\"animate-spin h-5 w-5\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n);\n\n// ============================================\n// BUTTON COMPONENT\n// ============================================\n\ninterface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: \"primary\" | \"secondary\";\n isLoading?: boolean;\n children: React.ReactNode;\n}\n\nconst Button: React.FC<ButtonProps> = ({\n variant = \"primary\",\n isLoading = false,\n disabled,\n children,\n className = \"\",\n ...props\n}) => {\n const baseClasses =\n \"min-h-[52px] px-6 rounded-[99px] font-semibold text-base transition-all duration-200 flex items-center justify-center gap-2 focus:outline-none\";\n\n const variantClasses = {\n primary: \"bg-black text-white active:opacity-80 active:scale-[0.98]\",\n secondary:\n \"bg-white text-black border border-black active:opacity-80 active:scale-[0.98]\",\n };\n\n const disabledClasses = \"opacity-40 cursor-not-allowed pointer-events-none\";\n\n return (\n <button\n className={`${baseClasses} ${variantClasses[variant]} ${\n disabled || isLoading ? disabledClasses : \"\"\n } ${className}`}\n disabled={disabled || isLoading}\n {...props}\n >\n {isLoading ? (\n <>\n <LoadingSpinner />\n <span>Loading...</span>\n </>\n ) : (\n children\n )}\n </button>\n );\n};\n\n// ============================================\n// INPUT COMPONENT\n// ============================================\n\ninterface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n label?: string;\n error?: string;\n}\n\nconst Input: React.FC<InputProps> = ({\n label,\n error,\n className = \"\",\n ...props\n}) => {\n return (\n <div className=\"space-y-1\">\n {label && (\n <label className=\"block text-sm font-medium text-gray-700\">\n {label}\n </label>\n )}\n <input\n className={`w-full px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-black focus:border-transparent ${\n error ? \"border-red-500\" : \"border-gray-300\"\n } ${className}`}\n {...props}\n />\n {error && <p className=\"text-sm text-red-500\">{error}</p>}\n </div>\n );\n};\n\n// ============================================\n// LOGIN PAGE VIEWS\n// ============================================\n\ntype View = \"main\" | \"email\";\n\n// ============================================\n// LOGIN PAGE COMPONENT\n// ============================================\n\n/**\n * LoginPage - Complete login UI component.\n * Gets config from AuthProvider context.\n * Handles Google, Apple, and Email sign-in.\n *\n * @example\n * ```tsx\n * function App() {\n * const { tokens, isAuthLoaded } = useAuth();\n *\n * if (!isAuthLoaded) return <SplashScreen />;\n * if (!tokens) return <LoginPage />;\n * return <MainApp />;\n * }\n * ```\n */\nexport function LoginPage() {\n const { config, _setTokens, _setLoading, isLoading } = useAuthInternal();\n\n const [view, setView] = useState<View>(\"main\");\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n const [fieldErrors, setFieldErrors] = useState<{\n email?: string;\n password?: string;\n }>({});\n\n // ============================================\n // HANDLERS\n // ============================================\n\n const handleGoogleLogin = async () => {\n if (!config.google) {\n setError(\"Google sign-in is not configured\");\n return;\n }\n\n setError(null);\n _setLoading(true);\n\n try {\n const result = await signInWithGoogle(config);\n\n if (result.success && result.tokens) {\n await _setTokens(result.tokens);\n } else if (result.state !== \"cancelled\") {\n setError(result.message || \"Google sign-in failed\");\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Google sign-in failed\");\n } finally {\n _setLoading(false);\n }\n };\n\n const handleAppleLogin = async () => {\n if (!config.apple) {\n setError(\"Apple sign-in is not configured\");\n return;\n }\n\n setError(null);\n _setLoading(true);\n\n try {\n const result = await signInWithApple(config);\n\n if (result.success && result.tokens) {\n await _setTokens(result.tokens);\n } else if (result.state !== \"cancelled\") {\n setError(result.message || \"Apple sign-in failed\");\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Apple sign-in failed\");\n } finally {\n _setLoading(false);\n }\n };\n\n const handleEmailLogin = async (e: React.FormEvent) => {\n e.preventDefault();\n\n // Validate\n const errors: { email?: string; password?: string } = {};\n if (!email.trim()) {\n errors.email = \"Email is required\";\n }\n if (!password) {\n errors.password = \"Password is required\";\n }\n\n if (Object.keys(errors).length > 0) {\n setFieldErrors(errors);\n return;\n }\n\n setError(null);\n setFieldErrors({});\n _setLoading(true);\n\n try {\n const result = await signInWithEmail(email, password, config);\n\n if (result.success && result.tokens) {\n await _setTokens(result.tokens);\n } else {\n setError(result.message || \"Email sign-in failed\");\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Email sign-in failed\");\n } finally {\n _setLoading(false);\n }\n };\n\n // ============================================\n // EMAIL VIEW\n // ============================================\n\n if (view === \"email\") {\n return (\n <div className=\"min-h-screen bg-white flex flex-col px-5 py-8\">\n <div className=\"flex-1 flex flex-col max-w-md mx-auto w-full\">\n {/* Back Button */}\n <button\n onClick={() => {\n setView(\"main\");\n setError(null);\n setFieldErrors({});\n }}\n className=\"self-start mb-8 flex items-center text-gray-600 active:opacity-80\"\n >\n <svg\n className=\"w-5 h-5 mr-2\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 19l-7-7 7-7\"\n />\n </svg>\n Back\n </button>\n\n {/* Header */}\n <div className=\"mb-12 text-center\">\n <h1 className=\"text-[30px] font-bold text-black mb-2\">Sign In</h1>\n <p className=\"text-base text-gray-600\">\n Enter your email and password\n </p>\n </div>\n\n {/* Error Message */}\n {error && (\n <div className=\"mb-6 p-4 bg-red-50 border border-red-200 rounded-lg\">\n <p className=\"text-sm text-red-600\">{error}</p>\n </div>\n )}\n\n {/* Email Form */}\n <form onSubmit={handleEmailLogin} className=\"space-y-6\">\n <Input\n type=\"email\"\n label=\"Email\"\n placeholder=\"Enter your email\"\n value={email}\n onChange={(e) => {\n setEmail(e.target.value);\n if (fieldErrors.email)\n setFieldErrors({ ...fieldErrors, email: undefined });\n }}\n error={fieldErrors.email}\n autoComplete=\"email\"\n />\n\n <Input\n type=\"password\"\n label=\"Password\"\n placeholder=\"Enter your password\"\n value={password}\n onChange={(e) => {\n setPassword(e.target.value);\n if (fieldErrors.password)\n setFieldErrors({ ...fieldErrors, password: undefined });\n }}\n error={fieldErrors.password}\n autoComplete=\"current-password\"\n />\n\n <Button\n type=\"submit\"\n variant=\"primary\"\n isLoading={isLoading}\n className=\"w-full mt-8\"\n >\n Sign In\n </Button>\n </form>\n </div>\n </div>\n );\n }\n\n // ============================================\n // MAIN VIEW\n // ============================================\n\n return (\n <div className=\"min-h-screen bg-white flex flex-col px-5 py-8\">\n <div className=\"flex-1 flex flex-col justify-center max-w-md mx-auto w-full\">\n {/* Header */}\n <div className=\"mb-12 text-center\">\n <h1 className=\"text-[30px] font-bold text-black mb-2\">\n Welcome Back\n </h1>\n <p className=\"text-base text-gray-600\">Sign in to continue</p>\n </div>\n\n {/* Error Message */}\n {error && (\n <div className=\"mb-6 p-4 bg-red-50 border border-red-200 rounded-lg\">\n <p className=\"text-sm text-red-600\">{error}</p>\n </div>\n )}\n\n {/* Social Login Buttons */}\n <div className=\"space-y-3 mb-8\">\n {config.google && (\n <Button\n variant=\"secondary\"\n onClick={handleGoogleLogin}\n disabled={isLoading}\n className=\"w-full\"\n >\n <GoogleIcon />\n Continue with Google\n </Button>\n )}\n\n {config.apple && (\n <Button\n variant=\"secondary\"\n onClick={handleAppleLogin}\n disabled={isLoading}\n className=\"w-full\"\n >\n <AppleIcon />\n Continue with Apple\n </Button>\n )}\n </div>\n\n {/* Divider */}\n {config.email?.enabled && (config.google || config.apple) && (\n <div className=\"relative mb-8\">\n <div className=\"absolute inset-0 flex items-center\">\n <div className=\"w-full border-t border-gray-300\"></div>\n </div>\n <div className=\"relative flex justify-center text-sm\">\n <span className=\"px-4 bg-white text-gray-500\">\n Or continue with email\n </span>\n </div>\n </div>\n )}\n\n {/* Email Login Button */}\n {config.email?.enabled && (\n <Button\n variant=\"primary\"\n onClick={() => setView(\"email\")}\n disabled={isLoading}\n className=\"w-full\"\n >\n Continue with Email\n </Button>\n )}\n </div>\n\n {/* Disclaimer */}\n <div className=\"pb-[36px] px-5\">\n <p className=\"text-xs text-gray-500 text-center leading-relaxed max-w-sm mx-auto\">\n By signing in, you agree to our{\" \"}\n <a\n href=\"https://app.godgpt.fun/terms-of-service/\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-gray-700 underline underline-offset-2 hover:text-gray-900\"\n >\n Terms of Service\n </a>{\" \"}\n and{\" \"}\n <a\n href=\"https://app.godgpt.fun/privacy-policy/\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-gray-700 underline underline-offset-2 hover:text-gray-900\"\n >\n Privacy Policy\n </a>\n .\n </p>\n </div>\n </div>\n );\n}\n\n\n\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/auth/config.ts","../src/auth/services/storageService.ts","../src/auth/components/AuthProvider.tsx","../src/auth/hooks/useAuth.ts","../src/auth/services/tokenService.ts","../src/auth/strategies/google.ts","../src/auth/strategies/apple.ts","../src/auth/strategies/email.ts","../src/auth/components/LoginPage.tsx"],"names":["createContext","useState","useRef","useEffect","useCallback","useMemo","useContext","jsxs","jsx","Fragment"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { AuthConfig } from \"./types\";\n\n// ============================================\n// CONFIGURATION VALIDATION\n// ============================================\n\n/**\n * Validate auth configuration.\n * Called by AuthProvider on mount.\n */\nexport function validateConfig(config: AuthConfig): void {\n if (!config.backendUrl) {\n throw new Error(\"[Auth] backendUrl is required in AuthConfig\");\n }\n\n if (!config.google && !config.apple && !config.email?.enabled) {\n console.warn(\n \"[Auth] No auth strategies configured. Enable at least one: google, apple, or email.\"\n );\n }\n\n // Validate Google config\n if (config.google && !config.google.clientId) {\n throw new Error(\"[Auth] google.clientId is required when google is enabled\");\n }\n\n // Validate Apple config\n if (config.apple && !config.apple.clientId) {\n throw new Error(\"[Auth] apple.clientId is required when apple is enabled\");\n }\n\n console.log(\"[Auth] Config validated:\", {\n backendUrl: config.backendUrl,\n hasGoogle: !!config.google,\n hasApple: !!config.apple,\n hasEmail: !!config.email?.enabled,\n });\n}\n","import type { JWTData } from \"../types\";\n\n// ============================================\n// STORAGE ADAPTER INTERFACE\n// ============================================\n\n/**\n * Interface for custom storage adapters.\n * Implement this to use your own storage (Redux, Zustand, AsyncStorage, etc.)\n */\nexport interface StorageAdapter {\n getItem: (key: string) => Promise<string | null> | string | null;\n setItem: (key: string, value: string) => Promise<void> | void;\n removeItem: (key: string) => Promise<void> | void;\n}\n\n// ============================================\n// DEFAULT ADAPTERS\n// ============================================\n\n/**\n * Default localStorage adapter for web\n * Includes SSR safety checks for Next.js and other SSR frameworks\n */\nexport const localStorageAdapter: StorageAdapter = {\n getItem: (key) => {\n if (typeof window === \"undefined\") return null;\n return localStorage.getItem(key);\n },\n setItem: (key, value) => {\n if (typeof window === \"undefined\") return;\n localStorage.setItem(key, value);\n },\n removeItem: (key) => {\n if (typeof window === \"undefined\") return;\n localStorage.removeItem(key);\n },\n};\n\n/**\n * Memory adapter for SSR or testing\n */\nexport const memoryStorageAdapter = (): StorageAdapter => {\n const store = new Map<string, string>();\n return {\n getItem: (key) => store.get(key) ?? null,\n setItem: (key, value) => {\n store.set(key, value);\n },\n removeItem: (key) => {\n store.delete(key);\n },\n };\n};\n\n// ============================================\n// STORAGE SERVICE FACTORY\n// ============================================\n\nconst TOKEN_KEY = \"auth_token_data\";\n\n/**\n * Creates a storage service with the provided adapter.\n * Reusable token logic with pluggable storage backend.\n */\nexport function createStorageService(adapter: StorageAdapter) {\n return {\n /**\n * Save tokens to storage\n */\n async saveTokens(tokens: JWTData): Promise<void> {\n try {\n const dataToStore = {\n ...tokens,\n stored_at: Date.now(),\n };\n await adapter.setItem(TOKEN_KEY, JSON.stringify(dataToStore));\n console.log(\"[Auth Storage] Tokens saved successfully\");\n } catch (error) {\n console.error(\"[Auth Storage] Failed to save tokens:\", error);\n throw error;\n }\n },\n\n /**\n * Get tokens from storage\n * Returns null if no tokens exist or if they're invalid\n */\n async getTokens(): Promise<JWTData | null> {\n try {\n const data = await adapter.getItem(TOKEN_KEY);\n if (!data) {\n return null;\n }\n\n const parsed = JSON.parse(data);\n\n // Return tokens without the stored_at metadata\n const { stored_at: _storedAt, ...tokens } = parsed;\n\n return tokens as JWTData;\n } catch (error) {\n console.error(\"[Auth Storage] Failed to get tokens:\", error);\n // Clear corrupted data\n await this.clearTokens();\n return null;\n }\n },\n\n /**\n * Get raw stored data (including metadata like stored_at)\n */\n async getRawData(): Promise<{ tokens: JWTData; stored_at: number } | null> {\n try {\n const data = await adapter.getItem(TOKEN_KEY);\n if (!data) {\n return null;\n }\n const parsed = JSON.parse(data);\n\n // Data is stored as flat object: { ...tokens, stored_at }\n // Extract stored_at and return in expected format\n const { stored_at, ...tokens } = parsed;\n\n return { tokens: tokens as JWTData, stored_at };\n } catch (error) {\n console.error(\"[Auth Storage] Failed to get raw data:\", error);\n return null;\n }\n },\n\n /**\n * Clear tokens from storage\n */\n async clearTokens(): Promise<void> {\n try {\n await adapter.removeItem(TOKEN_KEY);\n console.log(\"[Auth Storage] Tokens cleared\");\n } catch (error) {\n console.error(\"[Auth Storage] Failed to clear tokens:\", error);\n }\n },\n\n /**\n * Check if tokens exist in storage\n */\n async hasTokens(): Promise<boolean> {\n const data = await adapter.getItem(TOKEN_KEY);\n return data !== null;\n },\n\n /**\n * Check if stored tokens are expired\n * Uses expires_in from the token data\n */\n async isTokenExpired(): Promise<boolean> {\n try {\n const rawData = await this.getRawData();\n if (!rawData) {\n return true;\n }\n\n const { stored_at, tokens } = rawData;\n const expiresIn = tokens.expires_in;\n\n if (!stored_at || !expiresIn) {\n return true;\n }\n\n // Check if current time is past expiration\n // expires_in is in seconds, so convert to milliseconds\n const expirationTime = stored_at + expiresIn * 1000;\n const isExpired = Date.now() >= expirationTime;\n\n if (isExpired) {\n console.log(\"[Auth Storage] Token is expired\");\n }\n\n return isExpired;\n } catch (error) {\n console.error(\n \"[Auth Storage] Failed to check token expiration:\",\n error\n );\n return true;\n }\n },\n\n /**\n * Get the time until token expires (in milliseconds)\n * Returns 0 if token is expired or doesn't exist\n */\n async getTimeUntilExpiry(): Promise<number> {\n try {\n const rawData = await this.getRawData();\n if (!rawData) {\n return 0;\n }\n\n const { stored_at, tokens } = rawData;\n const expiresIn = tokens.expires_in;\n\n if (!stored_at || !expiresIn) {\n return 0;\n }\n\n const expirationTime = stored_at + expiresIn * 1000;\n const timeRemaining = expirationTime - Date.now();\n\n return Math.max(0, timeRemaining);\n } catch (error) {\n console.error(\"[Auth Storage] Failed to get time until expiry:\", error);\n return 0;\n }\n },\n };\n}\n\n// ============================================\n// STORAGE SERVICE TYPE\n// ============================================\n\nexport type StorageService = ReturnType<typeof createStorageService>;\n\n// ============================================\n// DEFAULT INSTANCE (backwards compatible)\n// ============================================\n\n/**\n * Default storage service using localStorage.\n * For custom storage, use createStorageService(yourAdapter) instead.\n */\nexport const storageService = createStorageService(localStorageAdapter);\n","import React, {\n createContext,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n AuthConfig,\n AuthInternalContextValue,\n JWTData,\n} from \"../types\";\nimport { validateConfig } from \"../config\";\nimport { storageService } from \"../services/storageService\";\n\n// ============================================\n// CONTEXT\n// ============================================\n\n/**\n * Internal context - includes config and _setTokens for LoginPage\n */\nexport const AuthInternalContext =\n createContext<AuthInternalContextValue | null>(null);\n\n// ============================================\n// PROVIDER PROPS\n// ============================================\n\ninterface AuthProviderProps {\n children: React.ReactNode;\n /** Auth configuration with backend URL and provider settings */\n config: AuthConfig;\n /**\n * Called when user logs out or tokens are invalid on mount.\n * Use this to redirect, clear app state, etc.\n */\n onLogout?: () => void;\n}\n\n// ============================================\n// AUTH PROVIDER COMPONENT\n// ============================================\n\n/**\n * AuthProvider - Wraps your app to provide authentication state.\n *\n * @example\n * ```tsx\n * <AuthProvider\n * config={{\n * backendUrl: import.meta.env.VITE_AUTH_BACKEND_URL,\n * google: { clientId: import.meta.env.VITE_GOOGLE_CLIENT_ID },\n * apple: { clientId: import.meta.env.VITE_APPLE_CLIENT_ID },\n * }}\n * onLogout={() => router.push('/')}\n * >\n * <App />\n * </AuthProvider>\n * ```\n */\nexport function AuthProvider({\n children,\n config,\n onLogout,\n}: AuthProviderProps) {\n // ============================================\n // STATE\n // ============================================\n\n const [tokens, setTokens] = useState<JWTData | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [isAuthLoaded, setIsAuthLoaded] = useState(false);\n\n // Use ref for callback to avoid re-running effect when callback changes\n const onLogoutRef = useRef(onLogout);\n onLogoutRef.current = onLogout;\n\n // Track if initialization has run\n const hasInitialized = useRef(false);\n\n // ============================================\n // INITIALIZATION\n // ============================================\n\n useEffect(() => {\n // Only run initialization once\n if (hasInitialized.current) {\n return;\n }\n hasInitialized.current = true;\n\n // Validate config on mount\n validateConfig(config);\n\n // Load tokens from storage\n const initializeAuth = async () => {\n console.log(\"[AuthProvider] Initializing auth state\");\n\n try {\n // Check if we have stored tokens\n const storedTokens = await storageService.getTokens();\n\n if (storedTokens) {\n // Check if tokens are expired\n const isExpired = await storageService.isTokenExpired();\n\n if (isExpired) {\n console.log(\"[AuthProvider] Stored tokens are expired, clearing\");\n await storageService.clearTokens();\n onLogoutRef.current?.();\n } else {\n console.log(\"[AuthProvider] Valid tokens found, restoring session\");\n setTokens(storedTokens);\n }\n } else {\n console.log(\"[AuthProvider] No stored tokens found\");\n }\n } catch (error) {\n console.error(\"[AuthProvider] Error initializing auth:\", error);\n // Clear any corrupted data\n await storageService.clearTokens();\n } finally {\n setIsAuthLoaded(true);\n }\n };\n\n initializeAuth();\n }, [config]);\n\n // ============================================\n // INTERNAL: SET TOKENS (for LoginPage)\n // ============================================\n\n const _setTokens = useCallback(async (newTokens: JWTData) => {\n console.log(\"[AuthProvider] Setting tokens\");\n\n // Save to storage\n await storageService.saveTokens(newTokens);\n\n // Update state\n setTokens(newTokens);\n }, []);\n\n // ============================================\n // INTERNAL: SET LOADING (for LoginPage)\n // ============================================\n\n const _setLoading = useCallback((loading: boolean) => {\n setIsLoading(loading);\n }, []);\n\n // ============================================\n // LOGOUT\n // ============================================\n\n const logout = useCallback(async () => {\n console.log(\"[AuthProvider] Logging out\");\n\n // Clear storage\n await storageService.clearTokens();\n\n // Clear state\n setTokens(null);\n\n // Call callback\n onLogoutRef.current?.();\n }, []);\n\n // ============================================\n // CONTEXT VALUE\n // ============================================\n\n const contextValue = useMemo<AuthInternalContextValue>(\n () => ({\n // Public API\n tokens,\n logout,\n isLoading,\n isAuthLoaded,\n\n // Internal API (for LoginPage)\n config,\n _setTokens,\n _setLoading,\n }),\n [tokens, logout, isLoading, isAuthLoaded, config, _setTokens, _setLoading]\n );\n\n return (\n <AuthInternalContext.Provider value={contextValue}>\n {children}\n </AuthInternalContext.Provider>\n );\n}\n\n\n\n","import { useContext } from \"react\";\nimport { AuthInternalContext } from \"../components/AuthProvider\";\nimport type { AuthContextValue, AuthInternalContextValue } from \"../types\";\n\n// ============================================\n// PUBLIC HOOK\n// ============================================\n\n/**\n * useAuth - Public hook for consumers.\n * Returns only the public API (tokens, logout, isLoading, isAuthLoaded).\n *\n * @example\n * ```tsx\n * function App() {\n * const { tokens, logout, isLoading, isAuthLoaded } = useAuth();\n *\n * if (!isAuthLoaded) return <SplashScreen />;\n * if (!tokens) return <LoginPage />;\n * return <MainApp onLogout={logout} />;\n * }\n * ```\n */\nexport function useAuth(): AuthContextValue {\n const context = useContext(AuthInternalContext);\n\n if (!context) {\n throw new Error(\"useAuth must be used within an AuthProvider\");\n }\n\n // Return only public API\n return {\n tokens: context.tokens,\n logout: context.logout,\n isLoading: context.isLoading,\n isAuthLoaded: context.isAuthLoaded,\n };\n}\n\n// ============================================\n// INTERNAL HOOK (for LoginPage)\n// ============================================\n\n/**\n * useAuthInternal - Internal hook for LoginPage.\n * Returns the full internal API including config, _setTokens, _setLoading.\n *\n * @internal\n */\nexport function useAuthInternal(): AuthInternalContextValue {\n const context = useContext(AuthInternalContext);\n\n if (!context) {\n throw new Error(\"useAuthInternal must be used within an AuthProvider\");\n }\n\n return context;\n}\n\n\n\n","import type {\n AuthConfig,\n AuthProviderType,\n AuthResult,\n JWTData,\n TokenRequestParams,\n} from \"../types\";\n\n// ============================================\n// TOKEN EXCHANGE SERVICE\n// ============================================\n\n/**\n * Exchange provider credentials for JWT tokens from the backend.\n * @param params - Auth parameters (id_token, code, username/password)\n * @param provider - The auth provider type\n * @param config - Auth configuration with backendUrl\n */\nexport async function exchangeToken(\n params: TokenRequestParams,\n provider: AuthProviderType,\n config: AuthConfig\n): Promise<AuthResult> {\n console.log(`[Auth Token] Exchanging ${provider} credentials for tokens`);\n\n try {\n const bodyParams: Record<string, string> = {\n grant_type: provider,\n client_id: \"AevatarAuthServer\", // TODO: Make configurable via config\n scope: \"Aevatar offline_access\",\n };\n\n // Add source only for non-password providers (OAuth flows)\n if (provider == \"google\") {\n bodyParams.source = \"web\"; // works for google web.\n } else if (provider == \"apple\") {\n bodyParams.source = \"ios\";\n }\n\n // Add provider-specific app IDs (only for the active provider)\n if (provider === \"google\" && config.appId) {\n bodyParams.google_app_id = config.appId;\n }\n if (provider === \"apple\" && config.apple) {\n // Use apple.appId if set, otherwise fall back to clientId\n bodyParams.apple_app_id = config.apple.appId || config.apple.clientId;\n }\n\n // Add auth params (id_token, code, username, password, etc.)\n if (params.id_token) {\n bodyParams.id_token = params.id_token;\n }\n if (params.code) {\n bodyParams.code = params.code;\n }\n if (params.username) {\n bodyParams.username = params.username;\n }\n if (params.password) {\n bodyParams.password = params.password;\n }\n\n // Encode as form data\n const body = Object.entries(bodyParams)\n .map(([k, v]) => `${k}=${encodeURIComponent(v)}`)\n .join(\"&\");\n\n // Add timeout to prevent hanging requests\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 15000);\n\n const response = await fetch(`${config.backendUrl}/connect/token`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n // Handle error responses\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error(\n `[Auth Token] Exchange failed (${provider}):`,\n response.status,\n errorData\n );\n\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message:\n errorData.error_description ||\n errorData.error ||\n `HTTP ${response.status}: ${response.statusText}`,\n provider,\n };\n }\n\n // Parse successful response\n const tokens = (await response.json()) as JWTData;\n\n console.log(`[Auth Token] Exchange successful for ${provider}`);\n\n return {\n success: true,\n state: \"success\",\n tokens: {\n access_token: tokens.access_token,\n refresh_token: tokens.refresh_token,\n expires_in: tokens.expires_in,\n token_type: tokens.token_type,\n },\n message: \"Login successful\",\n provider,\n };\n } catch (error) {\n // Handle timeout\n const isTimeout = error instanceof Error && error.name === \"AbortError\";\n const errorMessage = isTimeout\n ? \"Request timed out. Please check your connection.\"\n : error instanceof Error\n ? error.message\n : \"Login failed\";\n\n console.error(`[Auth Token] Exchange error (${provider}):`, error);\n\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: errorMessage,\n provider,\n };\n }\n}\n\n// ============================================\n// TOKEN REFRESH SERVICE\n// ============================================\n\n/**\n * Refresh an expired access token using the refresh token.\n * @param refresh_token - The refresh token\n * @param backendUrl - The backend API URL\n */\nexport async function refreshToken(\n refresh_token: string,\n backendUrl: string\n): Promise<JWTData | null> {\n console.log(\"[Auth Token] Refreshing access token\");\n\n try {\n const body = new URLSearchParams({\n grant_type: \"refresh_token\",\n client_id: \"AevatarAuthServer\", // TODO: Make configurable\n refresh_token,\n }).toString();\n\n // Add timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 15000);\n\n const response = await fetch(`${backendUrl}/connect/token`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error(\"[Auth Token] Refresh failed:\", response.status, errorData);\n throw new Error(\n errorData.error_description || `Refresh failed: ${response.status}`\n );\n }\n\n const tokens = (await response.json()) as JWTData;\n\n console.log(\"[Auth Token] Refresh successful\");\n\n return {\n access_token: tokens.access_token,\n refresh_token: tokens.refresh_token,\n expires_in: tokens.expires_in,\n token_type: tokens.token_type,\n };\n } catch (error) {\n const isTimeout = error instanceof Error && error.name === \"AbortError\";\n console.error(\n \"[Auth Token] Refresh error:\",\n isTimeout ? \"Request timed out\" : error\n );\n return null;\n }\n}\n","import type { AuthConfig, AuthResult } from \"../types\";\nimport { exchangeToken } from \"../services/tokenService\";\n\n// ============================================\n// GOOGLE IDENTITY SERVICES TYPES\n// ============================================\n\ndeclare global {\n interface Window {\n google?: {\n accounts: {\n id: {\n initialize: (config: GoogleInitConfig) => void;\n prompt: (callback?: (notification: PromptNotification) => void) => void;\n renderButton: (element: HTMLElement, config: ButtonConfig) => void;\n revoke: (hint: string, callback: () => void) => void;\n cancel: () => void;\n };\n };\n };\n }\n}\n\ninterface GoogleInitConfig {\n client_id: string;\n callback: (response: GoogleCredentialResponse) => void;\n auto_select?: boolean;\n cancel_on_tap_outside?: boolean;\n context?: \"signin\" | \"signup\" | \"use\";\n ux_mode?: \"popup\" | \"redirect\";\n login_uri?: string;\n nonce?: string;\n use_fedcm_for_prompt?: boolean;\n}\n\ninterface GoogleCredentialResponse {\n credential: string; // JWT id_token\n select_by?: string;\n clientId?: string;\n}\n\ninterface PromptNotification {\n isNotDisplayed: () => boolean;\n isSkippedMoment: () => boolean;\n isDismissedMoment: () => boolean;\n getNotDisplayedReason: () => string;\n getSkippedReason: () => string;\n getDismissedReason: () => string;\n}\n\ninterface ButtonConfig {\n type?: \"standard\" | \"icon\";\n theme?: \"outline\" | \"filled_blue\" | \"filled_black\";\n size?: \"large\" | \"medium\" | \"small\";\n text?: \"signin_with\" | \"signup_with\" | \"continue_with\" | \"signin\";\n shape?: \"rectangular\" | \"pill\" | \"circle\" | \"square\";\n logo_alignment?: \"left\" | \"center\";\n width?: number;\n locale?: string;\n}\n\n// ============================================\n// STATE\n// ============================================\n\nlet googleSDKLoaded = false;\nlet googleSDKLoading: Promise<void> | null = null;\n\n// ============================================\n// SDK LOADER\n// ============================================\n\n/**\n * Load Google Identity Services SDK\n */\nexport function loadGoogleSDK(): Promise<void> {\n // Already loaded\n if (googleSDKLoaded && window.google?.accounts) {\n return Promise.resolve();\n }\n\n // Already loading\n if (googleSDKLoading) {\n return googleSDKLoading;\n }\n\n googleSDKLoading = new Promise((resolve, reject) => {\n // Check if already in DOM\n if (window.google?.accounts) {\n googleSDKLoaded = true;\n resolve();\n return;\n }\n\n console.log(\"[Auth Google] Loading Google Identity Services SDK\");\n\n const script = document.createElement(\"script\");\n script.src = \"https://accounts.google.com/gsi/client\";\n script.async = true;\n script.defer = true;\n\n script.onload = () => {\n console.log(\"[Auth Google] SDK loaded successfully\");\n googleSDKLoaded = true;\n resolve();\n };\n\n script.onerror = () => {\n console.error(\"[Auth Google] Failed to load SDK\");\n googleSDKLoading = null;\n reject(new Error(\"Failed to load Google Identity Services SDK\"));\n };\n\n document.head.appendChild(script);\n });\n\n return googleSDKLoading;\n}\n\n// ============================================\n// SIGN IN\n// ============================================\n\n/**\n * Sign in with Google using Google Identity Services.\n * Uses One Tap flow with popup fallback.\n *\n * @param config - Auth configuration with Google client ID\n * @returns AuthResult with tokens on success\n */\nexport async function signInWithGoogle(config: AuthConfig): Promise<AuthResult> {\n console.log(\"[Auth Google] Starting Google sign-in\");\n console.log(\"[Auth Google] Current origin:\", window.location.origin);\n\n // Validate config\n if (!config.google?.clientId) {\n console.error(\"[Auth Google] No client ID configured\");\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Google client ID not configured\",\n provider: \"google\",\n };\n }\n\n console.log(\"[Auth Google] Client ID:\", config.google.clientId.substring(0, 20) + \"...\");\n\n try {\n // Load SDK if not loaded\n console.log(\"[Auth Google] Loading SDK...\");\n await loadGoogleSDK();\n\n if (!window.google?.accounts) {\n throw new Error(\"Google SDK not available after loading\");\n }\n\n console.log(\"[Auth Google] SDK loaded, starting OAuth flow...\");\n\n // Use direct OAuth popup flow (more reliable than One Tap)\n return await signInWithGoogleRedirect(config);\n } catch (error) {\n console.error(\"[Auth Google] Sign-in error:\", error);\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: error instanceof Error ? error.message : \"Google login failed\",\n provider: \"google\",\n };\n }\n}\n\n/**\n * Sign in using OAuth popup flow\n */\nasync function signInWithGooglePopup(config: AuthConfig): Promise<AuthResult> {\n return new Promise((resolve) => {\n console.log(\"[Auth Google] Using popup flow\");\n\n // Generate nonce for security\n const nonce = Math.random().toString(36).substring(2, 15);\n\n // Initialize Google Sign-In\n window.google!.accounts.id.initialize({\n client_id: config.google!.clientId,\n callback: async (response: GoogleCredentialResponse) => {\n console.log(\"[Auth Google] Received credential response\");\n\n if (response.credential) {\n // Exchange id_token for our backend tokens\n const result = await exchangeToken(\n { id_token: response.credential },\n \"google\",\n config\n );\n resolve(result);\n } else {\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: \"No credential received from Google\",\n provider: \"google\",\n });\n }\n },\n auto_select: false,\n cancel_on_tap_outside: true,\n context: \"signin\",\n nonce,\n });\n\n // Show the One Tap prompt\n window.google!.accounts.id.prompt((notification: PromptNotification) => {\n if (notification.isNotDisplayed()) {\n const reason = notification.getNotDisplayedReason();\n console.log(\"[Auth Google] Prompt not displayed:\", reason);\n\n // Fall back to OAuth redirect if One Tap fails\n if (reason === \"opt_out_or_no_session\" || reason === \"suppressed_by_user\") {\n console.log(\"[Auth Google] Falling back to OAuth redirect\");\n signInWithGoogleRedirect(config).then(resolve);\n } else {\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: `Google Sign-In not available: ${reason}`,\n provider: \"google\",\n });\n }\n } else if (notification.isSkippedMoment()) {\n const reason = notification.getSkippedReason();\n console.log(\"[Auth Google] Prompt skipped:\", reason);\n resolve({\n success: false,\n state: \"cancelled\",\n tokens: null,\n message: \"Google Sign-In was skipped\",\n provider: \"google\",\n });\n } else if (notification.isDismissedMoment()) {\n const reason = notification.getDismissedReason();\n console.log(\"[Auth Google] Prompt dismissed:\", reason);\n\n if (reason === \"credential_returned\") {\n // Success - callback will handle this\n return;\n }\n\n resolve({\n success: false,\n state: \"cancelled\",\n tokens: null,\n message: \"Google Sign-In was cancelled\",\n provider: \"google\",\n });\n }\n });\n });\n}\n\n/**\n * Fallback: Sign in using OAuth redirect flow\n */\nasync function signInWithGoogleRedirect(config: AuthConfig): Promise<AuthResult> {\n return new Promise((resolve) => {\n const clientId = config.google!.clientId;\n const redirectUri = window.location.origin;\n const nonce = Math.random().toString(36).substring(2, 15);\n\n console.log(\"[Auth Google] OAuth redirect flow:\");\n console.log(\" - Client ID:\", clientId);\n console.log(\" - Redirect URI:\", redirectUri);\n console.log(\" ⚠️ Make sure this redirect URI is added to Google Cloud Console!\");\n\n const params = new URLSearchParams({\n client_id: clientId,\n redirect_uri: redirectUri,\n response_type: \"id_token\",\n scope: \"openid email profile\",\n nonce,\n prompt: \"select_account\",\n });\n\n const authUrl = `https://accounts.google.com/o/oauth2/v2/auth?${params}`;\n console.log(\"[Auth Google] Auth URL:\", authUrl);\n\n // Open popup\n const width = 500;\n const height = 600;\n const left = window.screenX + (window.outerWidth - width) / 2;\n const top = window.screenY + (window.outerHeight - height) / 2;\n\n const popup = window.open(\n authUrl,\n \"google-auth\",\n `width=${width},height=${height},left=${left},top=${top}`\n );\n\n if (!popup) {\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Popup was blocked. Please allow popups for this site.\",\n provider: \"google\",\n });\n return;\n }\n\n // Poll for popup close or redirect\n const pollInterval = setInterval(() => {\n try {\n // Check if popup was closed\n if (popup.closed) {\n clearInterval(pollInterval);\n resolve({\n success: false,\n state: \"cancelled\",\n tokens: null,\n message: \"Google Sign-In was cancelled\",\n provider: \"google\",\n });\n return;\n }\n\n // Try to read URL (will fail while on Google's domain)\n const url = popup.location.href;\n\n // Check if redirected back to our origin\n if (url.startsWith(redirectUri)) {\n clearInterval(pollInterval);\n popup.close();\n\n // Parse the hash fragment\n const hash = new URL(url.replace(\"#\", \"?\")).searchParams;\n const idToken = hash.get(\"id_token\");\n const error = hash.get(\"error\");\n\n if (error) {\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: hash.get(\"error_description\") || error,\n provider: \"google\",\n });\n return;\n }\n\n if (idToken) {\n // Exchange id_token for our backend tokens\n exchangeToken({ id_token: idToken }, \"google\", config).then(resolve);\n } else {\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: \"No token received from Google\",\n provider: \"google\",\n });\n }\n }\n } catch {\n // Cross-origin error - popup still on Google's domain, keep polling\n }\n }, 500);\n\n // Timeout after 5 minutes\n setTimeout(() => {\n clearInterval(pollInterval);\n if (!popup.closed) {\n popup.close();\n }\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Google Sign-In timed out\",\n provider: \"google\",\n });\n }, 5 * 60 * 1000);\n });\n}\n\n","import type { AuthConfig, AuthResult } from \"../types\";\nimport { exchangeToken } from \"../services/tokenService\";\n\n// ============================================\n// APPLE SIGN IN JS TYPES\n// ============================================\n\ndeclare global {\n interface Window {\n AppleID?: {\n auth: {\n init: (config: AppleInitConfig) => void;\n signIn: (config?: AppleSignInConfig) => Promise<AppleSignInResponse>;\n };\n };\n }\n}\n\ninterface AppleInitConfig {\n clientId: string;\n scope?: string;\n redirectURI: string;\n state?: string;\n nonce?: string;\n usePopup?: boolean;\n}\n\ninterface AppleSignInConfig {\n scope?: string;\n state?: string;\n nonce?: string;\n}\n\ninterface AppleSignInResponse {\n authorization: {\n code: string;\n id_token?: string;\n state?: string;\n };\n user?: {\n email?: string;\n name?: {\n firstName?: string;\n lastName?: string;\n };\n };\n}\n\ninterface AppleSignInError {\n error: string;\n}\n\n// ============================================\n// STATE\n// ============================================\n\nlet appleSDKLoaded = false;\nlet appleSDKLoading: Promise<void> | null = null;\nlet appleInitialized = false;\n\n// ============================================\n// SDK LOADER\n// ============================================\n\n/**\n * Load Apple Sign In JS SDK\n */\nexport function loadAppleSDK(): Promise<void> {\n // Already loaded\n if (appleSDKLoaded && window.AppleID) {\n return Promise.resolve();\n }\n\n // Already loading\n if (appleSDKLoading) {\n return appleSDKLoading;\n }\n\n appleSDKLoading = new Promise((resolve, reject) => {\n // Check if already in DOM\n if (window.AppleID) {\n appleSDKLoaded = true;\n resolve();\n return;\n }\n\n console.log(\"[Auth Apple] Loading Apple Sign In JS SDK\");\n\n const script = document.createElement(\"script\");\n script.src =\n \"https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js\";\n script.async = true;\n\n script.onload = () => {\n console.log(\"[Auth Apple] SDK loaded successfully\");\n appleSDKLoaded = true;\n resolve();\n };\n\n script.onerror = () => {\n console.error(\"[Auth Apple] Failed to load SDK\");\n appleSDKLoading = null;\n reject(new Error(\"Failed to load Apple Sign In JS SDK\"));\n };\n\n document.head.appendChild(script);\n });\n\n return appleSDKLoading;\n}\n\n// ============================================\n// INITIALIZE\n// ============================================\n\n/**\n * Initialize Apple Sign In with configuration\n */\nfunction initializeApple(config: AuthConfig): void {\n if (appleInitialized || !window.AppleID || !config.apple) {\n return;\n }\n\n // For localhost testing, always use current origin\n // Apple requires exact domain matching\n const isLocalhost =\n window.location.hostname === \"localhost\" ||\n window.location.hostname === \"127.0.0.1\";\n const redirectUri = isLocalhost\n ? window.location.origin\n : config.apple.redirectUri || window.location.origin;\n\n console.log(\"[Auth Apple] Initializing with config:\", {\n clientId: config.apple.clientId,\n redirectUri,\n isLocalhost,\n currentOrigin: window.location.origin,\n });\n\n window.AppleID.auth.init({\n clientId: config.apple.clientId,\n scope: \"name email\",\n redirectURI: redirectUri,\n usePopup: true,\n });\n\n appleInitialized = true;\n}\n\n// ============================================\n// SIGN IN\n// ============================================\n\n/**\n * Sign in with Apple using Apple Sign In JS.\n *\n * @param config - Auth configuration with Apple client ID\n * @returns AuthResult with tokens on success\n */\nexport async function signInWithApple(config: AuthConfig): Promise<AuthResult> {\n console.log(\"[Auth Apple] Starting Apple sign-in\");\n\n // Validate config\n if (!config.apple?.clientId) {\n console.error(\"[Auth Apple] No client ID configured\");\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Apple client ID not configured\",\n provider: \"apple\",\n };\n }\n\n // Check if running on localhost - warn about Apple limitations\n const isLocalhost =\n window.location.hostname === \"localhost\" ||\n window.location.hostname === \"127.0.0.1\";\n if (isLocalhost) {\n console.warn(\"[Auth Apple] Running on localhost - Apple Sign In requires:\");\n console.warn(\n \" 1. Your Service ID (com.gpt.godweb) must have localhost configured in Apple Developer Portal\"\n );\n console.warn(\n \" 2. Return URL must include: http://localhost:5173 (or your port)\"\n );\n }\n\n try {\n // Load SDK if not loaded\n console.log(\"[Auth Apple] Loading SDK...\");\n await loadAppleSDK();\n\n if (!window.AppleID) {\n throw new Error(\"Apple SDK not available after loading\");\n }\n\n // Reset initialization to ensure fresh config\n appleInitialized = false;\n\n // Initialize Apple Sign In\n initializeApple(config);\n\n console.log(\"[Auth Apple] Calling Apple signIn...\");\n\n // Attempt sign in\n const response = await window.AppleID.auth.signIn();\n\n console.log(\"[Auth Apple] Received response\");\n\n // Apple returns authorization.code for web\n const code = response.authorization?.code;\n const idToken = response.authorization?.id_token;\n\n if (code) {\n console.log(\"[Auth Apple] Exchanging authorization code\", code);\n return await exchangeToken({ code }, \"apple\", config);\n } else if (idToken) {\n console.log(\"[Auth Apple] Exchanging id_token\");\n return await exchangeToken({ id_token: idToken }, \"apple\", config);\n } else {\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"No authorization code or token received from Apple\",\n provider: \"apple\",\n };\n }\n } catch (error) {\n // Apple throws specific errors\n const appleError = error as AppleSignInError;\n\n // User cancelled\n if (\n appleError?.error === \"popup_closed_by_user\" ||\n appleError?.error === \"user_cancelled_authorize\"\n ) {\n console.log(\"[Auth Apple] Sign-in cancelled by user\");\n return {\n success: false,\n state: \"cancelled\",\n tokens: null,\n message: \"Apple Sign-In was cancelled\",\n provider: \"apple\",\n };\n }\n\n console.error(\"[Auth Apple] Sign-in error:\", error);\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message:\n appleError?.error ||\n (error instanceof Error ? error.message : \"Apple login failed\"),\n provider: \"apple\",\n };\n }\n}\n","import type { AuthConfig, AuthResult } from \"../types\";\nimport { exchangeToken } from \"../services/tokenService\";\n\n// ============================================\n// EMAIL SIGN-IN STRATEGY\n// ============================================\n\n/**\n * Sign in with email and password.\n * Sends credentials to backend for authentication.\n *\n * @param email - User's email address\n * @param password - User's password\n * @param config - Auth configuration with backendUrl\n * @returns AuthResult with tokens on success\n */\nexport async function signInWithEmail(\n email: string,\n password: string,\n config: AuthConfig\n): Promise<AuthResult> {\n console.log(\"[Auth Email] Starting email sign-in\");\n\n // Validate inputs\n if (!email || !email.trim()) {\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Email is required\",\n provider: \"password\",\n };\n }\n\n if (!password) {\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Password is required\",\n provider: \"password\",\n };\n }\n\n // Basic email format validation\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(email.trim())) {\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Please enter a valid email address\",\n provider: \"password\",\n };\n }\n\n try {\n // Exchange credentials for tokens\n // Note: grant_type is \"password\" for email/password auth (OAuth2 standard)\n const result = await exchangeToken(\n {\n username: email.trim(),\n password,\n },\n \"password\",\n config\n );\n\n if (result.success) {\n console.log(\"[Auth Email] Sign-in successful\");\n } else {\n console.log(\"[Auth Email] Sign-in failed:\", result.message);\n }\n\n return result;\n } catch (error) {\n console.error(\"[Auth Email] Sign-in error:\", error);\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: error instanceof Error ? error.message : \"Email login failed\",\n provider: \"password\",\n };\n }\n}\n\n","import React, { useState } from \"react\";\nimport { useAuthInternal } from \"../hooks/useAuth\";\nimport { signInWithGoogle } from \"../strategies/google\";\nimport { signInWithApple } from \"../strategies/apple\";\nimport { signInWithEmail } from \"../strategies/email\";\n\n// ============================================\n// ICONS\n// ============================================\n\nconst GoogleIcon = () => (\n <svg className=\"w-5 h-5\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z\"\n fill=\"#4285F4\"\n />\n <path\n d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"\n fill=\"#34A853\"\n />\n <path\n d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\"\n fill=\"#FBBC05\"\n />\n <path\n d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"\n fill=\"#EA4335\"\n />\n </svg>\n);\n\nconst AppleIcon = () => (\n <svg className=\"w-5 h-5\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.48-3.24 0-1.44.62-2.2.44-3.06-.4C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09l.01-.01zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z\" />\n </svg>\n);\n\nconst LoadingSpinner = () => (\n <svg\n className=\"animate-spin h-5 w-5\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n);\n\n// ============================================\n// BUTTON COMPONENT\n// ============================================\n\ninterface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: \"primary\" | \"secondary\";\n isLoading?: boolean;\n children: React.ReactNode;\n}\n\nconst Button: React.FC<ButtonProps> = ({\n variant = \"primary\",\n isLoading = false,\n disabled,\n children,\n className = \"\",\n ...props\n}) => {\n const baseClasses =\n \"min-h-[52px] px-6 rounded-[99px] font-semibold text-base transition-all duration-200 flex items-center justify-center gap-2 focus:outline-none\";\n\n const variantClasses = {\n primary: \"bg-black text-white active:opacity-80 active:scale-[0.98]\",\n secondary:\n \"bg-white text-black border border-black active:opacity-80 active:scale-[0.98]\",\n };\n\n const disabledClasses = \"opacity-40 cursor-not-allowed pointer-events-none\";\n\n return (\n <button\n className={`${baseClasses} ${variantClasses[variant]} ${\n disabled || isLoading ? disabledClasses : \"\"\n } ${className}`}\n disabled={disabled || isLoading}\n {...props}\n >\n {isLoading ? (\n <>\n <LoadingSpinner />\n <span>Loading...</span>\n </>\n ) : (\n children\n )}\n </button>\n );\n};\n\n// ============================================\n// INPUT COMPONENT\n// ============================================\n\ninterface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n label?: string;\n error?: string;\n}\n\nconst Input: React.FC<InputProps> = ({\n label,\n error,\n className = \"\",\n ...props\n}) => {\n return (\n <div className=\"space-y-1\">\n {label && (\n <label className=\"block text-sm font-medium text-gray-700\">\n {label}\n </label>\n )}\n <input\n className={`w-full px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-black focus:border-transparent ${\n error ? \"border-red-500\" : \"border-gray-300\"\n } ${className}`}\n {...props}\n />\n {error && <p className=\"text-sm text-red-500\">{error}</p>}\n </div>\n );\n};\n\n// ============================================\n// LOGIN PAGE VIEWS\n// ============================================\n\ntype View = \"main\" | \"email\";\n\n// ============================================\n// LOGIN PAGE COMPONENT\n// ============================================\n\n/**\n * LoginPage - Complete login UI component.\n * Gets config from AuthProvider context.\n * Handles Google, Apple, and Email sign-in.\n *\n * @example\n * ```tsx\n * function App() {\n * const { tokens, isAuthLoaded } = useAuth();\n *\n * if (!isAuthLoaded) return <SplashScreen />;\n * if (!tokens) return <LoginPage />;\n * return <MainApp />;\n * }\n * ```\n */\nexport function LoginPage() {\n const { config, _setTokens, _setLoading, isLoading } = useAuthInternal();\n\n const [view, setView] = useState<View>(\"main\");\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n const [fieldErrors, setFieldErrors] = useState<{\n email?: string;\n password?: string;\n }>({});\n\n // ============================================\n // HANDLERS\n // ============================================\n\n const handleGoogleLogin = async () => {\n if (!config.google) {\n setError(\"Google sign-in is not configured\");\n return;\n }\n\n setError(null);\n _setLoading(true);\n\n try {\n const result = await signInWithGoogle(config);\n\n if (result.success && result.tokens) {\n await _setTokens(result.tokens);\n } else if (result.state !== \"cancelled\") {\n setError(result.message || \"Google sign-in failed\");\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Google sign-in failed\");\n } finally {\n _setLoading(false);\n }\n };\n\n const handleAppleLogin = async () => {\n if (!config.apple) {\n setError(\"Apple sign-in is not configured\");\n return;\n }\n\n setError(null);\n _setLoading(true);\n\n try {\n const result = await signInWithApple(config);\n\n if (result.success && result.tokens) {\n await _setTokens(result.tokens);\n } else if (result.state !== \"cancelled\") {\n setError(result.message || \"Apple sign-in failed\");\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Apple sign-in failed\");\n } finally {\n _setLoading(false);\n }\n };\n\n const handleEmailLogin = async (e: React.FormEvent) => {\n e.preventDefault();\n\n // Validate\n const errors: { email?: string; password?: string } = {};\n if (!email.trim()) {\n errors.email = \"Email is required\";\n }\n if (!password) {\n errors.password = \"Password is required\";\n }\n\n if (Object.keys(errors).length > 0) {\n setFieldErrors(errors);\n return;\n }\n\n setError(null);\n setFieldErrors({});\n _setLoading(true);\n\n try {\n const result = await signInWithEmail(email, password, config);\n\n if (result.success && result.tokens) {\n await _setTokens(result.tokens);\n } else {\n setError(result.message || \"Email sign-in failed\");\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Email sign-in failed\");\n } finally {\n _setLoading(false);\n }\n };\n\n // ============================================\n // EMAIL VIEW\n // ============================================\n\n if (view === \"email\") {\n return (\n <div className=\"min-h-screen bg-white flex flex-col px-5 py-8\">\n <div className=\"flex-1 flex flex-col max-w-md mx-auto w-full\">\n {/* Back Button */}\n <button\n onClick={() => {\n setView(\"main\");\n setError(null);\n setFieldErrors({});\n }}\n className=\"self-start mb-8 flex items-center text-gray-600 active:opacity-80\"\n >\n <svg\n className=\"w-5 h-5 mr-2\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 19l-7-7 7-7\"\n />\n </svg>\n Back\n </button>\n\n {/* Header */}\n <div className=\"mb-12 text-center\">\n <h1 className=\"text-[30px] font-bold text-black mb-2\">Sign In</h1>\n <p className=\"text-base text-gray-600\">\n Enter your email and password\n </p>\n </div>\n\n {/* Error Message */}\n {error && (\n <div className=\"mb-6 p-4 bg-red-50 border border-red-200 rounded-lg\">\n <p className=\"text-sm text-red-600\">{error}</p>\n </div>\n )}\n\n {/* Email Form */}\n <form onSubmit={handleEmailLogin} className=\"space-y-6\">\n <Input\n type=\"email\"\n label=\"Email\"\n placeholder=\"Enter your email\"\n value={email}\n onChange={(e) => {\n setEmail(e.target.value);\n if (fieldErrors.email)\n setFieldErrors({ ...fieldErrors, email: undefined });\n }}\n error={fieldErrors.email}\n autoComplete=\"email\"\n />\n\n <Input\n type=\"password\"\n label=\"Password\"\n placeholder=\"Enter your password\"\n value={password}\n onChange={(e) => {\n setPassword(e.target.value);\n if (fieldErrors.password)\n setFieldErrors({ ...fieldErrors, password: undefined });\n }}\n error={fieldErrors.password}\n autoComplete=\"current-password\"\n />\n\n <Button\n type=\"submit\"\n variant=\"primary\"\n isLoading={isLoading}\n className=\"w-full mt-8\"\n >\n Sign In\n </Button>\n </form>\n </div>\n </div>\n );\n }\n\n // ============================================\n // MAIN VIEW\n // ============================================\n\n return (\n <div className=\"min-h-screen bg-white flex flex-col px-5 py-8\">\n <div className=\"flex-1 flex flex-col justify-center max-w-md mx-auto w-full\">\n {/* Header */}\n <div className=\"mb-12 text-center\">\n <h1 className=\"text-[30px] font-bold text-black mb-2\">\n Welcome Back\n </h1>\n <p className=\"text-base text-gray-600\">Sign in to continue</p>\n </div>\n\n {/* Error Message */}\n {error && (\n <div className=\"mb-6 p-4 bg-red-50 border border-red-200 rounded-lg\">\n <p className=\"text-sm text-red-600\">{error}</p>\n </div>\n )}\n\n {/* Social Login Buttons */}\n <div className=\"space-y-3 mb-8\">\n {config.google && (\n <Button\n variant=\"secondary\"\n onClick={handleGoogleLogin}\n disabled={isLoading}\n className=\"w-full\"\n >\n <GoogleIcon />\n Continue with Google\n </Button>\n )}\n\n {config.apple && (\n <Button\n variant=\"secondary\"\n onClick={handleAppleLogin}\n disabled={isLoading}\n className=\"w-full\"\n >\n <AppleIcon />\n Continue with Apple\n </Button>\n )}\n </div>\n\n {/* Divider */}\n {config.email?.enabled && (config.google || config.apple) && (\n <div className=\"relative mb-8\">\n <div className=\"absolute inset-0 flex items-center\">\n <div className=\"w-full border-t border-gray-300\"></div>\n </div>\n <div className=\"relative flex justify-center text-sm\">\n <span className=\"px-4 bg-white text-gray-500\">\n Or continue with email\n </span>\n </div>\n </div>\n )}\n\n {/* Email Login Button */}\n {config.email?.enabled && (\n <Button\n variant=\"primary\"\n onClick={() => setView(\"email\")}\n disabled={isLoading}\n className=\"w-full\"\n >\n Continue with Email\n </Button>\n )}\n </div>\n\n {/* Disclaimer */}\n <div className=\"pb-[36px] px-5\">\n <p className=\"text-xs text-gray-500 text-center leading-relaxed max-w-sm mx-auto\">\n By signing in, you agree to our{\" \"}\n <a\n href=\"https://app.godgpt.fun/terms-of-service/\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-gray-700 underline underline-offset-2 hover:text-gray-900\"\n >\n Terms of Service\n </a>{\" \"}\n and{\" \"}\n <a\n href=\"https://app.godgpt.fun/privacy-policy/\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-gray-700 underline underline-offset-2 hover:text-gray-900\"\n >\n Privacy Policy\n </a>\n .\n </p>\n </div>\n </div>\n );\n}\n\n\n\n"]}
|
package/dist/index.js
CHANGED
|
@@ -647,8 +647,12 @@ async function signInWithApple(config) {
|
|
|
647
647
|
const isLocalhost = window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1";
|
|
648
648
|
if (isLocalhost) {
|
|
649
649
|
console.warn("[Auth Apple] Running on localhost - Apple Sign In requires:");
|
|
650
|
-
console.warn(
|
|
651
|
-
|
|
650
|
+
console.warn(
|
|
651
|
+
" 1. Your Service ID (com.gpt.godweb) must have localhost configured in Apple Developer Portal"
|
|
652
|
+
);
|
|
653
|
+
console.warn(
|
|
654
|
+
" 2. Return URL must include: http://localhost:5173 (or your port)"
|
|
655
|
+
);
|
|
652
656
|
}
|
|
653
657
|
try {
|
|
654
658
|
console.log("[Auth Apple] Loading SDK...");
|
|
@@ -664,7 +668,7 @@ async function signInWithApple(config) {
|
|
|
664
668
|
const code = response.authorization?.code;
|
|
665
669
|
const idToken = response.authorization?.id_token;
|
|
666
670
|
if (code) {
|
|
667
|
-
console.log("[Auth Apple] Exchanging authorization code");
|
|
671
|
+
console.log("[Auth Apple] Exchanging authorization code", code);
|
|
668
672
|
return await exchangeToken({ code }, "apple", config);
|
|
669
673
|
} else if (idToken) {
|
|
670
674
|
console.log("[Auth Apple] Exchanging id_token");
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/auth/config.ts","../src/auth/services/storageService.ts","../src/auth/components/AuthProvider.tsx","../src/auth/hooks/useAuth.ts","../src/auth/services/tokenService.ts","../src/auth/strategies/google.ts","../src/auth/strategies/apple.ts","../src/auth/strategies/email.ts","../src/auth/components/LoginPage.tsx"],"names":["jsx","useState"],"mappings":"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","file":"index.js","sourcesContent":["import type { AuthConfig } from \"./types\";\n\n// ============================================\n// CONFIGURATION VALIDATION\n// ============================================\n\n/**\n * Validate auth configuration.\n * Called by AuthProvider on mount.\n */\nexport function validateConfig(config: AuthConfig): void {\n if (!config.backendUrl) {\n throw new Error(\"[Auth] backendUrl is required in AuthConfig\");\n }\n\n if (!config.google && !config.apple && !config.email?.enabled) {\n console.warn(\n \"[Auth] No auth strategies configured. Enable at least one: google, apple, or email.\"\n );\n }\n\n // Validate Google config\n if (config.google && !config.google.clientId) {\n throw new Error(\"[Auth] google.clientId is required when google is enabled\");\n }\n\n // Validate Apple config\n if (config.apple && !config.apple.clientId) {\n throw new Error(\"[Auth] apple.clientId is required when apple is enabled\");\n }\n\n console.log(\"[Auth] Config validated:\", {\n backendUrl: config.backendUrl,\n hasGoogle: !!config.google,\n hasApple: !!config.apple,\n hasEmail: !!config.email?.enabled,\n });\n}\n","import type { JWTData } from \"../types\";\n\n// ============================================\n// STORAGE ADAPTER INTERFACE\n// ============================================\n\n/**\n * Interface for custom storage adapters.\n * Implement this to use your own storage (Redux, Zustand, AsyncStorage, etc.)\n */\nexport interface StorageAdapter {\n getItem: (key: string) => Promise<string | null> | string | null;\n setItem: (key: string, value: string) => Promise<void> | void;\n removeItem: (key: string) => Promise<void> | void;\n}\n\n// ============================================\n// DEFAULT ADAPTERS\n// ============================================\n\n/**\n * Default localStorage adapter for web\n * Includes SSR safety checks for Next.js and other SSR frameworks\n */\nexport const localStorageAdapter: StorageAdapter = {\n getItem: (key) => {\n if (typeof window === \"undefined\") return null;\n return localStorage.getItem(key);\n },\n setItem: (key, value) => {\n if (typeof window === \"undefined\") return;\n localStorage.setItem(key, value);\n },\n removeItem: (key) => {\n if (typeof window === \"undefined\") return;\n localStorage.removeItem(key);\n },\n};\n\n/**\n * Memory adapter for SSR or testing\n */\nexport const memoryStorageAdapter = (): StorageAdapter => {\n const store = new Map<string, string>();\n return {\n getItem: (key) => store.get(key) ?? null,\n setItem: (key, value) => {\n store.set(key, value);\n },\n removeItem: (key) => {\n store.delete(key);\n },\n };\n};\n\n// ============================================\n// STORAGE SERVICE FACTORY\n// ============================================\n\nconst TOKEN_KEY = \"auth_token_data\";\n\n/**\n * Creates a storage service with the provided adapter.\n * Reusable token logic with pluggable storage backend.\n */\nexport function createStorageService(adapter: StorageAdapter) {\n return {\n /**\n * Save tokens to storage\n */\n async saveTokens(tokens: JWTData): Promise<void> {\n try {\n const dataToStore = {\n ...tokens,\n stored_at: Date.now(),\n };\n await adapter.setItem(TOKEN_KEY, JSON.stringify(dataToStore));\n console.log(\"[Auth Storage] Tokens saved successfully\");\n } catch (error) {\n console.error(\"[Auth Storage] Failed to save tokens:\", error);\n throw error;\n }\n },\n\n /**\n * Get tokens from storage\n * Returns null if no tokens exist or if they're invalid\n */\n async getTokens(): Promise<JWTData | null> {\n try {\n const data = await adapter.getItem(TOKEN_KEY);\n if (!data) {\n return null;\n }\n\n const parsed = JSON.parse(data);\n\n // Return tokens without the stored_at metadata\n const { stored_at: _storedAt, ...tokens } = parsed;\n\n return tokens as JWTData;\n } catch (error) {\n console.error(\"[Auth Storage] Failed to get tokens:\", error);\n // Clear corrupted data\n await this.clearTokens();\n return null;\n }\n },\n\n /**\n * Get raw stored data (including metadata like stored_at)\n */\n async getRawData(): Promise<{ tokens: JWTData; stored_at: number } | null> {\n try {\n const data = await adapter.getItem(TOKEN_KEY);\n if (!data) {\n return null;\n }\n const parsed = JSON.parse(data);\n\n // Data is stored as flat object: { ...tokens, stored_at }\n // Extract stored_at and return in expected format\n const { stored_at, ...tokens } = parsed;\n\n return { tokens: tokens as JWTData, stored_at };\n } catch (error) {\n console.error(\"[Auth Storage] Failed to get raw data:\", error);\n return null;\n }\n },\n\n /**\n * Clear tokens from storage\n */\n async clearTokens(): Promise<void> {\n try {\n await adapter.removeItem(TOKEN_KEY);\n console.log(\"[Auth Storage] Tokens cleared\");\n } catch (error) {\n console.error(\"[Auth Storage] Failed to clear tokens:\", error);\n }\n },\n\n /**\n * Check if tokens exist in storage\n */\n async hasTokens(): Promise<boolean> {\n const data = await adapter.getItem(TOKEN_KEY);\n return data !== null;\n },\n\n /**\n * Check if stored tokens are expired\n * Uses expires_in from the token data\n */\n async isTokenExpired(): Promise<boolean> {\n try {\n const rawData = await this.getRawData();\n if (!rawData) {\n return true;\n }\n\n const { stored_at, tokens } = rawData;\n const expiresIn = tokens.expires_in;\n\n if (!stored_at || !expiresIn) {\n return true;\n }\n\n // Check if current time is past expiration\n // expires_in is in seconds, so convert to milliseconds\n const expirationTime = stored_at + expiresIn * 1000;\n const isExpired = Date.now() >= expirationTime;\n\n if (isExpired) {\n console.log(\"[Auth Storage] Token is expired\");\n }\n\n return isExpired;\n } catch (error) {\n console.error(\n \"[Auth Storage] Failed to check token expiration:\",\n error\n );\n return true;\n }\n },\n\n /**\n * Get the time until token expires (in milliseconds)\n * Returns 0 if token is expired or doesn't exist\n */\n async getTimeUntilExpiry(): Promise<number> {\n try {\n const rawData = await this.getRawData();\n if (!rawData) {\n return 0;\n }\n\n const { stored_at, tokens } = rawData;\n const expiresIn = tokens.expires_in;\n\n if (!stored_at || !expiresIn) {\n return 0;\n }\n\n const expirationTime = stored_at + expiresIn * 1000;\n const timeRemaining = expirationTime - Date.now();\n\n return Math.max(0, timeRemaining);\n } catch (error) {\n console.error(\"[Auth Storage] Failed to get time until expiry:\", error);\n return 0;\n }\n },\n };\n}\n\n// ============================================\n// STORAGE SERVICE TYPE\n// ============================================\n\nexport type StorageService = ReturnType<typeof createStorageService>;\n\n// ============================================\n// DEFAULT INSTANCE (backwards compatible)\n// ============================================\n\n/**\n * Default storage service using localStorage.\n * For custom storage, use createStorageService(yourAdapter) instead.\n */\nexport const storageService = createStorageService(localStorageAdapter);\n","import React, {\n createContext,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n AuthConfig,\n AuthInternalContextValue,\n JWTData,\n} from \"../types\";\nimport { validateConfig } from \"../config\";\nimport { storageService } from \"../services/storageService\";\n\n// ============================================\n// CONTEXT\n// ============================================\n\n/**\n * Internal context - includes config and _setTokens for LoginPage\n */\nexport const AuthInternalContext =\n createContext<AuthInternalContextValue | null>(null);\n\n// ============================================\n// PROVIDER PROPS\n// ============================================\n\ninterface AuthProviderProps {\n children: React.ReactNode;\n /** Auth configuration with backend URL and provider settings */\n config: AuthConfig;\n /**\n * Called when user logs out or tokens are invalid on mount.\n * Use this to redirect, clear app state, etc.\n */\n onLogout?: () => void;\n}\n\n// ============================================\n// AUTH PROVIDER COMPONENT\n// ============================================\n\n/**\n * AuthProvider - Wraps your app to provide authentication state.\n *\n * @example\n * ```tsx\n * <AuthProvider\n * config={{\n * backendUrl: import.meta.env.VITE_AUTH_BACKEND_URL,\n * google: { clientId: import.meta.env.VITE_GOOGLE_CLIENT_ID },\n * apple: { clientId: import.meta.env.VITE_APPLE_CLIENT_ID },\n * }}\n * onLogout={() => router.push('/')}\n * >\n * <App />\n * </AuthProvider>\n * ```\n */\nexport function AuthProvider({\n children,\n config,\n onLogout,\n}: AuthProviderProps) {\n // ============================================\n // STATE\n // ============================================\n\n const [tokens, setTokens] = useState<JWTData | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [isAuthLoaded, setIsAuthLoaded] = useState(false);\n\n // Use ref for callback to avoid re-running effect when callback changes\n const onLogoutRef = useRef(onLogout);\n onLogoutRef.current = onLogout;\n\n // Track if initialization has run\n const hasInitialized = useRef(false);\n\n // ============================================\n // INITIALIZATION\n // ============================================\n\n useEffect(() => {\n // Only run initialization once\n if (hasInitialized.current) {\n return;\n }\n hasInitialized.current = true;\n\n // Validate config on mount\n validateConfig(config);\n\n // Load tokens from storage\n const initializeAuth = async () => {\n console.log(\"[AuthProvider] Initializing auth state\");\n\n try {\n // Check if we have stored tokens\n const storedTokens = await storageService.getTokens();\n\n if (storedTokens) {\n // Check if tokens are expired\n const isExpired = await storageService.isTokenExpired();\n\n if (isExpired) {\n console.log(\"[AuthProvider] Stored tokens are expired, clearing\");\n await storageService.clearTokens();\n onLogoutRef.current?.();\n } else {\n console.log(\"[AuthProvider] Valid tokens found, restoring session\");\n setTokens(storedTokens);\n }\n } else {\n console.log(\"[AuthProvider] No stored tokens found\");\n }\n } catch (error) {\n console.error(\"[AuthProvider] Error initializing auth:\", error);\n // Clear any corrupted data\n await storageService.clearTokens();\n } finally {\n setIsAuthLoaded(true);\n }\n };\n\n initializeAuth();\n }, [config]);\n\n // ============================================\n // INTERNAL: SET TOKENS (for LoginPage)\n // ============================================\n\n const _setTokens = useCallback(async (newTokens: JWTData) => {\n console.log(\"[AuthProvider] Setting tokens\");\n\n // Save to storage\n await storageService.saveTokens(newTokens);\n\n // Update state\n setTokens(newTokens);\n }, []);\n\n // ============================================\n // INTERNAL: SET LOADING (for LoginPage)\n // ============================================\n\n const _setLoading = useCallback((loading: boolean) => {\n setIsLoading(loading);\n }, []);\n\n // ============================================\n // LOGOUT\n // ============================================\n\n const logout = useCallback(async () => {\n console.log(\"[AuthProvider] Logging out\");\n\n // Clear storage\n await storageService.clearTokens();\n\n // Clear state\n setTokens(null);\n\n // Call callback\n onLogoutRef.current?.();\n }, []);\n\n // ============================================\n // CONTEXT VALUE\n // ============================================\n\n const contextValue = useMemo<AuthInternalContextValue>(\n () => ({\n // Public API\n tokens,\n logout,\n isLoading,\n isAuthLoaded,\n\n // Internal API (for LoginPage)\n config,\n _setTokens,\n _setLoading,\n }),\n [tokens, logout, isLoading, isAuthLoaded, config, _setTokens, _setLoading]\n );\n\n return (\n <AuthInternalContext.Provider value={contextValue}>\n {children}\n </AuthInternalContext.Provider>\n );\n}\n\n\n\n","import { useContext } from \"react\";\nimport { AuthInternalContext } from \"../components/AuthProvider\";\nimport type { AuthContextValue, AuthInternalContextValue } from \"../types\";\n\n// ============================================\n// PUBLIC HOOK\n// ============================================\n\n/**\n * useAuth - Public hook for consumers.\n * Returns only the public API (tokens, logout, isLoading, isAuthLoaded).\n *\n * @example\n * ```tsx\n * function App() {\n * const { tokens, logout, isLoading, isAuthLoaded } = useAuth();\n *\n * if (!isAuthLoaded) return <SplashScreen />;\n * if (!tokens) return <LoginPage />;\n * return <MainApp onLogout={logout} />;\n * }\n * ```\n */\nexport function useAuth(): AuthContextValue {\n const context = useContext(AuthInternalContext);\n\n if (!context) {\n throw new Error(\"useAuth must be used within an AuthProvider\");\n }\n\n // Return only public API\n return {\n tokens: context.tokens,\n logout: context.logout,\n isLoading: context.isLoading,\n isAuthLoaded: context.isAuthLoaded,\n };\n}\n\n// ============================================\n// INTERNAL HOOK (for LoginPage)\n// ============================================\n\n/**\n * useAuthInternal - Internal hook for LoginPage.\n * Returns the full internal API including config, _setTokens, _setLoading.\n *\n * @internal\n */\nexport function useAuthInternal(): AuthInternalContextValue {\n const context = useContext(AuthInternalContext);\n\n if (!context) {\n throw new Error(\"useAuthInternal must be used within an AuthProvider\");\n }\n\n return context;\n}\n\n\n\n","import type {\n AuthConfig,\n AuthProviderType,\n AuthResult,\n JWTData,\n TokenRequestParams,\n} from \"../types\";\n\n// ============================================\n// TOKEN EXCHANGE SERVICE\n// ============================================\n\n/**\n * Exchange provider credentials for JWT tokens from the backend.\n * @param params - Auth parameters (id_token, code, username/password)\n * @param provider - The auth provider type\n * @param config - Auth configuration with backendUrl\n */\nexport async function exchangeToken(\n params: TokenRequestParams,\n provider: AuthProviderType,\n config: AuthConfig\n): Promise<AuthResult> {\n console.log(`[Auth Token] Exchanging ${provider} credentials for tokens`);\n\n try {\n const bodyParams: Record<string, string> = {\n grant_type: provider,\n client_id: \"AevatarAuthServer\", // TODO: Make configurable via config\n scope: \"Aevatar offline_access\",\n };\n\n // Add source only for non-password providers (OAuth flows)\n if (provider == \"google\") {\n bodyParams.source = \"web\"; // works for google web.\n } else if (provider == \"apple\") {\n bodyParams.source = \"ios\";\n }\n\n // Add provider-specific app IDs (only for the active provider)\n if (provider === \"google\" && config.appId) {\n bodyParams.google_app_id = config.appId;\n }\n if (provider === \"apple\" && config.apple) {\n // Use apple.appId if set, otherwise fall back to clientId\n bodyParams.apple_app_id = config.apple.appId || config.apple.clientId;\n }\n\n // Add auth params (id_token, code, username, password, etc.)\n if (params.id_token) {\n bodyParams.id_token = params.id_token;\n }\n if (params.code) {\n bodyParams.code = params.code;\n }\n if (params.username) {\n bodyParams.username = params.username;\n }\n if (params.password) {\n bodyParams.password = params.password;\n }\n\n // Encode as form data\n const body = Object.entries(bodyParams)\n .map(([k, v]) => `${k}=${encodeURIComponent(v)}`)\n .join(\"&\");\n\n // Add timeout to prevent hanging requests\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 15000);\n\n const response = await fetch(`${config.backendUrl}/connect/token`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n // Handle error responses\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error(\n `[Auth Token] Exchange failed (${provider}):`,\n response.status,\n errorData\n );\n\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message:\n errorData.error_description ||\n errorData.error ||\n `HTTP ${response.status}: ${response.statusText}`,\n provider,\n };\n }\n\n // Parse successful response\n const tokens = (await response.json()) as JWTData;\n\n console.log(`[Auth Token] Exchange successful for ${provider}`);\n\n return {\n success: true,\n state: \"success\",\n tokens: {\n access_token: tokens.access_token,\n refresh_token: tokens.refresh_token,\n expires_in: tokens.expires_in,\n token_type: tokens.token_type,\n },\n message: \"Login successful\",\n provider,\n };\n } catch (error) {\n // Handle timeout\n const isTimeout = error instanceof Error && error.name === \"AbortError\";\n const errorMessage = isTimeout\n ? \"Request timed out. Please check your connection.\"\n : error instanceof Error\n ? error.message\n : \"Login failed\";\n\n console.error(`[Auth Token] Exchange error (${provider}):`, error);\n\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: errorMessage,\n provider,\n };\n }\n}\n\n// ============================================\n// TOKEN REFRESH SERVICE\n// ============================================\n\n/**\n * Refresh an expired access token using the refresh token.\n * @param refresh_token - The refresh token\n * @param backendUrl - The backend API URL\n */\nexport async function refreshToken(\n refresh_token: string,\n backendUrl: string\n): Promise<JWTData | null> {\n console.log(\"[Auth Token] Refreshing access token\");\n\n try {\n const body = new URLSearchParams({\n grant_type: \"refresh_token\",\n client_id: \"AevatarAuthServer\", // TODO: Make configurable\n refresh_token,\n }).toString();\n\n // Add timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 15000);\n\n const response = await fetch(`${backendUrl}/connect/token`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error(\"[Auth Token] Refresh failed:\", response.status, errorData);\n throw new Error(\n errorData.error_description || `Refresh failed: ${response.status}`\n );\n }\n\n const tokens = (await response.json()) as JWTData;\n\n console.log(\"[Auth Token] Refresh successful\");\n\n return {\n access_token: tokens.access_token,\n refresh_token: tokens.refresh_token,\n expires_in: tokens.expires_in,\n token_type: tokens.token_type,\n };\n } catch (error) {\n const isTimeout = error instanceof Error && error.name === \"AbortError\";\n console.error(\n \"[Auth Token] Refresh error:\",\n isTimeout ? \"Request timed out\" : error\n );\n return null;\n }\n}\n","import type { AuthConfig, AuthResult } from \"../types\";\nimport { exchangeToken } from \"../services/tokenService\";\n\n// ============================================\n// GOOGLE IDENTITY SERVICES TYPES\n// ============================================\n\ndeclare global {\n interface Window {\n google?: {\n accounts: {\n id: {\n initialize: (config: GoogleInitConfig) => void;\n prompt: (callback?: (notification: PromptNotification) => void) => void;\n renderButton: (element: HTMLElement, config: ButtonConfig) => void;\n revoke: (hint: string, callback: () => void) => void;\n cancel: () => void;\n };\n };\n };\n }\n}\n\ninterface GoogleInitConfig {\n client_id: string;\n callback: (response: GoogleCredentialResponse) => void;\n auto_select?: boolean;\n cancel_on_tap_outside?: boolean;\n context?: \"signin\" | \"signup\" | \"use\";\n ux_mode?: \"popup\" | \"redirect\";\n login_uri?: string;\n nonce?: string;\n use_fedcm_for_prompt?: boolean;\n}\n\ninterface GoogleCredentialResponse {\n credential: string; // JWT id_token\n select_by?: string;\n clientId?: string;\n}\n\ninterface PromptNotification {\n isNotDisplayed: () => boolean;\n isSkippedMoment: () => boolean;\n isDismissedMoment: () => boolean;\n getNotDisplayedReason: () => string;\n getSkippedReason: () => string;\n getDismissedReason: () => string;\n}\n\ninterface ButtonConfig {\n type?: \"standard\" | \"icon\";\n theme?: \"outline\" | \"filled_blue\" | \"filled_black\";\n size?: \"large\" | \"medium\" | \"small\";\n text?: \"signin_with\" | \"signup_with\" | \"continue_with\" | \"signin\";\n shape?: \"rectangular\" | \"pill\" | \"circle\" | \"square\";\n logo_alignment?: \"left\" | \"center\";\n width?: number;\n locale?: string;\n}\n\n// ============================================\n// STATE\n// ============================================\n\nlet googleSDKLoaded = false;\nlet googleSDKLoading: Promise<void> | null = null;\n\n// ============================================\n// SDK LOADER\n// ============================================\n\n/**\n * Load Google Identity Services SDK\n */\nexport function loadGoogleSDK(): Promise<void> {\n // Already loaded\n if (googleSDKLoaded && window.google?.accounts) {\n return Promise.resolve();\n }\n\n // Already loading\n if (googleSDKLoading) {\n return googleSDKLoading;\n }\n\n googleSDKLoading = new Promise((resolve, reject) => {\n // Check if already in DOM\n if (window.google?.accounts) {\n googleSDKLoaded = true;\n resolve();\n return;\n }\n\n console.log(\"[Auth Google] Loading Google Identity Services SDK\");\n\n const script = document.createElement(\"script\");\n script.src = \"https://accounts.google.com/gsi/client\";\n script.async = true;\n script.defer = true;\n\n script.onload = () => {\n console.log(\"[Auth Google] SDK loaded successfully\");\n googleSDKLoaded = true;\n resolve();\n };\n\n script.onerror = () => {\n console.error(\"[Auth Google] Failed to load SDK\");\n googleSDKLoading = null;\n reject(new Error(\"Failed to load Google Identity Services SDK\"));\n };\n\n document.head.appendChild(script);\n });\n\n return googleSDKLoading;\n}\n\n// ============================================\n// SIGN IN\n// ============================================\n\n/**\n * Sign in with Google using Google Identity Services.\n * Uses One Tap flow with popup fallback.\n *\n * @param config - Auth configuration with Google client ID\n * @returns AuthResult with tokens on success\n */\nexport async function signInWithGoogle(config: AuthConfig): Promise<AuthResult> {\n console.log(\"[Auth Google] Starting Google sign-in\");\n console.log(\"[Auth Google] Current origin:\", window.location.origin);\n\n // Validate config\n if (!config.google?.clientId) {\n console.error(\"[Auth Google] No client ID configured\");\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Google client ID not configured\",\n provider: \"google\",\n };\n }\n\n console.log(\"[Auth Google] Client ID:\", config.google.clientId.substring(0, 20) + \"...\");\n\n try {\n // Load SDK if not loaded\n console.log(\"[Auth Google] Loading SDK...\");\n await loadGoogleSDK();\n\n if (!window.google?.accounts) {\n throw new Error(\"Google SDK not available after loading\");\n }\n\n console.log(\"[Auth Google] SDK loaded, starting OAuth flow...\");\n\n // Use direct OAuth popup flow (more reliable than One Tap)\n return await signInWithGoogleRedirect(config);\n } catch (error) {\n console.error(\"[Auth Google] Sign-in error:\", error);\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: error instanceof Error ? error.message : \"Google login failed\",\n provider: \"google\",\n };\n }\n}\n\n/**\n * Sign in using OAuth popup flow\n */\nasync function signInWithGooglePopup(config: AuthConfig): Promise<AuthResult> {\n return new Promise((resolve) => {\n console.log(\"[Auth Google] Using popup flow\");\n\n // Generate nonce for security\n const nonce = Math.random().toString(36).substring(2, 15);\n\n // Initialize Google Sign-In\n window.google!.accounts.id.initialize({\n client_id: config.google!.clientId,\n callback: async (response: GoogleCredentialResponse) => {\n console.log(\"[Auth Google] Received credential response\");\n\n if (response.credential) {\n // Exchange id_token for our backend tokens\n const result = await exchangeToken(\n { id_token: response.credential },\n \"google\",\n config\n );\n resolve(result);\n } else {\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: \"No credential received from Google\",\n provider: \"google\",\n });\n }\n },\n auto_select: false,\n cancel_on_tap_outside: true,\n context: \"signin\",\n nonce,\n });\n\n // Show the One Tap prompt\n window.google!.accounts.id.prompt((notification: PromptNotification) => {\n if (notification.isNotDisplayed()) {\n const reason = notification.getNotDisplayedReason();\n console.log(\"[Auth Google] Prompt not displayed:\", reason);\n\n // Fall back to OAuth redirect if One Tap fails\n if (reason === \"opt_out_or_no_session\" || reason === \"suppressed_by_user\") {\n console.log(\"[Auth Google] Falling back to OAuth redirect\");\n signInWithGoogleRedirect(config).then(resolve);\n } else {\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: `Google Sign-In not available: ${reason}`,\n provider: \"google\",\n });\n }\n } else if (notification.isSkippedMoment()) {\n const reason = notification.getSkippedReason();\n console.log(\"[Auth Google] Prompt skipped:\", reason);\n resolve({\n success: false,\n state: \"cancelled\",\n tokens: null,\n message: \"Google Sign-In was skipped\",\n provider: \"google\",\n });\n } else if (notification.isDismissedMoment()) {\n const reason = notification.getDismissedReason();\n console.log(\"[Auth Google] Prompt dismissed:\", reason);\n\n if (reason === \"credential_returned\") {\n // Success - callback will handle this\n return;\n }\n\n resolve({\n success: false,\n state: \"cancelled\",\n tokens: null,\n message: \"Google Sign-In was cancelled\",\n provider: \"google\",\n });\n }\n });\n });\n}\n\n/**\n * Fallback: Sign in using OAuth redirect flow\n */\nasync function signInWithGoogleRedirect(config: AuthConfig): Promise<AuthResult> {\n return new Promise((resolve) => {\n const clientId = config.google!.clientId;\n const redirectUri = window.location.origin;\n const nonce = Math.random().toString(36).substring(2, 15);\n\n console.log(\"[Auth Google] OAuth redirect flow:\");\n console.log(\" - Client ID:\", clientId);\n console.log(\" - Redirect URI:\", redirectUri);\n console.log(\" ⚠️ Make sure this redirect URI is added to Google Cloud Console!\");\n\n const params = new URLSearchParams({\n client_id: clientId,\n redirect_uri: redirectUri,\n response_type: \"id_token\",\n scope: \"openid email profile\",\n nonce,\n prompt: \"select_account\",\n });\n\n const authUrl = `https://accounts.google.com/o/oauth2/v2/auth?${params}`;\n console.log(\"[Auth Google] Auth URL:\", authUrl);\n\n // Open popup\n const width = 500;\n const height = 600;\n const left = window.screenX + (window.outerWidth - width) / 2;\n const top = window.screenY + (window.outerHeight - height) / 2;\n\n const popup = window.open(\n authUrl,\n \"google-auth\",\n `width=${width},height=${height},left=${left},top=${top}`\n );\n\n if (!popup) {\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Popup was blocked. Please allow popups for this site.\",\n provider: \"google\",\n });\n return;\n }\n\n // Poll for popup close or redirect\n const pollInterval = setInterval(() => {\n try {\n // Check if popup was closed\n if (popup.closed) {\n clearInterval(pollInterval);\n resolve({\n success: false,\n state: \"cancelled\",\n tokens: null,\n message: \"Google Sign-In was cancelled\",\n provider: \"google\",\n });\n return;\n }\n\n // Try to read URL (will fail while on Google's domain)\n const url = popup.location.href;\n\n // Check if redirected back to our origin\n if (url.startsWith(redirectUri)) {\n clearInterval(pollInterval);\n popup.close();\n\n // Parse the hash fragment\n const hash = new URL(url.replace(\"#\", \"?\")).searchParams;\n const idToken = hash.get(\"id_token\");\n const error = hash.get(\"error\");\n\n if (error) {\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: hash.get(\"error_description\") || error,\n provider: \"google\",\n });\n return;\n }\n\n if (idToken) {\n // Exchange id_token for our backend tokens\n exchangeToken({ id_token: idToken }, \"google\", config).then(resolve);\n } else {\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: \"No token received from Google\",\n provider: \"google\",\n });\n }\n }\n } catch {\n // Cross-origin error - popup still on Google's domain, keep polling\n }\n }, 500);\n\n // Timeout after 5 minutes\n setTimeout(() => {\n clearInterval(pollInterval);\n if (!popup.closed) {\n popup.close();\n }\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Google Sign-In timed out\",\n provider: \"google\",\n });\n }, 5 * 60 * 1000);\n });\n}\n\n","import type { AuthConfig, AuthResult } from \"../types\";\nimport { exchangeToken } from \"../services/tokenService\";\n\n// ============================================\n// APPLE SIGN IN JS TYPES\n// ============================================\n\ndeclare global {\n interface Window {\n AppleID?: {\n auth: {\n init: (config: AppleInitConfig) => void;\n signIn: (config?: AppleSignInConfig) => Promise<AppleSignInResponse>;\n };\n };\n }\n}\n\ninterface AppleInitConfig {\n clientId: string;\n scope?: string;\n redirectURI: string;\n state?: string;\n nonce?: string;\n usePopup?: boolean;\n}\n\ninterface AppleSignInConfig {\n scope?: string;\n state?: string;\n nonce?: string;\n}\n\ninterface AppleSignInResponse {\n authorization: {\n code: string;\n id_token?: string;\n state?: string;\n };\n user?: {\n email?: string;\n name?: {\n firstName?: string;\n lastName?: string;\n };\n };\n}\n\ninterface AppleSignInError {\n error: string;\n}\n\n// ============================================\n// STATE\n// ============================================\n\nlet appleSDKLoaded = false;\nlet appleSDKLoading: Promise<void> | null = null;\nlet appleInitialized = false;\n\n// ============================================\n// SDK LOADER\n// ============================================\n\n/**\n * Load Apple Sign In JS SDK\n */\nexport function loadAppleSDK(): Promise<void> {\n // Already loaded\n if (appleSDKLoaded && window.AppleID) {\n return Promise.resolve();\n }\n\n // Already loading\n if (appleSDKLoading) {\n return appleSDKLoading;\n }\n\n appleSDKLoading = new Promise((resolve, reject) => {\n // Check if already in DOM\n if (window.AppleID) {\n appleSDKLoaded = true;\n resolve();\n return;\n }\n\n console.log(\"[Auth Apple] Loading Apple Sign In JS SDK\");\n\n const script = document.createElement(\"script\");\n script.src =\n \"https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js\";\n script.async = true;\n\n script.onload = () => {\n console.log(\"[Auth Apple] SDK loaded successfully\");\n appleSDKLoaded = true;\n resolve();\n };\n\n script.onerror = () => {\n console.error(\"[Auth Apple] Failed to load SDK\");\n appleSDKLoading = null;\n reject(new Error(\"Failed to load Apple Sign In JS SDK\"));\n };\n\n document.head.appendChild(script);\n });\n\n return appleSDKLoading;\n}\n\n// ============================================\n// INITIALIZE\n// ============================================\n\n/**\n * Initialize Apple Sign In with configuration\n */\nfunction initializeApple(config: AuthConfig): void {\n if (appleInitialized || !window.AppleID || !config.apple) {\n return;\n }\n\n // For localhost testing, always use current origin\n // Apple requires exact domain matching\n const isLocalhost = window.location.hostname === \"localhost\" || \n window.location.hostname === \"127.0.0.1\";\n const redirectUri = isLocalhost \n ? window.location.origin \n : (config.apple.redirectUri || window.location.origin);\n\n console.log(\"[Auth Apple] Initializing with config:\", {\n clientId: config.apple.clientId,\n redirectUri,\n isLocalhost,\n currentOrigin: window.location.origin,\n });\n\n window.AppleID.auth.init({\n clientId: config.apple.clientId,\n scope: \"name email\",\n redirectURI: redirectUri,\n usePopup: true,\n });\n\n appleInitialized = true;\n}\n\n// ============================================\n// SIGN IN\n// ============================================\n\n/**\n * Sign in with Apple using Apple Sign In JS.\n *\n * @param config - Auth configuration with Apple client ID\n * @returns AuthResult with tokens on success\n */\nexport async function signInWithApple(config: AuthConfig): Promise<AuthResult> {\n console.log(\"[Auth Apple] Starting Apple sign-in\");\n\n // Validate config\n if (!config.apple?.clientId) {\n console.error(\"[Auth Apple] No client ID configured\");\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Apple client ID not configured\",\n provider: \"apple\",\n };\n }\n\n // Check if running on localhost - warn about Apple limitations\n const isLocalhost = window.location.hostname === \"localhost\" || \n window.location.hostname === \"127.0.0.1\";\n if (isLocalhost) {\n console.warn(\"[Auth Apple] Running on localhost - Apple Sign In requires:\");\n console.warn(\" 1. Your Service ID (com.gpt.godweb) must have localhost configured in Apple Developer Portal\");\n console.warn(\" 2. Return URL must include: http://localhost:5173 (or your port)\");\n }\n\n try {\n // Load SDK if not loaded\n console.log(\"[Auth Apple] Loading SDK...\");\n await loadAppleSDK();\n\n if (!window.AppleID) {\n throw new Error(\"Apple SDK not available after loading\");\n }\n\n // Reset initialization to ensure fresh config\n appleInitialized = false;\n \n // Initialize Apple Sign In\n initializeApple(config);\n\n console.log(\"[Auth Apple] Calling Apple signIn...\");\n\n // Attempt sign in\n const response = await window.AppleID.auth.signIn();\n\n console.log(\"[Auth Apple] Received response\");\n\n // Apple returns authorization.code for web\n const code = response.authorization?.code;\n const idToken = response.authorization?.id_token;\n\n if (code) {\n console.log(\"[Auth Apple] Exchanging authorization code\");\n return await exchangeToken({ code }, \"apple\", config);\n } else if (idToken) {\n console.log(\"[Auth Apple] Exchanging id_token\");\n return await exchangeToken({ id_token: idToken }, \"apple\", config);\n } else {\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"No authorization code or token received from Apple\",\n provider: \"apple\",\n };\n }\n } catch (error) {\n // Apple throws specific errors\n const appleError = error as AppleSignInError;\n\n // User cancelled\n if (\n appleError?.error === \"popup_closed_by_user\" ||\n appleError?.error === \"user_cancelled_authorize\"\n ) {\n console.log(\"[Auth Apple] Sign-in cancelled by user\");\n return {\n success: false,\n state: \"cancelled\",\n tokens: null,\n message: \"Apple Sign-In was cancelled\",\n provider: \"apple\",\n };\n }\n\n console.error(\"[Auth Apple] Sign-in error:\", error);\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message:\n appleError?.error ||\n (error instanceof Error ? error.message : \"Apple login failed\"),\n provider: \"apple\",\n };\n }\n}\n\n","import type { AuthConfig, AuthResult } from \"../types\";\nimport { exchangeToken } from \"../services/tokenService\";\n\n// ============================================\n// EMAIL SIGN-IN STRATEGY\n// ============================================\n\n/**\n * Sign in with email and password.\n * Sends credentials to backend for authentication.\n *\n * @param email - User's email address\n * @param password - User's password\n * @param config - Auth configuration with backendUrl\n * @returns AuthResult with tokens on success\n */\nexport async function signInWithEmail(\n email: string,\n password: string,\n config: AuthConfig\n): Promise<AuthResult> {\n console.log(\"[Auth Email] Starting email sign-in\");\n\n // Validate inputs\n if (!email || !email.trim()) {\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Email is required\",\n provider: \"password\",\n };\n }\n\n if (!password) {\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Password is required\",\n provider: \"password\",\n };\n }\n\n // Basic email format validation\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(email.trim())) {\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Please enter a valid email address\",\n provider: \"password\",\n };\n }\n\n try {\n // Exchange credentials for tokens\n // Note: grant_type is \"password\" for email/password auth (OAuth2 standard)\n const result = await exchangeToken(\n {\n username: email.trim(),\n password,\n },\n \"password\",\n config\n );\n\n if (result.success) {\n console.log(\"[Auth Email] Sign-in successful\");\n } else {\n console.log(\"[Auth Email] Sign-in failed:\", result.message);\n }\n\n return result;\n } catch (error) {\n console.error(\"[Auth Email] Sign-in error:\", error);\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: error instanceof Error ? error.message : \"Email login failed\",\n provider: \"password\",\n };\n }\n}\n\n","import React, { useState } from \"react\";\nimport { useAuthInternal } from \"../hooks/useAuth\";\nimport { signInWithGoogle } from \"../strategies/google\";\nimport { signInWithApple } from \"../strategies/apple\";\nimport { signInWithEmail } from \"../strategies/email\";\n\n// ============================================\n// ICONS\n// ============================================\n\nconst GoogleIcon = () => (\n <svg className=\"w-5 h-5\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z\"\n fill=\"#4285F4\"\n />\n <path\n d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"\n fill=\"#34A853\"\n />\n <path\n d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\"\n fill=\"#FBBC05\"\n />\n <path\n d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"\n fill=\"#EA4335\"\n />\n </svg>\n);\n\nconst AppleIcon = () => (\n <svg className=\"w-5 h-5\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.48-3.24 0-1.44.62-2.2.44-3.06-.4C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09l.01-.01zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z\" />\n </svg>\n);\n\nconst LoadingSpinner = () => (\n <svg\n className=\"animate-spin h-5 w-5\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n);\n\n// ============================================\n// BUTTON COMPONENT\n// ============================================\n\ninterface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: \"primary\" | \"secondary\";\n isLoading?: boolean;\n children: React.ReactNode;\n}\n\nconst Button: React.FC<ButtonProps> = ({\n variant = \"primary\",\n isLoading = false,\n disabled,\n children,\n className = \"\",\n ...props\n}) => {\n const baseClasses =\n \"min-h-[52px] px-6 rounded-[99px] font-semibold text-base transition-all duration-200 flex items-center justify-center gap-2 focus:outline-none\";\n\n const variantClasses = {\n primary: \"bg-black text-white active:opacity-80 active:scale-[0.98]\",\n secondary:\n \"bg-white text-black border border-black active:opacity-80 active:scale-[0.98]\",\n };\n\n const disabledClasses = \"opacity-40 cursor-not-allowed pointer-events-none\";\n\n return (\n <button\n className={`${baseClasses} ${variantClasses[variant]} ${\n disabled || isLoading ? disabledClasses : \"\"\n } ${className}`}\n disabled={disabled || isLoading}\n {...props}\n >\n {isLoading ? (\n <>\n <LoadingSpinner />\n <span>Loading...</span>\n </>\n ) : (\n children\n )}\n </button>\n );\n};\n\n// ============================================\n// INPUT COMPONENT\n// ============================================\n\ninterface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n label?: string;\n error?: string;\n}\n\nconst Input: React.FC<InputProps> = ({\n label,\n error,\n className = \"\",\n ...props\n}) => {\n return (\n <div className=\"space-y-1\">\n {label && (\n <label className=\"block text-sm font-medium text-gray-700\">\n {label}\n </label>\n )}\n <input\n className={`w-full px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-black focus:border-transparent ${\n error ? \"border-red-500\" : \"border-gray-300\"\n } ${className}`}\n {...props}\n />\n {error && <p className=\"text-sm text-red-500\">{error}</p>}\n </div>\n );\n};\n\n// ============================================\n// LOGIN PAGE VIEWS\n// ============================================\n\ntype View = \"main\" | \"email\";\n\n// ============================================\n// LOGIN PAGE COMPONENT\n// ============================================\n\n/**\n * LoginPage - Complete login UI component.\n * Gets config from AuthProvider context.\n * Handles Google, Apple, and Email sign-in.\n *\n * @example\n * ```tsx\n * function App() {\n * const { tokens, isAuthLoaded } = useAuth();\n *\n * if (!isAuthLoaded) return <SplashScreen />;\n * if (!tokens) return <LoginPage />;\n * return <MainApp />;\n * }\n * ```\n */\nexport function LoginPage() {\n const { config, _setTokens, _setLoading, isLoading } = useAuthInternal();\n\n const [view, setView] = useState<View>(\"main\");\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n const [fieldErrors, setFieldErrors] = useState<{\n email?: string;\n password?: string;\n }>({});\n\n // ============================================\n // HANDLERS\n // ============================================\n\n const handleGoogleLogin = async () => {\n if (!config.google) {\n setError(\"Google sign-in is not configured\");\n return;\n }\n\n setError(null);\n _setLoading(true);\n\n try {\n const result = await signInWithGoogle(config);\n\n if (result.success && result.tokens) {\n await _setTokens(result.tokens);\n } else if (result.state !== \"cancelled\") {\n setError(result.message || \"Google sign-in failed\");\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Google sign-in failed\");\n } finally {\n _setLoading(false);\n }\n };\n\n const handleAppleLogin = async () => {\n if (!config.apple) {\n setError(\"Apple sign-in is not configured\");\n return;\n }\n\n setError(null);\n _setLoading(true);\n\n try {\n const result = await signInWithApple(config);\n\n if (result.success && result.tokens) {\n await _setTokens(result.tokens);\n } else if (result.state !== \"cancelled\") {\n setError(result.message || \"Apple sign-in failed\");\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Apple sign-in failed\");\n } finally {\n _setLoading(false);\n }\n };\n\n const handleEmailLogin = async (e: React.FormEvent) => {\n e.preventDefault();\n\n // Validate\n const errors: { email?: string; password?: string } = {};\n if (!email.trim()) {\n errors.email = \"Email is required\";\n }\n if (!password) {\n errors.password = \"Password is required\";\n }\n\n if (Object.keys(errors).length > 0) {\n setFieldErrors(errors);\n return;\n }\n\n setError(null);\n setFieldErrors({});\n _setLoading(true);\n\n try {\n const result = await signInWithEmail(email, password, config);\n\n if (result.success && result.tokens) {\n await _setTokens(result.tokens);\n } else {\n setError(result.message || \"Email sign-in failed\");\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Email sign-in failed\");\n } finally {\n _setLoading(false);\n }\n };\n\n // ============================================\n // EMAIL VIEW\n // ============================================\n\n if (view === \"email\") {\n return (\n <div className=\"min-h-screen bg-white flex flex-col px-5 py-8\">\n <div className=\"flex-1 flex flex-col max-w-md mx-auto w-full\">\n {/* Back Button */}\n <button\n onClick={() => {\n setView(\"main\");\n setError(null);\n setFieldErrors({});\n }}\n className=\"self-start mb-8 flex items-center text-gray-600 active:opacity-80\"\n >\n <svg\n className=\"w-5 h-5 mr-2\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 19l-7-7 7-7\"\n />\n </svg>\n Back\n </button>\n\n {/* Header */}\n <div className=\"mb-12 text-center\">\n <h1 className=\"text-[30px] font-bold text-black mb-2\">Sign In</h1>\n <p className=\"text-base text-gray-600\">\n Enter your email and password\n </p>\n </div>\n\n {/* Error Message */}\n {error && (\n <div className=\"mb-6 p-4 bg-red-50 border border-red-200 rounded-lg\">\n <p className=\"text-sm text-red-600\">{error}</p>\n </div>\n )}\n\n {/* Email Form */}\n <form onSubmit={handleEmailLogin} className=\"space-y-6\">\n <Input\n type=\"email\"\n label=\"Email\"\n placeholder=\"Enter your email\"\n value={email}\n onChange={(e) => {\n setEmail(e.target.value);\n if (fieldErrors.email)\n setFieldErrors({ ...fieldErrors, email: undefined });\n }}\n error={fieldErrors.email}\n autoComplete=\"email\"\n />\n\n <Input\n type=\"password\"\n label=\"Password\"\n placeholder=\"Enter your password\"\n value={password}\n onChange={(e) => {\n setPassword(e.target.value);\n if (fieldErrors.password)\n setFieldErrors({ ...fieldErrors, password: undefined });\n }}\n error={fieldErrors.password}\n autoComplete=\"current-password\"\n />\n\n <Button\n type=\"submit\"\n variant=\"primary\"\n isLoading={isLoading}\n className=\"w-full mt-8\"\n >\n Sign In\n </Button>\n </form>\n </div>\n </div>\n );\n }\n\n // ============================================\n // MAIN VIEW\n // ============================================\n\n return (\n <div className=\"min-h-screen bg-white flex flex-col px-5 py-8\">\n <div className=\"flex-1 flex flex-col justify-center max-w-md mx-auto w-full\">\n {/* Header */}\n <div className=\"mb-12 text-center\">\n <h1 className=\"text-[30px] font-bold text-black mb-2\">\n Welcome Back\n </h1>\n <p className=\"text-base text-gray-600\">Sign in to continue</p>\n </div>\n\n {/* Error Message */}\n {error && (\n <div className=\"mb-6 p-4 bg-red-50 border border-red-200 rounded-lg\">\n <p className=\"text-sm text-red-600\">{error}</p>\n </div>\n )}\n\n {/* Social Login Buttons */}\n <div className=\"space-y-3 mb-8\">\n {config.google && (\n <Button\n variant=\"secondary\"\n onClick={handleGoogleLogin}\n disabled={isLoading}\n className=\"w-full\"\n >\n <GoogleIcon />\n Continue with Google\n </Button>\n )}\n\n {config.apple && (\n <Button\n variant=\"secondary\"\n onClick={handleAppleLogin}\n disabled={isLoading}\n className=\"w-full\"\n >\n <AppleIcon />\n Continue with Apple\n </Button>\n )}\n </div>\n\n {/* Divider */}\n {config.email?.enabled && (config.google || config.apple) && (\n <div className=\"relative mb-8\">\n <div className=\"absolute inset-0 flex items-center\">\n <div className=\"w-full border-t border-gray-300\"></div>\n </div>\n <div className=\"relative flex justify-center text-sm\">\n <span className=\"px-4 bg-white text-gray-500\">\n Or continue with email\n </span>\n </div>\n </div>\n )}\n\n {/* Email Login Button */}\n {config.email?.enabled && (\n <Button\n variant=\"primary\"\n onClick={() => setView(\"email\")}\n disabled={isLoading}\n className=\"w-full\"\n >\n Continue with Email\n </Button>\n )}\n </div>\n\n {/* Disclaimer */}\n <div className=\"pb-[36px] px-5\">\n <p className=\"text-xs text-gray-500 text-center leading-relaxed max-w-sm mx-auto\">\n By signing in, you agree to our{\" \"}\n <a\n href=\"https://app.godgpt.fun/terms-of-service/\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-gray-700 underline underline-offset-2 hover:text-gray-900\"\n >\n Terms of Service\n </a>{\" \"}\n and{\" \"}\n <a\n href=\"https://app.godgpt.fun/privacy-policy/\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-gray-700 underline underline-offset-2 hover:text-gray-900\"\n >\n Privacy Policy\n </a>\n .\n </p>\n </div>\n </div>\n );\n}\n\n\n\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/auth/config.ts","../src/auth/services/storageService.ts","../src/auth/components/AuthProvider.tsx","../src/auth/hooks/useAuth.ts","../src/auth/services/tokenService.ts","../src/auth/strategies/google.ts","../src/auth/strategies/apple.ts","../src/auth/strategies/email.ts","../src/auth/components/LoginPage.tsx"],"names":["jsx","useState"],"mappings":";;;;;;AAUO,SAAS,eAAe,MAAA,EAA0B;AACvD,EAAA,IAAI,CAAC,OAAO,UAAA,EAAY;AACtB,IAAA,MAAM,IAAI,MAAM,6CAA6C,CAAA;AAAA,EAC/D;AAEA,EAAA,IAAI,CAAC,OAAO,MAAA,IAAU,CAAC,OAAO,KAAA,IAAS,CAAC,MAAA,CAAO,KAAA,EAAO,OAAA,EAAS;AAC7D,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN;AAAA,KACF;AAAA,EACF;AAGA,EAAA,IAAI,MAAA,CAAO,MAAA,IAAU,CAAC,MAAA,CAAO,OAAO,QAAA,EAAU;AAC5C,IAAA,MAAM,IAAI,MAAM,2DAA2D,CAAA;AAAA,EAC7E;AAGA,EAAA,IAAI,MAAA,CAAO,KAAA,IAAS,CAAC,MAAA,CAAO,MAAM,QAAA,EAAU;AAC1C,IAAA,MAAM,IAAI,MAAM,yDAAyD,CAAA;AAAA,EAC3E;AAEA,EAAA,OAAA,CAAQ,IAAI,0BAAA,EAA4B;AAAA,IACtC,YAAY,MAAA,CAAO,UAAA;AAAA,IACnB,SAAA,EAAW,CAAC,CAAC,MAAA,CAAO,MAAA;AAAA,IACpB,QAAA,EAAU,CAAC,CAAC,MAAA,CAAO,KAAA;AAAA,IACnB,QAAA,EAAU,CAAC,CAAC,MAAA,CAAO,KAAA,EAAO;AAAA,GAC3B,CAAA;AACH;;;ACbO,IAAM,mBAAA,GAAsC;AAAA,EACjD,OAAA,EAAS,CAAC,GAAA,KAAQ;AAChB,IAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,IAAA;AAC1C,IAAA,OAAO,YAAA,CAAa,QAAQ,GAAG,CAAA;AAAA,EACjC,CAAA;AAAA,EACA,OAAA,EAAS,CAAC,GAAA,EAAK,KAAA,KAAU;AACvB,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACnC,IAAA,YAAA,CAAa,OAAA,CAAQ,KAAK,KAAK,CAAA;AAAA,EACjC,CAAA;AAAA,EACA,UAAA,EAAY,CAAC,GAAA,KAAQ;AACnB,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACnC,IAAA,YAAA,CAAa,WAAW,GAAG,CAAA;AAAA,EAC7B;AACF;AAKO,IAAM,uBAAuB,MAAsB;AACxD,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAoB;AACtC,EAAA,OAAO;AAAA,IACL,SAAS,CAAC,GAAA,KAAQ,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA,IAAK,IAAA;AAAA,IACpC,OAAA,EAAS,CAAC,GAAA,EAAK,KAAA,KAAU;AACvB,MAAA,KAAA,CAAM,GAAA,CAAI,KAAK,KAAK,CAAA;AAAA,IACtB,CAAA;AAAA,IACA,UAAA,EAAY,CAAC,GAAA,KAAQ;AACnB,MAAA,KAAA,CAAM,OAAO,GAAG,CAAA;AAAA,IAClB;AAAA,GACF;AACF;AAMA,IAAM,SAAA,GAAY,iBAAA;AAMX,SAAS,qBAAqB,OAAA,EAAyB;AAC5D,EAAA,OAAO;AAAA;AAAA;AAAA;AAAA,IAIL,MAAM,WAAW,MAAA,EAAgC;AAC/C,MAAA,IAAI;AACF,QAAA,MAAM,WAAA,GAAc;AAAA,UAClB,GAAG,MAAA;AAAA,UACH,SAAA,EAAW,KAAK,GAAA;AAAI,SACtB;AACA,QAAA,MAAM,QAAQ,OAAA,CAAQ,SAAA,EAAW,IAAA,CAAK,SAAA,CAAU,WAAW,CAAC,CAAA;AAC5D,QAAA,OAAA,CAAQ,IAAI,0CAA0C,CAAA;AAAA,MACxD,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAA,CAAM,yCAAyC,KAAK,CAAA;AAC5D,QAAA,MAAM,KAAA;AAAA,MACR;AAAA,IACF,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAM,SAAA,GAAqC;AACzC,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,OAAA,CAAQ,SAAS,CAAA;AAC5C,QAAA,IAAI,CAAC,IAAA,EAAM;AACT,UAAA,OAAO,IAAA;AAAA,QACT;AAEA,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAG9B,QAAA,MAAM,EAAE,SAAA,EAAW,SAAA,EAAW,GAAG,QAAO,GAAI,MAAA;AAE5C,QAAA,OAAO,MAAA;AAAA,MACT,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAA,CAAM,wCAAwC,KAAK,CAAA;AAE3D,QAAA,MAAM,KAAK,WAAA,EAAY;AACvB,QAAA,OAAO,IAAA;AAAA,MACT;AAAA,IACF,CAAA;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,UAAA,GAAqE;AACzE,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,OAAA,CAAQ,SAAS,CAAA;AAC5C,QAAA,IAAI,CAAC,IAAA,EAAM;AACT,UAAA,OAAO,IAAA;AAAA,QACT;AACA,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAI9B,QAAA,MAAM,EAAE,SAAA,EAAW,GAAG,MAAA,EAAO,GAAI,MAAA;AAEjC,QAAA,OAAO,EAAE,QAA2B,SAAA,EAAU;AAAA,MAChD,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAA,CAAM,0CAA0C,KAAK,CAAA;AAC7D,QAAA,OAAO,IAAA;AAAA,MACT;AAAA,IACF,CAAA;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,WAAA,GAA6B;AACjC,MAAA,IAAI;AACF,QAAA,MAAM,OAAA,CAAQ,WAAW,SAAS,CAAA;AAClC,QAAA,OAAA,CAAQ,IAAI,+BAA+B,CAAA;AAAA,MAC7C,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAA,CAAM,0CAA0C,KAAK,CAAA;AAAA,MAC/D;AAAA,IACF,CAAA;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,SAAA,GAA8B;AAClC,MAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,OAAA,CAAQ,SAAS,CAAA;AAC5C,MAAA,OAAO,IAAA,KAAS,IAAA;AAAA,IAClB,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAM,cAAA,GAAmC;AACvC,MAAA,IAAI;AACF,QAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,UAAA,EAAW;AACtC,QAAA,IAAI,CAAC,OAAA,EAAS;AACZ,UAAA,OAAO,IAAA;AAAA,QACT;AAEA,QAAA,MAAM,EAAE,SAAA,EAAW,MAAA,EAAO,GAAI,OAAA;AAC9B,QAAA,MAAM,YAAY,MAAA,CAAO,UAAA;AAEzB,QAAA,IAAI,CAAC,SAAA,IAAa,CAAC,SAAA,EAAW;AAC5B,UAAA,OAAO,IAAA;AAAA,QACT;AAIA,QAAA,MAAM,cAAA,GAAiB,YAAY,SAAA,GAAY,GAAA;AAC/C,QAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,EAAI,IAAK,cAAA;AAEhC,QAAA,IAAI,SAAA,EAAW;AACb,UAAA,OAAA,CAAQ,IAAI,iCAAiC,CAAA;AAAA,QAC/C;AAEA,QAAA,OAAO,SAAA;AAAA,MACT,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAA;AAAA,UACN,kDAAA;AAAA,UACA;AAAA,SACF;AACA,QAAA,OAAO,IAAA;AAAA,MACT;AAAA,IACF,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAM,kBAAA,GAAsC;AAC1C,MAAA,IAAI;AACF,QAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,UAAA,EAAW;AACtC,QAAA,IAAI,CAAC,OAAA,EAAS;AACZ,UAAA,OAAO,CAAA;AAAA,QACT;AAEA,QAAA,MAAM,EAAE,SAAA,EAAW,MAAA,EAAO,GAAI,OAAA;AAC9B,QAAA,MAAM,YAAY,MAAA,CAAO,UAAA;AAEzB,QAAA,IAAI,CAAC,SAAA,IAAa,CAAC,SAAA,EAAW;AAC5B,UAAA,OAAO,CAAA;AAAA,QACT;AAEA,QAAA,MAAM,cAAA,GAAiB,YAAY,SAAA,GAAY,GAAA;AAC/C,QAAA,MAAM,aAAA,GAAgB,cAAA,GAAiB,IAAA,CAAK,GAAA,EAAI;AAEhD,QAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,aAAa,CAAA;AAAA,MAClC,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAA,CAAM,mDAAmD,KAAK,CAAA;AACtE,QAAA,OAAO,CAAA;AAAA,MACT;AAAA,IACF;AAAA,GACF;AACF;AAgBO,IAAM,cAAA,GAAiB,qBAAqB,mBAAmB;ACjN/D,IAAM,mBAAA,GACX,cAA+C,IAAI,CAAA;AAsC9C,SAAS,YAAA,CAAa;AAAA,EAC3B,QAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAAsB;AAKpB,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAAyB,IAAI,CAAA;AACzD,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,KAAK,CAAA;AAChD,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAS,KAAK,CAAA;AAGtD,EAAA,MAAM,WAAA,GAAc,OAAO,QAAQ,CAAA;AACnC,EAAA,WAAA,CAAY,OAAA,GAAU,QAAA;AAGtB,EAAA,MAAM,cAAA,GAAiB,OAAO,KAAK,CAAA;AAMnC,EAAA,SAAA,CAAU,MAAM;AAEd,IAAA,IAAI,eAAe,OAAA,EAAS;AAC1B,MAAA;AAAA,IACF;AACA,IAAA,cAAA,CAAe,OAAA,GAAU,IAAA;AAGzB,IAAA,cAAA,CAAe,MAAM,CAAA;AAGrB,IAAA,MAAM,iBAAiB,YAAY;AACjC,MAAA,OAAA,CAAQ,IAAI,wCAAwC,CAAA;AAEpD,MAAA,IAAI;AAEF,QAAA,MAAM,YAAA,GAAe,MAAM,cAAA,CAAe,SAAA,EAAU;AAEpD,QAAA,IAAI,YAAA,EAAc;AAEhB,UAAA,MAAM,SAAA,GAAY,MAAM,cAAA,CAAe,cAAA,EAAe;AAEtD,UAAA,IAAI,SAAA,EAAW;AACb,YAAA,OAAA,CAAQ,IAAI,oDAAoD,CAAA;AAChE,YAAA,MAAM,eAAe,WAAA,EAAY;AACjC,YAAA,WAAA,CAAY,OAAA,IAAU;AAAA,UACxB,CAAA,MAAO;AACL,YAAA,OAAA,CAAQ,IAAI,sDAAsD,CAAA;AAClE,YAAA,SAAA,CAAU,YAAY,CAAA;AAAA,UACxB;AAAA,QACF,CAAA,MAAO;AACL,UAAA,OAAA,CAAQ,IAAI,uCAAuC,CAAA;AAAA,QACrD;AAAA,MACF,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAA,CAAM,2CAA2C,KAAK,CAAA;AAE9D,QAAA,MAAM,eAAe,WAAA,EAAY;AAAA,MACnC,CAAA,SAAE;AACA,QAAA,eAAA,CAAgB,IAAI,CAAA;AAAA,MACtB;AAAA,IACF,CAAA;AAEA,IAAA,cAAA,EAAe;AAAA,EACjB,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAMX,EAAA,MAAM,UAAA,GAAa,WAAA,CAAY,OAAO,SAAA,KAAuB;AAC3D,IAAA,OAAA,CAAQ,IAAI,+BAA+B,CAAA;AAG3C,IAAA,MAAM,cAAA,CAAe,WAAW,SAAS,CAAA;AAGzC,IAAA,SAAA,CAAU,SAAS,CAAA;AAAA,EACrB,CAAA,EAAG,EAAE,CAAA;AAML,EAAA,MAAM,WAAA,GAAc,WAAA,CAAY,CAAC,OAAA,KAAqB;AACpD,IAAA,YAAA,CAAa,OAAO,CAAA;AAAA,EACtB,CAAA,EAAG,EAAE,CAAA;AAML,EAAA,MAAM,MAAA,GAAS,YAAY,YAAY;AACrC,IAAA,OAAA,CAAQ,IAAI,4BAA4B,CAAA;AAGxC,IAAA,MAAM,eAAe,WAAA,EAAY;AAGjC,IAAA,SAAA,CAAU,IAAI,CAAA;AAGd,IAAA,WAAA,CAAY,OAAA,IAAU;AAAA,EACxB,CAAA,EAAG,EAAE,CAAA;AAML,EAAA,MAAM,YAAA,GAAe,OAAA;AAAA,IACnB,OAAO;AAAA;AAAA,MAEL,MAAA;AAAA,MACA,MAAA;AAAA,MACA,SAAA;AAAA,MACA,YAAA;AAAA;AAAA,MAGA,MAAA;AAAA,MACA,UAAA;AAAA,MACA;AAAA,KACF,CAAA;AAAA,IACA,CAAC,MAAA,EAAQ,MAAA,EAAQ,WAAW,YAAA,EAAc,MAAA,EAAQ,YAAY,WAAW;AAAA,GAC3E;AAEA,EAAA,2BACG,mBAAA,CAAoB,QAAA,EAApB,EAA6B,KAAA,EAAO,cAClC,QAAA,EACH,CAAA;AAEJ;AC5KO,SAAS,OAAA,GAA4B;AAC1C,EAAA,MAAM,OAAA,GAAU,WAAW,mBAAmB,CAAA;AAE9C,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAI,MAAM,6CAA6C,CAAA;AAAA,EAC/D;AAGA,EAAA,OAAO;AAAA,IACL,QAAQ,OAAA,CAAQ,MAAA;AAAA,IAChB,QAAQ,OAAA,CAAQ,MAAA;AAAA,IAChB,WAAW,OAAA,CAAQ,SAAA;AAAA,IACnB,cAAc,OAAA,CAAQ;AAAA,GACxB;AACF;AAYO,SAAS,eAAA,GAA4C;AAC1D,EAAA,MAAM,OAAA,GAAU,WAAW,mBAAmB,CAAA;AAE9C,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAI,MAAM,qDAAqD,CAAA;AAAA,EACvE;AAEA,EAAA,OAAO,OAAA;AACT;;;ACvCA,eAAsB,aAAA,CACpB,MAAA,EACA,QAAA,EACA,MAAA,EACqB;AACrB,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,wBAAA,EAA2B,QAAQ,CAAA,uBAAA,CAAyB,CAAA;AAExE,EAAA,IAAI;AACF,IAAA,MAAM,UAAA,GAAqC;AAAA,MACzC,UAAA,EAAY,QAAA;AAAA,MACZ,SAAA,EAAW,mBAAA;AAAA;AAAA,MACX,KAAA,EAAO;AAAA,KACT;AAGA,IAAA,IAAI,YAAY,QAAA,EAAU;AACxB,MAAA,UAAA,CAAW,MAAA,GAAS,KAAA;AAAA,IACtB,CAAA,MAAA,IAAW,YAAY,OAAA,EAAS;AAC9B,MAAA,UAAA,CAAW,MAAA,GAAS,KAAA;AAAA,IACtB;AAGA,IAAA,IAAI,QAAA,KAAa,QAAA,IAAY,MAAA,CAAO,KAAA,EAAO;AACzC,MAAA,UAAA,CAAW,gBAAgB,MAAA,CAAO,KAAA;AAAA,IACpC;AACA,IAAA,IAAI,QAAA,KAAa,OAAA,IAAW,MAAA,CAAO,KAAA,EAAO;AAExC,MAAA,UAAA,CAAW,YAAA,GAAe,MAAA,CAAO,KAAA,CAAM,KAAA,IAAS,OAAO,KAAA,CAAM,QAAA;AAAA,IAC/D;AAGA,IAAA,IAAI,OAAO,QAAA,EAAU;AACnB,MAAA,UAAA,CAAW,WAAW,MAAA,CAAO,QAAA;AAAA,IAC/B;AACA,IAAA,IAAI,OAAO,IAAA,EAAM;AACf,MAAA,UAAA,CAAW,OAAO,MAAA,CAAO,IAAA;AAAA,IAC3B;AACA,IAAA,IAAI,OAAO,QAAA,EAAU;AACnB,MAAA,UAAA,CAAW,WAAW,MAAA,CAAO,QAAA;AAAA,IAC/B;AACA,IAAA,IAAI,OAAO,QAAA,EAAU;AACnB,MAAA,UAAA,CAAW,WAAW,MAAA,CAAO,QAAA;AAAA,IAC/B;AAGA,IAAA,MAAM,IAAA,GAAO,OAAO,OAAA,CAAQ,UAAU,EACnC,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,CAAC,MAAM,CAAA,EAAG,CAAC,IAAI,kBAAA,CAAmB,CAAC,CAAC,CAAA,CAAE,CAAA,CAC/C,KAAK,GAAG,CAAA;AAGX,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,YAAY,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,IAAK,CAAA;AAE5D,IAAA,MAAM,WAAW,MAAM,KAAA,CAAM,CAAA,EAAG,MAAA,CAAO,UAAU,CAAA,cAAA,CAAA,EAAkB;AAAA,MACjE,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,mCAAA;AAAA,QAChB,MAAA,EAAQ;AAAA,OACV;AAAA,MACA,IAAA;AAAA,MACA,QAAQ,UAAA,CAAW;AAAA,KACpB,CAAA;AAED,IAAA,YAAA,CAAa,SAAS,CAAA;AAGtB,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,IAAA,GAAO,KAAA,CAAM,OAAO,EAAC,CAAE,CAAA;AACxD,MAAA,OAAA,CAAQ,KAAA;AAAA,QACN,iCAAiC,QAAQ,CAAA,EAAA,CAAA;AAAA,QACzC,QAAA,CAAS,MAAA;AAAA,QACT;AAAA,OACF;AAEA,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,KAAA,EAAO,OAAA;AAAA,QACP,MAAA,EAAQ,IAAA;AAAA,QACR,OAAA,EACE,SAAA,CAAU,iBAAA,IACV,SAAA,CAAU,KAAA,IACV,QAAQ,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,QAAA,CAAS,UAAU,CAAA,CAAA;AAAA,QACjD;AAAA,OACF;AAAA,IACF;AAGA,IAAA,MAAM,MAAA,GAAU,MAAM,QAAA,CAAS,IAAA,EAAK;AAEpC,IAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,qCAAA,EAAwC,QAAQ,CAAA,CAAE,CAAA;AAE9D,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,IAAA;AAAA,MACT,KAAA,EAAO,SAAA;AAAA,MACP,MAAA,EAAQ;AAAA,QACN,cAAc,MAAA,CAAO,YAAA;AAAA,QACrB,eAAe,MAAA,CAAO,aAAA;AAAA,QACtB,YAAY,MAAA,CAAO,UAAA;AAAA,QACnB,YAAY,MAAA,CAAO;AAAA,OACrB;AAAA,MACA,OAAA,EAAS,kBAAA;AAAA,MACT;AAAA,KACF;AAAA,EACF,SAAS,KAAA,EAAO;AAEd,IAAA,MAAM,SAAA,GAAY,KAAA,YAAiB,KAAA,IAAS,KAAA,CAAM,IAAA,KAAS,YAAA;AAC3D,IAAA,MAAM,eAAe,SAAA,GACjB,kDAAA,GACA,KAAA,YAAiB,KAAA,GACjB,MAAM,OAAA,GACN,cAAA;AAEJ,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,6BAAA,EAAgC,QAAQ,CAAA,EAAA,CAAA,EAAM,KAAK,CAAA;AAEjE,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,KAAA,EAAO,OAAA;AAAA,MACP,MAAA,EAAQ,IAAA;AAAA,MACR,OAAA,EAAS,YAAA;AAAA,MACT;AAAA,KACF;AAAA,EACF;AACF;AAWA,eAAsB,YAAA,CACpB,eACA,UAAA,EACyB;AACzB,EAAA,OAAA,CAAQ,IAAI,sCAAsC,CAAA;AAElD,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAO,IAAI,eAAA,CAAgB;AAAA,MAC/B,UAAA,EAAY,eAAA;AAAA,MACZ,SAAA,EAAW,mBAAA;AAAA;AAAA,MACX;AAAA,KACD,EAAE,QAAA,EAAS;AAGZ,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,YAAY,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,IAAK,CAAA;AAE5D,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,cAAA,CAAA,EAAkB;AAAA,MAC1D,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,mCAAA;AAAA,QAChB,MAAA,EAAQ;AAAA,OACV;AAAA,MACA,IAAA;AAAA,MACA,QAAQ,UAAA,CAAW;AAAA,KACpB,CAAA;AAED,IAAA,YAAA,CAAa,SAAS,CAAA;AAEtB,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,IAAA,GAAO,KAAA,CAAM,OAAO,EAAC,CAAE,CAAA;AACxD,MAAA,OAAA,CAAQ,KAAA,CAAM,8BAAA,EAAgC,QAAA,CAAS,MAAA,EAAQ,SAAS,CAAA;AACxE,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,SAAA,CAAU,iBAAA,IAAqB,CAAA,gBAAA,EAAmB,QAAA,CAAS,MAAM,CAAA;AAAA,OACnE;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GAAU,MAAM,QAAA,CAAS,IAAA,EAAK;AAEpC,IAAA,OAAA,CAAQ,IAAI,iCAAiC,CAAA;AAE7C,IAAA,OAAO;AAAA,MACL,cAAc,MAAA,CAAO,YAAA;AAAA,MACrB,eAAe,MAAA,CAAO,aAAA;AAAA,MACtB,YAAY,MAAA,CAAO,UAAA;AAAA,MACnB,YAAY,MAAA,CAAO;AAAA,KACrB;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,SAAA,GAAY,KAAA,YAAiB,KAAA,IAAS,KAAA,CAAM,IAAA,KAAS,YAAA;AAC3D,IAAA,OAAA,CAAQ,KAAA;AAAA,MACN,6BAAA;AAAA,MACA,YAAY,mBAAA,GAAsB;AAAA,KACpC;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AACF;;;AC7IA,IAAI,eAAA,GAAkB,KAAA;AACtB,IAAI,gBAAA,GAAyC,IAAA;AAStC,SAAS,aAAA,GAA+B;AAE7C,EAAA,IAAI,eAAA,IAAmB,MAAA,CAAO,MAAA,EAAQ,QAAA,EAAU;AAC9C,IAAA,OAAO,QAAQ,OAAA,EAAQ;AAAA,EACzB;AAGA,EAAA,IAAI,gBAAA,EAAkB;AACpB,IAAA,OAAO,gBAAA;AAAA,EACT;AAEA,EAAA,gBAAA,GAAmB,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AAElD,IAAA,IAAI,MAAA,CAAO,QAAQ,QAAA,EAAU;AAC3B,MAAA,eAAA,GAAkB,IAAA;AAClB,MAAA,OAAA,EAAQ;AACR,MAAA;AAAA,IACF;AAEA,IAAA,OAAA,CAAQ,IAAI,oDAAoD,CAAA;AAEhE,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,IAAA,MAAA,CAAO,GAAA,GAAM,wCAAA;AACb,IAAA,MAAA,CAAO,KAAA,GAAQ,IAAA;AACf,IAAA,MAAA,CAAO,KAAA,GAAQ,IAAA;AAEf,IAAA,MAAA,CAAO,SAAS,MAAM;AACpB,MAAA,OAAA,CAAQ,IAAI,uCAAuC,CAAA;AACnD,MAAA,eAAA,GAAkB,IAAA;AAClB,MAAA,OAAA,EAAQ;AAAA,IACV,CAAA;AAEA,IAAA,MAAA,CAAO,UAAU,MAAM;AACrB,MAAA,OAAA,CAAQ,MAAM,kCAAkC,CAAA;AAChD,MAAA,gBAAA,GAAmB,IAAA;AACnB,MAAA,MAAA,CAAO,IAAI,KAAA,CAAM,6CAA6C,CAAC,CAAA;AAAA,IACjE,CAAA;AAEA,IAAA,QAAA,CAAS,IAAA,CAAK,YAAY,MAAM,CAAA;AAAA,EAClC,CAAC,CAAA;AAED,EAAA,OAAO,gBAAA;AACT;AAaA,eAAsB,iBAAiB,MAAA,EAAyC;AAC9E,EAAA,OAAA,CAAQ,IAAI,uCAAuC,CAAA;AACnD,EAAA,OAAA,CAAQ,GAAA,CAAI,+BAAA,EAAiC,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA;AAGnE,EAAA,IAAI,CAAC,MAAA,CAAO,MAAA,EAAQ,QAAA,EAAU;AAC5B,IAAA,OAAA,CAAQ,MAAM,uCAAuC,CAAA;AACrD,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,KAAA,EAAO,OAAA;AAAA,MACP,MAAA,EAAQ,IAAA;AAAA,MACR,OAAA,EAAS,iCAAA;AAAA,MACT,QAAA,EAAU;AAAA,KACZ;AAAA,EACF;AAEA,EAAA,OAAA,CAAQ,GAAA,CAAI,4BAA4B,MAAA,CAAO,MAAA,CAAO,SAAS,SAAA,CAAU,CAAA,EAAG,EAAE,CAAA,GAAI,KAAK,CAAA;AAEvF,EAAA,IAAI;AAEF,IAAA,OAAA,CAAQ,IAAI,8BAA8B,CAAA;AAC1C,IAAA,MAAM,aAAA,EAAc;AAEpB,IAAA,IAAI,CAAC,MAAA,CAAO,MAAA,EAAQ,QAAA,EAAU;AAC5B,MAAA,MAAM,IAAI,MAAM,wCAAwC,CAAA;AAAA,IAC1D;AAEA,IAAA,OAAA,CAAQ,IAAI,kDAAkD,CAAA;AAG9D,IAAA,OAAO,MAAM,yBAAyB,MAAM,CAAA;AAAA,EAC9C,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,gCAAgC,KAAK,CAAA;AACnD,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,KAAA,EAAO,OAAA;AAAA,MACP,MAAA,EAAQ,IAAA;AAAA,MACR,OAAA,EAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,qBAAA;AAAA,MAClD,QAAA,EAAU;AAAA,KACZ;AAAA,EACF;AACF;AA+FA,eAAe,yBAAyB,MAAA,EAAyC;AAC/E,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC9B,IAAA,MAAM,QAAA,GAAW,OAAO,MAAA,CAAQ,QAAA;AAChC,IAAA,MAAM,WAAA,GAAc,OAAO,QAAA,CAAS,MAAA;AACpC,IAAA,MAAM,KAAA,GAAQ,KAAK,MAAA,EAAO,CAAE,SAAS,EAAE,CAAA,CAAE,SAAA,CAAU,CAAA,EAAG,EAAE,CAAA;AAExD,IAAA,OAAA,CAAQ,IAAI,oCAAoC,CAAA;AAChD,IAAA,OAAA,CAAQ,GAAA,CAAI,kBAAkB,QAAQ,CAAA;AACtC,IAAA,OAAA,CAAQ,GAAA,CAAI,qBAAqB,WAAW,CAAA;AAC5C,IAAA,OAAA,CAAQ,IAAI,8EAAoE,CAAA;AAEhF,IAAA,MAAM,MAAA,GAAS,IAAI,eAAA,CAAgB;AAAA,MACjC,SAAA,EAAW,QAAA;AAAA,MACX,YAAA,EAAc,WAAA;AAAA,MACd,aAAA,EAAe,UAAA;AAAA,MACf,KAAA,EAAO,sBAAA;AAAA,MACP,KAAA;AAAA,MACA,MAAA,EAAQ;AAAA,KACT,CAAA;AAED,IAAA,MAAM,OAAA,GAAU,gDAAgD,MAAM,CAAA,CAAA;AACtE,IAAA,OAAA,CAAQ,GAAA,CAAI,2BAA2B,OAAO,CAAA;AAG9C,IAAA,MAAM,KAAA,GAAQ,GAAA;AACd,IAAA,MAAM,MAAA,GAAS,GAAA;AACf,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,OAAA,GAAA,CAAW,MAAA,CAAO,aAAa,KAAA,IAAS,CAAA;AAC5D,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,OAAA,GAAA,CAAW,MAAA,CAAO,cAAc,MAAA,IAAU,CAAA;AAE7D,IAAA,MAAM,QAAQ,MAAA,CAAO,IAAA;AAAA,MACnB,OAAA;AAAA,MACA,aAAA;AAAA,MACA,SAAS,KAAK,CAAA,QAAA,EAAW,MAAM,CAAA,MAAA,EAAS,IAAI,QAAQ,GAAG,CAAA;AAAA,KACzD;AAEA,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,OAAA,CAAQ;AAAA,QACN,OAAA,EAAS,KAAA;AAAA,QACT,KAAA,EAAO,OAAA;AAAA,QACP,MAAA,EAAQ,IAAA;AAAA,QACR,OAAA,EAAS,uDAAA;AAAA,QACT,QAAA,EAAU;AAAA,OACX,CAAA;AACD,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,YAAA,GAAe,YAAY,MAAM;AACrC,MAAA,IAAI;AAEF,QAAA,IAAI,MAAM,MAAA,EAAQ;AAChB,UAAA,aAAA,CAAc,YAAY,CAAA;AAC1B,UAAA,OAAA,CAAQ;AAAA,YACN,OAAA,EAAS,KAAA;AAAA,YACT,KAAA,EAAO,WAAA;AAAA,YACP,MAAA,EAAQ,IAAA;AAAA,YACR,OAAA,EAAS,8BAAA;AAAA,YACT,QAAA,EAAU;AAAA,WACX,CAAA;AACD,UAAA;AAAA,QACF;AAGA,QAAA,MAAM,GAAA,GAAM,MAAM,QAAA,CAAS,IAAA;AAG3B,QAAA,IAAI,GAAA,CAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC/B,UAAA,aAAA,CAAc,YAAY,CAAA;AAC1B,UAAA,KAAA,CAAM,KAAA,EAAM;AAGZ,UAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,GAAA,CAAI,QAAQ,GAAA,EAAK,GAAG,CAAC,CAAA,CAAE,YAAA;AAC5C,UAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,UAAU,CAAA;AACnC,UAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA;AAE9B,UAAA,IAAI,KAAA,EAAO;AACT,YAAA,OAAA,CAAQ;AAAA,cACN,OAAA,EAAS,KAAA;AAAA,cACT,KAAA,EAAO,OAAA;AAAA,cACP,MAAA,EAAQ,IAAA;AAAA,cACR,OAAA,EAAS,IAAA,CAAK,GAAA,CAAI,mBAAmB,CAAA,IAAK,KAAA;AAAA,cAC1C,QAAA,EAAU;AAAA,aACX,CAAA;AACD,YAAA;AAAA,UACF;AAEA,UAAA,IAAI,OAAA,EAAS;AAEX,YAAA,aAAA,CAAc,EAAE,UAAU,OAAA,EAAQ,EAAG,UAAU,MAAM,CAAA,CAAE,KAAK,OAAO,CAAA;AAAA,UACrE,CAAA,MAAO;AACL,YAAA,OAAA,CAAQ;AAAA,cACN,OAAA,EAAS,KAAA;AAAA,cACT,KAAA,EAAO,OAAA;AAAA,cACP,MAAA,EAAQ,IAAA;AAAA,cACR,OAAA,EAAS,+BAAA;AAAA,cACT,QAAA,EAAU;AAAA,aACX,CAAA;AAAA,UACH;AAAA,QACF;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF,GAAG,GAAG,CAAA;AAGN,IAAA,UAAA,CAAW,MAAM;AACf,MAAA,aAAA,CAAc,YAAY,CAAA;AAC1B,MAAA,IAAI,CAAC,MAAM,MAAA,EAAQ;AACjB,QAAA,KAAA,CAAM,KAAA,EAAM;AAAA,MACd;AACA,MAAA,OAAA,CAAQ;AAAA,QACN,OAAA,EAAS,KAAA;AAAA,QACT,KAAA,EAAO,OAAA;AAAA,QACP,MAAA,EAAQ,IAAA;AAAA,QACR,OAAA,EAAS,0BAAA;AAAA,QACT,QAAA,EAAU;AAAA,OACX,CAAA;AAAA,IACH,CAAA,EAAG,CAAA,GAAI,EAAA,GAAK,GAAI,CAAA;AAAA,EAClB,CAAC,CAAA;AACH;;;ACzUA,IAAI,cAAA,GAAiB,KAAA;AACrB,IAAI,eAAA,GAAwC,IAAA;AAC5C,IAAI,gBAAA,GAAmB,KAAA;AAShB,SAAS,YAAA,GAA8B;AAE5C,EAAA,IAAI,cAAA,IAAkB,OAAO,OAAA,EAAS;AACpC,IAAA,OAAO,QAAQ,OAAA,EAAQ;AAAA,EACzB;AAGA,EAAA,IAAI,eAAA,EAAiB;AACnB,IAAA,OAAO,eAAA;AAAA,EACT;AAEA,EAAA,eAAA,GAAkB,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AAEjD,IAAA,IAAI,OAAO,OAAA,EAAS;AAClB,MAAA,cAAA,GAAiB,IAAA;AACjB,MAAA,OAAA,EAAQ;AACR,MAAA;AAAA,IACF;AAEA,IAAA,OAAA,CAAQ,IAAI,2CAA2C,CAAA;AAEvD,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,IAAA,MAAA,CAAO,GAAA,GACL,sFAAA;AACF,IAAA,MAAA,CAAO,KAAA,GAAQ,IAAA;AAEf,IAAA,MAAA,CAAO,SAAS,MAAM;AACpB,MAAA,OAAA,CAAQ,IAAI,sCAAsC,CAAA;AAClD,MAAA,cAAA,GAAiB,IAAA;AACjB,MAAA,OAAA,EAAQ;AAAA,IACV,CAAA;AAEA,IAAA,MAAA,CAAO,UAAU,MAAM;AACrB,MAAA,OAAA,CAAQ,MAAM,iCAAiC,CAAA;AAC/C,MAAA,eAAA,GAAkB,IAAA;AAClB,MAAA,MAAA,CAAO,IAAI,KAAA,CAAM,qCAAqC,CAAC,CAAA;AAAA,IACzD,CAAA;AAEA,IAAA,QAAA,CAAS,IAAA,CAAK,YAAY,MAAM,CAAA;AAAA,EAClC,CAAC,CAAA;AAED,EAAA,OAAO,eAAA;AACT;AASA,SAAS,gBAAgB,MAAA,EAA0B;AACjD,EAAA,IAAI,oBAAoB,CAAC,MAAA,CAAO,OAAA,IAAW,CAAC,OAAO,KAAA,EAAO;AACxD,IAAA;AAAA,EACF;AAIA,EAAA,MAAM,cACJ,MAAA,CAAO,QAAA,CAAS,aAAa,WAAA,IAC7B,MAAA,CAAO,SAAS,QAAA,KAAa,WAAA;AAC/B,EAAA,MAAM,WAAA,GAAc,cAChB,MAAA,CAAO,QAAA,CAAS,SAChB,MAAA,CAAO,KAAA,CAAM,WAAA,IAAe,MAAA,CAAO,QAAA,CAAS,MAAA;AAEhD,EAAA,OAAA,CAAQ,IAAI,wCAAA,EAA0C;AAAA,IACpD,QAAA,EAAU,OAAO,KAAA,CAAM,QAAA;AAAA,IACvB,WAAA;AAAA,IACA,WAAA;AAAA,IACA,aAAA,EAAe,OAAO,QAAA,CAAS;AAAA,GAChC,CAAA;AAED,EAAA,MAAA,CAAO,OAAA,CAAQ,KAAK,IAAA,CAAK;AAAA,IACvB,QAAA,EAAU,OAAO,KAAA,CAAM,QAAA;AAAA,IACvB,KAAA,EAAO,YAAA;AAAA,IACP,WAAA,EAAa,WAAA;AAAA,IACb,QAAA,EAAU;AAAA,GACX,CAAA;AAED,EAAA,gBAAA,GAAmB,IAAA;AACrB;AAYA,eAAsB,gBAAgB,MAAA,EAAyC;AAC7E,EAAA,OAAA,CAAQ,IAAI,qCAAqC,CAAA;AAGjD,EAAA,IAAI,CAAC,MAAA,CAAO,KAAA,EAAO,QAAA,EAAU;AAC3B,IAAA,OAAA,CAAQ,MAAM,sCAAsC,CAAA;AACpD,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,KAAA,EAAO,OAAA;AAAA,MACP,MAAA,EAAQ,IAAA;AAAA,MACR,OAAA,EAAS,gCAAA;AAAA,MACT,QAAA,EAAU;AAAA,KACZ;AAAA,EACF;AAGA,EAAA,MAAM,cACJ,MAAA,CAAO,QAAA,CAAS,aAAa,WAAA,IAC7B,MAAA,CAAO,SAAS,QAAA,KAAa,WAAA;AAC/B,EAAA,IAAI,WAAA,EAAa;AACf,IAAA,OAAA,CAAQ,KAAK,6DAA6D,CAAA;AAC1E,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN;AAAA,KACF;AACA,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN;AAAA,KACF;AAAA,EACF;AAEA,EAAA,IAAI;AAEF,IAAA,OAAA,CAAQ,IAAI,6BAA6B,CAAA;AACzC,IAAA,MAAM,YAAA,EAAa;AAEnB,IAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,MAAA,MAAM,IAAI,MAAM,uCAAuC,CAAA;AAAA,IACzD;AAGA,IAAA,gBAAA,GAAmB,KAAA;AAGnB,IAAA,eAAA,CAAgB,MAAM,CAAA;AAEtB,IAAA,OAAA,CAAQ,IAAI,sCAAsC,CAAA;AAGlD,IAAA,MAAM,QAAA,GAAW,MAAM,MAAA,CAAO,OAAA,CAAQ,KAAK,MAAA,EAAO;AAElD,IAAA,OAAA,CAAQ,IAAI,gCAAgC,CAAA;AAG5C,IAAA,MAAM,IAAA,GAAO,SAAS,aAAA,EAAe,IAAA;AACrC,IAAA,MAAM,OAAA,GAAU,SAAS,aAAA,EAAe,QAAA;AAExC,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,OAAA,CAAQ,GAAA,CAAI,8CAA8C,IAAI,CAAA;AAC9D,MAAA,OAAO,MAAM,aAAA,CAAc,EAAE,IAAA,EAAK,EAAG,SAAS,MAAM,CAAA;AAAA,IACtD,WAAW,OAAA,EAAS;AAClB,MAAA,OAAA,CAAQ,IAAI,kCAAkC,CAAA;AAC9C,MAAA,OAAO,MAAM,aAAA,CAAc,EAAE,UAAU,OAAA,EAAQ,EAAG,SAAS,MAAM,CAAA;AAAA,IACnE,CAAA,MAAO;AACL,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,KAAA,EAAO,OAAA;AAAA,QACP,MAAA,EAAQ,IAAA;AAAA,QACR,OAAA,EAAS,oDAAA;AAAA,QACT,QAAA,EAAU;AAAA,OACZ;AAAA,IACF;AAAA,EACF,SAAS,KAAA,EAAO;AAEd,IAAA,MAAM,UAAA,GAAa,KAAA;AAGnB,IAAA,IACE,UAAA,EAAY,KAAA,KAAU,sBAAA,IACtB,UAAA,EAAY,UAAU,0BAAA,EACtB;AACA,MAAA,OAAA,CAAQ,IAAI,wCAAwC,CAAA;AACpD,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,KAAA,EAAO,WAAA;AAAA,QACP,MAAA,EAAQ,IAAA;AAAA,QACR,OAAA,EAAS,6BAAA;AAAA,QACT,QAAA,EAAU;AAAA,OACZ;AAAA,IACF;AAEA,IAAA,OAAA,CAAQ,KAAA,CAAM,+BAA+B,KAAK,CAAA;AAClD,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,KAAA,EAAO,OAAA;AAAA,MACP,MAAA,EAAQ,IAAA;AAAA,MACR,SACE,UAAA,EAAY,KAAA,KACX,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,oBAAA,CAAA;AAAA,MAC5C,QAAA,EAAU;AAAA,KACZ;AAAA,EACF;AACF;;;ACnPA,eAAsB,eAAA,CACpB,KAAA,EACA,QAAA,EACA,MAAA,EACqB;AACrB,EAAA,OAAA,CAAQ,IAAI,qCAAqC,CAAA;AAGjD,EAAA,IAAI,CAAC,KAAA,IAAS,CAAC,KAAA,CAAM,MAAK,EAAG;AAC3B,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,KAAA,EAAO,OAAA;AAAA,MACP,MAAA,EAAQ,IAAA;AAAA,MACR,OAAA,EAAS,mBAAA;AAAA,MACT,QAAA,EAAU;AAAA,KACZ;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,KAAA,EAAO,OAAA;AAAA,MACP,MAAA,EAAQ,IAAA;AAAA,MACR,OAAA,EAAS,sBAAA;AAAA,MACT,QAAA,EAAU;AAAA,KACZ;AAAA,EACF;AAGA,EAAA,MAAM,UAAA,GAAa,4BAAA;AACnB,EAAA,IAAI,CAAC,UAAA,CAAW,IAAA,CAAK,KAAA,CAAM,IAAA,EAAM,CAAA,EAAG;AAClC,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,KAAA,EAAO,OAAA;AAAA,MACP,MAAA,EAAQ,IAAA;AAAA,MACR,OAAA,EAAS,oCAAA;AAAA,MACT,QAAA,EAAU;AAAA,KACZ;AAAA,EACF;AAEA,EAAA,IAAI;AAGF,IAAA,MAAM,SAAS,MAAM,aAAA;AAAA,MACnB;AAAA,QACE,QAAA,EAAU,MAAM,IAAA,EAAK;AAAA,QACrB;AAAA,OACF;AAAA,MACA,UAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,IAAI,OAAO,OAAA,EAAS;AAClB,MAAA,OAAA,CAAQ,IAAI,iCAAiC,CAAA;AAAA,IAC/C,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,GAAA,CAAI,8BAAA,EAAgC,MAAA,CAAO,OAAO,CAAA;AAAA,IAC5D;AAEA,IAAA,OAAO,MAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,+BAA+B,KAAK,CAAA;AAClD,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,KAAA,EAAO,OAAA;AAAA,MACP,MAAA,EAAQ,IAAA;AAAA,MACR,OAAA,EAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,oBAAA;AAAA,MAClD,QAAA,EAAU;AAAA,KACZ;AAAA,EACF;AACF;AC3EA,IAAM,UAAA,GAAa,sBACjB,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,SAAA,EAAU,OAAA,EAAQ,WAAA,EAAY,IAAA,EAAK,cAAA,EAChD,QAAA,EAAA;AAAA,kBAAAA,GAAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,CAAA,EAAE,yHAAA;AAAA,MACF,IAAA,EAAK;AAAA;AAAA,GACP;AAAA,kBACAA,GAAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,CAAA,EAAE,uIAAA;AAAA,MACF,IAAA,EAAK;AAAA;AAAA,GACP;AAAA,kBACAA,GAAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,CAAA,EAAE,+HAAA;AAAA,MACF,IAAA,EAAK;AAAA;AAAA,GACP;AAAA,kBACAA,GAAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,CAAA,EAAE,qIAAA;AAAA,MACF,IAAA,EAAK;AAAA;AAAA;AACP,CAAA,EACF,CAAA;AAGF,IAAM,YAAY,sBAChBA,GAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,SAAA,EAAU,OAAA,EAAQ,WAAA,EAAY,IAAA,EAAK,gBAChD,QAAA,kBAAAA,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,qUAAoU,CAAA,EAC9U,CAAA;AAGF,IAAM,iBAAiB,sBACrB,IAAA;AAAA,EAAC,KAAA;AAAA,EAAA;AAAA,IACC,SAAA,EAAU,sBAAA;AAAA,IACV,KAAA,EAAM,4BAAA;AAAA,IACN,IAAA,EAAK,MAAA;AAAA,IACL,OAAA,EAAQ,WAAA;AAAA,IAER,QAAA,EAAA;AAAA,sBAAAA,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAU,YAAA;AAAA,UACV,EAAA,EAAG,IAAA;AAAA,UACH,EAAA,EAAG,IAAA;AAAA,UACH,CAAA,EAAE,IAAA;AAAA,UACF,MAAA,EAAO,cAAA;AAAA,UACP,WAAA,EAAY;AAAA;AAAA,OACd;AAAA,sBACAA,GAAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAU,YAAA;AAAA,UACV,IAAA,EAAK,cAAA;AAAA,UACL,CAAA,EAAE;AAAA;AAAA;AACJ;AAAA;AACF,CAAA;AAaF,IAAM,SAAgC,CAAC;AAAA,EACrC,OAAA,GAAU,SAAA;AAAA,EACV,SAAA,GAAY,KAAA;AAAA,EACZ,QAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,GAAG;AACL,CAAA,KAAM;AACJ,EAAA,MAAM,WAAA,GACJ,gJAAA;AAEF,EAAA,MAAM,cAAA,GAAiB;AAAA,IACrB,OAAA,EAAS,2DAAA;AAAA,IACT,SAAA,EACE;AAAA,GACJ;AAEA,EAAA,MAAM,eAAA,GAAkB,mDAAA;AAExB,EAAA,uBACEA,GAAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,CAAA,EAAG,WAAW,CAAA,CAAA,EAAI,cAAA,CAAe,OAAO,CAAC,CAAA,CAAA,EAClD,QAAA,IAAY,SAAA,GAAY,eAAA,GAAkB,EAC5C,IAAI,SAAS,CAAA,CAAA;AAAA,MACb,UAAU,QAAA,IAAY,SAAA;AAAA,MACrB,GAAG,KAAA;AAAA,MAEH,sCACC,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,wBAAAA,IAAC,cAAA,EAAA,EAAe,CAAA;AAAA,wBAChBA,GAAAA,CAAC,MAAA,EAAA,EAAK,QAAA,EAAA,YAAA,EAAU;AAAA,OAAA,EAClB,CAAA,GAEA;AAAA;AAAA,GAEJ;AAEJ,CAAA;AAWA,IAAM,QAA8B,CAAC;AAAA,EACnC,KAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,GAAG;AACL,CAAA,KAAM;AACJ,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,WAAA,EACZ,QAAA,EAAA;AAAA,IAAA,KAAA,oBACCA,GAAAA,CAAC,OAAA,EAAA,EAAM,SAAA,EAAU,2CACd,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,oBAEFA,GAAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,WAAW,CAAA,6GAAA,EACT,KAAA,GAAQ,gBAAA,GAAmB,iBAC7B,IAAI,SAAS,CAAA,CAAA;AAAA,QACZ,GAAG;AAAA;AAAA,KACN;AAAA,IACC,yBAASA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,wBAAwB,QAAA,EAAA,KAAA,EAAM;AAAA,GAAA,EACvD,CAAA;AAEJ,CAAA;AA4BO,SAAS,SAAA,GAAY;AAC1B,EAAA,MAAM,EAAE,MAAA,EAAQ,UAAA,EAAY,WAAA,EAAa,SAAA,KAAc,eAAA,EAAgB;AAEvE,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIC,SAAe,MAAM,CAAA;AAC7C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,SAAS,EAAE,CAAA;AACrC,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIA,SAAS,EAAE,CAAA;AAC3C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,SAAwB,IAAI,CAAA;AACtD,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAIA,QAAAA,CAGnC,EAAE,CAAA;AAML,EAAA,MAAM,oBAAoB,YAAY;AACpC,IAAA,IAAI,CAAC,OAAO,MAAA,EAAQ;AAClB,MAAA,QAAA,CAAS,kCAAkC,CAAA;AAC3C,MAAA;AAAA,IACF;AAEA,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,WAAA,CAAY,IAAI,CAAA;AAEhB,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,gBAAA,CAAiB,MAAM,CAAA;AAE5C,MAAA,IAAI,MAAA,CAAO,OAAA,IAAW,MAAA,CAAO,MAAA,EAAQ;AACnC,QAAA,MAAM,UAAA,CAAW,OAAO,MAAM,CAAA;AAAA,MAChC,CAAA,MAAA,IAAW,MAAA,CAAO,KAAA,KAAU,WAAA,EAAa;AACvC,QAAA,QAAA,CAAS,MAAA,CAAO,WAAW,uBAAuB,CAAA;AAAA,MACpD;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,QAAA,CAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,uBAAuB,CAAA;AAAA,IACvE,CAAA,SAAE;AACA,MAAA,WAAA,CAAY,KAAK,CAAA;AAAA,IACnB;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,mBAAmB,YAAY;AACnC,IAAA,IAAI,CAAC,OAAO,KAAA,EAAO;AACjB,MAAA,QAAA,CAAS,iCAAiC,CAAA;AAC1C,MAAA;AAAA,IACF;AAEA,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,WAAA,CAAY,IAAI,CAAA;AAEhB,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,eAAA,CAAgB,MAAM,CAAA;AAE3C,MAAA,IAAI,MAAA,CAAO,OAAA,IAAW,MAAA,CAAO,MAAA,EAAQ;AACnC,QAAA,MAAM,UAAA,CAAW,OAAO,MAAM,CAAA;AAAA,MAChC,CAAA,MAAA,IAAW,MAAA,CAAO,KAAA,KAAU,WAAA,EAAa;AACvC,QAAA,QAAA,CAAS,MAAA,CAAO,WAAW,sBAAsB,CAAA;AAAA,MACnD;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,QAAA,CAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,sBAAsB,CAAA;AAAA,IACtE,CAAA,SAAE;AACA,MAAA,WAAA,CAAY,KAAK,CAAA;AAAA,IACnB;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,gBAAA,GAAmB,OAAO,CAAA,KAAuB;AACrD,IAAA,CAAA,CAAE,cAAA,EAAe;AAGjB,IAAA,MAAM,SAAgD,EAAC;AACvD,IAAA,IAAI,CAAC,KAAA,CAAM,IAAA,EAAK,EAAG;AACjB,MAAA,MAAA,CAAO,KAAA,GAAQ,mBAAA;AAAA,IACjB;AACA,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA,MAAA,CAAO,QAAA,GAAW,sBAAA;AAAA,IACpB;AAEA,IAAA,IAAI,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,CAAE,SAAS,CAAA,EAAG;AAClC,MAAA,cAAA,CAAe,MAAM,CAAA;AACrB,MAAA;AAAA,IACF;AAEA,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,cAAA,CAAe,EAAE,CAAA;AACjB,IAAA,WAAA,CAAY,IAAI,CAAA;AAEhB,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,eAAA,CAAgB,KAAA,EAAO,UAAU,MAAM,CAAA;AAE5D,MAAA,IAAI,MAAA,CAAO,OAAA,IAAW,MAAA,CAAO,MAAA,EAAQ;AACnC,QAAA,MAAM,UAAA,CAAW,OAAO,MAAM,CAAA;AAAA,MAChC,CAAA,MAAO;AACL,QAAA,QAAA,CAAS,MAAA,CAAO,WAAW,sBAAsB,CAAA;AAAA,MACnD;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,QAAA,CAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,sBAAsB,CAAA;AAAA,IACtE,CAAA,SAAE;AACA,MAAA,WAAA,CAAY,KAAK,CAAA;AAAA,IACnB;AAAA,EACF,CAAA;AAMA,EAAA,IAAI,SAAS,OAAA,EAAS;AACpB,IAAA,uBACED,IAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iDACb,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,8CAAA,EAEb,QAAA,EAAA;AAAA,sBAAA,IAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,SAAS,MAAM;AACb,YAAA,OAAA,CAAQ,MAAM,CAAA;AACd,YAAA,QAAA,CAAS,IAAI,CAAA;AACb,YAAA,cAAA,CAAe,EAAE,CAAA;AAAA,UACnB,CAAA;AAAA,UACA,SAAA,EAAU,mEAAA;AAAA,UAEV,QAAA,EAAA;AAAA,4BAAAA,GAAAA;AAAA,cAAC,KAAA;AAAA,cAAA;AAAA,gBACC,SAAA,EAAU,cAAA;AAAA,gBACV,IAAA,EAAK,MAAA;AAAA,gBACL,MAAA,EAAO,cAAA;AAAA,gBACP,OAAA,EAAQ,WAAA;AAAA,gBAER,QAAA,kBAAAA,GAAAA;AAAA,kBAAC,MAAA;AAAA,kBAAA;AAAA,oBACC,aAAA,EAAc,OAAA;AAAA,oBACd,cAAA,EAAe,OAAA;AAAA,oBACf,WAAA,EAAa,CAAA;AAAA,oBACb,CAAA,EAAE;AAAA;AAAA;AACJ;AAAA,aACF;AAAA,YAAM;AAAA;AAAA;AAAA,OAER;AAAA,sBAGA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mBAAA,EACb,QAAA,EAAA;AAAA,wBAAAA,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,uCAAA,EAAwC,QAAA,EAAA,SAAA,EAAO,CAAA;AAAA,wBAC7DA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,2BAA0B,QAAA,EAAA,+BAAA,EAEvC;AAAA,OAAA,EACF,CAAA;AAAA,MAGC,KAAA,oBACCA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qDAAA,EACb,QAAA,kBAAAA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,sBAAA,EAAwB,QAAA,EAAA,KAAA,EAAM,CAAA,EAC7C,CAAA;AAAA,sBAIF,IAAA,CAAC,MAAA,EAAA,EAAK,QAAA,EAAU,gBAAA,EAAkB,WAAU,WAAA,EAC1C,QAAA,EAAA;AAAA,wBAAAA,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,OAAA;AAAA,YACL,KAAA,EAAM,OAAA;AAAA,YACN,WAAA,EAAY,kBAAA;AAAA,YACZ,KAAA,EAAO,KAAA;AAAA,YACP,QAAA,EAAU,CAAC,CAAA,KAAM;AACf,cAAA,QAAA,CAAS,CAAA,CAAE,OAAO,KAAK,CAAA;AACvB,cAAA,IAAI,WAAA,CAAY,KAAA;AACd,gBAAA,cAAA,CAAe,EAAE,GAAG,WAAA,EAAa,KAAA,EAAO,QAAW,CAAA;AAAA,YACvD,CAAA;AAAA,YACA,OAAO,WAAA,CAAY,KAAA;AAAA,YACnB,YAAA,EAAa;AAAA;AAAA,SACf;AAAA,wBAEAA,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,UAAA;AAAA,YACL,KAAA,EAAM,UAAA;AAAA,YACN,WAAA,EAAY,qBAAA;AAAA,YACZ,KAAA,EAAO,QAAA;AAAA,YACP,QAAA,EAAU,CAAC,CAAA,KAAM;AACf,cAAA,WAAA,CAAY,CAAA,CAAE,OAAO,KAAK,CAAA;AAC1B,cAAA,IAAI,WAAA,CAAY,QAAA;AACd,gBAAA,cAAA,CAAe,EAAE,GAAG,WAAA,EAAa,QAAA,EAAU,QAAW,CAAA;AAAA,YAC1D,CAAA;AAAA,YACA,OAAO,WAAA,CAAY,QAAA;AAAA,YACnB,YAAA,EAAa;AAAA;AAAA,SACf;AAAA,wBAEAA,GAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAQ,SAAA;AAAA,YACR,SAAA;AAAA,YACA,SAAA,EAAU,aAAA;AAAA,YACX,QAAA,EAAA;AAAA;AAAA;AAED,OAAA,EACF;AAAA,KAAA,EACF,CAAA,EACF,CAAA;AAAA,EAEJ;AAMA,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,+CAAA,EACb,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,6DAAA,EAEb,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,mBAAA,EACb,QAAA,EAAA;AAAA,wBAAAA,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,uCAAA,EAAwC,QAAA,EAAA,cAAA,EAEtD,CAAA;AAAA,wBACAA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,2BAA0B,QAAA,EAAA,qBAAA,EAAmB;AAAA,OAAA,EAC5D,CAAA;AAAA,MAGC,KAAA,oBACCA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qDAAA,EACb,QAAA,kBAAAA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,sBAAA,EAAwB,QAAA,EAAA,KAAA,EAAM,CAAA,EAC7C,CAAA;AAAA,sBAIF,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gBAAA,EACZ,QAAA,EAAA;AAAA,QAAA,MAAA,CAAO,MAAA,oBACN,IAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAQ,WAAA;AAAA,YACR,OAAA,EAAS,iBAAA;AAAA,YACT,QAAA,EAAU,SAAA;AAAA,YACV,SAAA,EAAU,QAAA;AAAA,YAEV,QAAA,EAAA;AAAA,8BAAAA,IAAC,UAAA,EAAA,EAAW,CAAA;AAAA,cAAE;AAAA;AAAA;AAAA,SAEhB;AAAA,QAGD,OAAO,KAAA,oBACN,IAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAQ,WAAA;AAAA,YACR,OAAA,EAAS,gBAAA;AAAA,YACT,QAAA,EAAU,SAAA;AAAA,YACV,SAAA,EAAU,QAAA;AAAA,YAEV,QAAA,EAAA;AAAA,8BAAAA,IAAC,SAAA,EAAA,EAAU,CAAA;AAAA,cAAE;AAAA;AAAA;AAAA;AAEf,OAAA,EAEJ,CAAA;AAAA,MAGC,MAAA,CAAO,KAAA,EAAO,OAAA,KAAY,MAAA,CAAO,MAAA,IAAU,OAAO,KAAA,CAAA,oBACjD,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,eAAA,EACb,QAAA,EAAA;AAAA,wBAAAA,GAAAA,CAAC,SAAI,SAAA,EAAU,oCAAA,EACb,0BAAAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iCAAA,EAAkC,CAAA,EACnD,CAAA;AAAA,wBACAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sCAAA,EACb,QAAA,kBAAAA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,6BAAA,EAA8B,QAAA,EAAA,wBAAA,EAE9C,CAAA,EACF;AAAA,OAAA,EACF,CAAA;AAAA,MAID,MAAA,CAAO,KAAA,EAAO,OAAA,oBACbA,GAAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,OAAA,EAAQ,SAAA;AAAA,UACR,OAAA,EAAS,MAAM,OAAA,CAAQ,OAAO,CAAA;AAAA,UAC9B,QAAA,EAAU,SAAA;AAAA,UACV,SAAA,EAAU,QAAA;AAAA,UACX,QAAA,EAAA;AAAA;AAAA;AAED,KAAA,EAEJ,CAAA;AAAA,oBAGAA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kBACb,QAAA,kBAAA,IAAA,CAAC,GAAA,EAAA,EAAE,WAAU,oEAAA,EAAqE,QAAA,EAAA;AAAA,MAAA,iCAAA;AAAA,MAChD,GAAA;AAAA,sBAChCA,GAAAA;AAAA,QAAC,GAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,0CAAA;AAAA,UACL,MAAA,EAAO,QAAA;AAAA,UACP,GAAA,EAAI,qBAAA;AAAA,UACJ,SAAA,EAAU,gEAAA;AAAA,UACX,QAAA,EAAA;AAAA;AAAA,OAED;AAAA,MAAK,GAAA;AAAA,MAAI,KAAA;AAAA,MACL,GAAA;AAAA,sBACJA,GAAAA;AAAA,QAAC,GAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,wCAAA;AAAA,UACL,MAAA,EAAO,QAAA;AAAA,UACP,GAAA,EAAI,qBAAA;AAAA,UACJ,SAAA,EAAU,gEAAA;AAAA,UACX,QAAA,EAAA;AAAA;AAAA,OAED;AAAA,MAAI;AAAA,KAAA,EAEN,CAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ","file":"index.js","sourcesContent":["import type { AuthConfig } from \"./types\";\n\n// ============================================\n// CONFIGURATION VALIDATION\n// ============================================\n\n/**\n * Validate auth configuration.\n * Called by AuthProvider on mount.\n */\nexport function validateConfig(config: AuthConfig): void {\n if (!config.backendUrl) {\n throw new Error(\"[Auth] backendUrl is required in AuthConfig\");\n }\n\n if (!config.google && !config.apple && !config.email?.enabled) {\n console.warn(\n \"[Auth] No auth strategies configured. Enable at least one: google, apple, or email.\"\n );\n }\n\n // Validate Google config\n if (config.google && !config.google.clientId) {\n throw new Error(\"[Auth] google.clientId is required when google is enabled\");\n }\n\n // Validate Apple config\n if (config.apple && !config.apple.clientId) {\n throw new Error(\"[Auth] apple.clientId is required when apple is enabled\");\n }\n\n console.log(\"[Auth] Config validated:\", {\n backendUrl: config.backendUrl,\n hasGoogle: !!config.google,\n hasApple: !!config.apple,\n hasEmail: !!config.email?.enabled,\n });\n}\n","import type { JWTData } from \"../types\";\n\n// ============================================\n// STORAGE ADAPTER INTERFACE\n// ============================================\n\n/**\n * Interface for custom storage adapters.\n * Implement this to use your own storage (Redux, Zustand, AsyncStorage, etc.)\n */\nexport interface StorageAdapter {\n getItem: (key: string) => Promise<string | null> | string | null;\n setItem: (key: string, value: string) => Promise<void> | void;\n removeItem: (key: string) => Promise<void> | void;\n}\n\n// ============================================\n// DEFAULT ADAPTERS\n// ============================================\n\n/**\n * Default localStorage adapter for web\n * Includes SSR safety checks for Next.js and other SSR frameworks\n */\nexport const localStorageAdapter: StorageAdapter = {\n getItem: (key) => {\n if (typeof window === \"undefined\") return null;\n return localStorage.getItem(key);\n },\n setItem: (key, value) => {\n if (typeof window === \"undefined\") return;\n localStorage.setItem(key, value);\n },\n removeItem: (key) => {\n if (typeof window === \"undefined\") return;\n localStorage.removeItem(key);\n },\n};\n\n/**\n * Memory adapter for SSR or testing\n */\nexport const memoryStorageAdapter = (): StorageAdapter => {\n const store = new Map<string, string>();\n return {\n getItem: (key) => store.get(key) ?? null,\n setItem: (key, value) => {\n store.set(key, value);\n },\n removeItem: (key) => {\n store.delete(key);\n },\n };\n};\n\n// ============================================\n// STORAGE SERVICE FACTORY\n// ============================================\n\nconst TOKEN_KEY = \"auth_token_data\";\n\n/**\n * Creates a storage service with the provided adapter.\n * Reusable token logic with pluggable storage backend.\n */\nexport function createStorageService(adapter: StorageAdapter) {\n return {\n /**\n * Save tokens to storage\n */\n async saveTokens(tokens: JWTData): Promise<void> {\n try {\n const dataToStore = {\n ...tokens,\n stored_at: Date.now(),\n };\n await adapter.setItem(TOKEN_KEY, JSON.stringify(dataToStore));\n console.log(\"[Auth Storage] Tokens saved successfully\");\n } catch (error) {\n console.error(\"[Auth Storage] Failed to save tokens:\", error);\n throw error;\n }\n },\n\n /**\n * Get tokens from storage\n * Returns null if no tokens exist or if they're invalid\n */\n async getTokens(): Promise<JWTData | null> {\n try {\n const data = await adapter.getItem(TOKEN_KEY);\n if (!data) {\n return null;\n }\n\n const parsed = JSON.parse(data);\n\n // Return tokens without the stored_at metadata\n const { stored_at: _storedAt, ...tokens } = parsed;\n\n return tokens as JWTData;\n } catch (error) {\n console.error(\"[Auth Storage] Failed to get tokens:\", error);\n // Clear corrupted data\n await this.clearTokens();\n return null;\n }\n },\n\n /**\n * Get raw stored data (including metadata like stored_at)\n */\n async getRawData(): Promise<{ tokens: JWTData; stored_at: number } | null> {\n try {\n const data = await adapter.getItem(TOKEN_KEY);\n if (!data) {\n return null;\n }\n const parsed = JSON.parse(data);\n\n // Data is stored as flat object: { ...tokens, stored_at }\n // Extract stored_at and return in expected format\n const { stored_at, ...tokens } = parsed;\n\n return { tokens: tokens as JWTData, stored_at };\n } catch (error) {\n console.error(\"[Auth Storage] Failed to get raw data:\", error);\n return null;\n }\n },\n\n /**\n * Clear tokens from storage\n */\n async clearTokens(): Promise<void> {\n try {\n await adapter.removeItem(TOKEN_KEY);\n console.log(\"[Auth Storage] Tokens cleared\");\n } catch (error) {\n console.error(\"[Auth Storage] Failed to clear tokens:\", error);\n }\n },\n\n /**\n * Check if tokens exist in storage\n */\n async hasTokens(): Promise<boolean> {\n const data = await adapter.getItem(TOKEN_KEY);\n return data !== null;\n },\n\n /**\n * Check if stored tokens are expired\n * Uses expires_in from the token data\n */\n async isTokenExpired(): Promise<boolean> {\n try {\n const rawData = await this.getRawData();\n if (!rawData) {\n return true;\n }\n\n const { stored_at, tokens } = rawData;\n const expiresIn = tokens.expires_in;\n\n if (!stored_at || !expiresIn) {\n return true;\n }\n\n // Check if current time is past expiration\n // expires_in is in seconds, so convert to milliseconds\n const expirationTime = stored_at + expiresIn * 1000;\n const isExpired = Date.now() >= expirationTime;\n\n if (isExpired) {\n console.log(\"[Auth Storage] Token is expired\");\n }\n\n return isExpired;\n } catch (error) {\n console.error(\n \"[Auth Storage] Failed to check token expiration:\",\n error\n );\n return true;\n }\n },\n\n /**\n * Get the time until token expires (in milliseconds)\n * Returns 0 if token is expired or doesn't exist\n */\n async getTimeUntilExpiry(): Promise<number> {\n try {\n const rawData = await this.getRawData();\n if (!rawData) {\n return 0;\n }\n\n const { stored_at, tokens } = rawData;\n const expiresIn = tokens.expires_in;\n\n if (!stored_at || !expiresIn) {\n return 0;\n }\n\n const expirationTime = stored_at + expiresIn * 1000;\n const timeRemaining = expirationTime - Date.now();\n\n return Math.max(0, timeRemaining);\n } catch (error) {\n console.error(\"[Auth Storage] Failed to get time until expiry:\", error);\n return 0;\n }\n },\n };\n}\n\n// ============================================\n// STORAGE SERVICE TYPE\n// ============================================\n\nexport type StorageService = ReturnType<typeof createStorageService>;\n\n// ============================================\n// DEFAULT INSTANCE (backwards compatible)\n// ============================================\n\n/**\n * Default storage service using localStorage.\n * For custom storage, use createStorageService(yourAdapter) instead.\n */\nexport const storageService = createStorageService(localStorageAdapter);\n","import React, {\n createContext,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n AuthConfig,\n AuthInternalContextValue,\n JWTData,\n} from \"../types\";\nimport { validateConfig } from \"../config\";\nimport { storageService } from \"../services/storageService\";\n\n// ============================================\n// CONTEXT\n// ============================================\n\n/**\n * Internal context - includes config and _setTokens for LoginPage\n */\nexport const AuthInternalContext =\n createContext<AuthInternalContextValue | null>(null);\n\n// ============================================\n// PROVIDER PROPS\n// ============================================\n\ninterface AuthProviderProps {\n children: React.ReactNode;\n /** Auth configuration with backend URL and provider settings */\n config: AuthConfig;\n /**\n * Called when user logs out or tokens are invalid on mount.\n * Use this to redirect, clear app state, etc.\n */\n onLogout?: () => void;\n}\n\n// ============================================\n// AUTH PROVIDER COMPONENT\n// ============================================\n\n/**\n * AuthProvider - Wraps your app to provide authentication state.\n *\n * @example\n * ```tsx\n * <AuthProvider\n * config={{\n * backendUrl: import.meta.env.VITE_AUTH_BACKEND_URL,\n * google: { clientId: import.meta.env.VITE_GOOGLE_CLIENT_ID },\n * apple: { clientId: import.meta.env.VITE_APPLE_CLIENT_ID },\n * }}\n * onLogout={() => router.push('/')}\n * >\n * <App />\n * </AuthProvider>\n * ```\n */\nexport function AuthProvider({\n children,\n config,\n onLogout,\n}: AuthProviderProps) {\n // ============================================\n // STATE\n // ============================================\n\n const [tokens, setTokens] = useState<JWTData | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [isAuthLoaded, setIsAuthLoaded] = useState(false);\n\n // Use ref for callback to avoid re-running effect when callback changes\n const onLogoutRef = useRef(onLogout);\n onLogoutRef.current = onLogout;\n\n // Track if initialization has run\n const hasInitialized = useRef(false);\n\n // ============================================\n // INITIALIZATION\n // ============================================\n\n useEffect(() => {\n // Only run initialization once\n if (hasInitialized.current) {\n return;\n }\n hasInitialized.current = true;\n\n // Validate config on mount\n validateConfig(config);\n\n // Load tokens from storage\n const initializeAuth = async () => {\n console.log(\"[AuthProvider] Initializing auth state\");\n\n try {\n // Check if we have stored tokens\n const storedTokens = await storageService.getTokens();\n\n if (storedTokens) {\n // Check if tokens are expired\n const isExpired = await storageService.isTokenExpired();\n\n if (isExpired) {\n console.log(\"[AuthProvider] Stored tokens are expired, clearing\");\n await storageService.clearTokens();\n onLogoutRef.current?.();\n } else {\n console.log(\"[AuthProvider] Valid tokens found, restoring session\");\n setTokens(storedTokens);\n }\n } else {\n console.log(\"[AuthProvider] No stored tokens found\");\n }\n } catch (error) {\n console.error(\"[AuthProvider] Error initializing auth:\", error);\n // Clear any corrupted data\n await storageService.clearTokens();\n } finally {\n setIsAuthLoaded(true);\n }\n };\n\n initializeAuth();\n }, [config]);\n\n // ============================================\n // INTERNAL: SET TOKENS (for LoginPage)\n // ============================================\n\n const _setTokens = useCallback(async (newTokens: JWTData) => {\n console.log(\"[AuthProvider] Setting tokens\");\n\n // Save to storage\n await storageService.saveTokens(newTokens);\n\n // Update state\n setTokens(newTokens);\n }, []);\n\n // ============================================\n // INTERNAL: SET LOADING (for LoginPage)\n // ============================================\n\n const _setLoading = useCallback((loading: boolean) => {\n setIsLoading(loading);\n }, []);\n\n // ============================================\n // LOGOUT\n // ============================================\n\n const logout = useCallback(async () => {\n console.log(\"[AuthProvider] Logging out\");\n\n // Clear storage\n await storageService.clearTokens();\n\n // Clear state\n setTokens(null);\n\n // Call callback\n onLogoutRef.current?.();\n }, []);\n\n // ============================================\n // CONTEXT VALUE\n // ============================================\n\n const contextValue = useMemo<AuthInternalContextValue>(\n () => ({\n // Public API\n tokens,\n logout,\n isLoading,\n isAuthLoaded,\n\n // Internal API (for LoginPage)\n config,\n _setTokens,\n _setLoading,\n }),\n [tokens, logout, isLoading, isAuthLoaded, config, _setTokens, _setLoading]\n );\n\n return (\n <AuthInternalContext.Provider value={contextValue}>\n {children}\n </AuthInternalContext.Provider>\n );\n}\n\n\n\n","import { useContext } from \"react\";\nimport { AuthInternalContext } from \"../components/AuthProvider\";\nimport type { AuthContextValue, AuthInternalContextValue } from \"../types\";\n\n// ============================================\n// PUBLIC HOOK\n// ============================================\n\n/**\n * useAuth - Public hook for consumers.\n * Returns only the public API (tokens, logout, isLoading, isAuthLoaded).\n *\n * @example\n * ```tsx\n * function App() {\n * const { tokens, logout, isLoading, isAuthLoaded } = useAuth();\n *\n * if (!isAuthLoaded) return <SplashScreen />;\n * if (!tokens) return <LoginPage />;\n * return <MainApp onLogout={logout} />;\n * }\n * ```\n */\nexport function useAuth(): AuthContextValue {\n const context = useContext(AuthInternalContext);\n\n if (!context) {\n throw new Error(\"useAuth must be used within an AuthProvider\");\n }\n\n // Return only public API\n return {\n tokens: context.tokens,\n logout: context.logout,\n isLoading: context.isLoading,\n isAuthLoaded: context.isAuthLoaded,\n };\n}\n\n// ============================================\n// INTERNAL HOOK (for LoginPage)\n// ============================================\n\n/**\n * useAuthInternal - Internal hook for LoginPage.\n * Returns the full internal API including config, _setTokens, _setLoading.\n *\n * @internal\n */\nexport function useAuthInternal(): AuthInternalContextValue {\n const context = useContext(AuthInternalContext);\n\n if (!context) {\n throw new Error(\"useAuthInternal must be used within an AuthProvider\");\n }\n\n return context;\n}\n\n\n\n","import type {\n AuthConfig,\n AuthProviderType,\n AuthResult,\n JWTData,\n TokenRequestParams,\n} from \"../types\";\n\n// ============================================\n// TOKEN EXCHANGE SERVICE\n// ============================================\n\n/**\n * Exchange provider credentials for JWT tokens from the backend.\n * @param params - Auth parameters (id_token, code, username/password)\n * @param provider - The auth provider type\n * @param config - Auth configuration with backendUrl\n */\nexport async function exchangeToken(\n params: TokenRequestParams,\n provider: AuthProviderType,\n config: AuthConfig\n): Promise<AuthResult> {\n console.log(`[Auth Token] Exchanging ${provider} credentials for tokens`);\n\n try {\n const bodyParams: Record<string, string> = {\n grant_type: provider,\n client_id: \"AevatarAuthServer\", // TODO: Make configurable via config\n scope: \"Aevatar offline_access\",\n };\n\n // Add source only for non-password providers (OAuth flows)\n if (provider == \"google\") {\n bodyParams.source = \"web\"; // works for google web.\n } else if (provider == \"apple\") {\n bodyParams.source = \"ios\";\n }\n\n // Add provider-specific app IDs (only for the active provider)\n if (provider === \"google\" && config.appId) {\n bodyParams.google_app_id = config.appId;\n }\n if (provider === \"apple\" && config.apple) {\n // Use apple.appId if set, otherwise fall back to clientId\n bodyParams.apple_app_id = config.apple.appId || config.apple.clientId;\n }\n\n // Add auth params (id_token, code, username, password, etc.)\n if (params.id_token) {\n bodyParams.id_token = params.id_token;\n }\n if (params.code) {\n bodyParams.code = params.code;\n }\n if (params.username) {\n bodyParams.username = params.username;\n }\n if (params.password) {\n bodyParams.password = params.password;\n }\n\n // Encode as form data\n const body = Object.entries(bodyParams)\n .map(([k, v]) => `${k}=${encodeURIComponent(v)}`)\n .join(\"&\");\n\n // Add timeout to prevent hanging requests\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 15000);\n\n const response = await fetch(`${config.backendUrl}/connect/token`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n // Handle error responses\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error(\n `[Auth Token] Exchange failed (${provider}):`,\n response.status,\n errorData\n );\n\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message:\n errorData.error_description ||\n errorData.error ||\n `HTTP ${response.status}: ${response.statusText}`,\n provider,\n };\n }\n\n // Parse successful response\n const tokens = (await response.json()) as JWTData;\n\n console.log(`[Auth Token] Exchange successful for ${provider}`);\n\n return {\n success: true,\n state: \"success\",\n tokens: {\n access_token: tokens.access_token,\n refresh_token: tokens.refresh_token,\n expires_in: tokens.expires_in,\n token_type: tokens.token_type,\n },\n message: \"Login successful\",\n provider,\n };\n } catch (error) {\n // Handle timeout\n const isTimeout = error instanceof Error && error.name === \"AbortError\";\n const errorMessage = isTimeout\n ? \"Request timed out. Please check your connection.\"\n : error instanceof Error\n ? error.message\n : \"Login failed\";\n\n console.error(`[Auth Token] Exchange error (${provider}):`, error);\n\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: errorMessage,\n provider,\n };\n }\n}\n\n// ============================================\n// TOKEN REFRESH SERVICE\n// ============================================\n\n/**\n * Refresh an expired access token using the refresh token.\n * @param refresh_token - The refresh token\n * @param backendUrl - The backend API URL\n */\nexport async function refreshToken(\n refresh_token: string,\n backendUrl: string\n): Promise<JWTData | null> {\n console.log(\"[Auth Token] Refreshing access token\");\n\n try {\n const body = new URLSearchParams({\n grant_type: \"refresh_token\",\n client_id: \"AevatarAuthServer\", // TODO: Make configurable\n refresh_token,\n }).toString();\n\n // Add timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 15000);\n\n const response = await fetch(`${backendUrl}/connect/token`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error(\"[Auth Token] Refresh failed:\", response.status, errorData);\n throw new Error(\n errorData.error_description || `Refresh failed: ${response.status}`\n );\n }\n\n const tokens = (await response.json()) as JWTData;\n\n console.log(\"[Auth Token] Refresh successful\");\n\n return {\n access_token: tokens.access_token,\n refresh_token: tokens.refresh_token,\n expires_in: tokens.expires_in,\n token_type: tokens.token_type,\n };\n } catch (error) {\n const isTimeout = error instanceof Error && error.name === \"AbortError\";\n console.error(\n \"[Auth Token] Refresh error:\",\n isTimeout ? \"Request timed out\" : error\n );\n return null;\n }\n}\n","import type { AuthConfig, AuthResult } from \"../types\";\nimport { exchangeToken } from \"../services/tokenService\";\n\n// ============================================\n// GOOGLE IDENTITY SERVICES TYPES\n// ============================================\n\ndeclare global {\n interface Window {\n google?: {\n accounts: {\n id: {\n initialize: (config: GoogleInitConfig) => void;\n prompt: (callback?: (notification: PromptNotification) => void) => void;\n renderButton: (element: HTMLElement, config: ButtonConfig) => void;\n revoke: (hint: string, callback: () => void) => void;\n cancel: () => void;\n };\n };\n };\n }\n}\n\ninterface GoogleInitConfig {\n client_id: string;\n callback: (response: GoogleCredentialResponse) => void;\n auto_select?: boolean;\n cancel_on_tap_outside?: boolean;\n context?: \"signin\" | \"signup\" | \"use\";\n ux_mode?: \"popup\" | \"redirect\";\n login_uri?: string;\n nonce?: string;\n use_fedcm_for_prompt?: boolean;\n}\n\ninterface GoogleCredentialResponse {\n credential: string; // JWT id_token\n select_by?: string;\n clientId?: string;\n}\n\ninterface PromptNotification {\n isNotDisplayed: () => boolean;\n isSkippedMoment: () => boolean;\n isDismissedMoment: () => boolean;\n getNotDisplayedReason: () => string;\n getSkippedReason: () => string;\n getDismissedReason: () => string;\n}\n\ninterface ButtonConfig {\n type?: \"standard\" | \"icon\";\n theme?: \"outline\" | \"filled_blue\" | \"filled_black\";\n size?: \"large\" | \"medium\" | \"small\";\n text?: \"signin_with\" | \"signup_with\" | \"continue_with\" | \"signin\";\n shape?: \"rectangular\" | \"pill\" | \"circle\" | \"square\";\n logo_alignment?: \"left\" | \"center\";\n width?: number;\n locale?: string;\n}\n\n// ============================================\n// STATE\n// ============================================\n\nlet googleSDKLoaded = false;\nlet googleSDKLoading: Promise<void> | null = null;\n\n// ============================================\n// SDK LOADER\n// ============================================\n\n/**\n * Load Google Identity Services SDK\n */\nexport function loadGoogleSDK(): Promise<void> {\n // Already loaded\n if (googleSDKLoaded && window.google?.accounts) {\n return Promise.resolve();\n }\n\n // Already loading\n if (googleSDKLoading) {\n return googleSDKLoading;\n }\n\n googleSDKLoading = new Promise((resolve, reject) => {\n // Check if already in DOM\n if (window.google?.accounts) {\n googleSDKLoaded = true;\n resolve();\n return;\n }\n\n console.log(\"[Auth Google] Loading Google Identity Services SDK\");\n\n const script = document.createElement(\"script\");\n script.src = \"https://accounts.google.com/gsi/client\";\n script.async = true;\n script.defer = true;\n\n script.onload = () => {\n console.log(\"[Auth Google] SDK loaded successfully\");\n googleSDKLoaded = true;\n resolve();\n };\n\n script.onerror = () => {\n console.error(\"[Auth Google] Failed to load SDK\");\n googleSDKLoading = null;\n reject(new Error(\"Failed to load Google Identity Services SDK\"));\n };\n\n document.head.appendChild(script);\n });\n\n return googleSDKLoading;\n}\n\n// ============================================\n// SIGN IN\n// ============================================\n\n/**\n * Sign in with Google using Google Identity Services.\n * Uses One Tap flow with popup fallback.\n *\n * @param config - Auth configuration with Google client ID\n * @returns AuthResult with tokens on success\n */\nexport async function signInWithGoogle(config: AuthConfig): Promise<AuthResult> {\n console.log(\"[Auth Google] Starting Google sign-in\");\n console.log(\"[Auth Google] Current origin:\", window.location.origin);\n\n // Validate config\n if (!config.google?.clientId) {\n console.error(\"[Auth Google] No client ID configured\");\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Google client ID not configured\",\n provider: \"google\",\n };\n }\n\n console.log(\"[Auth Google] Client ID:\", config.google.clientId.substring(0, 20) + \"...\");\n\n try {\n // Load SDK if not loaded\n console.log(\"[Auth Google] Loading SDK...\");\n await loadGoogleSDK();\n\n if (!window.google?.accounts) {\n throw new Error(\"Google SDK not available after loading\");\n }\n\n console.log(\"[Auth Google] SDK loaded, starting OAuth flow...\");\n\n // Use direct OAuth popup flow (more reliable than One Tap)\n return await signInWithGoogleRedirect(config);\n } catch (error) {\n console.error(\"[Auth Google] Sign-in error:\", error);\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: error instanceof Error ? error.message : \"Google login failed\",\n provider: \"google\",\n };\n }\n}\n\n/**\n * Sign in using OAuth popup flow\n */\nasync function signInWithGooglePopup(config: AuthConfig): Promise<AuthResult> {\n return new Promise((resolve) => {\n console.log(\"[Auth Google] Using popup flow\");\n\n // Generate nonce for security\n const nonce = Math.random().toString(36).substring(2, 15);\n\n // Initialize Google Sign-In\n window.google!.accounts.id.initialize({\n client_id: config.google!.clientId,\n callback: async (response: GoogleCredentialResponse) => {\n console.log(\"[Auth Google] Received credential response\");\n\n if (response.credential) {\n // Exchange id_token for our backend tokens\n const result = await exchangeToken(\n { id_token: response.credential },\n \"google\",\n config\n );\n resolve(result);\n } else {\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: \"No credential received from Google\",\n provider: \"google\",\n });\n }\n },\n auto_select: false,\n cancel_on_tap_outside: true,\n context: \"signin\",\n nonce,\n });\n\n // Show the One Tap prompt\n window.google!.accounts.id.prompt((notification: PromptNotification) => {\n if (notification.isNotDisplayed()) {\n const reason = notification.getNotDisplayedReason();\n console.log(\"[Auth Google] Prompt not displayed:\", reason);\n\n // Fall back to OAuth redirect if One Tap fails\n if (reason === \"opt_out_or_no_session\" || reason === \"suppressed_by_user\") {\n console.log(\"[Auth Google] Falling back to OAuth redirect\");\n signInWithGoogleRedirect(config).then(resolve);\n } else {\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: `Google Sign-In not available: ${reason}`,\n provider: \"google\",\n });\n }\n } else if (notification.isSkippedMoment()) {\n const reason = notification.getSkippedReason();\n console.log(\"[Auth Google] Prompt skipped:\", reason);\n resolve({\n success: false,\n state: \"cancelled\",\n tokens: null,\n message: \"Google Sign-In was skipped\",\n provider: \"google\",\n });\n } else if (notification.isDismissedMoment()) {\n const reason = notification.getDismissedReason();\n console.log(\"[Auth Google] Prompt dismissed:\", reason);\n\n if (reason === \"credential_returned\") {\n // Success - callback will handle this\n return;\n }\n\n resolve({\n success: false,\n state: \"cancelled\",\n tokens: null,\n message: \"Google Sign-In was cancelled\",\n provider: \"google\",\n });\n }\n });\n });\n}\n\n/**\n * Fallback: Sign in using OAuth redirect flow\n */\nasync function signInWithGoogleRedirect(config: AuthConfig): Promise<AuthResult> {\n return new Promise((resolve) => {\n const clientId = config.google!.clientId;\n const redirectUri = window.location.origin;\n const nonce = Math.random().toString(36).substring(2, 15);\n\n console.log(\"[Auth Google] OAuth redirect flow:\");\n console.log(\" - Client ID:\", clientId);\n console.log(\" - Redirect URI:\", redirectUri);\n console.log(\" ⚠️ Make sure this redirect URI is added to Google Cloud Console!\");\n\n const params = new URLSearchParams({\n client_id: clientId,\n redirect_uri: redirectUri,\n response_type: \"id_token\",\n scope: \"openid email profile\",\n nonce,\n prompt: \"select_account\",\n });\n\n const authUrl = `https://accounts.google.com/o/oauth2/v2/auth?${params}`;\n console.log(\"[Auth Google] Auth URL:\", authUrl);\n\n // Open popup\n const width = 500;\n const height = 600;\n const left = window.screenX + (window.outerWidth - width) / 2;\n const top = window.screenY + (window.outerHeight - height) / 2;\n\n const popup = window.open(\n authUrl,\n \"google-auth\",\n `width=${width},height=${height},left=${left},top=${top}`\n );\n\n if (!popup) {\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Popup was blocked. Please allow popups for this site.\",\n provider: \"google\",\n });\n return;\n }\n\n // Poll for popup close or redirect\n const pollInterval = setInterval(() => {\n try {\n // Check if popup was closed\n if (popup.closed) {\n clearInterval(pollInterval);\n resolve({\n success: false,\n state: \"cancelled\",\n tokens: null,\n message: \"Google Sign-In was cancelled\",\n provider: \"google\",\n });\n return;\n }\n\n // Try to read URL (will fail while on Google's domain)\n const url = popup.location.href;\n\n // Check if redirected back to our origin\n if (url.startsWith(redirectUri)) {\n clearInterval(pollInterval);\n popup.close();\n\n // Parse the hash fragment\n const hash = new URL(url.replace(\"#\", \"?\")).searchParams;\n const idToken = hash.get(\"id_token\");\n const error = hash.get(\"error\");\n\n if (error) {\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: hash.get(\"error_description\") || error,\n provider: \"google\",\n });\n return;\n }\n\n if (idToken) {\n // Exchange id_token for our backend tokens\n exchangeToken({ id_token: idToken }, \"google\", config).then(resolve);\n } else {\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: \"No token received from Google\",\n provider: \"google\",\n });\n }\n }\n } catch {\n // Cross-origin error - popup still on Google's domain, keep polling\n }\n }, 500);\n\n // Timeout after 5 minutes\n setTimeout(() => {\n clearInterval(pollInterval);\n if (!popup.closed) {\n popup.close();\n }\n resolve({\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Google Sign-In timed out\",\n provider: \"google\",\n });\n }, 5 * 60 * 1000);\n });\n}\n\n","import type { AuthConfig, AuthResult } from \"../types\";\nimport { exchangeToken } from \"../services/tokenService\";\n\n// ============================================\n// APPLE SIGN IN JS TYPES\n// ============================================\n\ndeclare global {\n interface Window {\n AppleID?: {\n auth: {\n init: (config: AppleInitConfig) => void;\n signIn: (config?: AppleSignInConfig) => Promise<AppleSignInResponse>;\n };\n };\n }\n}\n\ninterface AppleInitConfig {\n clientId: string;\n scope?: string;\n redirectURI: string;\n state?: string;\n nonce?: string;\n usePopup?: boolean;\n}\n\ninterface AppleSignInConfig {\n scope?: string;\n state?: string;\n nonce?: string;\n}\n\ninterface AppleSignInResponse {\n authorization: {\n code: string;\n id_token?: string;\n state?: string;\n };\n user?: {\n email?: string;\n name?: {\n firstName?: string;\n lastName?: string;\n };\n };\n}\n\ninterface AppleSignInError {\n error: string;\n}\n\n// ============================================\n// STATE\n// ============================================\n\nlet appleSDKLoaded = false;\nlet appleSDKLoading: Promise<void> | null = null;\nlet appleInitialized = false;\n\n// ============================================\n// SDK LOADER\n// ============================================\n\n/**\n * Load Apple Sign In JS SDK\n */\nexport function loadAppleSDK(): Promise<void> {\n // Already loaded\n if (appleSDKLoaded && window.AppleID) {\n return Promise.resolve();\n }\n\n // Already loading\n if (appleSDKLoading) {\n return appleSDKLoading;\n }\n\n appleSDKLoading = new Promise((resolve, reject) => {\n // Check if already in DOM\n if (window.AppleID) {\n appleSDKLoaded = true;\n resolve();\n return;\n }\n\n console.log(\"[Auth Apple] Loading Apple Sign In JS SDK\");\n\n const script = document.createElement(\"script\");\n script.src =\n \"https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js\";\n script.async = true;\n\n script.onload = () => {\n console.log(\"[Auth Apple] SDK loaded successfully\");\n appleSDKLoaded = true;\n resolve();\n };\n\n script.onerror = () => {\n console.error(\"[Auth Apple] Failed to load SDK\");\n appleSDKLoading = null;\n reject(new Error(\"Failed to load Apple Sign In JS SDK\"));\n };\n\n document.head.appendChild(script);\n });\n\n return appleSDKLoading;\n}\n\n// ============================================\n// INITIALIZE\n// ============================================\n\n/**\n * Initialize Apple Sign In with configuration\n */\nfunction initializeApple(config: AuthConfig): void {\n if (appleInitialized || !window.AppleID || !config.apple) {\n return;\n }\n\n // For localhost testing, always use current origin\n // Apple requires exact domain matching\n const isLocalhost =\n window.location.hostname === \"localhost\" ||\n window.location.hostname === \"127.0.0.1\";\n const redirectUri = isLocalhost\n ? window.location.origin\n : config.apple.redirectUri || window.location.origin;\n\n console.log(\"[Auth Apple] Initializing with config:\", {\n clientId: config.apple.clientId,\n redirectUri,\n isLocalhost,\n currentOrigin: window.location.origin,\n });\n\n window.AppleID.auth.init({\n clientId: config.apple.clientId,\n scope: \"name email\",\n redirectURI: redirectUri,\n usePopup: true,\n });\n\n appleInitialized = true;\n}\n\n// ============================================\n// SIGN IN\n// ============================================\n\n/**\n * Sign in with Apple using Apple Sign In JS.\n *\n * @param config - Auth configuration with Apple client ID\n * @returns AuthResult with tokens on success\n */\nexport async function signInWithApple(config: AuthConfig): Promise<AuthResult> {\n console.log(\"[Auth Apple] Starting Apple sign-in\");\n\n // Validate config\n if (!config.apple?.clientId) {\n console.error(\"[Auth Apple] No client ID configured\");\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Apple client ID not configured\",\n provider: \"apple\",\n };\n }\n\n // Check if running on localhost - warn about Apple limitations\n const isLocalhost =\n window.location.hostname === \"localhost\" ||\n window.location.hostname === \"127.0.0.1\";\n if (isLocalhost) {\n console.warn(\"[Auth Apple] Running on localhost - Apple Sign In requires:\");\n console.warn(\n \" 1. Your Service ID (com.gpt.godweb) must have localhost configured in Apple Developer Portal\"\n );\n console.warn(\n \" 2. Return URL must include: http://localhost:5173 (or your port)\"\n );\n }\n\n try {\n // Load SDK if not loaded\n console.log(\"[Auth Apple] Loading SDK...\");\n await loadAppleSDK();\n\n if (!window.AppleID) {\n throw new Error(\"Apple SDK not available after loading\");\n }\n\n // Reset initialization to ensure fresh config\n appleInitialized = false;\n\n // Initialize Apple Sign In\n initializeApple(config);\n\n console.log(\"[Auth Apple] Calling Apple signIn...\");\n\n // Attempt sign in\n const response = await window.AppleID.auth.signIn();\n\n console.log(\"[Auth Apple] Received response\");\n\n // Apple returns authorization.code for web\n const code = response.authorization?.code;\n const idToken = response.authorization?.id_token;\n\n if (code) {\n console.log(\"[Auth Apple] Exchanging authorization code\", code);\n return await exchangeToken({ code }, \"apple\", config);\n } else if (idToken) {\n console.log(\"[Auth Apple] Exchanging id_token\");\n return await exchangeToken({ id_token: idToken }, \"apple\", config);\n } else {\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"No authorization code or token received from Apple\",\n provider: \"apple\",\n };\n }\n } catch (error) {\n // Apple throws specific errors\n const appleError = error as AppleSignInError;\n\n // User cancelled\n if (\n appleError?.error === \"popup_closed_by_user\" ||\n appleError?.error === \"user_cancelled_authorize\"\n ) {\n console.log(\"[Auth Apple] Sign-in cancelled by user\");\n return {\n success: false,\n state: \"cancelled\",\n tokens: null,\n message: \"Apple Sign-In was cancelled\",\n provider: \"apple\",\n };\n }\n\n console.error(\"[Auth Apple] Sign-in error:\", error);\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message:\n appleError?.error ||\n (error instanceof Error ? error.message : \"Apple login failed\"),\n provider: \"apple\",\n };\n }\n}\n","import type { AuthConfig, AuthResult } from \"../types\";\nimport { exchangeToken } from \"../services/tokenService\";\n\n// ============================================\n// EMAIL SIGN-IN STRATEGY\n// ============================================\n\n/**\n * Sign in with email and password.\n * Sends credentials to backend for authentication.\n *\n * @param email - User's email address\n * @param password - User's password\n * @param config - Auth configuration with backendUrl\n * @returns AuthResult with tokens on success\n */\nexport async function signInWithEmail(\n email: string,\n password: string,\n config: AuthConfig\n): Promise<AuthResult> {\n console.log(\"[Auth Email] Starting email sign-in\");\n\n // Validate inputs\n if (!email || !email.trim()) {\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Email is required\",\n provider: \"password\",\n };\n }\n\n if (!password) {\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Password is required\",\n provider: \"password\",\n };\n }\n\n // Basic email format validation\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(email.trim())) {\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: \"Please enter a valid email address\",\n provider: \"password\",\n };\n }\n\n try {\n // Exchange credentials for tokens\n // Note: grant_type is \"password\" for email/password auth (OAuth2 standard)\n const result = await exchangeToken(\n {\n username: email.trim(),\n password,\n },\n \"password\",\n config\n );\n\n if (result.success) {\n console.log(\"[Auth Email] Sign-in successful\");\n } else {\n console.log(\"[Auth Email] Sign-in failed:\", result.message);\n }\n\n return result;\n } catch (error) {\n console.error(\"[Auth Email] Sign-in error:\", error);\n return {\n success: false,\n state: \"error\",\n tokens: null,\n message: error instanceof Error ? error.message : \"Email login failed\",\n provider: \"password\",\n };\n }\n}\n\n","import React, { useState } from \"react\";\nimport { useAuthInternal } from \"../hooks/useAuth\";\nimport { signInWithGoogle } from \"../strategies/google\";\nimport { signInWithApple } from \"../strategies/apple\";\nimport { signInWithEmail } from \"../strategies/email\";\n\n// ============================================\n// ICONS\n// ============================================\n\nconst GoogleIcon = () => (\n <svg className=\"w-5 h-5\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z\"\n fill=\"#4285F4\"\n />\n <path\n d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"\n fill=\"#34A853\"\n />\n <path\n d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\"\n fill=\"#FBBC05\"\n />\n <path\n d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"\n fill=\"#EA4335\"\n />\n </svg>\n);\n\nconst AppleIcon = () => (\n <svg className=\"w-5 h-5\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.48-3.24 0-1.44.62-2.2.44-3.06-.4C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09l.01-.01zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z\" />\n </svg>\n);\n\nconst LoadingSpinner = () => (\n <svg\n className=\"animate-spin h-5 w-5\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n);\n\n// ============================================\n// BUTTON COMPONENT\n// ============================================\n\ninterface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: \"primary\" | \"secondary\";\n isLoading?: boolean;\n children: React.ReactNode;\n}\n\nconst Button: React.FC<ButtonProps> = ({\n variant = \"primary\",\n isLoading = false,\n disabled,\n children,\n className = \"\",\n ...props\n}) => {\n const baseClasses =\n \"min-h-[52px] px-6 rounded-[99px] font-semibold text-base transition-all duration-200 flex items-center justify-center gap-2 focus:outline-none\";\n\n const variantClasses = {\n primary: \"bg-black text-white active:opacity-80 active:scale-[0.98]\",\n secondary:\n \"bg-white text-black border border-black active:opacity-80 active:scale-[0.98]\",\n };\n\n const disabledClasses = \"opacity-40 cursor-not-allowed pointer-events-none\";\n\n return (\n <button\n className={`${baseClasses} ${variantClasses[variant]} ${\n disabled || isLoading ? disabledClasses : \"\"\n } ${className}`}\n disabled={disabled || isLoading}\n {...props}\n >\n {isLoading ? (\n <>\n <LoadingSpinner />\n <span>Loading...</span>\n </>\n ) : (\n children\n )}\n </button>\n );\n};\n\n// ============================================\n// INPUT COMPONENT\n// ============================================\n\ninterface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n label?: string;\n error?: string;\n}\n\nconst Input: React.FC<InputProps> = ({\n label,\n error,\n className = \"\",\n ...props\n}) => {\n return (\n <div className=\"space-y-1\">\n {label && (\n <label className=\"block text-sm font-medium text-gray-700\">\n {label}\n </label>\n )}\n <input\n className={`w-full px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-black focus:border-transparent ${\n error ? \"border-red-500\" : \"border-gray-300\"\n } ${className}`}\n {...props}\n />\n {error && <p className=\"text-sm text-red-500\">{error}</p>}\n </div>\n );\n};\n\n// ============================================\n// LOGIN PAGE VIEWS\n// ============================================\n\ntype View = \"main\" | \"email\";\n\n// ============================================\n// LOGIN PAGE COMPONENT\n// ============================================\n\n/**\n * LoginPage - Complete login UI component.\n * Gets config from AuthProvider context.\n * Handles Google, Apple, and Email sign-in.\n *\n * @example\n * ```tsx\n * function App() {\n * const { tokens, isAuthLoaded } = useAuth();\n *\n * if (!isAuthLoaded) return <SplashScreen />;\n * if (!tokens) return <LoginPage />;\n * return <MainApp />;\n * }\n * ```\n */\nexport function LoginPage() {\n const { config, _setTokens, _setLoading, isLoading } = useAuthInternal();\n\n const [view, setView] = useState<View>(\"main\");\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n const [fieldErrors, setFieldErrors] = useState<{\n email?: string;\n password?: string;\n }>({});\n\n // ============================================\n // HANDLERS\n // ============================================\n\n const handleGoogleLogin = async () => {\n if (!config.google) {\n setError(\"Google sign-in is not configured\");\n return;\n }\n\n setError(null);\n _setLoading(true);\n\n try {\n const result = await signInWithGoogle(config);\n\n if (result.success && result.tokens) {\n await _setTokens(result.tokens);\n } else if (result.state !== \"cancelled\") {\n setError(result.message || \"Google sign-in failed\");\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Google sign-in failed\");\n } finally {\n _setLoading(false);\n }\n };\n\n const handleAppleLogin = async () => {\n if (!config.apple) {\n setError(\"Apple sign-in is not configured\");\n return;\n }\n\n setError(null);\n _setLoading(true);\n\n try {\n const result = await signInWithApple(config);\n\n if (result.success && result.tokens) {\n await _setTokens(result.tokens);\n } else if (result.state !== \"cancelled\") {\n setError(result.message || \"Apple sign-in failed\");\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Apple sign-in failed\");\n } finally {\n _setLoading(false);\n }\n };\n\n const handleEmailLogin = async (e: React.FormEvent) => {\n e.preventDefault();\n\n // Validate\n const errors: { email?: string; password?: string } = {};\n if (!email.trim()) {\n errors.email = \"Email is required\";\n }\n if (!password) {\n errors.password = \"Password is required\";\n }\n\n if (Object.keys(errors).length > 0) {\n setFieldErrors(errors);\n return;\n }\n\n setError(null);\n setFieldErrors({});\n _setLoading(true);\n\n try {\n const result = await signInWithEmail(email, password, config);\n\n if (result.success && result.tokens) {\n await _setTokens(result.tokens);\n } else {\n setError(result.message || \"Email sign-in failed\");\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Email sign-in failed\");\n } finally {\n _setLoading(false);\n }\n };\n\n // ============================================\n // EMAIL VIEW\n // ============================================\n\n if (view === \"email\") {\n return (\n <div className=\"min-h-screen bg-white flex flex-col px-5 py-8\">\n <div className=\"flex-1 flex flex-col max-w-md mx-auto w-full\">\n {/* Back Button */}\n <button\n onClick={() => {\n setView(\"main\");\n setError(null);\n setFieldErrors({});\n }}\n className=\"self-start mb-8 flex items-center text-gray-600 active:opacity-80\"\n >\n <svg\n className=\"w-5 h-5 mr-2\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 19l-7-7 7-7\"\n />\n </svg>\n Back\n </button>\n\n {/* Header */}\n <div className=\"mb-12 text-center\">\n <h1 className=\"text-[30px] font-bold text-black mb-2\">Sign In</h1>\n <p className=\"text-base text-gray-600\">\n Enter your email and password\n </p>\n </div>\n\n {/* Error Message */}\n {error && (\n <div className=\"mb-6 p-4 bg-red-50 border border-red-200 rounded-lg\">\n <p className=\"text-sm text-red-600\">{error}</p>\n </div>\n )}\n\n {/* Email Form */}\n <form onSubmit={handleEmailLogin} className=\"space-y-6\">\n <Input\n type=\"email\"\n label=\"Email\"\n placeholder=\"Enter your email\"\n value={email}\n onChange={(e) => {\n setEmail(e.target.value);\n if (fieldErrors.email)\n setFieldErrors({ ...fieldErrors, email: undefined });\n }}\n error={fieldErrors.email}\n autoComplete=\"email\"\n />\n\n <Input\n type=\"password\"\n label=\"Password\"\n placeholder=\"Enter your password\"\n value={password}\n onChange={(e) => {\n setPassword(e.target.value);\n if (fieldErrors.password)\n setFieldErrors({ ...fieldErrors, password: undefined });\n }}\n error={fieldErrors.password}\n autoComplete=\"current-password\"\n />\n\n <Button\n type=\"submit\"\n variant=\"primary\"\n isLoading={isLoading}\n className=\"w-full mt-8\"\n >\n Sign In\n </Button>\n </form>\n </div>\n </div>\n );\n }\n\n // ============================================\n // MAIN VIEW\n // ============================================\n\n return (\n <div className=\"min-h-screen bg-white flex flex-col px-5 py-8\">\n <div className=\"flex-1 flex flex-col justify-center max-w-md mx-auto w-full\">\n {/* Header */}\n <div className=\"mb-12 text-center\">\n <h1 className=\"text-[30px] font-bold text-black mb-2\">\n Welcome Back\n </h1>\n <p className=\"text-base text-gray-600\">Sign in to continue</p>\n </div>\n\n {/* Error Message */}\n {error && (\n <div className=\"mb-6 p-4 bg-red-50 border border-red-200 rounded-lg\">\n <p className=\"text-sm text-red-600\">{error}</p>\n </div>\n )}\n\n {/* Social Login Buttons */}\n <div className=\"space-y-3 mb-8\">\n {config.google && (\n <Button\n variant=\"secondary\"\n onClick={handleGoogleLogin}\n disabled={isLoading}\n className=\"w-full\"\n >\n <GoogleIcon />\n Continue with Google\n </Button>\n )}\n\n {config.apple && (\n <Button\n variant=\"secondary\"\n onClick={handleAppleLogin}\n disabled={isLoading}\n className=\"w-full\"\n >\n <AppleIcon />\n Continue with Apple\n </Button>\n )}\n </div>\n\n {/* Divider */}\n {config.email?.enabled && (config.google || config.apple) && (\n <div className=\"relative mb-8\">\n <div className=\"absolute inset-0 flex items-center\">\n <div className=\"w-full border-t border-gray-300\"></div>\n </div>\n <div className=\"relative flex justify-center text-sm\">\n <span className=\"px-4 bg-white text-gray-500\">\n Or continue with email\n </span>\n </div>\n </div>\n )}\n\n {/* Email Login Button */}\n {config.email?.enabled && (\n <Button\n variant=\"primary\"\n onClick={() => setView(\"email\")}\n disabled={isLoading}\n className=\"w-full\"\n >\n Continue with Email\n </Button>\n )}\n </div>\n\n {/* Disclaimer */}\n <div className=\"pb-[36px] px-5\">\n <p className=\"text-xs text-gray-500 text-center leading-relaxed max-w-sm mx-auto\">\n By signing in, you agree to our{\" \"}\n <a\n href=\"https://app.godgpt.fun/terms-of-service/\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-gray-700 underline underline-offset-2 hover:text-gray-900\"\n >\n Terms of Service\n </a>{\" \"}\n and{\" \"}\n <a\n href=\"https://app.godgpt.fun/privacy-policy/\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-gray-700 underline underline-offset-2 hover:text-gray-900\"\n >\n Privacy Policy\n </a>\n .\n </p>\n </div>\n </div>\n );\n}\n\n\n\n"]}
|