Spaces:
Running
Running
Add support for allowing users based on their domain (#1651)
Browse filese.g.
ALLOWED_USER_DOMAINS=`["example.com"]`
will allow both [email protected] and [email protected]
A user can log in if one of the conditions is true:
- ALLOWED_USER_DOMAINS and ALLOWED_USER_EMAILS are empty
- their email is in ALLOWED_USER_EMAILS
- their email domain ALLOWED_USER_DOMAINS
Co-authored-by: Nathan Sarrazin <[email protected]>
- .env +2 -0
- src/routes/login/callback/+page.server.ts +14 -3
.env
CHANGED
@@ -71,6 +71,8 @@ OPENID_CONFIG=
|
|
71 |
MESSAGES_BEFORE_LOGIN=# how many messages a user can send in a conversation before having to login. set to 0 to force login right away
|
72 |
# if it's defined, only these emails will be allowed to use login
|
73 |
ALLOWED_USER_EMAILS=`[]`
|
|
|
|
|
74 |
# valid alternative redirect URLs for OAuth, used for HuggingChat apps
|
75 |
ALTERNATIVE_REDIRECT_URLS=`[]`
|
76 |
### Cookies
|
|
|
71 |
MESSAGES_BEFORE_LOGIN=# how many messages a user can send in a conversation before having to login. set to 0 to force login right away
|
72 |
# if it's defined, only these emails will be allowed to use login
|
73 |
ALLOWED_USER_EMAILS=`[]`
|
74 |
+
# If it's defined, users with emails matching these domains will also be allowed to use login
|
75 |
+
ALLOWED_USER_DOMAINS=`[]`
|
76 |
# valid alternative redirect URLs for OAuth, used for HuggingChat apps
|
77 |
ALTERNATIVE_REDIRECT_URLS=`[]`
|
78 |
### Cookies
|
src/routes/login/callback/+page.server.ts
CHANGED
@@ -12,6 +12,12 @@ const allowedUserEmails = z
|
|
12 |
.default([])
|
13 |
.parse(JSON5.parse(env.ALLOWED_USER_EMAILS));
|
14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
export async function load({ url, locals, cookies, request, getClientAddress }) {
|
16 |
const { error: errorName, error_description: errorDescription } = z
|
17 |
.object({
|
@@ -46,8 +52,8 @@ export async function load({ url, locals, cookies, request, getClientAddress })
|
|
46 |
iss
|
47 |
);
|
48 |
|
49 |
-
// Filter by allowed user emails
|
50 |
-
if (allowedUserEmails.length > 0) {
|
51 |
if (!userData.email) {
|
52 |
error(403, "User not allowed: email not returned");
|
53 |
}
|
@@ -55,7 +61,12 @@ export async function load({ url, locals, cookies, request, getClientAddress })
|
|
55 |
if (!emailVerified) {
|
56 |
error(403, "User not allowed: email not verified");
|
57 |
}
|
58 |
-
|
|
|
|
|
|
|
|
|
|
|
59 |
error(403, "User not allowed");
|
60 |
}
|
61 |
}
|
|
|
12 |
.default([])
|
13 |
.parse(JSON5.parse(env.ALLOWED_USER_EMAILS));
|
14 |
|
15 |
+
const allowedUserDomains = z
|
16 |
+
.array(z.string().regex(/\.\w+$/)) // Contains at least a dot
|
17 |
+
.optional()
|
18 |
+
.default([])
|
19 |
+
.parse(JSON5.parse(env.ALLOWED_USER_DOMAINS));
|
20 |
+
|
21 |
export async function load({ url, locals, cookies, request, getClientAddress }) {
|
22 |
const { error: errorName, error_description: errorDescription } = z
|
23 |
.object({
|
|
|
52 |
iss
|
53 |
);
|
54 |
|
55 |
+
// Filter by allowed user emails or domains
|
56 |
+
if (allowedUserEmails.length > 0 || allowedUserDomains.length > 0) {
|
57 |
if (!userData.email) {
|
58 |
error(403, "User not allowed: email not returned");
|
59 |
}
|
|
|
61 |
if (!emailVerified) {
|
62 |
error(403, "User not allowed: email not verified");
|
63 |
}
|
64 |
+
|
65 |
+
const emailDomain = userData.email.split("@")[1];
|
66 |
+
const isEmailAllowed = allowedUserEmails.includes(userData.email);
|
67 |
+
const isDomainAllowed = allowedUserDomains.includes(emailDomain);
|
68 |
+
|
69 |
+
if (!isEmailAllowed && !isDomainAllowed) {
|
70 |
error(403, "User not allowed");
|
71 |
}
|
72 |
}
|