Spaces:
Running
Running
Simple Email Authorization (#801)
Browse files* Add ALLOWED_USER_EMAILS validation in login callback
* Update src/routes/login/callback/+page.server.ts
Adding email validation
Co-authored-by: Nathan Sarrazin <[email protected]>
* Update src/routes/login/callback/+page.server.ts
More detailed error when missing email
Co-authored-by: Nathan Sarrazin <[email protected]>
---------
Co-authored-by: Nathan Sarrazin <[email protected]>
- .env +3 -1
- src/routes/login/callback/+page.server.ts +22 -0
.env
CHANGED
|
@@ -136,4 +136,6 @@ ENABLE_ASSISTANTS=false #set to true to enable assistants feature
|
|
| 136 |
|
| 137 |
ALTERNATIVE_REDIRECT_URLS=`[]` #valide alternative redirect URL for OAuth
|
| 138 |
|
| 139 |
-
WEBHOOK_URL_REPORT_ASSISTANT=#provide webhook url to get notified when an assistant gets reported
|
|
|
|
|
|
|
|
|
| 136 |
|
| 137 |
ALTERNATIVE_REDIRECT_URLS=`[]` #valide alternative redirect URL for OAuth
|
| 138 |
|
| 139 |
+
WEBHOOK_URL_REPORT_ASSISTANT=#provide webhook url to get notified when an assistant gets reported
|
| 140 |
+
|
| 141 |
+
ALLOWED_USER_EMAILS=`[]` # if it's defined, only these emails will be allowed to use the app
|
src/routes/login/callback/+page.server.ts
CHANGED
|
@@ -3,6 +3,14 @@ import { getOIDCUserData, validateAndParseCsrfToken } from "$lib/server/auth";
|
|
| 3 |
import { z } from "zod";
|
| 4 |
import { base } from "$app/paths";
|
| 5 |
import { updateUser } from "./updateUser";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
|
| 7 |
export async function load({ url, locals, cookies, request, getClientAddress }) {
|
| 8 |
const { error: errorName, error_description: errorDescription } = z
|
|
@@ -33,6 +41,20 @@ export async function load({ url, locals, cookies, request, getClientAddress })
|
|
| 33 |
|
| 34 |
const { userData } = await getOIDCUserData({ redirectURI: validatedToken.redirectUrl }, code);
|
| 35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
await updateUser({
|
| 37 |
userData,
|
| 38 |
locals,
|
|
|
|
| 3 |
import { z } from "zod";
|
| 4 |
import { base } from "$app/paths";
|
| 5 |
import { updateUser } from "./updateUser";
|
| 6 |
+
import { ALLOWED_USER_EMAILS } from "$env/static/private";
|
| 7 |
+
import JSON5 from "json5";
|
| 8 |
+
|
| 9 |
+
const allowedUserEmails = z
|
| 10 |
+
.array(z.string().email())
|
| 11 |
+
.optional()
|
| 12 |
+
.default([])
|
| 13 |
+
.parse(JSON5.parse(ALLOWED_USER_EMAILS));
|
| 14 |
|
| 15 |
export async function load({ url, locals, cookies, request, getClientAddress }) {
|
| 16 |
const { error: errorName, error_description: errorDescription } = z
|
|
|
|
| 41 |
|
| 42 |
const { userData } = await getOIDCUserData({ redirectURI: validatedToken.redirectUrl }, code);
|
| 43 |
|
| 44 |
+
// Filter by allowed user emails
|
| 45 |
+
if (allowedUserEmails.length > 0) {
|
| 46 |
+
if (!userData.email) {
|
| 47 |
+
throw error(403, "User not allowed: email not returned");
|
| 48 |
+
}
|
| 49 |
+
const emailVerified = userData.email_verified ?? true;
|
| 50 |
+
if (!emailVerified) {
|
| 51 |
+
throw error(403, "User not allowed: email not verified");
|
| 52 |
+
}
|
| 53 |
+
if (!allowedUserEmails.includes(userData.email)) {
|
| 54 |
+
throw error(403, "User not allowed");
|
| 55 |
+
}
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
await updateUser({
|
| 59 |
userData,
|
| 60 |
locals,
|