79 lines
2.1 KiB
TypeScript

import { createSession, setSessionTokenCookie } from "$lib/server/auth";
import { authentik } from "$lib/server/oauth";
import { decodeIdToken } from "arctic";
import type { RequestEvent } from "@sveltejs/kit";
import type { OAuth2Tokens } from "arctic";
import { db } from '$lib/server/db';
import { eq } from 'drizzle-orm';
import * as table from '$lib/server/db/schema';
export async function GET(event: RequestEvent): Promise<Response> {
const code = event.url.searchParams.get("code");
const state = event.url.searchParams.get("state");
const storedState = event.cookies.get("authentik_oauth_state") ?? null;
const codeVerifier = event.cookies.get("authentik_code_verifier") ?? null;
if (code === null || state === null || storedState === null || codeVerifier === null) {
return new Response(null, {
status: 400
});
}
if (state !== storedState) {
return new Response(null, {
status: 400
});
}
let tokens: OAuth2Tokens;
try {
tokens = await authentik.validateAuthorizationCode(code, codeVerifier);
} catch (e) {
// Invalid code or client credentials
return new Response(null, {
status: 400
});
}
const claims = decodeIdToken(tokens.idToken()) as { sub: string, preferred_username: string, name: string };
console.info("claims", claims);
const userId: string = claims.sub;
const username: string = claims.preferred_username;
const existingUser = await db.query.users.findFirst({where: eq(table.users.id, userId)});
if (existingUser) {
const session = await createSession(existingUser.id);
setSessionTokenCookie(event, session.id, session.expiresAt);
return new Response(null, {
status: 302,
headers: {
Location: "/"
}
});
}
const user: table.User = {
id: userId,
username,
name: claims.name as string,
};
try {
await db.insert(table.users).values(user);
const session = await createSession(user.id);
setSessionTokenCookie(event, session.id, session.expiresAt);
} catch (e) {
console.error('failed to create user', e);
return new Response(null, {
status: 500
});
}
return new Response(null, {
status: 302,
headers: {
Location: "/"
}
});
}