// Wrapper de autenticação — Supabase Auth com fallback mock // // Comportamento: // - Se window.SUPABASE_URL e window.SUPABASE_ANON_KEY estiverem // configurados, usa Supabase Auth de verdade (Google/Apple/Email). // - Se não, cai pro modo mock que apenas simula o login e avança o // fluxo (mesmo comportamento da versão anterior, sem servidor). (function () { const URL = window.SUPABASE_URL || ''; const KEY = window.SUPABASE_ANON_KEY || ''; let client = null; function getClient() { if (client) return client; if (!URL || !KEY) return null; if (!window.supabase || typeof window.supabase.createClient !== 'function') { console.warn('[Auth] SDK do Supabase não foi carregado.'); return null; } client = window.supabase.createClient(URL, KEY, { auth: { persistSession: true, autoRefreshToken: true }, }); return client; } function mockUser(email, provider) { return { id: 'mock-' + Date.now(), email: email || `demo-${provider || 'guest'}@centraldavida.app`, provider: provider || 'mock', isMock: true, }; } function mapUser(supabaseUser) { if (!supabaseUser) return null; const meta = supabaseUser.user_metadata || {}; return { id: supabaseUser.id, email: supabaseUser.email, name: meta.name || null, provider: supabaseUser.app_metadata && supabaseUser.app_metadata.provider, isMock: false, }; } const Auth = { isConfigured() { return !!getClient(); }, async signInWithEmail(email, password) { const c = getClient(); if (!c) return mockUser(email, 'email'); const { data, error } = await c.auth.signInWithPassword({ email, password }); if (error) throw error; return mapUser(data.user); }, async signUpWithEmail(email, password, name) { const c = getClient(); if (!c) { const u = mockUser(email, 'email'); if (name) u.name = name; return u; } const { data, error } = await c.auth.signUp({ email, password, options: { data: name ? { name } : {} }, }); if (error) throw error; const mapped = mapUser(data.user); // Grava nome no profile (o trigger cria a linha com email; aqui só completa). if (name && mapped && mapped.id) { try { await c.from('profiles').upsert( { user_id: mapped.id, email: mapped.email, name }, { onConflict: 'user_id' } ); mapped.name = name; } catch (e) { console.warn('[Auth] falha ao salvar nome no profile:', e && e.message); } } return mapped; }, async signInWithProvider(provider) { // provider: 'google' | 'apple' const c = getClient(); if (!c) return mockUser(null, provider); const { error } = await c.auth.signInWithOAuth({ provider, options: { redirectTo: window.location.origin + window.location.pathname }, }); if (error) throw error; // OAuth redireciona — o retorno é tratado pelo onAuthStateChange return null; }, async resetPassword(email) { const c = getClient(); if (!c) { // modo mock: só simula return { ok: true, mock: true }; } const { error } = await c.auth.resetPasswordForEmail(email, { redirectTo: window.location.origin + window.location.pathname, }); if (error) throw error; return { ok: true, mock: false }; }, async signOut() { const c = getClient(); if (!c) return; await c.auth.signOut(); }, async getSession() { const c = getClient(); if (!c) return null; const { data } = await c.auth.getSession(); return data.session ? mapUser(data.session.user) : null; }, onAuthStateChange(callback) { const c = getClient(); if (!c) { return { unsubscribe: () => {} }; } const { data } = c.auth.onAuthStateChange((_event, session) => { callback(session ? mapUser(session.user) : null); }); return data.subscription; }, // Exposto para cloud-sync.jsx reaproveitar o mesmo client. _client() { return getClient(); }, }; window.Auth = Auth; })();