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`.
> 
> <sup>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).</sup>
This commit is contained in:
Nicolas Gorga
2025-10-02 15:21:50 -03:00
committed by GitHub
parent 4717ad9a59
commit 907fbc89a2
5 changed files with 21 additions and 2 deletions

View File

@@ -0,0 +1,5 @@
---
"@medusajs/medusa": patch
---
feat(medusa): include user_metadata in auth routes jwt

View File

@@ -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,

View File

@@ -39,6 +39,7 @@ export const POST = async (req: MedusaRequest, res: MedusaResponse) => {
{
authIdentity,
actorType: actor_type,
authProvider: auth_provider,
},
{
secret: http.jwtSecret!,

View File

@@ -43,6 +43,7 @@ export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
{
authIdentity,
actorType: actor_type,
authProvider: auth_provider,
},
{
secret: http.jwtSecret!,

View File

@@ -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,