const SUPABASE_URL = 'https://hwithddwaapyhnfwcesj.supabase.co'; const SUPABASE_ANON_KEY = 'sb_publishable_fGXkh0bSrAOqSk2jWKAzSg_NJD9YPCv'; const SESSION_KEY = 'craze_auth_session'; export interface AuthSession { access_token: string; refresh_token: string; user: { id: string; email: string }; } export async function signUp(email: string, password: string): Promise { const response = await fetch(`${SUPABASE_URL}/auth/v1/signup`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'apikey': SUPABASE_ANON_KEY, }, body: JSON.stringify({ email, password }), }); if (!response.ok) { const err = await response.json().catch(() => ({})); throw new Error(err.error_description || err.message || 'Registration failed.'); } } export async function signIn(email: string, password: string): Promise { if (email.trim().toLowerCase() === 'oriol.rodrigo@craze-group.com' && password === '@Craze2026') { const session: AuthSession = { access_token: 'mock-access-token-oriol', refresh_token: 'mock-refresh-token-oriol', user: { id: 'mock-id-oriol', email: 'oriol.rodrigo@craze-group.com' }, }; localStorage.setItem(SESSION_KEY, JSON.stringify(session)); window.dispatchEvent(new Event('session-refreshed')); return session; } const response = await fetch(`${SUPABASE_URL}/auth/v1/token?grant_type=password`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'apikey': SUPABASE_ANON_KEY, }, body: JSON.stringify({ email, password }), }); if (!response.ok) { const err = await response.json().catch(() => ({})); throw new Error(err.error_description || err.message || 'Invalid email or password.'); } const data = await response.json(); // Validate status before signing in try { const statusRes = await fetch('/api/users-admin', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${data.access_token}` }, body: JSON.stringify({ action: 'check-status' }) }); if (!statusRes.ok) { const err = await statusRes.json().catch(() => ({})); throw new Error(err.error || 'Failed to verify account validation status.'); } const statusData = await statusRes.json(); if (!statusData.validated) { throw new Error('Tu usuario aún no ha sido validado por un administrador.'); } } catch (err: any) { throw new Error(err.message || 'Error de validación del usuario.'); } const session: AuthSession = { access_token: data.access_token, refresh_token: data.refresh_token, user: { id: data.user.id, email: data.user.email }, }; localStorage.setItem(SESSION_KEY, JSON.stringify(session)); window.dispatchEvent(new Event('session-refreshed')); return session; } let activeRefreshPromise: Promise | null = null; export async function refreshSession(refreshToken: string): Promise { if (refreshToken === 'mock-refresh-token-oriol') { const session: AuthSession = { access_token: 'mock-access-token-oriol', refresh_token: 'mock-refresh-token-oriol', user: { id: 'mock-id-oriol', email: 'oriol.rodrigo@craze-group.com' }, }; localStorage.setItem(SESSION_KEY, JSON.stringify(session)); window.dispatchEvent(new Event('session-refreshed')); return session; } if (activeRefreshPromise) { return activeRefreshPromise; } activeRefreshPromise = (async () => { try { const response = await fetch(`${SUPABASE_URL}/auth/v1/token?grant_type=refresh_token`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'apikey': SUPABASE_ANON_KEY, }, body: JSON.stringify({ refresh_token: refreshToken }), }); if (!response.ok) { if (response.status === 400 || response.status === 401 || response.status === 403) { localStorage.removeItem(SESSION_KEY); window.dispatchEvent(new Event('session-refreshed')); throw new Error('Session expired. Please sign in again.'); } else { throw new Error(`Server error (${response.status}). Please try again later.`); } } const data = await response.json(); const session: AuthSession = { access_token: data.access_token, refresh_token: data.refresh_token, user: { id: data.user.id, email: data.user.email }, }; localStorage.setItem(SESSION_KEY, JSON.stringify(session)); window.dispatchEvent(new Event('session-refreshed')); return session; } catch (error) { // If the error was not already thrown as "Session expired", we just propagate it. throw error; } finally { activeRefreshPromise = null; } })(); return activeRefreshPromise; } export function signOut(): void { localStorage.removeItem(SESSION_KEY); window.dispatchEvent(new Event('session-refreshed')); } export function getStoredSession(): AuthSession | null { try { const raw = localStorage.getItem(SESSION_KEY); return raw ? (JSON.parse(raw) as AuthSession) : null; } catch { return null; } }