File size: 1,928 Bytes
566c2fc
d72b096
566c2fc
 
41e9886
a8a9533
9908345
 
 
 
 
 
a8a9533
566c2fc
45ec8d7
7475b24
566c2fc
 
7475b24
566c2fc
 
 
 
06feee8
566c2fc
 
0fcb8db
566c2fc
 
 
0fcb8db
566c2fc
 
 
 
 
d72b096
566c2fc
d72b096
06feee8
566c2fc
 
0fcb8db
 
 
 
 
566c2fc
9908345
 
 
06feee8
9908345
 
 
06feee8
9908345
 
06feee8
9908345
 
 
45ec8d7
 
 
 
 
 
 
566c2fc
06feee8
566c2fc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import { redirect, error } from "@sveltejs/kit";
import { getOIDCUserData, validateAndParseCsrfToken } from "$lib/server/auth";
import { z } from "zod";
import { base } from "$app/paths";
import { updateUser } from "./updateUser";
import { env } from "$env/dynamic/private";
import JSON5 from "json5";

const allowedUserEmails = z
	.array(z.string().email())
	.optional()
	.default([])
	.parse(JSON5.parse(env.ALLOWED_USER_EMAILS));

export async function load({ url, locals, cookies, request, getClientAddress }) {
	const { error: errorName, error_description: errorDescription } = z
		.object({
			error: z.string().optional(),
			error_description: z.string().optional(),
		})
		.parse(Object.fromEntries(url.searchParams.entries()));

	if (errorName) {
		error(400, errorName + (errorDescription ? ": " + errorDescription : ""));
	}

	const { code, state, iss } = z
		.object({
			code: z.string(),
			state: z.string(),
			iss: z.string().optional(),
		})
		.parse(Object.fromEntries(url.searchParams.entries()));

	const csrfToken = Buffer.from(state, "base64").toString("utf-8");

	const validatedToken = await validateAndParseCsrfToken(csrfToken, locals.sessionId);

	if (!validatedToken) {
		error(403, "Invalid or expired CSRF token");
	}

	const { userData } = await getOIDCUserData(
		{ redirectURI: validatedToken.redirectUrl },
		code,
		iss
	);

	// Filter by allowed user emails
	if (allowedUserEmails.length > 0) {
		if (!userData.email) {
			error(403, "User not allowed: email not returned");
		}
		const emailVerified = userData.email_verified ?? true;
		if (!emailVerified) {
			error(403, "User not allowed: email not verified");
		}
		if (!allowedUserEmails.includes(userData.email)) {
			error(403, "User not allowed");
		}
	}

	await updateUser({
		userData,
		locals,
		cookies,
		userAgent: request.headers.get("user-agent") ?? undefined,
		ip: getClientAddress(),
	});

	redirect(302, `${base}/`);
}