From 7b7114b141c1e0af9ed6f2993cbd8deac19a4b33 Mon Sep 17 00:00:00 2001 From: Nicolas Martinez Date: Wed, 14 Feb 2024 06:23:28 -0500 Subject: [PATCH] Simple Email Authorization (#801) * Add ALLOWED_USER_EMAILS validation in login callback * Update src/routes/login/callback/+page.server.ts Adding email validation Co-authored-by: Nathan Sarrazin * Update src/routes/login/callback/+page.server.ts More detailed error when missing email Co-authored-by: Nathan Sarrazin --------- Co-authored-by: Nathan Sarrazin --- .env | 4 +++- src/routes/login/callback/+page.server.ts | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/.env b/.env index 76d11b73dc7..609e21b05ea 100644 --- a/.env +++ b/.env @@ -136,4 +136,6 @@ ENABLE_ASSISTANTS=false #set to true to enable assistants feature ALTERNATIVE_REDIRECT_URLS=`[]` #valide alternative redirect URL for OAuth -WEBHOOK_URL_REPORT_ASSISTANT=#provide webhook url to get notified when an assistant gets reported \ No newline at end of file +WEBHOOK_URL_REPORT_ASSISTANT=#provide webhook url to get notified when an assistant gets reported + +ALLOWED_USER_EMAILS=`[]` # if it's defined, only these emails will be allowed to use the app \ No newline at end of file diff --git a/src/routes/login/callback/+page.server.ts b/src/routes/login/callback/+page.server.ts index 01411fff6ea..020c077c253 100644 --- a/src/routes/login/callback/+page.server.ts +++ b/src/routes/login/callback/+page.server.ts @@ -3,6 +3,14 @@ import { getOIDCUserData, validateAndParseCsrfToken } from "$lib/server/auth"; import { z } from "zod"; import { base } from "$app/paths"; import { updateUser } from "./updateUser"; +import { ALLOWED_USER_EMAILS } from "$env/static/private"; +import JSON5 from "json5"; + +const allowedUserEmails = z + .array(z.string().email()) + .optional() + .default([]) + .parse(JSON5.parse(ALLOWED_USER_EMAILS)); export async function load({ url, locals, cookies, request, getClientAddress }) { const { error: errorName, error_description: errorDescription } = z @@ -33,6 +41,20 @@ export async function load({ url, locals, cookies, request, getClientAddress }) const { userData } = await getOIDCUserData({ redirectURI: validatedToken.redirectUrl }, code); + // Filter by allowed user emails + if (allowedUserEmails.length > 0) { + if (!userData.email) { + throw error(403, "User not allowed: email not returned"); + } + const emailVerified = userData.email_verified ?? true; + if (!emailVerified) { + throw error(403, "User not allowed: email not verified"); + } + if (!allowedUserEmails.includes(userData.email)) { + throw error(403, "User not allowed"); + } + } + await updateUser({ userData, locals,