aboutsummaryrefslogtreecommitdiff
path: root/apps/web/app/api/ensureAuth.ts
blob: 92a5e3e8492d2e291d04fee53b4ac9acc76b45fc (plain) (blame)
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
97
98
99
100
101
102
103
104
105
import { NextRequest } from "next/server";
import { db } from "../../server/db";
import { accounts, sessions, users } from "@repo/db/schema";
import { eq } from "drizzle-orm";

export async function ensureAuth(req: NextRequest) {
	// A helper function to protect routes

	const token =
		req.cookies.get("next-auth.session-token")?.value ??
		req.cookies.get("__Secure-authjs.session-token")?.value ??
		req.cookies.get("authjs.session-token")?.value ??
		req.headers.get("Authorization")?.replace("Bearer ", "");

	if (!token) {
		return undefined;
	}

	let sessionData = await db
		.select()
		.from(sessions)
		.innerJoin(users, eq(users.id, sessions.userId))
		.where(eq(sessions.sessionToken, token!));

	const isMobile =
		token.split("?") && token.split("?")[1] === `source="mobile"`;

	if (isMobile) {
		// remove everything after ? in token
		const newToken = token.split("?").slice(0, -1).join("?");

		console.log(token, newToken);

		const authUserFetch = await fetch(
			`https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=${newToken}`,
		);

		if (!authUserFetch.ok) {
			console.error(
				"Error fetching Google user,",
				authUserFetch.statusText,
				await authUserFetch.text(),
			);
			console.log("Google user not found or error.");
			return undefined;
		}

		const authUserData = (await authUserFetch.json()) as {
			email: string;
			audience: string;
			issued_to: string;
		};

		console.log(authUserData);

		if (
			!(
				authUserData.audience.split("-")[0] ===
					process.env.GOOGLE_CLIENT_ID.split("-")[0] &&
				authUserData.issued_to.split("-")[0] ===
					process.env.GOOGLE_CLIENT_ID.split("-")[0]
			)
		) {
			console.log(
				"Google user not authorized because of audience or issued_to mismatch",
			);
			return undefined;
		}

		const authUserEmail = authUserData.email;

		let user = await db
			.select()
			.from(users)
			.where(eq(users.email, authUserEmail))
			.limit(1);

		if (!user || user.length === 0) {
			// create the user
			user = await db
				.insert(users)
				.values({
					email: authUserEmail,
					name: authUserEmail.split("@")[0],
				})
				.returning();
		}

		sessionData = [
			{
				...sessionData[0]!,
				user: user[0]!,
			},
		];
	}

	if (!sessionData || sessionData.length === 0) {
		return undefined;
	}

	return {
		user: sessionData[0]!.user,
		session: sessionData[0]!,
	};
}