diff --git a/src/pages/api/auth/login.ts b/src/pages/api/auth/login.ts index dde23f2..15e8b6b 100644 --- a/src/pages/api/auth/login.ts +++ b/src/pages/api/auth/login.ts @@ -1,5 +1,7 @@ +// src/pages/api/auth/login.ts (ENHANCED - Consistent cookie handling) import type { APIRoute } from 'astro'; import { generateAuthUrl, generateState, logAuthEvent } from '../../../utils/auth.js'; +import { serialize } from 'cookie'; export const prerender = false; @@ -8,14 +10,28 @@ export const GET: APIRoute = async ({ url, redirect }) => { const state = generateState(); const authUrl = generateAuthUrl(state); - console.log('Generated auth URL:', authUrl); + console.log('[AUTH] Generated auth URL:', authUrl); const returnTo = url.searchParams.get('returnTo') || '/'; logAuthEvent('Login initiated', { returnTo, authUrl }); const stateData = JSON.stringify({ state, returnTo }); - const stateCookie = `auth_state=${encodeURIComponent(stateData)}; HttpOnly; SameSite=Lax; Path=/; Max-Age=600`; + + // Use consistent cookie serialization (same as session cookies) + const publicBaseUrl = process.env.PUBLIC_BASE_URL || ''; + const isProduction = process.env.NODE_ENV === 'production'; + const isSecure = publicBaseUrl.startsWith('https://') || isProduction; + + const stateCookie = serialize('auth_state', stateData, { + httpOnly: true, + secure: isSecure, + sameSite: 'lax', + maxAge: 600, // 10 minutes + path: '/' + }); + + console.log('[AUTH] Setting auth state cookie:', stateCookie.substring(0, 50) + '...'); return new Response(null, { status: 302, diff --git a/src/pages/api/auth/process.ts b/src/pages/api/auth/process.ts index e7abed9..694fe62 100644 --- a/src/pages/api/auth/process.ts +++ b/src/pages/api/auth/process.ts @@ -1,4 +1,4 @@ -// src/pages/api/auth/process.ts (FIXED - Proper cookie handling) +// src/pages/api/auth/process.ts (ENHANCED - Proper auth success indication) import type { APIRoute } from 'astro'; import { verifyAuthState, @@ -7,7 +7,7 @@ import { createSessionWithCookie, logAuthEvent } from '../../../utils/auth.js'; -import { apiError, apiSpecial, apiWithHeaders, handleAPIRequest } from '../../../utils/api.js'; +import { apiError, apiSpecial, handleAPIRequest } from '../../../utils/api.js'; export const prerender = false; @@ -30,9 +30,15 @@ export const POST: APIRoute = async ({ request }) => { const stateVerification = verifyAuthState(request, state); if (!stateVerification.isValid || !stateVerification.stateData) { + logAuthEvent('State verification failed', { + error: stateVerification.error, + hasStateData: !!stateVerification.stateData + }); return apiError.badRequest(stateVerification.error || 'Invalid state parameter'); } + console.log('[AUTH] State verification successful, exchanging code for tokens'); + const tokens = await exchangeCodeForTokens(code); const userInfo = await getUserInfo(tokens.access_token); @@ -43,6 +49,13 @@ export const POST: APIRoute = async ({ request }) => { email: sessionResult.userEmail }); + // Add auth success indicator to the return URL + const returnUrl = new URL(stateVerification.stateData.returnTo, request.url); + returnUrl.searchParams.set('auth', 'success'); + const redirectUrl = returnUrl.toString(); + + console.log('[AUTH] Redirecting to:', redirectUrl); + const responseHeaders = new Headers(); responseHeaders.set('Content-Type', 'application/json'); @@ -51,7 +64,7 @@ export const POST: APIRoute = async ({ request }) => { return new Response(JSON.stringify({ success: true, - redirectTo: stateVerification.stateData.returnTo + redirectTo: redirectUrl }), { status: 200, headers: responseHeaders diff --git a/src/pages/knowledgebase/[slug].astro b/src/pages/knowledgebase/[slug].astro index 0002d39..7bac0f0 100644 --- a/src/pages/knowledgebase/[slug].astro +++ b/src/pages/knowledgebase/[slug].astro @@ -62,24 +62,33 @@ const currentUrl = Astro.url.href; {requiresAuth && (