diff --git a/src/lib/api.ts b/src/lib/api.ts index dd020a2..5731c78 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -8,10 +8,30 @@ const AUTH_BASE = import.meta.env.PROD ? 'https://api.thenetwork.donovankelly.xyz' : ''; +const TOKEN_KEY = 'network-auth-token'; + class ApiClient { + private getToken(): string | null { + return localStorage.getItem(TOKEN_KEY); + } + + setToken(token: string | null) { + if (token) { + localStorage.setItem(TOKEN_KEY, token); + } else { + localStorage.removeItem(TOKEN_KEY); + } + } + + private authHeaders(): HeadersInit { + const token = this.getToken(); + return token ? { Authorization: `Bearer ${token}` } : {}; + } + private async fetch(path: string, options: RequestInit = {}): Promise { const headers: HeadersInit = { 'Content-Type': 'application/json', + ...this.authHeaders(), ...options.headers, }; @@ -43,23 +63,33 @@ class ApiClient { const error = await response.json().catch(() => ({ message: 'Login failed' })); throw new Error(error.message || 'Login failed'); } + // Capture bearer token from response header + const authToken = response.headers.get('set-auth-token'); + if (authToken) { + this.setToken(authToken); + } return response.json(); } async logout() { await fetch(`${AUTH_BASE}/api/auth/sign-out`, { method: 'POST', + headers: this.authHeaders(), credentials: 'include', }); + this.setToken(null); } async getSession(): Promise<{ user: User } | null> { try { const response = await fetch(`${AUTH_BASE}/api/auth/get-session`, { + headers: this.authHeaders(), credentials: 'include', }); if (!response.ok) return null; - return response.json(); + const data = await response.json(); + if (!data || !data.user) return null; + return data; } catch { return null; } diff --git a/src/stores/auth.ts b/src/stores/auth.ts index 519b0f5..747daa2 100644 --- a/src/stores/auth.ts +++ b/src/stores/auth.ts @@ -46,6 +46,7 @@ export const useAuthStore = create()( try { await api.logout(); } finally { + api.setToken(null); set({ user: null, isAuthenticated: false }); } },