nsarrazin commited on
Commit
6a1be24
·
unverified ·
1 Parent(s): 98ff794

fix(featureflags): rewrite feature flag system

Browse files

getting orgs from userdata on login wasn't working in prod, so ended up doing it the other way. fetch the user list first and compare the user id on login

chart/env/prod.yaml CHANGED
@@ -328,8 +328,8 @@ envVars:
328
  }]
329
  WEBSEARCH_BLOCKLIST: '["youtube.com", "twitter.com"]'
330
  XFF_DEPTH: '2'
331
- HF_ORG_ADMIN: '644171cfbd0c97265298aa99'
332
- HF_ORG_EARLY_ACCESS: '5e67bd5b1009063689407478'
333
 
334
  infisical:
335
  enabled: true
 
328
  }]
329
  WEBSEARCH_BLOCKLIST: '["youtube.com", "twitter.com"]'
330
  XFF_DEPTH: '2'
331
+ HF_ORG_ADMIN: 'huggingchat'
332
+ HF_ORG_EARLY_ACCESS: 'huggingface'
333
 
334
  infisical:
335
  enabled: true
src/routes/login/callback/+page.server.ts CHANGED
@@ -5,7 +5,6 @@ import { base } from "$app/paths";
5
  import { updateUser } from "./updateUser";
6
  import { env } from "$env/dynamic/private";
7
  import JSON5 from "json5";
8
- import { logger } from "$lib/server/logger";
9
 
10
  const allowedUserEmails = z
11
  .array(z.string().email())
@@ -61,8 +60,6 @@ export async function load({ url, locals, cookies, request, getClientAddress })
61
  }
62
  }
63
 
64
- logger.info("updating user");
65
-
66
  await updateUser({
67
  userData,
68
  locals,
 
5
  import { updateUser } from "./updateUser";
6
  import { env } from "$env/dynamic/private";
7
  import JSON5 from "json5";
 
8
 
9
  const allowedUserEmails = z
10
  .array(z.string().email())
 
60
  }
61
  }
62
 
 
 
63
  await updateUser({
64
  userData,
65
  locals,
src/routes/login/callback/updateUser.ts CHANGED
@@ -12,6 +12,26 @@ import { OIDConfig } from "$lib/server/auth";
12
  import { HF_ORG_ADMIN, HF_ORG_EARLY_ACCESS } from "$env/static/private";
13
  import { logger } from "$lib/server/logger";
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  export async function updateUser(params: {
16
  userData: UserinfoResponse;
17
  locals: App.Locals;
@@ -33,7 +53,6 @@ export async function updateUser(params: {
33
  email,
34
  picture: avatarUrl,
35
  sub: hfUserId,
36
- orgs,
37
  } = z
38
  .object({
39
  preferred_username: z.string().optional(),
@@ -79,19 +98,17 @@ export async function updateUser(params: {
79
  // Dynamically access user data based on NAME_CLAIM from environment
80
  // This approach allows us to adapt to different OIDC providers flexibly.
81
 
82
- logger.info(
83
- {
84
- login_username: username,
85
- login_name: name,
86
- login_email: email,
87
- login_orgs: orgs?.map((el) => el.sub),
88
- },
89
- "user login"
90
- );
91
- // if using huggingface as auth provider, check orgs for earl access and amin rights
92
- const isAdmin = (HF_ORG_ADMIN && orgs?.some((org) => org.sub === HF_ORG_ADMIN)) || false;
93
- const isEarlyAccess =
94
- (HF_ORG_EARLY_ACCESS && orgs?.some((org) => org.sub === HF_ORG_EARLY_ACCESS)) || false;
95
 
96
  // check if user already exists
97
  const existingUser = await collections.users.findOne({ hfUserId });
@@ -112,7 +129,8 @@ export async function updateUser(params: {
112
  // update existing user if any
113
  await collections.users.updateOne(
114
  { _id: existingUser._id },
115
- { $set: { username, name, avatarUrl, isAdmin, isEarlyAccess } }
 
116
  );
117
 
118
  // remove previous session if it exists and add new one
@@ -129,18 +147,21 @@ export async function updateUser(params: {
129
  });
130
  } else {
131
  // user doesn't exist yet, create a new one
132
- const { insertedId } = await collections.users.insertOne({
133
- _id: new ObjectId(),
134
- createdAt: new Date(),
135
- updatedAt: new Date(),
136
- username,
137
- name,
138
- email,
139
- avatarUrl,
140
- hfUserId,
141
- isAdmin,
142
- isEarlyAccess,
143
- });
 
 
 
144
 
145
  userId = insertedId;
146
 
 
12
  import { HF_ORG_ADMIN, HF_ORG_EARLY_ACCESS } from "$env/static/private";
13
  import { logger } from "$lib/server/logger";
14
 
15
+ const earlyAccessIds = HF_ORG_EARLY_ACCESS
16
+ ? await fetch(`https://huggingface.co/api/organizations/${HF_ORG_EARLY_ACCESS}/members`)
17
+ .then((res) => res.json())
18
+ .then((res: Array<{ _id: string }>) => res.map((user: { _id: string }) => user._id))
19
+ .catch((err) => {
20
+ logger.error(err, "Failed to fetch early access members");
21
+ return null;
22
+ })
23
+ : null;
24
+
25
+ const adminIds = HF_ORG_ADMIN
26
+ ? await fetch(`https://huggingface.co/api/organizations/${HF_ORG_ADMIN}/members`)
27
+ .then((res) => res.json())
28
+ .then((res: Array<{ _id: string }>) => res.map((user) => user._id))
29
+ .catch((err) => {
30
+ logger.error(err, "Failed to fetch admin members");
31
+ return null;
32
+ })
33
+ : null;
34
+
35
  export async function updateUser(params: {
36
  userData: UserinfoResponse;
37
  locals: App.Locals;
 
53
  email,
54
  picture: avatarUrl,
55
  sub: hfUserId,
 
56
  } = z
57
  .object({
58
  preferred_username: z.string().optional(),
 
98
  // Dynamically access user data based on NAME_CLAIM from environment
99
  // This approach allows us to adapt to different OIDC providers flexibly.
100
 
101
+ let isAdmin = undefined;
102
+ let isEarlyAccess = undefined;
103
+
104
+ if (hfUserId) {
105
+ if (adminIds !== null) {
106
+ isAdmin = adminIds.includes(hfUserId);
107
+ }
108
+ if (earlyAccessIds !== null) {
109
+ isEarlyAccess = earlyAccessIds.includes(hfUserId);
110
+ }
111
+ }
 
 
112
 
113
  // check if user already exists
114
  const existingUser = await collections.users.findOne({ hfUserId });
 
129
  // update existing user if any
130
  await collections.users.updateOne(
131
  { _id: existingUser._id },
132
+ { $set: { username, name, avatarUrl, isAdmin, isEarlyAccess } },
133
+ { ignoreUndefined: true }
134
  );
135
 
136
  // remove previous session if it exists and add new one
 
147
  });
148
  } else {
149
  // user doesn't exist yet, create a new one
150
+ const { insertedId } = await collections.users.insertOne(
151
+ {
152
+ _id: new ObjectId(),
153
+ createdAt: new Date(),
154
+ updatedAt: new Date(),
155
+ username,
156
+ name,
157
+ email,
158
+ avatarUrl,
159
+ hfUserId,
160
+ isAdmin,
161
+ isEarlyAccess,
162
+ },
163
+ { ignoreUndefined: true }
164
+ );
165
 
166
  userId = insertedId;
167