Spaces:
Running
Running
| /** | |
| * Auth Client - DataVision Authentication Module | |
| * Provides auth operations using the backend JWT auth system. | |
| */ | |
| import { api } from '../services/api'; | |
| // Internal auth state helpers (used by auth methods below) | |
| const _authState = { | |
| getSession: async () => { | |
| const token = localStorage.getItem('auth_token'); | |
| const userStr = localStorage.getItem('auth_user'); | |
| if (token && userStr) { | |
| try { | |
| return { data: { session: { access_token: token, user: JSON.parse(userStr) } }, error: null }; | |
| } catch (e) { | |
| return { data: { session: null }, error: null }; | |
| } | |
| } | |
| return { data: { session: null }, error: null }; | |
| }, | |
| getUser: async () => { | |
| const userStr = localStorage.getItem('auth_user'); | |
| if (userStr) { | |
| try { | |
| return { data: { user: JSON.parse(userStr) }, error: null }; | |
| } catch (e) { | |
| return { data: { user: null }, error: null }; | |
| } | |
| } | |
| return { data: { user: null }, error: null }; | |
| }, | |
| onAuthStateChange: (callback: (event: string, session: any) => void) => { | |
| // Simplified - not reactive but prevents errors | |
| return { data: { subscription: { unsubscribe: () => {} } } }; | |
| }, | |
| updateUser: async (attributes: any) => { | |
| try { | |
| if (attributes.password) { | |
| await api.post('/api/v1/auth/magic-link', { email: 'current-user-email' }); | |
| } | |
| return { data: { user: {} }, error: null }; | |
| } catch (e: any) { | |
| return { data: null, error: e }; | |
| } | |
| }, | |
| setSession: async ({ access_token, refresh_token }: any) => { | |
| localStorage.setItem('auth_token', access_token); | |
| return { data: { session: { access_token } }, error: null }; | |
| } | |
| }; | |
| /** | |
| * Primary auth client — use this for all auth operations. | |
| */ | |
| export const auth = { | |
| signUp: async (email: string, password: string, metadata?: Record<string, any>) => { | |
| try { | |
| const res = await api.post('/api/v1/auth/signup', { | |
| email, | |
| password, | |
| full_name: metadata?.full_name, | |
| company_name: metadata?.company_name | |
| }); | |
| if (res.data.session) { | |
| localStorage.setItem('auth_token', res.data.session.access_token); | |
| localStorage.setItem('auth_user', JSON.stringify(res.data.user)); | |
| if (res.data.user?.id) { | |
| localStorage.setItem('userId', res.data.user.id); | |
| } | |
| } | |
| return { data: res.data, error: null }; | |
| } catch (error: any) { | |
| return { data: null, error: error.response?.data?.detail || 'Signup failed' }; | |
| } | |
| }, | |
| signIn: async (email: string, password: string) => { | |
| try { | |
| const res = await api.post('/api/v1/auth/login', { email, password }); | |
| if (res.data.session) { | |
| localStorage.setItem('auth_token', res.data.session.access_token); | |
| localStorage.setItem('auth_user', JSON.stringify(res.data.user)); | |
| if (res.data.user?.id) { | |
| localStorage.setItem('userId', res.data.user.id); | |
| } | |
| } | |
| return { data: res.data, error: null }; | |
| } catch (error: any) { | |
| return { data: null, error: error.response?.data?.detail || 'Invalid credentials' }; | |
| } | |
| }, | |
| signInWithMagicLink: async (email: string) => { | |
| try { | |
| const res = await api.post('/api/v1/auth/magic-link', { email }); | |
| return { data: res.data, error: null }; | |
| } catch (error: any) { | |
| return { data: null, error: error.response?.data?.detail || 'Failed to send magic link' }; | |
| } | |
| }, | |
| signInWithOAuth: async (provider: 'google' | 'github') => { | |
| try { | |
| const baseUrl = import.meta.env.VITE_API_URL || ''; | |
| window.location.href = `${baseUrl}/api/v1/auth/oauth/${provider}`; | |
| return { data: null, error: null }; | |
| } catch (error: any) { | |
| return { data: null, error: 'OAuth failed' }; | |
| } | |
| }, | |
| signOut: async () => { | |
| try { | |
| await api.post('/api/v1/auth/logout'); | |
| } catch (e) { | |
| console.error('Logout error', e); | |
| } | |
| localStorage.removeItem('auth_token'); | |
| localStorage.removeItem('auth_user'); | |
| window.location.href = '/login'; | |
| return { error: null }; | |
| }, | |
| getSession: async () => { | |
| return _authState.getSession(); | |
| }, | |
| getUser: async () => { | |
| return _authState.getUser(); | |
| }, | |
| resetPassword: async (email: string) => { | |
| try { | |
| const res = await api.post('/api/v1/auth/magic-link', { email }); | |
| return { data: res.data, error: null }; | |
| } catch (error: any) { | |
| return { data: null, error: error.response?.data?.detail || 'Reset failed' }; | |
| } | |
| }, | |
| onAuthStateChange: (callback: (event: string, session: any) => void) => { | |
| return _authState.onAuthStateChange(callback); | |
| }, | |
| updateUser: async (attributes: any) => { | |
| return _authState.updateUser(attributes); | |
| }, | |
| setSession: async (tokens: { access_token: string; refresh_token?: string }) => { | |
| return _authState.setSession(tokens); | |
| } | |
| }; | |
| export default auth; | |