File size: 2,699 Bytes
eb6d216
5da61b4
 
b3563cb
 
 
 
5da61b4
b9f029b
 
2e28042
067b52a
 
41b9769
067b52a
 
 
2e28042
 
 
 
 
 
3da7ec7
2e28042
 
3da7ec7
2e28042
 
 
b9f029b
2e28042
b9f029b
 
2e28042
 
b9f029b
2e28042
b9f029b
 
 
 
 
 
2e28042
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b9f029b
 
3ddb8c6
41b9769
5da61b4
fff76f9
e518a94
eb6d216
3ddb8c6
5da61b4
3ddb8c6
067b52a
184689c
 
 
 
 
b3563cb
184689c
 
 
 
b3563cb
 
 
184689c
 
067b52a
 
 
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import { dev } from "$app/environment";
import { COOKIE_NAME } from "$env/static/private";
import type { Handle } from "@sveltejs/kit";
import {
	PUBLIC_GOOGLE_ANALYTICS_ID,
	PUBLIC_DEPRECATED_GOOGLE_ANALYTICS_ID,
} from "$env/static/public";
import { addYears } from "date-fns";
import { collections } from "$lib/server/database";
import { base } from "$app/paths";
import { requiresUser } from "$lib/server/auth";

export const handle: Handle = async ({ event, resolve }) => {
	const token = event.cookies.get(COOKIE_NAME);

	event.locals.sessionId = token || crypto.randomUUID();

	const user = await collections.users.findOne({ sessionId: event.locals.sessionId });

	if (user) {
		event.locals.userId = user._id;
	}

	if (
		!event.url.pathname.startsWith(`${base}/admin`) &&
		!["GET", "OPTIONS", "HEAD"].includes(event.request.method)
	) {
		const sendJson =
			event.request.headers.get("accept")?.includes("application/json") ||
			event.request.headers.get("content-type")?.includes("application/json");

		if (!user && requiresUser) {
			return new Response(
				sendJson
					? JSON.stringify({ error: "You need to be logged in first" })
					: "You need to be logged in first",
				{
					status: 401,
					headers: {
						"content-type": sendJson ? "application/json" : "text/plain",
					},
				}
			);
		}

		if (!event.url.pathname.startsWith(`${base}/settings`)) {
			const hasAcceptedEthicsModal = await collections.settings.countDocuments({
				sessionId: event.locals.sessionId,
				ethicsModalAcceptedAt: { $exists: true },
			});

			if (!hasAcceptedEthicsModal) {
				return new Response(
					sendJson
						? JSON.stringify({ error: "You need to accept the welcome modal first" })
						: "You need to accept the welcome modal first",
					{
						status: 405,
						headers: {
							"content-type": sendJson ? "application/json" : "text/plain",
						},
					}
				);
			}
		}
	}

	// Refresh cookie expiration date
	event.cookies.set(COOKIE_NAME, event.locals.sessionId, {
		path: "/",
		// So that it works inside the space's iframe
		sameSite: dev ? "lax" : "none",
		secure: !dev,
		httpOnly: true,
		expires: addYears(new Date(), 1),
	});

	let replaced = false;

	const response = await resolve(event, {
		transformPageChunk: (chunk) => {
			// For some reason, Sveltekit doesn't let us load env variables from .env in the app.html template
			if (replaced || !chunk.html.includes("%gaId%") || !chunk.html.includes("%gaIdDeprecated%")) {
				return chunk.html;
			}
			replaced = true;

			return chunk.html
				.replace("%gaId%", PUBLIC_GOOGLE_ANALYTICS_ID)
				.replace("%gaIdDeprecated%", PUBLIC_DEPRECATED_GOOGLE_ANALYTICS_ID);
		},
	});

	return response;
};