From ead1e006dce8f11c7e02ea2f4b6ed23a8a7f1935 Mon Sep 17 00:00:00 2001 From: Usman Baig Date: Mon, 9 Feb 2026 09:38:44 +0100 Subject: [PATCH] fix: validate returnTo parameter in auth callback and update default organization name in welcome page --- app/auth/callback/page.tsx | 5 +++-- app/welcome/page.tsx | 4 ++-- lib/auth/context.tsx | 15 +++++++++------ 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/app/auth/callback/page.tsx b/app/auth/callback/page.tsx index e364b31..21be4cb 100644 --- a/app/auth/callback/page.tsx +++ b/app/auth/callback/page.tsx @@ -69,8 +69,9 @@ function AuthCallbackContent() { if (typeof window !== 'undefined' && localStorage.getItem('pulse_pending_checkout')) { router.push('/welcome') } else { - const returnTo = searchParams.get('returnTo') || '/' - router.push(returnTo) + const raw = searchParams.get('returnTo') || '/' + const safe = (typeof raw === 'string' && raw.startsWith('/') && !raw.startsWith('//')) ? raw : '/' + router.push(safe) } } else { setError(authMessageFromErrorType('invalid')) diff --git a/app/welcome/page.tsx b/app/welcome/page.tsx index 6112548..67f3fbd 100644 --- a/app/welcome/page.tsx +++ b/app/welcome/page.tsx @@ -47,12 +47,12 @@ import Link from 'next/link' import ScriptSetupBlock from '@/components/sites/ScriptSetupBlock' const TOTAL_STEPS = 5 -const DEFAULT_ORG_NAME = 'My workspace' +const DEFAULT_ORG_NAME = 'My organization' const SITE_DRAFT_KEY = 'pulse_welcome_site_draft' const WELCOME_COMPLETED_KEY = 'pulse_welcome_completed' function slugFromName(name: string): string { - return name.toLowerCase().replace(/[^a-z0-9]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '') || 'my-workspace' + return name.toLowerCase().replace(/[^a-z0-9]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '') || 'my-organization' } function suggestSlugVariant(slug: string): string { diff --git a/lib/auth/context.tsx b/lib/auth/context.tsx index 0a8245f..61e2b45 100644 --- a/lib/auth/context.tsx +++ b/lib/auth/context.tsx @@ -167,12 +167,15 @@ export function AuthProvider({ children }: { children: React.ReactNode }) { // * Update session cookie const result = await setSessionAction(access_token) if (result.success && result.user) { - setUser(result.user) - localStorage.setItem('user', JSON.stringify(result.user)) - - // * Force hard reload to ensure browser sends new cookie to backend - // * router.refresh() is not enough for Client Components fetching data immediately - // window.location.reload() + try { + const fullProfile = await apiRequest<{ id: string; email: string; display_name?: string; totp_enabled: boolean; org_id?: string; role?: string }>('/auth/user/me') + const merged = { ...fullProfile, org_id: result.user.org_id ?? fullProfile.org_id, role: result.user.role ?? fullProfile.role } + setUser(merged) + localStorage.setItem('user', JSON.stringify(merged)) + } catch { + setUser(result.user) + localStorage.setItem('user', JSON.stringify(result.user)) + } router.refresh() } } catch (e) {