import { cookies } from 'next/headers'; import { randomUUID } from 'crypto'; import type { AuthService, AuthSession, AuthUser } from './AuthService'; import { createStaticRacingSeed } from '@gridpilot/testing-support'; const SESSION_COOKIE = 'gp_demo_session'; const STATE_COOKIE = 'gp_demo_auth_state'; function parseCookieValue(raw: string | undefined): AuthSession | null { if (!raw) return null; try { const parsed = JSON.parse(raw) as AuthSession; if (!parsed.expiresAt || Date.now() > parsed.expiresAt) { return null; } return parsed; } catch { return null; } } function serializeSession(session: AuthSession): string { return JSON.stringify(session); } export class InMemoryAuthService implements AuthService { private readonly seedDriverId: string; constructor() { const seed = createStaticRacingSeed(42); this.seedDriverId = seed.drivers[0]?.id ?? 'driver-1'; } async getCurrentSession(): Promise { const store = await cookies(); const raw = store.get(SESSION_COOKIE)?.value; return parseCookieValue(raw); } async startIracingAuthRedirect( returnTo?: string, ): Promise<{ redirectUrl: string; state: string }> { const state = randomUUID(); const params = new URLSearchParams(); params.set('code', 'dummy-code'); params.set('state', state); if (returnTo) { params.set('returnTo', returnTo); } return { redirectUrl: `/auth/iracing/callback?${params.toString()}`, state, }; } async loginWithIracingCallback(params: { code: string; state: string; returnTo?: string; }): Promise { if (!params.code) { throw new Error('Missing auth code'); } if (!params.state) { throw new Error('Missing auth state'); } const user: AuthUser = { id: 'demo-user', displayName: 'GridPilot Demo Driver', iracingCustomerId: '000000', primaryDriverId: this.seedDriverId, avatarUrl: `/api/avatar/${this.seedDriverId}`, }; const now = Date.now(); const expiresAt = now + 24 * 60 * 60 * 1000; const session: AuthSession = { user, issuedAt: now, expiresAt, token: randomUUID(), }; return session; } async logout(): Promise { // Intentionally does nothing; cookie deletion is handled by route handlers. return; } }