import type { Writable } from 'svelte/store'; import { writable } from 'svelte/store'; // Types export interface User { id: string; email: string; first_name: string; last_name: string; tenant_id: string; role: 'CLIENT_ADMIN' | 'CLIENT_USER'; is_active: boolean; is_two_factor_enabled: boolean; created_at: string; } export interface AuthState { user: User | null; token: string | null; isAuthenticated: boolean; isLoading: boolean; } export interface LoginRequest { email: string; password: string; tenant_slug: string; totp_code?: string; } export interface LoginResponse { access_token: string; token_type: string; expires_in: number; user: User; } // Initial state const initialState: AuthState = { user: null, token: null, isAuthenticated: false, isLoading: false }; // Create auth store function createAuthStore() { const { subscribe, set, update }: Writable = writable(initialState); return { subscribe, // Initialize auth from localStorage init: () => { if (typeof window !== 'undefined') { const token = localStorage.getItem('auth_token'); const user = localStorage.getItem('auth_user'); if (token && user) { try { const parsedUser = JSON.parse(user); set({ user: parsedUser, token, isAuthenticated: true, isLoading: false }); } catch (error) { console.error('Error parsing stored auth data:', error); localStorage.removeItem('auth_token'); localStorage.removeItem('auth_user'); } } } }, // Login login: async (credentials: LoginRequest): Promise => { update(state => ({ ...state, isLoading: true })); try { const response = await fetch('/api/v1/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(credentials) }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Login failed'); } const data: LoginResponse = await response.json(); // Store auth data if (typeof window !== 'undefined') { localStorage.setItem('auth_token', data.access_token); localStorage.setItem('auth_user', JSON.stringify(data.user)); } set({ user: data.user, token: data.access_token, isAuthenticated: true, isLoading: false }); } catch (error) { update(state => ({ ...state, isLoading: false })); throw error; } }, // Logout logout: () => { if (typeof window !== 'undefined') { localStorage.removeItem('auth_token'); localStorage.removeItem('auth_user'); // Immediate redirect after cleanup window.location.href = '/login'; } set(initialState); }, // Update user data updateUser: (user: User) => { update(state => ({ ...state, user })); if (typeof window !== 'undefined') { localStorage.setItem('auth_user', JSON.stringify(user)); } }, // Set loading state setLoading: (isLoading: boolean) => { update(state => ({ ...state, isLoading })); } }; } export const auth = createAuthStore();