diff --git a/apps/calendar/apps/web/src/lib/stores/auth.svelte.ts b/apps/calendar/apps/web/src/lib/stores/auth.svelte.ts index 699583569..327881b8b 100644 --- a/apps/calendar/apps/web/src/lib/stores/auth.svelte.ts +++ b/apps/calendar/apps/web/src/lib/stores/auth.svelte.ts @@ -4,20 +4,21 @@ */ import { browser } from '$app/environment'; -import { initializeWebAuth } from '@manacore/shared-auth'; -import type { UserData } from '@manacore/shared-auth'; +import { initializeWebAuth, type UserData } from '@manacore/shared-auth'; + +// Default URLs for local development only +const DEV_AUTH_URL = 'http://localhost:3001'; +const DEV_BACKEND_URL = 'http://localhost:3014'; // Get auth URL dynamically at runtime - fallback for SSR and client function getAuthUrl(): string { if (browser && typeof window !== 'undefined') { - // Client-side: use injected window variable (set by hooks.server.ts) - // Falls back to localhost for local development const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) .__PUBLIC_MANA_CORE_AUTH_URL__; - return injectedUrl || 'http://localhost:3001'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_AUTH_URL : ''; } - // Server-side (SSR): use Docker internal URL for container-to-container communication - return process.env.PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001'; + return process.env.PUBLIC_MANA_CORE_AUTH_URL || DEV_AUTH_URL; } // Get backend URL dynamically at runtime @@ -25,9 +26,10 @@ function getBackendUrl(): string { if (browser && typeof window !== 'undefined') { const injectedUrl = (window as unknown as { __PUBLIC_BACKEND_URL__?: string }) .__PUBLIC_BACKEND_URL__; - return injectedUrl || 'http://localhost:3014'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_BACKEND_URL : ''; } - return process.env.PUBLIC_BACKEND_URL || 'http://localhost:3014'; + return process.env.PUBLIC_BACKEND_URL || DEV_BACKEND_URL; } // Lazy initialization to avoid SSR issues with localStorage @@ -39,7 +41,7 @@ function getAuthService() { if (!_authService) { const auth = initializeWebAuth({ baseUrl: getAuthUrl(), - backendUrl: getBackendUrl(), // Enables automatic token refresh on 401 responses + backendUrl: getBackendUrl(), }); _authService = auth.authService; _tokenManager = auth.tokenManager; diff --git a/apps/chat/apps/web/src/lib/stores/auth.svelte.ts b/apps/chat/apps/web/src/lib/stores/auth.svelte.ts index d50b3c91a..10574ae72 100644 --- a/apps/chat/apps/web/src/lib/stores/auth.svelte.ts +++ b/apps/chat/apps/web/src/lib/stores/auth.svelte.ts @@ -4,20 +4,21 @@ */ import { browser } from '$app/environment'; -import { initializeWebAuth } from '@manacore/shared-auth'; -import type { UserData } from '@manacore/shared-auth'; +import { initializeWebAuth, type UserData } from '@manacore/shared-auth'; + +// Default URLs for local development only +const DEV_AUTH_URL = 'http://localhost:3001'; +const DEV_BACKEND_URL = 'http://localhost:3002'; // Get auth URL dynamically at runtime - fallback for SSR and client function getAuthUrl(): string { if (browser && typeof window !== 'undefined') { - // Client-side: use injected window variable (set by hooks.server.ts) - // Falls back to localhost for local development const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) .__PUBLIC_MANA_CORE_AUTH_URL__; - return injectedUrl || 'http://localhost:3001'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_AUTH_URL : ''; } - // Server-side (SSR): use Docker internal URL for container-to-container communication - return process.env.PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001'; + return process.env.PUBLIC_MANA_CORE_AUTH_URL || DEV_AUTH_URL; } // Get backend URL dynamically at runtime @@ -25,9 +26,10 @@ function getBackendUrl(): string { if (browser && typeof window !== 'undefined') { const injectedUrl = (window as unknown as { __PUBLIC_BACKEND_URL__?: string }) .__PUBLIC_BACKEND_URL__; - return injectedUrl || 'http://localhost:3002'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_BACKEND_URL : ''; } - return process.env.PUBLIC_BACKEND_URL || 'http://localhost:3002'; + return process.env.PUBLIC_BACKEND_URL || DEV_BACKEND_URL; } // Lazy initialization to avoid SSR issues with localStorage @@ -136,7 +138,7 @@ export const authStore = { const userData = await authService.getUserFromToken(); user = userData; - return { success: true, error: null }; + return { success: true }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; return { success: false, error: errorMessage }; @@ -163,7 +165,7 @@ export const authStore = { // Mana Core Auth requires separate login after signup if (result.needsVerification) { - return { success: true, error: null, needsVerification: true }; + return { success: true, needsVerification: true }; } // Auto sign in after successful signup @@ -205,13 +207,14 @@ export const authStore = { } try { - const result = await authService.forgotPassword(email); + const redirectTo = browser ? window.location.origin : undefined; + const result = await authService.forgotPassword(email, redirectTo); if (!result.success) { return { success: false, error: result.error || 'Password reset failed' }; } - return { success: true, error: null }; + return { success: true }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; return { success: false, error: errorMessage }; diff --git a/apps/citycorners/apps/web/src/lib/stores/auth.svelte.ts b/apps/citycorners/apps/web/src/lib/stores/auth.svelte.ts index 7d2cefd82..5816eee68 100644 --- a/apps/citycorners/apps/web/src/lib/stores/auth.svelte.ts +++ b/apps/citycorners/apps/web/src/lib/stores/auth.svelte.ts @@ -7,22 +7,28 @@ import { browser } from '$app/environment'; import { initializeWebAuth } from '@manacore/shared-auth'; import type { UserData } from '@manacore/shared-auth'; +// Default URLs for local development only +const DEV_AUTH_URL = 'http://localhost:3001'; +const DEV_BACKEND_URL = 'http://localhost:3025'; + function getAuthUrl(): string { if (browser && typeof window !== 'undefined') { const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) .__PUBLIC_MANA_CORE_AUTH_URL__; - return injectedUrl || 'http://localhost:3001'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_AUTH_URL : ''; } - return process.env.PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001'; + return process.env.PUBLIC_MANA_CORE_AUTH_URL || DEV_AUTH_URL; } function getBackendUrl(): string { if (browser && typeof window !== 'undefined') { const injectedUrl = (window as unknown as { __PUBLIC_BACKEND_URL__?: string }) .__PUBLIC_BACKEND_URL__; - return injectedUrl || 'http://localhost:3025'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_BACKEND_URL : ''; } - return process.env.PUBLIC_BACKEND_URL || 'http://localhost:3025'; + return process.env.PUBLIC_BACKEND_URL || DEV_BACKEND_URL; } let _authService: ReturnType['authService'] | null = null; @@ -168,7 +174,8 @@ export const authStore = { } try { - const result = await authService.forgotPassword(email); + const redirectTo = browser ? window.location.origin : undefined; + const result = await authService.forgotPassword(email, redirectTo); if (!result.success) { return { success: false, error: result.error || 'Password reset failed' }; } diff --git a/apps/clock/apps/web/src/lib/stores/auth.svelte.ts b/apps/clock/apps/web/src/lib/stores/auth.svelte.ts index 9174d2d7b..9f489afdb 100644 --- a/apps/clock/apps/web/src/lib/stores/auth.svelte.ts +++ b/apps/clock/apps/web/src/lib/stores/auth.svelte.ts @@ -6,17 +6,19 @@ import { browser } from '$app/environment'; import { initializeWebAuth, type UserData } from '@manacore/shared-auth'; +// Default URLs for local development only +const DEV_AUTH_URL = 'http://localhost:3001'; +const DEV_BACKEND_URL = 'http://localhost:3017'; + // Get auth URL dynamically at runtime - fallback for SSR and client function getAuthUrl(): string { if (browser && typeof window !== 'undefined') { - // Client-side: use injected window variable (set by hooks.server.ts) - // Falls back to localhost for local development const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) .__PUBLIC_MANA_CORE_AUTH_URL__; - return injectedUrl || 'http://localhost:3001'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_AUTH_URL : ''; } - // Server-side (SSR): use Docker internal URL for container-to-container communication - return process.env.PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001'; + return process.env.PUBLIC_MANA_CORE_AUTH_URL || DEV_AUTH_URL; } // Get backend URL dynamically at runtime @@ -24,9 +26,10 @@ function getBackendUrl(): string { if (browser && typeof window !== 'undefined') { const injectedUrl = (window as unknown as { __PUBLIC_BACKEND_URL__?: string }) .__PUBLIC_BACKEND_URL__; - return injectedUrl || 'http://localhost:3017'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_BACKEND_URL : ''; } - return process.env.PUBLIC_BACKEND_URL || 'http://localhost:3017'; + return process.env.PUBLIC_BACKEND_URL || DEV_BACKEND_URL; } // Lazy initialization to avoid SSR issues with localStorage @@ -204,7 +207,8 @@ export const authStore = { } try { - const result = await authService.forgotPassword(email); + const redirectTo = browser ? window.location.origin : undefined; + const result = await authService.forgotPassword(email, redirectTo); if (!result.success) { return { success: false, error: result.error || 'Password reset failed' }; diff --git a/apps/contacts/apps/web/src/lib/stores/auth.svelte.ts b/apps/contacts/apps/web/src/lib/stores/auth.svelte.ts index 2973c217b..fd1775857 100644 --- a/apps/contacts/apps/web/src/lib/stores/auth.svelte.ts +++ b/apps/contacts/apps/web/src/lib/stores/auth.svelte.ts @@ -4,20 +4,21 @@ */ import { browser } from '$app/environment'; -import { initializeWebAuth } from '@manacore/shared-auth'; -import type { UserData } from '@manacore/shared-auth'; +import { initializeWebAuth, type UserData } from '@manacore/shared-auth'; + +// Default URLs for local development only +const DEV_AUTH_URL = 'http://localhost:3001'; +const DEV_BACKEND_URL = 'http://localhost:3015'; // Get auth URL dynamically at runtime - fallback for SSR and client function getAuthUrl(): string { if (browser && typeof window !== 'undefined') { - // Client-side: use injected window variable (set by hooks.server.ts) - // Falls back to localhost for local development const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) .__PUBLIC_MANA_CORE_AUTH_URL__; - return injectedUrl || 'http://localhost:3001'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_AUTH_URL : ''; } - // Server-side (SSR): use Docker internal URL for container-to-container communication - return process.env.PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001'; + return process.env.PUBLIC_MANA_CORE_AUTH_URL || DEV_AUTH_URL; } // Get backend URL dynamically at runtime @@ -25,9 +26,10 @@ function getBackendUrl(): string { if (browser && typeof window !== 'undefined') { const injectedUrl = (window as unknown as { __PUBLIC_BACKEND_URL__?: string }) .__PUBLIC_BACKEND_URL__; - return injectedUrl || 'http://localhost:3015'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_BACKEND_URL : ''; } - return process.env.PUBLIC_BACKEND_URL || 'http://localhost:3015'; + return process.env.PUBLIC_BACKEND_URL || DEV_BACKEND_URL; } // Lazy initialization to avoid SSR issues with localStorage @@ -205,7 +207,8 @@ export const authStore = { } try { - const result = await authService.forgotPassword(email); + const redirectTo = browser ? window.location.origin : undefined; + const result = await authService.forgotPassword(email, redirectTo); if (!result.success) { return { success: false, error: result.error || 'Password reset failed' }; diff --git a/apps/context/apps/web/src/lib/stores/auth.svelte.ts b/apps/context/apps/web/src/lib/stores/auth.svelte.ts index 6f6d1f339..4280d9896 100644 --- a/apps/context/apps/web/src/lib/stores/auth.svelte.ts +++ b/apps/context/apps/web/src/lib/stores/auth.svelte.ts @@ -6,14 +6,28 @@ import { browser } from '$app/environment'; import { initializeWebAuth, type UserData } from '@manacore/shared-auth'; -// Get auth URL dynamically at runtime - fallback for SSR and client +// Default URLs for local development only +const DEV_AUTH_URL = 'http://localhost:3001'; +const DEV_BACKEND_URL = 'http://localhost:3020'; + function getAuthUrl(): string { if (browser && typeof window !== 'undefined') { const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) .__PUBLIC_MANA_CORE_AUTH_URL__; - return injectedUrl || 'http://localhost:3001'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_AUTH_URL : ''; } - return process.env.PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001'; + return process.env.PUBLIC_MANA_CORE_AUTH_URL || DEV_AUTH_URL; +} + +function getBackendUrl(): string { + if (browser && typeof window !== 'undefined') { + const injectedUrl = (window as unknown as { __PUBLIC_BACKEND_URL__?: string }) + .__PUBLIC_BACKEND_URL__; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_BACKEND_URL : ''; + } + return process.env.PUBLIC_BACKEND_URL || DEV_BACKEND_URL; } // Lazy initialization to avoid SSR issues with localStorage @@ -25,6 +39,7 @@ function getAuthService() { if (!_authService) { const auth = initializeWebAuth({ baseUrl: getAuthUrl(), + backendUrl: getBackendUrl(), }); _authService = auth.authService; _tokenManager = auth.tokenManager; @@ -163,7 +178,8 @@ export const authStore = { } try { - const result = await authService.forgotPassword(email); + const redirectTo = browser ? window.location.origin : undefined; + const result = await authService.forgotPassword(email, redirectTo); if (!result.success) { return { success: false, error: result.error || 'Password reset failed' }; diff --git a/apps/manacore/apps/web/src/lib/stores/auth.svelte.ts b/apps/manacore/apps/web/src/lib/stores/auth.svelte.ts index 78b6f1f8e..6a89ec062 100644 --- a/apps/manacore/apps/web/src/lib/stores/auth.svelte.ts +++ b/apps/manacore/apps/web/src/lib/stores/auth.svelte.ts @@ -4,20 +4,20 @@ */ import { browser } from '$app/environment'; -import { initializeWebAuth } from '@manacore/shared-auth'; -import type { UserData } from '@manacore/shared-auth'; +import { initializeWebAuth, type UserData } from '@manacore/shared-auth'; + +// Default URL for local development only +const DEV_AUTH_URL = 'http://localhost:3001'; // Get auth URL dynamically at runtime - fallback for SSR and client function getAuthUrl(): string { if (browser && typeof window !== 'undefined') { - // Client-side: use injected window variable (set by hooks.server.ts) - // Falls back to localhost for local development const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) .__PUBLIC_MANA_CORE_AUTH_URL__; - return injectedUrl || 'http://localhost:3001'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_AUTH_URL : ''; } - // Server-side (SSR): use Docker internal URL for container-to-container communication - return process.env.PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001'; + return process.env.PUBLIC_MANA_CORE_AUTH_URL || DEV_AUTH_URL; } // Lazy initialization to avoid SSR issues with localStorage @@ -203,7 +203,8 @@ export const authStore = { } try { - const result = await authService.forgotPassword(email); + const redirectTo = browser ? window.location.origin : undefined; + const result = await authService.forgotPassword(email, redirectTo); if (!result.success) { return { success: false, error: result.error || 'Password reset failed' }; diff --git a/apps/manadeck/apps/web/src/lib/stores/auth.svelte.ts b/apps/manadeck/apps/web/src/lib/stores/auth.svelte.ts index 6c0e8c53b..5f1471d3a 100644 --- a/apps/manadeck/apps/web/src/lib/stores/auth.svelte.ts +++ b/apps/manadeck/apps/web/src/lib/stores/auth.svelte.ts @@ -123,7 +123,8 @@ export const authStore = { * Send password reset email */ async forgotPassword(email: string) { - return authService.forgotPassword(email); + const redirectTo = browser ? window.location.origin : undefined; + return authService.forgotPassword(email, redirectTo); }, /** diff --git a/apps/mukke/apps/web/src/lib/stores/auth.svelte.ts b/apps/mukke/apps/web/src/lib/stores/auth.svelte.ts index 6b30a6bb7..791254643 100644 --- a/apps/mukke/apps/web/src/lib/stores/auth.svelte.ts +++ b/apps/mukke/apps/web/src/lib/stores/auth.svelte.ts @@ -7,24 +7,28 @@ import { browser } from '$app/environment'; import { initializeWebAuth } from '@manacore/shared-auth'; import type { UserData } from '@manacore/shared-auth'; -// Get auth URL dynamically at runtime - fallback for SSR and client +// Default URLs for local development only +const DEV_AUTH_URL = 'http://localhost:3001'; +const DEV_BACKEND_URL = 'http://localhost:3010'; + function getAuthUrl(): string { if (browser && typeof window !== 'undefined') { const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) .__PUBLIC_MANA_CORE_AUTH_URL__; - return injectedUrl || 'http://localhost:3001'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_AUTH_URL : ''; } - return process.env.PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001'; + return process.env.PUBLIC_MANA_CORE_AUTH_URL || DEV_AUTH_URL; } -// Get backend URL dynamically at runtime function getBackendUrl(): string { if (browser && typeof window !== 'undefined') { const injectedUrl = (window as unknown as { __PUBLIC_BACKEND_URL__?: string }) .__PUBLIC_BACKEND_URL__; - return injectedUrl || 'http://localhost:3010'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_BACKEND_URL : ''; } - return process.env.PUBLIC_BACKEND_URL || 'http://localhost:3010'; + return process.env.PUBLIC_BACKEND_URL || DEV_BACKEND_URL; } // Lazy initialization to avoid SSR issues with localStorage @@ -196,8 +200,8 @@ export const authStore = { } try { - const sourceAppUrl = browser ? window.location.origin : undefined; - const result = await authService.forgotPassword(email, sourceAppUrl); + const redirectTo = browser ? window.location.origin : undefined; + const result = await authService.forgotPassword(email, redirectTo); if (!result.success) { return { success: false, error: result.error || 'Failed to send reset email' }; diff --git a/apps/nutriphi/apps/web/src/lib/stores/auth.svelte.ts b/apps/nutriphi/apps/web/src/lib/stores/auth.svelte.ts index c646e6126..deee6cf72 100644 --- a/apps/nutriphi/apps/web/src/lib/stores/auth.svelte.ts +++ b/apps/nutriphi/apps/web/src/lib/stores/auth.svelte.ts @@ -7,27 +7,28 @@ import { browser } from '$app/environment'; import { initializeWebAuth } from '@manacore/shared-auth'; import type { UserData } from '@manacore/shared-auth'; -// Get auth URL dynamically at runtime - fallback for SSR and client +// Default URLs for local development only +const DEV_AUTH_URL = 'http://localhost:3001'; +const DEV_BACKEND_URL = 'http://localhost:3023'; + function getAuthUrl(): string { if (browser && typeof window !== 'undefined') { - // Client-side: use injected window variable (set by hooks.server.ts) - // Falls back to localhost for local development const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) .__PUBLIC_MANA_CORE_AUTH_URL__; - return injectedUrl || 'http://localhost:3001'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_AUTH_URL : ''; } - // Server-side (SSR): use Docker internal URL for container-to-container communication - return process.env.PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001'; + return process.env.PUBLIC_MANA_CORE_AUTH_URL || DEV_AUTH_URL; } -// Get backend URL dynamically at runtime function getBackendUrl(): string { if (browser && typeof window !== 'undefined') { const injectedUrl = (window as unknown as { __PUBLIC_BACKEND_URL__?: string }) .__PUBLIC_BACKEND_URL__; - return injectedUrl || 'http://localhost:3023'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_BACKEND_URL : ''; } - return process.env.PUBLIC_BACKEND_URL || 'http://localhost:3023'; + return process.env.PUBLIC_BACKEND_URL || DEV_BACKEND_URL; } // Lazy initialization to avoid SSR issues with localStorage @@ -202,7 +203,8 @@ export const authStore = { } try { - const result = await authService.forgotPassword(email); + const redirectTo = browser ? window.location.origin : undefined; + const result = await authService.forgotPassword(email, redirectTo); if (!result.success) { return { success: false, error: result.error || 'Password reset failed' }; diff --git a/apps/photos/apps/web/src/lib/stores/auth.svelte.ts b/apps/photos/apps/web/src/lib/stores/auth.svelte.ts index 2069217ce..c44f17943 100644 --- a/apps/photos/apps/web/src/lib/stores/auth.svelte.ts +++ b/apps/photos/apps/web/src/lib/stores/auth.svelte.ts @@ -7,24 +7,28 @@ import { browser } from '$app/environment'; import { initializeWebAuth } from '@manacore/shared-auth'; import type { UserData } from '@manacore/shared-auth'; -// Get auth URL dynamically at runtime +// Default URLs for local development only +const DEV_AUTH_URL = 'http://localhost:3001'; +const DEV_BACKEND_URL = 'http://localhost:3019'; + function getAuthUrl(): string { if (browser && typeof window !== 'undefined') { const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) .__PUBLIC_MANA_CORE_AUTH_URL__; - return injectedUrl || 'http://localhost:3001'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_AUTH_URL : ''; } - return process.env.PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001'; + return process.env.PUBLIC_MANA_CORE_AUTH_URL || DEV_AUTH_URL; } -// Get backend URL dynamically at runtime function getBackendUrl(): string { if (browser && typeof window !== 'undefined') { const injectedUrl = (window as unknown as { __PUBLIC_BACKEND_URL__?: string }) .__PUBLIC_BACKEND_URL__; - return injectedUrl || 'http://localhost:3019'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_BACKEND_URL : ''; } - return process.env.PUBLIC_BACKEND_URL || 'http://localhost:3019'; + return process.env.PUBLIC_BACKEND_URL || DEV_BACKEND_URL; } // Lazy initialization to avoid SSR issues with localStorage @@ -177,7 +181,8 @@ export const authStore = { } try { - const result = await authService.forgotPassword(email); + const redirectTo = browser ? window.location.origin : undefined; + const result = await authService.forgotPassword(email, redirectTo); if (!result.success) { return { success: false, error: result.error || 'Password reset failed' }; diff --git a/apps/picture/apps/web/src/lib/stores/auth.svelte.ts b/apps/picture/apps/web/src/lib/stores/auth.svelte.ts index eb3b66e4a..72ef847f1 100644 --- a/apps/picture/apps/web/src/lib/stores/auth.svelte.ts +++ b/apps/picture/apps/web/src/lib/stores/auth.svelte.ts @@ -1,52 +1,57 @@ /** * Auth Store - Manages authentication state using Svelte 5 runes - * Now using Mana Core Auth instead of Supabase Auth + * Uses Mana Core Auth */ import { browser } from '$app/environment'; -import { env } from '$env/dynamic/public'; +import { initializeWebAuth, type UserData } from '@manacore/shared-auth'; -const MANA_AUTH_URL = env.PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001'; -const BACKEND_URL = env.PUBLIC_BACKEND_URL || 'http://localhost:3006'; +// Default URLs for local development only +const DEV_AUTH_URL = 'http://localhost:3001'; +const DEV_BACKEND_URL = 'http://localhost:3006'; -export interface UserData { - id: string; - email: string; - role?: string; +// Get auth URL dynamically at runtime - fallback for SSR and client +function getAuthUrl(): string { + if (browser && typeof window !== 'undefined') { + const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) + .__PUBLIC_MANA_CORE_AUTH_URL__; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_AUTH_URL : ''; + } + return process.env.PUBLIC_MANA_CORE_AUTH_URL || DEV_AUTH_URL; } -interface AuthResult { - success: boolean; - error?: string; +// Get backend URL dynamically at runtime +function getBackendUrl(): string { + if (browser && typeof window !== 'undefined') { + const injectedUrl = (window as unknown as { __PUBLIC_BACKEND_URL__?: string }) + .__PUBLIC_BACKEND_URL__; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_BACKEND_URL : ''; + } + return process.env.PUBLIC_BACKEND_URL || DEV_BACKEND_URL; } -// Internal auth service reference -let _authService: any = null; -let _tokenManager: any = null; +// Lazy initialization to avoid SSR issues with localStorage +let _authService: ReturnType['authService'] | null = null; +let _tokenManager: ReturnType['tokenManager'] | null = null; -async function getAuthService() { +function getAuthService() { if (!browser) return null; if (!_authService) { - try { - const { initializeWebAuth } = await import('@manacore/shared-auth'); - const auth = initializeWebAuth({ - baseUrl: MANA_AUTH_URL, - backendUrl: BACKEND_URL, // Enables automatic token refresh on 401 responses - }); - _authService = auth.authService; - _tokenManager = auth.tokenManager; - } catch (error) { - console.error('Failed to initialize auth service:', error); - return null; - } + const auth = initializeWebAuth({ + baseUrl: getAuthUrl(), + backendUrl: getBackendUrl(), + }); + _authService = auth.authService; + _tokenManager = auth.tokenManager; } return _authService; } -async function getTokenManager() { +function getTokenManager() { if (!browser) return null; - // Ensure auth service is initialized first - await getAuthService(); + getAuthService(); return _tokenManager; } @@ -69,158 +74,174 @@ export const authStore = { return initialized; }, + /** + * Initialize auth state from stored tokens + * Also tries SSO if no local tokens exist (cross-domain authentication) + */ async initialize() { - if (!browser || initialized) return; + if (initialized) return; + + const authService = getAuthService(); + if (!authService) { + initialized = true; + loading = false; + return; + } loading = true; - try { - const authService = await getAuthService(); - if (authService) { - // First, check if we have valid local tokens - let authenticated = await authService.isAuthenticated(); + // First, check if we have valid local tokens + let authenticated = await authService.isAuthenticated(); - // If not authenticated locally, try SSO (shared session cookie) - if (!authenticated) { - console.log('No local tokens, trying SSO...'); - const ssoResult = await authService.trySSO(); - if (ssoResult.success) { - console.log('SSO successful, user authenticated via shared session'); - authenticated = true; - } - } - - if (authenticated) { - const userData = await authService.getUserFromToken(); - user = userData; + // If not authenticated locally, try SSO (shared session cookie) + if (!authenticated) { + console.log('No local tokens, trying SSO...'); + const ssoResult = await authService.trySSO(); + if (ssoResult.success) { + console.log('SSO successful, user authenticated via shared session'); + authenticated = true; } } + + if (authenticated) { + const userData = await authService.getUserFromToken(); + user = userData; + } + initialized = true; } catch (error) { - console.error('Auth initialization error:', error); + console.error('Failed to initialize auth:', error); user = null; } finally { loading = false; - initialized = true; } }, - async signIn(email: string, password: string): Promise { - const authService = await getAuthService(); + /** + * Sign in with email and password + */ + async signIn(email: string, password: string) { + const authService = getAuthService(); if (!authService) { - return { success: false, error: 'Auth service not available' }; + return { success: false, error: 'Auth not available on server' }; } try { - loading = true; const result = await authService.signIn(email, password); - if (result.success) { - const userData = await authService.getUserFromToken(); - user = userData; - return { success: true }; + if (!result.success) { + return { success: false, error: result.error || 'Login failed' }; } - return { success: false, error: result.error || 'Login failed' }; + const userData = await authService.getUserFromToken(); + user = userData; + + return { success: true }; } catch (error) { - return { - success: false, - error: error instanceof Error ? error.message : 'Login failed', - }; - } finally { - loading = false; + const errorMessage = error instanceof Error ? error.message : 'Unknown error'; + return { success: false, error: errorMessage }; } }, - async signUp(email: string, password: string): Promise { - const authService = await getAuthService(); + /** + * Sign up with email and password + */ + async signUp(email: string, password: string) { + const authService = getAuthService(); if (!authService) { - return { success: false, error: 'Auth service not available' }; + return { success: false, error: 'Auth not available on server', needsVerification: false }; } try { - loading = true; - // Pass the current app URL for post-verification redirect const sourceAppUrl = browser ? window.location.origin : undefined; const result = await authService.signUp(email, password, sourceAppUrl); - if (result.success) { - // Auto-login after signup - const signInResult = await this.signIn(email, password); - return signInResult; + if (!result.success) { + return { success: false, error: result.error || 'Signup failed', needsVerification: false }; } - return { success: false, error: result.error || 'Signup failed' }; + if (result.needsVerification) { + return { success: true, needsVerification: true }; + } + + const signInResult = await this.signIn(email, password); + return { ...signInResult, needsVerification: false }; } catch (error) { - return { - success: false, - error: error instanceof Error ? error.message : 'Signup failed', - }; - } finally { - loading = false; + const errorMessage = error instanceof Error ? error.message : 'Unknown error'; + return { success: false, error: errorMessage, needsVerification: false }; } }, - async signOut(): Promise { - const authService = await getAuthService(); - if (authService) { - try { - await authService.signOut(); - } catch (error) { - console.error('Sign out error:', error); - } - } - user = null; - }, - - async resetPassword(email: string): Promise { - const authService = await getAuthService(); + /** + * Sign out + */ + async signOut() { + const authService = getAuthService(); if (!authService) { - return { success: false, error: 'Auth service not available' }; + user = null; + return; } try { - const result = await authService.forgotPassword(email); - return { - success: result.success, - error: result.error, - }; + await authService.signOut(); + user = null; } catch (error) { - return { - success: false, - error: error instanceof Error ? error.message : 'Password reset failed', - }; + console.error('Sign out error:', error); + user = null; } }, /** - * Get access token for API calls (raw token, no refresh) - * @deprecated Use getValidToken() instead for automatic refresh + * Send password reset email */ - async getAccessToken(): Promise { - const authService = await getAuthService(); - if (!authService) return null; - return authService.getAppToken(); + async resetPassword(email: string) { + const authService = getAuthService(); + if (!authService) { + return { success: false, error: 'Auth not available on server' }; + } + + try { + const redirectTo = browser ? window.location.origin : undefined; + const result = await authService.forgotPassword(email, redirectTo); + + if (!result.success) { + return { success: false, error: result.error || 'Password reset failed' }; + } + + return { success: true }; + } catch (error) { + const errorMessage = error instanceof Error ? error.message : 'Unknown error'; + return { success: false, error: errorMessage }; + } }, /** - * Get a valid access token for API calls - * Automatically refreshes if the token is expired or about to expire + * Reset password with token (from reset email link) */ - async getValidToken(): Promise { - const tokenManager = await getTokenManager(); - if (!tokenManager) { - return null; + async resetPasswordWithToken(token: string, newPassword: string) { + const authService = getAuthService(); + if (!authService) { + return { success: false, error: 'Auth not available on server' }; + } + + try { + const result = await authService.resetPassword(token, newPassword); + if (!result.success) { + return { success: false, error: result.error || 'Failed to reset password' }; + } + return { success: true }; + } catch (error) { + const errorMessage = error instanceof Error ? error.message : 'Unknown error'; + return { success: false, error: errorMessage }; } - return await tokenManager.getValidToken(); }, /** * Resend verification email */ async resendVerificationEmail(email: string) { - const authService = await getAuthService(); + const authService = getAuthService(); if (!authService) { - return { success: false, error: 'Auth service not available' }; + return { success: false, error: 'Auth not available on server' }; } try { @@ -233,28 +254,32 @@ export const authStore = { return { success: true }; } catch (error) { - return { - success: false, - error: error instanceof Error ? error.message : 'Failed to resend verification email', - }; + const errorMessage = error instanceof Error ? error.message : 'Unknown error'; + return { success: false, error: errorMessage }; } }, - // For compatibility with old code that reads user store directly - setUser(userData: UserData | null) { - user = userData; + /** + * Get access token for API calls (raw token, no refresh) + * @deprecated Use getValidToken() instead for automatic refresh + */ + async getAccessToken() { + const authService = getAuthService(); + if (!authService) { + return null; + } + return await authService.getAppToken(); + }, + + /** + * Get a valid access token for API calls + * Automatically refreshes if the token is expired or about to expire + */ + async getValidToken(): Promise { + const tokenManager = getTokenManager(); + if (!tokenManager) { + return null; + } + return await tokenManager.getValidToken(); }, }; - -// Export individual reactive getters for backward compatibility -export function getUser() { - return user; -} - -export function getLoading() { - return loading; -} - -export function getIsAuthenticated() { - return !!user; -} diff --git a/apps/planta/apps/web/src/lib/stores/auth.svelte.ts b/apps/planta/apps/web/src/lib/stores/auth.svelte.ts index f83ca6872..d736fa8af 100644 --- a/apps/planta/apps/web/src/lib/stores/auth.svelte.ts +++ b/apps/planta/apps/web/src/lib/stores/auth.svelte.ts @@ -7,24 +7,28 @@ import { browser } from '$app/environment'; import { initializeWebAuth } from '@manacore/shared-auth'; import type { UserData } from '@manacore/shared-auth'; -// Get auth URL dynamically at runtime +// Default URLs for local development only +const DEV_AUTH_URL = 'http://localhost:3001'; +const DEV_BACKEND_URL = 'http://localhost:3022'; + function getAuthUrl(): string { if (browser && typeof window !== 'undefined') { const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) .__PUBLIC_MANA_CORE_AUTH_URL__; - return injectedUrl || 'http://localhost:3001'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_AUTH_URL : ''; } - return process.env.PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001'; + return process.env.PUBLIC_MANA_CORE_AUTH_URL || DEV_AUTH_URL; } -// Get backend URL dynamically at runtime function getBackendUrl(): string { if (browser && typeof window !== 'undefined') { const injectedUrl = (window as unknown as { __PUBLIC_BACKEND_URL__?: string }) .__PUBLIC_BACKEND_URL__; - return injectedUrl || 'http://localhost:3022'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_BACKEND_URL : ''; } - return process.env.PUBLIC_BACKEND_URL || 'http://localhost:3022'; + return process.env.PUBLIC_BACKEND_URL || DEV_BACKEND_URL; } // Lazy initialization to avoid SSR issues @@ -187,7 +191,8 @@ export const authStore = { } try { - const result = await authService.forgotPassword(email); + const redirectTo = browser ? window.location.origin : undefined; + const result = await authService.forgotPassword(email, redirectTo); if (!result.success) { return { success: false, error: result.error || 'Password reset failed' }; diff --git a/apps/playground/apps/web/src/lib/stores/auth.svelte.ts b/apps/playground/apps/web/src/lib/stores/auth.svelte.ts index b0a9098be..d6efeb1d2 100644 --- a/apps/playground/apps/web/src/lib/stores/auth.svelte.ts +++ b/apps/playground/apps/web/src/lib/stores/auth.svelte.ts @@ -2,43 +2,56 @@ import { browser } from '$app/environment'; import { goto } from '$app/navigation'; import { initializeWebAuth, type AuthService, type UserData } from '@manacore/shared-auth'; +// Default URLs for local development only +const DEV_AUTH_URL = 'http://localhost:3001'; +const DEV_BACKEND_URL = 'http://localhost:3025'; + +function getAuthUrl(): string { + if (browser && typeof window !== 'undefined') { + const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) + .__PUBLIC_MANA_CORE_AUTH_URL__; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_AUTH_URL : ''; + } + return process.env.PUBLIC_MANA_CORE_AUTH_URL || DEV_AUTH_URL; +} + +function getBackendUrl(): string { + if (browser && typeof window !== 'undefined') { + const injectedUrl = (window as unknown as { __PUBLIC_MANA_LLM_URL__?: string }) + .__PUBLIC_MANA_LLM_URL__; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_BACKEND_URL : ''; + } + return process.env.PUBLIC_MANA_LLM_URL || DEV_BACKEND_URL; +} + let user = $state(null); let loading = $state(true); let initialized = $state(false); let _authService: AuthService | null = null; - -function getAuthUrl(): string { - if (!browser) return ''; - return ( - (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) - .__PUBLIC_MANA_CORE_AUTH_URL__ || - import.meta.env.PUBLIC_MANA_CORE_AUTH_URL || - 'http://localhost:3001' - ); -} - -function getLlmUrl(): string { - if (!browser) return ''; - return ( - (window as unknown as { __PUBLIC_MANA_LLM_URL__?: string }).__PUBLIC_MANA_LLM_URL__ || - import.meta.env.PUBLIC_MANA_LLM_URL || - 'http://localhost:3025' - ); -} +let _tokenManager: ReturnType['tokenManager'] | null = null; function getAuthService(): AuthService | null { if (!browser) return null; if (!_authService) { const auth = initializeWebAuth({ baseUrl: getAuthUrl(), - backendUrl: getLlmUrl(), + backendUrl: getBackendUrl(), }); _authService = auth.authService; + _tokenManager = auth.tokenManager; } return _authService; } +function getTokenManager() { + if (!browser) return null; + getAuthService(); + return _tokenManager; +} + export const authStore = { get user() { return user; @@ -118,10 +131,29 @@ export const authStore = { goto('/login'); }, - async getValidToken(): Promise { + async resetPassword(email: string) { const authService = getAuthService(); - if (!authService) return null; - return authService.getAppToken(); + if (!authService) { + return { success: false, error: 'Auth not available on server' }; + } + + try { + const redirectTo = browser ? window.location.origin : undefined; + const result = await authService.forgotPassword(email, redirectTo); + if (!result.success) { + return { success: false, error: result.error || 'Password reset failed' }; + } + return { success: true }; + } catch (error) { + const errorMessage = error instanceof Error ? error.message : 'Unknown error'; + return { success: false, error: errorMessage }; + } + }, + + async getValidToken(): Promise { + const tokenManager = getTokenManager(); + if (!tokenManager) return null; + return await tokenManager.getValidToken(); }, async resendVerificationEmail(email: string) { diff --git a/apps/presi/apps/web/src/lib/stores/auth.svelte.ts b/apps/presi/apps/web/src/lib/stores/auth.svelte.ts index bfd8e6abc..47500e369 100644 --- a/apps/presi/apps/web/src/lib/stores/auth.svelte.ts +++ b/apps/presi/apps/web/src/lib/stores/auth.svelte.ts @@ -4,12 +4,33 @@ */ import { browser } from '$app/environment'; -import { initializeWebAuth } from '@manacore/shared-auth'; -import type { UserData } from '@manacore/shared-auth'; -import { PUBLIC_MANA_CORE_AUTH_URL } from '$env/static/public'; +import { initializeWebAuth, type UserData } from '@manacore/shared-auth'; -// Initialize Mana Core Auth only on the client side -const MANA_AUTH_URL = PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001'; +// Default URLs for local development only +const DEV_AUTH_URL = 'http://localhost:3001'; +const DEV_BACKEND_URL = 'http://localhost:3008'; + +// Get auth URL dynamically at runtime - fallback for SSR and client +function getAuthUrl(): string { + if (browser && typeof window !== 'undefined') { + const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) + .__PUBLIC_MANA_CORE_AUTH_URL__; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_AUTH_URL : ''; + } + return process.env.PUBLIC_MANA_CORE_AUTH_URL || DEV_AUTH_URL; +} + +// Get backend URL dynamically at runtime +function getBackendUrl(): string { + if (browser && typeof window !== 'undefined') { + const injectedUrl = (window as unknown as { __PUBLIC_BACKEND_URL__?: string }) + .__PUBLIC_BACKEND_URL__; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_BACKEND_URL : ''; + } + return process.env.PUBLIC_BACKEND_URL || DEV_BACKEND_URL; +} // Lazy initialization to avoid SSR issues with localStorage let _authService: ReturnType['authService'] | null = null; @@ -18,13 +39,22 @@ let _tokenManager: ReturnType['tokenManager'] | null = function getAuthService() { if (!browser) return null; if (!_authService) { - const auth = initializeWebAuth({ baseUrl: MANA_AUTH_URL }); + const auth = initializeWebAuth({ + baseUrl: getAuthUrl(), + backendUrl: getBackendUrl(), + }); _authService = auth.authService; _tokenManager = auth.tokenManager; } return _authService; } +function getTokenManager() { + if (!browser) return null; + getAuthService(); + return _tokenManager; +} + // State let user = $state(null); let loading = $state(true); @@ -61,10 +91,8 @@ export const auth = { loading = true; try { - // First, check if we have valid local tokens let authenticated = await authService.isAuthenticated(); - // If not authenticated locally, try SSO (shared session cookie) if (!authenticated) { console.log('No local tokens, trying SSO...'); const ssoResult = await authService.trySSO(); @@ -89,7 +117,6 @@ export const auth = { /** * Sign in with email and password - * Returns AuthResult compatible format for shared-auth-ui */ async login(email: string, password: string): Promise<{ success: boolean; error?: string }> { const authService = getAuthService(); @@ -104,7 +131,6 @@ export const auth = { return { success: false, error: result.error || 'Login failed' }; } - // Get user data from token const userData = await authService.getUserFromToken(); user = userData; @@ -128,7 +154,6 @@ export const auth = { } try { - // Pass the current app URL for post-verification redirect const sourceAppUrl = browser ? window.location.origin : undefined; const result = await authService.signUp(email, password, sourceAppUrl); @@ -136,12 +161,10 @@ export const auth = { return { success: false, error: result.error || 'Signup failed', needsVerification: false }; } - // Mana Core Auth requires separate login after signup if (result.needsVerification) { return { success: true, needsVerification: true }; } - // Auto sign in after successful signup const signInResult = await this.login(email, password); return { ...signInResult, needsVerification: false }; } catch (error) { @@ -165,7 +188,6 @@ export const auth = { user = null; } catch (error) { console.error('Sign out error:', error); - // Clear user even if sign out fails user = null; } }, @@ -180,7 +202,8 @@ export const auth = { } try { - const result = await authService.forgotPassword(email); + const redirectTo = browser ? window.location.origin : undefined; + const result = await authService.forgotPassword(email, redirectTo); if (!result.success) { return { success: false, error: result.error || 'Password reset failed' }; @@ -216,6 +239,7 @@ export const auth = { /** * Get access token for API calls + * @deprecated Use getValidToken() instead for automatic refresh */ async getAccessToken() { const authService = getAuthService(); @@ -225,6 +249,18 @@ export const auth = { return await authService.getAppToken(); }, + /** + * Get a valid access token for API calls + * Automatically refreshes if the token is expired or about to expire + */ + async getValidToken(): Promise { + const tokenManager = getTokenManager(); + if (!tokenManager) { + return null; + } + return await tokenManager.getValidToken(); + }, + /** * Resend verification email */ diff --git a/apps/questions/apps/web/src/lib/stores/auth.svelte.ts b/apps/questions/apps/web/src/lib/stores/auth.svelte.ts index 060d80f61..bb2d8a9e3 100644 --- a/apps/questions/apps/web/src/lib/stores/auth.svelte.ts +++ b/apps/questions/apps/web/src/lib/stores/auth.svelte.ts @@ -7,22 +7,28 @@ import { browser } from '$app/environment'; import { initializeWebAuth } from '@manacore/shared-auth'; import type { UserData } from '@manacore/shared-auth'; +// Default URLs for local development only +const DEV_AUTH_URL = 'http://localhost:3001'; +const DEV_BACKEND_URL = 'http://localhost:3011'; + function getAuthUrl(): string { if (browser && typeof window !== 'undefined') { const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) .__PUBLIC_MANA_CORE_AUTH_URL__; - return injectedUrl || 'http://localhost:3001'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_AUTH_URL : ''; } - return process.env.PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001'; + return process.env.PUBLIC_MANA_CORE_AUTH_URL || DEV_AUTH_URL; } function getBackendUrl(): string { if (browser && typeof window !== 'undefined') { const injectedUrl = (window as unknown as { __PUBLIC_BACKEND_URL__?: string }) .__PUBLIC_BACKEND_URL__; - return injectedUrl || 'http://localhost:3011'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_BACKEND_URL : ''; } - return process.env.PUBLIC_BACKEND_URL || 'http://localhost:3011'; + return process.env.PUBLIC_BACKEND_URL || DEV_BACKEND_URL; } let _authService: ReturnType['authService'] | null = null; @@ -179,7 +185,8 @@ export const authStore = { } try { - const result = await authService.forgotPassword(email); + const redirectTo = browser ? window.location.origin : undefined; + const result = await authService.forgotPassword(email, redirectTo); if (!result.success) { return { success: false, error: result.error || 'Password reset failed' }; diff --git a/apps/skilltree/apps/web/src/lib/stores/auth.svelte.ts b/apps/skilltree/apps/web/src/lib/stores/auth.svelte.ts index 87cc0cd14..d312b0af5 100644 --- a/apps/skilltree/apps/web/src/lib/stores/auth.svelte.ts +++ b/apps/skilltree/apps/web/src/lib/stores/auth.svelte.ts @@ -197,7 +197,8 @@ export const authStore = { } try { - const result = await authService.forgotPassword(email); + const redirectTo = browser ? window.location.origin : undefined; + const result = await authService.forgotPassword(email, redirectTo); if (!result.success) { return { success: false, error: result.error || 'Password reset failed' }; diff --git a/apps/storage/apps/web/src/lib/stores/auth.svelte.ts b/apps/storage/apps/web/src/lib/stores/auth.svelte.ts index 5988f2a44..117bd3e03 100644 --- a/apps/storage/apps/web/src/lib/stores/auth.svelte.ts +++ b/apps/storage/apps/web/src/lib/stores/auth.svelte.ts @@ -6,33 +6,56 @@ import { browser } from '$app/environment'; import { initializeWebAuth, type UserData } from '@manacore/shared-auth'; +// Default URLs for local development only +const DEV_AUTH_URL = 'http://localhost:3001'; +const DEV_BACKEND_URL = 'http://localhost:3016'; + // Get auth URL dynamically at runtime - fallback for SSR and client function getAuthUrl(): string { if (browser && typeof window !== 'undefined') { - // Client-side: use injected window variable (set by hooks.server.ts) const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) .__PUBLIC_MANA_CORE_AUTH_URL__; - return injectedUrl || 'http://localhost:3001'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_AUTH_URL : ''; } - // Server-side (SSR): use Docker internal URL for container-to-container communication - return process.env.PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001'; + return process.env.PUBLIC_MANA_CORE_AUTH_URL || DEV_AUTH_URL; } -const MANA_AUTH_URL = getAuthUrl(); +// Get backend URL dynamically at runtime +function getBackendUrl(): string { + if (browser && typeof window !== 'undefined') { + const injectedUrl = (window as unknown as { __PUBLIC_BACKEND_URL__?: string }) + .__PUBLIC_BACKEND_URL__; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_BACKEND_URL : ''; + } + return process.env.PUBLIC_BACKEND_URL || DEV_BACKEND_URL; +} +// Lazy initialization to avoid SSR issues with localStorage let _authService: ReturnType['authService'] | null = null; let _tokenManager: ReturnType['tokenManager'] | null = null; function getAuthService() { if (!browser) return null; if (!_authService) { - const auth = initializeWebAuth({ baseUrl: MANA_AUTH_URL }); + const auth = initializeWebAuth({ + baseUrl: getAuthUrl(), + backendUrl: getBackendUrl(), + }); _authService = auth.authService; _tokenManager = auth.tokenManager; } return _authService; } +function getTokenManager() { + if (!browser) return null; + getAuthService(); + return _tokenManager; +} + +// State let user = $state(null); let loading = $state(true); let initialized = $state(false); @@ -67,10 +90,8 @@ export const authStore = { loading = true; try { - // First, check if we have valid local tokens let authenticated = await authService.isAuthenticated(); - // If not authenticated locally, try SSO (shared session cookie) if (!authenticated) { console.log('No local tokens, trying SSO...'); const ssoResult = await authService.trySSO(); @@ -93,6 +114,9 @@ export const authStore = { } }, + /** + * Sign in with email and password + */ async signIn(email: string, password: string) { const authService = getAuthService(); if (!authService) { @@ -116,6 +140,9 @@ export const authStore = { } }, + /** + * Sign up with email and password + */ async signUp(email: string, password: string) { const authService = getAuthService(); if (!authService) { @@ -123,7 +150,6 @@ export const authStore = { } try { - // Pass the current app URL for post-verification redirect const sourceAppUrl = browser ? window.location.origin : undefined; const result = await authService.signUp(email, password, sourceAppUrl); @@ -143,6 +169,9 @@ export const authStore = { } }, + /** + * Sign out + */ async signOut() { const authService = getAuthService(); if (!authService) { @@ -159,6 +188,9 @@ export const authStore = { } }, + /** + * Send password reset email + */ async resetPassword(email: string) { const authService = getAuthService(); if (!authService) { @@ -166,7 +198,8 @@ export const authStore = { } try { - const result = await authService.forgotPassword(email); + const redirectTo = browser ? window.location.origin : undefined; + const result = await authService.forgotPassword(email, redirectTo); if (!result.success) { return { success: false, error: result.error || 'Password reset failed' }; @@ -179,12 +212,25 @@ export const authStore = { } }, - async getAccessToken() { + /** + * Reset password with token (from reset email link) + */ + async resetPasswordWithToken(token: string, newPassword: string) { const authService = getAuthService(); if (!authService) { - return null; + return { success: false, error: 'Auth not available on server' }; + } + + try { + const result = await authService.resetPassword(token, newPassword); + if (!result.success) { + return { success: false, error: result.error || 'Failed to reset password' }; + } + return { success: true }; + } catch (error) { + const errorMessage = error instanceof Error ? error.message : 'Unknown error'; + return { success: false, error: errorMessage }; } - return await authService.getAppToken(); }, /** @@ -210,4 +256,28 @@ export const authStore = { return { success: false, error: errorMessage }; } }, + + /** + * Get access token for API calls (raw token, no refresh) + * @deprecated Use getValidToken() instead for automatic refresh + */ + async getAccessToken() { + const authService = getAuthService(); + if (!authService) { + return null; + } + return await authService.getAppToken(); + }, + + /** + * Get a valid access token for API calls + * Automatically refreshes if the token is expired or about to expire + */ + async getValidToken(): Promise { + const tokenManager = getTokenManager(); + if (!tokenManager) { + return null; + } + return await tokenManager.getValidToken(); + }, }; diff --git a/apps/todo/apps/web/src/lib/stores/auth.svelte.ts b/apps/todo/apps/web/src/lib/stores/auth.svelte.ts index 4b6bffd34..371c33ac7 100644 --- a/apps/todo/apps/web/src/lib/stores/auth.svelte.ts +++ b/apps/todo/apps/web/src/lib/stores/auth.svelte.ts @@ -227,7 +227,8 @@ export const authStore = { } try { - const result = await authService.forgotPassword(email); + const redirectTo = browser ? window.location.origin : undefined; + const result = await authService.forgotPassword(email, redirectTo); if (!result.success) { return { success: false, error: result.error || 'Password reset failed' }; diff --git a/apps/zitare/apps/web/src/lib/stores/auth.svelte.ts b/apps/zitare/apps/web/src/lib/stores/auth.svelte.ts index bad6eb84e..d12538694 100644 --- a/apps/zitare/apps/web/src/lib/stores/auth.svelte.ts +++ b/apps/zitare/apps/web/src/lib/stores/auth.svelte.ts @@ -4,20 +4,21 @@ */ import { browser } from '$app/environment'; -import { initializeWebAuth } from '@manacore/shared-auth'; -import type { UserData } from '@manacore/shared-auth'; +import { initializeWebAuth, type UserData } from '@manacore/shared-auth'; + +// Default URLs for local development only +const DEV_AUTH_URL = 'http://localhost:3001'; +const DEV_BACKEND_URL = 'http://localhost:3007'; // Get auth URL dynamically at runtime - fallback for SSR and client function getAuthUrl(): string { if (browser && typeof window !== 'undefined') { - // Client-side: use injected window variable (set by hooks.server.ts) - // Falls back to localhost for local development const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) .__PUBLIC_MANA_CORE_AUTH_URL__; - return injectedUrl || 'http://localhost:3001'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_AUTH_URL : ''; } - // Server-side (SSR): use Docker internal URL for container-to-container communication - return process.env.PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001'; + return process.env.PUBLIC_MANA_CORE_AUTH_URL || DEV_AUTH_URL; } // Get backend URL dynamically at runtime @@ -25,9 +26,10 @@ function getBackendUrl(): string { if (browser && typeof window !== 'undefined') { const injectedUrl = (window as unknown as { __PUBLIC_BACKEND_URL__?: string }) .__PUBLIC_BACKEND_URL__; - return injectedUrl || 'http://localhost:3007'; + if (injectedUrl) return injectedUrl; + return import.meta.env.DEV ? DEV_BACKEND_URL : ''; } - return process.env.PUBLIC_BACKEND_URL || 'http://localhost:3007'; + return process.env.PUBLIC_BACKEND_URL || DEV_BACKEND_URL; } // Lazy initialization to avoid SSR issues with localStorage @@ -205,7 +207,8 @@ export const authStore = { } try { - const result = await authService.forgotPassword(email); + const redirectTo = browser ? window.location.origin : undefined; + const result = await authService.forgotPassword(email, redirectTo); if (!result.success) { return { success: false, error: result.error || 'Password reset failed' };