From 907fbc89a2566f516c65a4eefdfeeb4f9dcb3579 Mon Sep 17 00:00:00 2001 From: Nicolas Gorga <62995075+NicolasGorga@users.noreply.github.com> Date: Thu, 2 Oct 2025 15:21:50 -0300 Subject: [PATCH] feat(medusa): include user_metadata in auth routes jwt (#13597) **What** Return provider specific user_metadata in jwt token returned by auth/[actor_type]/[auth_provider] routes. **Why** When implementing thrid party auth flows, to create the Medusa entity representing the actor type, you will need information obtained from the callback after the user consents. For google for example, you need the email, which so far is stored in the provider user_metadata property but is never returned in the http response. This causes one to circumvent around this issue by creating an additional http route which gets the auth_identity from the auth_context object, to access the providers array and then look for the specific element matching the current auth_provider route. **How** Pass the auth_provider obtained from the route path param and pass it down to `generateJwtTokenForAuthIdentity` and inside it, find the provider matching the auth provider passed from route handler inside the auth identity `provider_identities` property. If found, assign its `user_metadata` value to the property of the same name in the payload of the token to be generated. Now the user has the user_metadata property included in the obtained token and can use it's information to create the corresponding Medusa entity for the actor type in context. In the case of google and customer actor type, they would use `user_metadata.email` to call the create customer api endpoint. **Testing** Haven't found anywhere in the codebase where the http layer of /auth functionality is tested, but tested locally with debugger and test storefront to guarantee the user_metadata is returned as expected, all working correctly. Fixes #13584 CLOSES CORE-437 --- > [!NOTE] > Propagates auth provider to JWT generation and embeds provider-specific user_metadata in tokens returned by auth routes. > > - **Auth JWT Payload**: > - `generateJwtTokenForAuthIdentity` now accepts optional `authProvider` and injects matching provider `user_metadata` into JWT payload. > - **Auth Routes** (`auth/[actor_type]/[auth_provider]/*`): > - Pass `authProvider` from route params to JWT generator in `authenticate`, `register`, and `callback` handlers. > - **Release**: > - Changeset adds patch for `@medusajs/medusa`. > > Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 4833faf84533ce7438bc37c15bd572f991988e69. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot). --- .changeset/soft-hotels-report.md | 5 +++++ .../[actor_type]/[auth_provider]/callback/route.ts | 2 +- .../[actor_type]/[auth_provider]/register/route.ts | 1 + .../api/auth/[actor_type]/[auth_provider]/route.ts | 1 + .../src/api/auth/utils/generate-jwt-token.ts | 14 +++++++++++++- 5 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 .changeset/soft-hotels-report.md diff --git a/.changeset/soft-hotels-report.md b/.changeset/soft-hotels-report.md new file mode 100644 index 0000000000..34f0cb75cd --- /dev/null +++ b/.changeset/soft-hotels-report.md @@ -0,0 +1,5 @@ +--- +"@medusajs/medusa": patch +--- + +feat(medusa): include user_metadata in auth routes jwt diff --git a/packages/medusa/src/api/auth/[actor_type]/[auth_provider]/callback/route.ts b/packages/medusa/src/api/auth/[actor_type]/[auth_provider]/callback/route.ts index a42f923b98..224cc9c685 100644 --- a/packages/medusa/src/api/auth/[actor_type]/[auth_provider]/callback/route.ts +++ b/packages/medusa/src/api/auth/[actor_type]/[auth_provider]/callback/route.ts @@ -36,7 +36,7 @@ export const GET = async (req: MedusaRequest, res: MedusaResponse) => { const { http } = config.projectConfig const token = generateJwtTokenForAuthIdentity( - { authIdentity, actorType: actor_type }, + { authIdentity, actorType: actor_type, authProvider: auth_provider }, { secret: http.jwtSecret!, expiresIn: http.jwtExpiresIn, diff --git a/packages/medusa/src/api/auth/[actor_type]/[auth_provider]/register/route.ts b/packages/medusa/src/api/auth/[actor_type]/[auth_provider]/register/route.ts index 1e790ab97c..9990831528 100644 --- a/packages/medusa/src/api/auth/[actor_type]/[auth_provider]/register/route.ts +++ b/packages/medusa/src/api/auth/[actor_type]/[auth_provider]/register/route.ts @@ -39,6 +39,7 @@ export const POST = async (req: MedusaRequest, res: MedusaResponse) => { { authIdentity, actorType: actor_type, + authProvider: auth_provider, }, { secret: http.jwtSecret!, diff --git a/packages/medusa/src/api/auth/[actor_type]/[auth_provider]/route.ts b/packages/medusa/src/api/auth/[actor_type]/[auth_provider]/route.ts index ca1cf6eeeb..3722bc056b 100644 --- a/packages/medusa/src/api/auth/[actor_type]/[auth_provider]/route.ts +++ b/packages/medusa/src/api/auth/[actor_type]/[auth_provider]/route.ts @@ -43,6 +43,7 @@ export const GET = async (req: MedusaRequest, res: MedusaResponse) => { { authIdentity, actorType: actor_type, + authProvider: auth_provider, }, { secret: http.jwtSecret!, diff --git a/packages/medusa/src/api/auth/utils/generate-jwt-token.ts b/packages/medusa/src/api/auth/utils/generate-jwt-token.ts index 0f38c3f90f..e6a7250ebf 100644 --- a/packages/medusa/src/api/auth/utils/generate-jwt-token.ts +++ b/packages/medusa/src/api/auth/utils/generate-jwt-token.ts @@ -9,7 +9,12 @@ export function generateJwtTokenForAuthIdentity( { authIdentity, actorType, - }: { authIdentity: AuthIdentityDTO; actorType: string }, + authProvider, + }: { + authIdentity: AuthIdentityDTO + actorType: string + authProvider?: string + }, { secret, expiresIn, @@ -26,6 +31,12 @@ export function generateJwtTokenForAuthIdentity( | string | undefined + const providerIdentity = !authProvider + ? undefined + : authIdentity.provider_identities?.filter( + (identity) => identity.provider === authProvider + )[0] + return generateJwtToken( { actor_id: entityId ?? "", @@ -34,6 +45,7 @@ export function generateJwtTokenForAuthIdentity( app_metadata: { [entityIdKey]: entityId, }, + user_metadata: providerIdentity?.user_metadata ?? {}, }, { secret,