Skip to content

Commit

Permalink
Enhance Dynamic User Attribute Handling in OIDC Integration (#885)
Browse files Browse the repository at this point in the history
* Refactor `updateUser` to Support Dynamic `nameClaim` Configuration

* style: run Prettier to fix lint errors

* Validate NAME_CLAIM in OIDConfig schema

* Refactor userData parsing

---------

Co-authored-by: Nathan Sarrazin <[email protected]>
Co-authored-by: ‘XGungo’ <‘[email protected]’>
  • Loading branch information
3 people committed Mar 22, 2024
1 parent 8583cf1 commit c6129c3
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 3 deletions.
4 changes: 3 additions & 1 deletion .env
Expand Up @@ -29,13 +29,15 @@ OPENID_CONFIG=`{
"PROVIDER_URL": "",
"CLIENT_ID": "",
"CLIENT_SECRET": "",
"SCOPES": ""
"SCOPES": "",
"NAME_CLAIM": ""
}`

# /!\ legacy openid settings, prefer the config above
OPENID_CLIENT_ID=
OPENID_CLIENT_SECRET=
OPENID_SCOPES="openid profile" # Add "email" for some providers like Google that do not provide preferred_username
OPENID_NAME_CLAIM="name" # Change to "username" for some providers that do not provide name
OPENID_PROVIDER_URL=https://huggingface.co # for Google, use https://accounts.google.com
OPENID_TOLERANCE=
OPENID_RESOURCE=
Expand Down
7 changes: 6 additions & 1 deletion src/lib/server/auth.ts
Expand Up @@ -6,6 +6,7 @@ import {
OPENID_CLIENT_SECRET,
OPENID_PROVIDER_URL,
OPENID_SCOPES,
OPENID_NAME_CLAIM,
OPENID_TOLERANCE,
OPENID_RESOURCE,
OPENID_CONFIG,
Expand All @@ -32,12 +33,16 @@ const stringWithDefault = (value: string) =>
.default(value)
.transform((el) => (el ? el : value));

const OIDConfig = z
export const OIDConfig = z
.object({
CLIENT_ID: stringWithDefault(OPENID_CLIENT_ID),
CLIENT_SECRET: stringWithDefault(OPENID_CLIENT_SECRET),
PROVIDER_URL: stringWithDefault(OPENID_PROVIDER_URL),
SCOPES: stringWithDefault(OPENID_SCOPES),
NAME_CLAIM: stringWithDefault(OPENID_NAME_CLAIM).refine(
(el) => !["preferred_username", "email", "picture", "sub"].includes(el),
{ message: "nameClaim cannot be one of the restricted keys." }
),
TOLERANCE: stringWithDefault(OPENID_TOLERANCE),
RESOURCE: stringWithDefault(OPENID_RESOURCE),
})
Expand Down
17 changes: 16 additions & 1 deletion src/routes/login/callback/updateUser.ts
Expand Up @@ -8,6 +8,7 @@ import { error, type Cookies } from "@sveltejs/kit";
import crypto from "crypto";
import { sha256 } from "$lib/utils/sha256";
import { addWeeks } from "date-fns";
import { OIDConfig } from "$lib/server/auth";

export async function updateUser(params: {
userData: UserinfoResponse;
Expand Down Expand Up @@ -38,10 +39,24 @@ export async function updateUser(params: {
sub: z.string(),
email: z.string().email().optional(),
})
.setKey(OIDConfig.NAME_CLAIM, z.string())
.refine((data) => data.preferred_username || data.email, {
message: "Either preferred_username or email must be provided by the provider.",
})
.parse(userData);
.transform((data) => ({
...data,
name: data[OIDConfig.NAME_CLAIM],
}))
.parse(userData) as {
preferred_username?: string;
email?: string;
picture?: string;
sub: string;
name: string;
} & Record<string, string>;

// Dynamically access user data based on NAME_CLAIM from environment
// This approach allows us to adapt to different OIDC providers flexibly.

// check if user already exists
const existingUser = await collections.users.findOne({ hfUserId });
Expand Down

0 comments on commit c6129c3

Please sign in to comment.