69 lines
2.3 KiB
TypeScript
69 lines
2.3 KiB
TypeScript
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 } });
|
|
};
|
|
|
|
|