import type { RequestHandler } from '@sveltejs/kit'; import { consumeAndValidateState, exchangeCodeForTokens, clearTokens, consumeRedirectCookie } from '$lib/server/beatleaderAuth'; import { upsertSession } from '../../../../lib/server/sessionStore'; export const GET: RequestHandler = async ({ url, cookies, fetch }) => { const code = url.searchParams.get('code'); const state = url.searchParams.get('state'); if (!code) { return new Response('Missing code', { status: 400 }); } if (!consumeAndValidateState(cookies, state)) { return new Response('Invalid state', { status: 400 }); } const tokenData = await exchangeCodeForTokens(url.origin, code); if (!tokenData || !tokenData.access_token) { clearTokens(cookies); return new Response('Token exchange failed', { status: 400 }); } try { const identityRes = await fetch('https://api.beatleader.com/oauth2/identity', { headers: { Authorization: `Bearer ${tokenData.access_token}` } }); if (!identityRes.ok) { clearTokens(cookies); return new Response('Failed to retrieve identity', { status: 502 }); } const identity = (await identityRes.json()) as { id?: string; name?: string }; if (!identity?.id) { clearTokens(cookies); return new Response('BeatLeader identity missing id', { status: 502 }); } let avatar: string | undefined; try { const profileRes = await fetch(`https://api.beatleader.com/player/${identity.id}`); if (profileRes.ok) { const profileJson = (await profileRes.json()) as { avatar?: string }; if (typeof profileJson.avatar === 'string') { avatar = profileJson.avatar; } } } catch (err) { console.error('Failed to prefetch BeatLeader avatar', err); } upsertSession(cookies, { beatleaderId: identity.id, name: identity.name ?? null, avatar: avatar ?? null }); clearTokens(cookies); } catch (err) { console.error('BeatLeader OAuth callback failed', err); clearTokens(cookies); return new Response('Internal error establishing session', { status: 500 }); } const redirectTo = consumeRedirectCookie(cookies) ?? url.searchParams.get('redirect_uri') ?? '/'; return new Response(null, { status: 302, headers: { Location: redirectTo } }); };