From 22ca22a2f058448a00668d9e87b1d5c32170ab2b Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Mon, 24 Nov 2025 15:43:05 +0200 Subject: [PATCH] docs: fix callback validation for third-party authentication (#14109) * docs: fix callback validation for third-party authentication * address comment --- .../post.js | 36 +++++---- .../post.ts | 38 ++++++---- .../specs/admin/openapi.full.yaml | 74 ++++++++++++------- .../post.js | 24 ++++-- .../post.ts | 24 ++++-- .../specs/store/openapi.full.yaml | 48 +++++++++--- .../auth/authentication-route/page.mdx | 12 +++ .../customers/third-party-login/page.mdx | 56 +++----------- www/apps/resources/generated/edit-dates.mjs | 4 +- ...h_[actor_type]_[auth_provider]_callback.ts | 74 ++++++++++++------- ...h_[actor_type]_[auth_provider]_callback.ts | 48 +++++++++--- 11 files changed, 272 insertions(+), 166 deletions(-) diff --git a/www/apps/api-reference/specs/admin/code_samples/JavaScript/auth_user_{auth_provider}_callback/post.js b/www/apps/api-reference/specs/admin/code_samples/JavaScript/auth_user_{auth_provider}_callback/post.js index c216efc565..87043a004a 100644 --- a/www/apps/api-reference/specs/admin/code_samples/JavaScript/auth_user_{auth_provider}_callback/post.js +++ b/www/apps/api-reference/specs/admin/code_samples/JavaScript/auth_user_{auth_provider}_callback/post.js @@ -1,4 +1,5 @@ import Medusa from "@medusajs/js-sdk" +import { decodeToken } from "react-jwt" export const sdk = new Medusa({ baseUrl: import.meta.env.VITE_BACKEND_URL || "/", @@ -8,7 +9,7 @@ export const sdk = new Medusa({ }, }) -await sdk.auth.callback( +const token = await sdk.auth.callback( "user", "google", { @@ -16,16 +17,25 @@ await sdk.auth.callback( state: "456" } ) - // all subsequent requests will use the token in the header -sdk.admin.invite.accept( - { - email: "user@gmail.com", - first_name: "John", - last_name: "Smith", - invite_token: "12345..." - }, -) -.then(({ user }) => { - console.log(user) -}) \ No newline at end of file + +const decodedToken = decodeToken(token) as { actor_id: string, user_metadata: Record } + +const shouldCreateUser = decodedToken.actor_id === "" + +if (shouldCreateUser) { + const user = await sdk.admin.invite.accept( + { + email: decodedToken.user_metadata.email as string, + first_name: "John", + last_name: "Smith", + invite_token: "12345..." + }, + ) + + // refresh auth token + await sdk.auth.refresh() + // all subsequent requests will use the new token in the header +} else { + // User already exists and is authenticated +} \ No newline at end of file diff --git a/www/apps/api-reference/specs/admin/code_samples/TypeScript/auth_user_{auth_provider}_callback/post.ts b/www/apps/api-reference/specs/admin/code_samples/TypeScript/auth_user_{auth_provider}_callback/post.ts index 09f7452589..26ede515ec 100644 --- a/www/apps/api-reference/specs/admin/code_samples/TypeScript/auth_user_{auth_provider}_callback/post.ts +++ b/www/apps/api-reference/specs/admin/code_samples/TypeScript/auth_user_{auth_provider}_callback/post.ts @@ -1,4 +1,5 @@ import Medusa from "@medusajs/js-sdk" +import { decodeToken } from "react-jwt" export const sdk = new Medusa({ baseUrl: import.meta.env.VITE_BACKEND_URL || "/", @@ -8,24 +9,33 @@ export const sdk = new Medusa({ }, }) -const authToken = await sdk.auth.callback( +const token = await sdk.auth.callback( "user", - "google", + "github", { code: "123", state: "456" } ) - // all subsequent requests will use the token in the header -sdk.admin.invite.accept( - { - email: "user@gmail.com", - first_name: "John", - last_name: "Smith", - invite_token: "12345..." - }, -) -.then(({ user }) => { - console.log(user) -}) \ No newline at end of file + +const decodedToken = decodeToken(token) as { actor_id: string, user_metadata: Record } + +const shouldCreateUser = decodedToken.actor_id === "" + +if (shouldCreateUser) { + const user = await sdk.admin.invite.accept( + { + email: decodedToken.user_metadata.email as string, + first_name: "John", + last_name: "Smith", + invite_token: "12345..." + }, + ) + + // refresh auth token + await sdk.auth.refresh() + // all subsequent requests will use the new token in the header +} else { + // User already exists and is authenticated +} \ No newline at end of file diff --git a/www/apps/api-reference/specs/admin/openapi.full.yaml b/www/apps/api-reference/specs/admin/openapi.full.yaml index 8e7670dd1e..065029ed94 100644 --- a/www/apps/api-reference/specs/admin/openapi.full.yaml +++ b/www/apps/api-reference/specs/admin/openapi.full.yaml @@ -64080,6 +64080,7 @@ paths: label: Google Provider source: |- import Medusa from "@medusajs/js-sdk" + import { decodeToken } from "react-jwt" export const sdk = new Medusa({ baseUrl: import.meta.env.VITE_BACKEND_URL || "/", @@ -64089,7 +64090,7 @@ paths: }, }) - await sdk.auth.callback( + const token = await sdk.auth.callback( "user", "google", { @@ -64097,23 +64098,33 @@ paths: state: "456" } ) - // all subsequent requests will use the token in the header - sdk.admin.invite.accept( - { - email: "user@gmail.com", - first_name: "John", - last_name: "Smith", - invite_token: "12345..." - }, - ) - .then(({ user }) => { - console.log(user) - }) + + const decodedToken = decodeToken(token) as { actor_id: string, user_metadata: Record } + + const shouldCreateUser = decodedToken.actor_id === "" + + if (shouldCreateUser) { + const user = await sdk.admin.invite.accept( + { + email: decodedToken.user_metadata.email as string, + first_name: "John", + last_name: "Smith", + invite_token: "12345..." + }, + ) + + // refresh auth token + await sdk.auth.refresh() + // all subsequent requests will use the new token in the header + } else { + // User already exists and is authenticated + } - lang: TypeScript label: GitHub Provider source: |- import Medusa from "@medusajs/js-sdk" + import { decodeToken } from "react-jwt" export const sdk = new Medusa({ baseUrl: import.meta.env.VITE_BACKEND_URL || "/", @@ -64123,27 +64134,36 @@ paths: }, }) - const authToken = await sdk.auth.callback( + const token = await sdk.auth.callback( "user", - "google", + "github", { code: "123", state: "456" } ) - // all subsequent requests will use the token in the header - sdk.admin.invite.accept( - { - email: "user@gmail.com", - first_name: "John", - last_name: "Smith", - invite_token: "12345..." - }, - ) - .then(({ user }) => { - console.log(user) - }) + + const decodedToken = decodeToken(token) as { actor_id: string, user_metadata: Record } + + const shouldCreateUser = decodedToken.actor_id === "" + + if (shouldCreateUser) { + const user = await sdk.admin.invite.accept( + { + email: decodedToken.user_metadata.email as string, + first_name: "John", + last_name: "Smith", + invite_token: "12345..." + }, + ) + + // refresh auth token + await sdk.auth.refresh() + // all subsequent requests will use the new token in the header + } else { + // User already exists and is authenticated + } tags: - Auth responses: diff --git a/www/apps/api-reference/specs/store/code_samples/JavaScript/auth_customer_{auth_provider}_callback/post.js b/www/apps/api-reference/specs/store/code_samples/JavaScript/auth_customer_{auth_provider}_callback/post.js index abf065875a..9f115f0fc1 100644 --- a/www/apps/api-reference/specs/store/code_samples/JavaScript/auth_customer_{auth_provider}_callback/post.js +++ b/www/apps/api-reference/specs/store/code_samples/JavaScript/auth_customer_{auth_provider}_callback/post.js @@ -1,4 +1,5 @@ import Medusa from "@medusajs/js-sdk" +import { decodeToken } from "react-jwt" let MEDUSA_BACKEND_URL = "http://localhost:9000" @@ -12,7 +13,7 @@ export const sdk = new Medusa({ publishableKey: process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY, }) -await sdk.auth.callback( +const token = await sdk.auth.callback( "customer", "google", { @@ -20,9 +21,20 @@ await sdk.auth.callback( state: "456" } ) - // all subsequent requests will use the token in the header -const { customer } = await sdk.store.customer.create({ - email: "customer@gmail.com", - password: "supersecret" -}) \ No newline at end of file + +const decodedToken = decodeToken(token) as { actor_id: string, user_metadata: Record } + +const shouldCreateCustomer = decodedToken.actor_id === "" + +if (shouldCreateCustomer) { + const { customer } = await sdk.store.customer.create({ + email: decodedToken.user_metadata.email as string, + }) + + // refresh auth token + await sdk.auth.refresh() + // all subsequent requests will use the new token in the header +} else { + // Customer already exists and is authenticated +} \ No newline at end of file diff --git a/www/apps/api-reference/specs/store/code_samples/TypeScript/auth_customer_{auth_provider}_callback/post.ts b/www/apps/api-reference/specs/store/code_samples/TypeScript/auth_customer_{auth_provider}_callback/post.ts index e681887491..859db7b6c3 100644 --- a/www/apps/api-reference/specs/store/code_samples/TypeScript/auth_customer_{auth_provider}_callback/post.ts +++ b/www/apps/api-reference/specs/store/code_samples/TypeScript/auth_customer_{auth_provider}_callback/post.ts @@ -1,4 +1,5 @@ import Medusa from "@medusajs/js-sdk" +import { decodeToken } from "react-jwt" let MEDUSA_BACKEND_URL = "http://localhost:9000" @@ -12,7 +13,7 @@ export const sdk = new Medusa({ publishableKey: process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY, }) -await sdk.auth.callback( +const token = await sdk.auth.callback( "customer", "github", { @@ -20,9 +21,20 @@ await sdk.auth.callback( state: "456" } ) - // all subsequent requests will use the token in the header -const { customer } = await sdk.store.customer.create({ - email: "customer@gmail.com", - password: "supersecret" -}) \ No newline at end of file + +const decodedToken = decodeToken(token) as { actor_id: string, user_metadata: Record } + +const shouldCreateCustomer = decodedToken.actor_id === "" + +if (shouldCreateCustomer) { + const { customer } = await sdk.store.customer.create({ + email: decodedToken.user_metadata.email as string, + }) + + // refresh auth token + await sdk.auth.refresh() + // all subsequent requests will use the new token in the header +} else { + // Customer already exists and is authenticated +} \ No newline at end of file diff --git a/www/apps/api-reference/specs/store/openapi.full.yaml b/www/apps/api-reference/specs/store/openapi.full.yaml index 75baf206ec..47b75a0491 100644 --- a/www/apps/api-reference/specs/store/openapi.full.yaml +++ b/www/apps/api-reference/specs/store/openapi.full.yaml @@ -290,6 +290,7 @@ paths: label: Google Provider source: |- import Medusa from "@medusajs/js-sdk" + import { decodeToken } from "react-jwt" let MEDUSA_BACKEND_URL = "http://localhost:9000" @@ -303,7 +304,7 @@ paths: publishableKey: process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY, }) - await sdk.auth.callback( + const token = await sdk.auth.callback( "customer", "google", { @@ -311,16 +312,28 @@ paths: state: "456" } ) - // all subsequent requests will use the token in the header - const { customer } = await sdk.store.customer.create({ - email: "customer@gmail.com", - password: "supersecret" - }) + + const decodedToken = decodeToken(token) as { actor_id: string, user_metadata: Record } + + const shouldCreateCustomer = decodedToken.actor_id === "" + + if (shouldCreateCustomer) { + const { customer } = await sdk.store.customer.create({ + email: decodedToken.user_metadata.email as string, + }) + + // refresh auth token + await sdk.auth.refresh() + // all subsequent requests will use the new token in the header + } else { + // Customer already exists and is authenticated + } - lang: TypeScript label: GitHub Provider source: |- import Medusa from "@medusajs/js-sdk" + import { decodeToken } from "react-jwt" let MEDUSA_BACKEND_URL = "http://localhost:9000" @@ -334,7 +347,7 @@ paths: publishableKey: process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY, }) - await sdk.auth.callback( + const token = await sdk.auth.callback( "customer", "github", { @@ -342,12 +355,23 @@ paths: state: "456" } ) - // all subsequent requests will use the token in the header - const { customer } = await sdk.store.customer.create({ - email: "customer@gmail.com", - password: "supersecret" - }) + + const decodedToken = decodeToken(token) as { actor_id: string, user_metadata: Record } + + const shouldCreateCustomer = decodedToken.actor_id === "" + + if (shouldCreateCustomer) { + const { customer } = await sdk.store.customer.create({ + email: decodedToken.user_metadata.email as string, + }) + + // refresh auth token + await sdk.auth.refresh() + // all subsequent requests will use the new token in the header + } else { + // Customer already exists and is authenticated + } tags: - Auth responses: diff --git a/www/apps/resources/app/commerce-modules/auth/authentication-route/page.mdx b/www/apps/resources/app/commerce-modules/auth/authentication-route/page.mdx index 75bcdf2a3a..63e28cb516 100644 --- a/www/apps/resources/app/commerce-modules/auth/authentication-route/page.mdx +++ b/www/apps/resources/app/commerce-modules/auth/authentication-route/page.mdx @@ -256,6 +256,18 @@ In your frontend, decode the token using tools like [react-jwt](https://www.npmj - If the decoded data has an `actor_id` property, the user is already registered. So, use this token for subsequent authenticated requests. - If not, use the token in the header of a request that creates the user, such as the [Create Customer API route](!api!/store#customers_postcustomers). +The decoded data may look like this: + +```json +{ + "actor_id": "", // Empty if the user is not registered + "user_metadata": { + "email": "Whitney_Schultz@gmail.com" + } + // other fields... +} +``` + --- ## Refresh Token Route diff --git a/www/apps/resources/app/storefront-development/customers/third-party-login/page.mdx b/www/apps/resources/app/storefront-development/customers/third-party-login/page.mdx index 2ebb7de8d8..00506d07c1 100644 --- a/www/apps/resources/app/storefront-development/customers/third-party-login/page.mdx +++ b/www/apps/resources/app/storefront-development/customers/third-party-login/page.mdx @@ -355,15 +355,12 @@ Finally, you'll add to the page a function that validates the authentication cal Add in the place of the new `TODO` the `validateCallback` function that runs when the page first loads to validate the authentication: - - - export const validateReactHighlights = [ ["2", "sendCallback", "Validate the callback in Medusa and retrieve the authentication token"], - ["4", "shouldCreateCustomer", "Check if the decoded token has an `actor_id` property to decide whether a customer needs to be created"], - ["7", "createCustomer", "Create a customer if the decoded token doesn't have `actor_id`"], - ["9", "refreshToken", "Fetch a new token for the created customer"], - ["13", "retrieve", "Retrieve the customer's details as an example of testing authentication"] + ["6", "shouldCreateCustomer", "Check if the decoded token has an `actor_id` property to decide whether a customer needs to be created"], + ["9", "createCustomer", "Create a customer if the decoded token doesn't have `actor_id`"], + ["11", "refreshToken", "Fetch a new token for the created customer"], + ["15", "retrieve", "Retrieve the customer's details as an example of testing authentication"] ] ```tsx highlights={validateReactHighlights} @@ -387,46 +384,9 @@ const validateCallback = async () => { setLoading(false) } - // TODO run validateCallback when the page loads ``` - - - -export const validateFetchHighlights = [ - ["2", "sendCallback", "Validate the callback in Medusa and retrieve the authentication token"], - ["4", "shouldCreateCustomer", "Check if the decoded token has an `actor_id` property to decide whether a customer needs to be created"], - ["7", "createCustomer", "Create a customer if the decoded token doesn't have `actor_id`"], - ["9", "refreshToken", "Fetch a new token for the created customer"], - ["13", "retrieve", "Retrieve the customer's details as an example of testing authentication"] -] - -```ts highlights={validateFetchHighlights} -const validateCallback = async () => { - const token = await sendCallback() - - const shouldCreateCustomer = (decodeToken(token) as { actor_id: string }).actor_id === "" - - if (shouldCreateCustomer) { - await createCustomer() - - await refreshToken() - } - - // use token to send authenticated requests - const { customer: customerData } = await sdk.store.customer.retrieve() - - setCustomer(customerData) - setLoading(false) -} - -// TODO run validateCallback when the page loads -``` - - - - The `validateCallback` function uses the functions added earlier to implement the following flow: 1. Send a request to the [Validate Callback API route](!api!/store#auth_postactor_typeauth_providercallback). This returns an authentication token. @@ -527,15 +487,17 @@ export default function GoogleCallback() { const validateCallback = async () => { const token = await sendCallback() - const shouldCreateCustomer = (decodeToken(token) as { actor_id: string }).actor_id === "" + const decodedToken = decodeToken(token) as { actor_id: string, user_metadata: Record } + + const shouldCreateCustomer = decodedToken.actor_id === "" if (shouldCreateCustomer) { - await createCustomer() + await createCustomer(decodedToken.user_metadata.email as string) await refreshToken() } - // all subsequent requests are authenticated + // use token to send authenticated requests const { customer: customerData } = await sdk.store.customer.retrieve() setCustomer(customerData) diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index 584414d5e0..7c8a540196 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -1,7 +1,7 @@ export const generatedEditDates = { "app/commerce-modules/auth/auth-providers/emailpass/page.mdx": "2025-01-13T11:31:35.361Z", "app/commerce-modules/auth/auth-providers/page.mdx": "2025-05-20T07:51:40.707Z", - "app/commerce-modules/auth/authentication-route/page.mdx": "2025-03-04T09:13:45.919Z", + "app/commerce-modules/auth/authentication-route/page.mdx": "2025-11-24T07:39:10.358Z", "app/commerce-modules/auth/examples/page.mdx": "2024-10-15T15:02:13.794Z", "app/commerce-modules/auth/module-options/page.mdx": "2025-03-11T08:56:10.338Z", "app/commerce-modules/auth/page.mdx": "2025-04-17T08:48:17.286Z", @@ -830,7 +830,7 @@ export const generatedEditDates = { "references/types/interfaces/types.BaseClaim/page.mdx": "2025-09-12T14:10:39.219Z", "app/commerce-modules/auth/auth-providers/github/page.mdx": "2025-01-13T11:31:35.361Z", "app/commerce-modules/auth/auth-providers/google/page.mdx": "2025-01-13T11:31:35.361Z", - "app/storefront-development/customers/third-party-login/page.mdx": "2025-09-17T11:42:53.434Z", + "app/storefront-development/customers/third-party-login/page.mdx": "2025-11-24T07:27:46.836Z", "references/types/HttpTypes/types/types.HttpTypes.AdminWorkflowRunResponse/page.mdx": "2024-12-09T13:21:34.761Z", "references/types/HttpTypes/types/types.HttpTypes.BatchResponse/page.mdx": "2025-04-11T09:04:46.523Z", "references/types/WorkflowsSdkTypes/types/types.WorkflowsSdkTypes.Acknowledgement/page.mdx": "2024-12-09T13:21:35.873Z", diff --git a/www/utils/generated/oas-output/operations/admin/post_auth_[actor_type]_[auth_provider]_callback.ts b/www/utils/generated/oas-output/operations/admin/post_auth_[actor_type]_[auth_provider]_callback.ts index 0dc1a2c2e7..ab7ed1cc0b 100644 --- a/www/utils/generated/oas-output/operations/admin/post_auth_[actor_type]_[auth_provider]_callback.ts +++ b/www/utils/generated/oas-output/operations/admin/post_auth_[actor_type]_[auth_provider]_callback.ts @@ -26,6 +26,7 @@ * label: Google Provider * source: |- * import Medusa from "@medusajs/js-sdk" + * import { decodeToken } from "react-jwt" * * export const sdk = new Medusa({ * baseUrl: import.meta.env.VITE_BACKEND_URL || "/", @@ -35,7 +36,7 @@ * }, * }) * - * await sdk.auth.callback( + * const token = await sdk.auth.callback( * "user", * "google", * { @@ -43,23 +44,33 @@ * state: "456" * } * ) - * * // all subsequent requests will use the token in the header - * sdk.admin.invite.accept( - * { - * email: "user@gmail.com", - * first_name: "John", - * last_name: "Smith", - * invite_token: "12345..." - * }, - * ) - * .then(({ user }) => { - * console.log(user) - * }) + * + * const decodedToken = decodeToken(token) as { actor_id: string, user_metadata: Record } + * + * const shouldCreateUser = decodedToken.actor_id === "" + * + * if (shouldCreateUser) { + * const user = await sdk.admin.invite.accept( + * { + * email: decodedToken.user_metadata.email as string, + * first_name: "John", + * last_name: "Smith", + * invite_token: "12345..." + * }, + * ) + * + * // refresh auth token + * await sdk.auth.refresh() + * // all subsequent requests will use the new token in the header + * } else { + * // User already exists and is authenticated + * } * - lang: TypeScript * label: GitHub Provider * source: |- * import Medusa from "@medusajs/js-sdk" + * import { decodeToken } from "react-jwt" * * export const sdk = new Medusa({ * baseUrl: import.meta.env.VITE_BACKEND_URL || "/", @@ -69,27 +80,36 @@ * }, * }) * - * const authToken = await sdk.auth.callback( + * const token = await sdk.auth.callback( * "user", - * "google", + * "github", * { * code: "123", * state: "456" * } * ) - * * // all subsequent requests will use the token in the header - * sdk.admin.invite.accept( - * { - * email: "user@gmail.com", - * first_name: "John", - * last_name: "Smith", - * invite_token: "12345..." - * }, - * ) - * .then(({ user }) => { - * console.log(user) - * }) + * + * const decodedToken = decodeToken(token) as { actor_id: string, user_metadata: Record } + * + * const shouldCreateUser = decodedToken.actor_id === "" + * + * if (shouldCreateUser) { + * const user = await sdk.admin.invite.accept( + * { + * email: decodedToken.user_metadata.email as string, + * first_name: "John", + * last_name: "Smith", + * invite_token: "12345..." + * }, + * ) + * + * // refresh auth token + * await sdk.auth.refresh() + * // all subsequent requests will use the new token in the header + * } else { + * // User already exists and is authenticated + * } * tags: * - Auth * responses: diff --git a/www/utils/generated/oas-output/operations/store/post_auth_[actor_type]_[auth_provider]_callback.ts b/www/utils/generated/oas-output/operations/store/post_auth_[actor_type]_[auth_provider]_callback.ts index 29a3621d1f..ab86023d5a 100644 --- a/www/utils/generated/oas-output/operations/store/post_auth_[actor_type]_[auth_provider]_callback.ts +++ b/www/utils/generated/oas-output/operations/store/post_auth_[actor_type]_[auth_provider]_callback.ts @@ -25,6 +25,7 @@ * label: Google Provider * source: |- * import Medusa from "@medusajs/js-sdk" + * import { decodeToken } from "react-jwt" * * let MEDUSA_BACKEND_URL = "http://localhost:9000" * @@ -38,7 +39,7 @@ * publishableKey: process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY, * }) * - * await sdk.auth.callback( + * const token = await sdk.auth.callback( * "customer", * "google", * { @@ -46,16 +47,28 @@ * state: "456" * } * ) - * * // all subsequent requests will use the token in the header - * const { customer } = await sdk.store.customer.create({ - * email: "customer@gmail.com", - * password: "supersecret" - * }) + * + * const decodedToken = decodeToken(token) as { actor_id: string, user_metadata: Record } + * + * const shouldCreateCustomer = decodedToken.actor_id === "" + * + * if (shouldCreateCustomer) { + * const { customer } = await sdk.store.customer.create({ + * email: decodedToken.user_metadata.email as string, + * }) + * + * // refresh auth token + * await sdk.auth.refresh() + * // all subsequent requests will use the new token in the header + * } else { + * // Customer already exists and is authenticated + * } * - lang: TypeScript * label: GitHub Provider * source: |- * import Medusa from "@medusajs/js-sdk" + * import { decodeToken } from "react-jwt" * * let MEDUSA_BACKEND_URL = "http://localhost:9000" * @@ -69,7 +82,7 @@ * publishableKey: process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY, * }) * - * await sdk.auth.callback( + * const token = await sdk.auth.callback( * "customer", * "github", * { @@ -77,12 +90,23 @@ * state: "456" * } * ) - * * // all subsequent requests will use the token in the header - * const { customer } = await sdk.store.customer.create({ - * email: "customer@gmail.com", - * password: "supersecret" - * }) + * + * const decodedToken = decodeToken(token) as { actor_id: string, user_metadata: Record } + * + * const shouldCreateCustomer = decodedToken.actor_id === "" + * + * if (shouldCreateCustomer) { + * const { customer } = await sdk.store.customer.create({ + * email: decodedToken.user_metadata.email as string, + * }) + * + * // refresh auth token + * await sdk.auth.refresh() + * // all subsequent requests will use the new token in the header + * } else { + * // Customer already exists and is authenticated + * } * tags: * - Auth * responses: