55 lines
1.8 KiB
TypeScript
55 lines
1.8 KiB
TypeScript
import { error, redirect } from "@sveltejs/kit";
|
|
import { discord, type DiscordUser } from "$lib/auth/discord";
|
|
import { OAuth2RequestError, type OAuth2Tokens } from "arctic";
|
|
import { createSession, generateSessionToken } from "$lib/auth/session";
|
|
import { setSessionTokenCookie } from "$lib/auth/cookie";
|
|
import { destr } from "destr";
|
|
import type { RequestHandler } from "./$types";
|
|
import type { CookieData } from "$lib/auth";
|
|
|
|
export const GET: RequestHandler = async ({ platform, url, cookies, fetch }) => {
|
|
const db = platform?.env?.TCL_GUESSR_D1 ?? null;
|
|
if (db === null) error(500, "could not access D1");
|
|
|
|
const code = url.searchParams.get("code");
|
|
const state = url.searchParams.get("state");
|
|
const cookie = destr<CookieData>(cookies.get("discord_oauth_state")) ?? null;
|
|
|
|
if (code === null || state === null || cookie === null) {
|
|
error(400, "missing things from oauth2 response");
|
|
}
|
|
|
|
if (state !== cookie.state) {
|
|
error(400, "state does not match");
|
|
}
|
|
|
|
let tokens: OAuth2Tokens;
|
|
try {
|
|
tokens = await discord.validateAuthorizationCode(code);
|
|
} catch (e) {
|
|
if (e instanceof OAuth2RequestError) {
|
|
error(400, e.message);
|
|
} else {
|
|
error(400, "could not validate auth code");
|
|
}
|
|
}
|
|
|
|
const discordUser: DiscordUser = await fetch("https://discord.com/api/v10/users/@me", {
|
|
headers: {
|
|
Authorization: `Bearer ${tokens.accessToken()}`,
|
|
},
|
|
}).then((r) => r.json());
|
|
|
|
await db
|
|
.prepare(
|
|
"INSERT INTO user(id, name, avatar_hash) VALUES (?, ?, ?) ON CONFLICT(id) DO UPDATE SET name=excluded.name, avatar_hash=excluded.avatar_hash;",
|
|
)
|
|
.bind(discordUser.id, discordUser.username, discordUser.avatar)
|
|
.run();
|
|
|
|
const sessionToken = generateSessionToken();
|
|
const session = await createSession(sessionToken, discordUser.id, db);
|
|
setSessionTokenCookie(cookies, sessionToken, session.expiresAt);
|
|
|
|
redirect(302, cookie.next);
|
|
};
|