@clerk/nextjs
Version:
Clerk SDK for NextJS
1 lines • 10.7 kB
Source Map (JSON)
{"version":3,"sources":["../../../../src/app-router/server/ClerkProvider.tsx"],"sourcesContent":["import type { InitialState, Without } from '@clerk/types';\nimport { headers } from 'next/headers';\nimport React from 'react';\n\nimport { PromisifiedAuthProvider } from '../../client-boundary/PromisifiedAuthProvider';\nimport { getDynamicAuthData } from '../../server/buildClerkProps';\nimport { createClerkClientWithOptions } from '../../server/createClerkClient';\nimport type { NextClerkProviderProps } from '../../types';\nimport { canUseKeyless } from '../../utils/feature-flags';\nimport { mergeNextClerkPropsWithEnv } from '../../utils/mergeNextClerkPropsWithEnv';\nimport { onlyTry } from '../../utils/only-try';\nimport { isNext13 } from '../../utils/sdk-versions';\nimport { ClientClerkProvider } from '../client/ClerkProvider';\nimport { deleteKeylessAction } from '../keyless-actions';\nimport { buildRequestLike, getScriptNonceFromHeader } from './utils';\n\nconst getDynamicClerkState = React.cache(async function getDynamicClerkState() {\n const request = await buildRequestLike();\n const data = getDynamicAuthData(request);\n\n return data;\n});\n\nconst getNonceFromCSPHeader = React.cache(async function getNonceFromCSPHeader() {\n return getScriptNonceFromHeader((await headers()).get('Content-Security-Policy') || '') || '';\n});\n\nexport async function ClerkProvider(\n props: Without<NextClerkProviderProps, '__unstable_invokeMiddlewareOnAuthStateChange'>,\n) {\n const { children, dynamic, ...rest } = props;\n\n async function generateStatePromise() {\n if (!dynamic) {\n return Promise.resolve(null);\n }\n if (isNext13) {\n /**\n * For some reason, Next 13 requires that functions which call `headers()` are awaited where they are invoked.\n * Without the await here, Next will throw a DynamicServerError during build.\n */\n return Promise.resolve(await getDynamicClerkState());\n }\n return getDynamicClerkState();\n }\n\n async function generateNonce() {\n if (!dynamic) {\n return Promise.resolve('');\n }\n if (isNext13) {\n /**\n * For some reason, Next 13 requires that functions which call `headers()` are awaited where they are invoked.\n * Without the await here, Next will throw a DynamicServerError during build.\n */\n return Promise.resolve(await getNonceFromCSPHeader());\n }\n return getNonceFromCSPHeader();\n }\n\n const propsWithEnvs = mergeNextClerkPropsWithEnv({\n ...rest,\n });\n\n let output = (\n <ClientClerkProvider\n {...mergeNextClerkPropsWithEnv(rest)}\n nonce={await generateNonce()}\n initialState={await generateStatePromise()}\n >\n {children}\n </ClientClerkProvider>\n );\n\n let [shouldRunAsKeyless, runningWithClaimedKeys] = [false, false];\n if (canUseKeyless) {\n const locallyStorePublishableKey = await import('../../server/keyless-node.js')\n .then(mod => mod.safeParseClerkFile()?.publishableKey)\n .catch(() => undefined);\n\n runningWithClaimedKeys =\n Boolean(propsWithEnvs.publishableKey) && propsWithEnvs.publishableKey === locallyStorePublishableKey;\n shouldRunAsKeyless = !propsWithEnvs.publishableKey || runningWithClaimedKeys;\n }\n\n if (shouldRunAsKeyless) {\n // NOTE: Create or read keys on every render. Usually this means only on hard refresh or hard navigations.\n\n const newOrReadKeys = await import('../../server/keyless-node.js')\n .then(mod => mod.createOrReadKeyless())\n .catch(() => null);\n const { clerkDevelopmentCache, createConfirmationMessage, createKeylessModeMessage } = await import(\n '../../server/keyless-log-cache.js'\n );\n\n if (newOrReadKeys) {\n const clientProvider = (\n <ClientClerkProvider\n {...mergeNextClerkPropsWithEnv({\n ...rest,\n publishableKey: newOrReadKeys.publishableKey,\n __internal_keyless_claimKeylessApplicationUrl: newOrReadKeys.claimUrl,\n __internal_keyless_copyInstanceKeysUrl: newOrReadKeys.apiKeysUrl,\n // Explicitly use `null` instead of `undefined` here to avoid persisting `deleteKeylessAction` during merging of options.\n __internal_keyless_dismissPrompt: runningWithClaimedKeys ? deleteKeylessAction : null,\n })}\n nonce={await generateNonce()}\n initialState={await generateStatePromise()}\n >\n {children}\n </ClientClerkProvider>\n );\n\n if (runningWithClaimedKeys) {\n try {\n const secretKey = await import('../../server/keyless-node.js').then(\n mod => mod.safeParseClerkFile()?.secretKey,\n );\n if (!secretKey) {\n // we will ignore it later\n throw new Error(secretKey);\n }\n const client = createClerkClientWithOptions({\n secretKey,\n });\n\n /**\n * Notifying the dashboard the should runs once. We are controlling this behaviour by caching the result of the request.\n * If the request fails, it will be considered stale after 10 minutes, otherwise it is cached for 24 hours.\n */\n await clerkDevelopmentCache?.run(\n () => client.__experimental_accountlessApplications.completeAccountlessApplicationOnboarding(),\n {\n cacheKey: `${newOrReadKeys.publishableKey}_complete`,\n onSuccessStale: 24 * 60 * 60 * 1000, // 24 hours\n },\n );\n } catch {\n // ignore\n }\n\n /**\n * Notify developers.\n */\n clerkDevelopmentCache?.log({\n cacheKey: `${newOrReadKeys.publishableKey}_claimed`,\n msg: createConfirmationMessage(),\n });\n\n output = clientProvider;\n } else {\n const KeylessCookieSync = await import('../client/keyless-cookie-sync.js').then(mod => mod.KeylessCookieSync);\n\n const headerStore = await headers();\n /**\n * Allow developer to return to local application after claiming\n */\n const host = headerStore.get('x-forwarded-host');\n const proto = headerStore.get('x-forwarded-proto');\n\n const claimUrl = new URL(newOrReadKeys.claimUrl);\n if (host && proto) {\n onlyTry(() => claimUrl.searchParams.set('return_url', new URL(`${proto}://${host}`).href));\n }\n\n /**\n * Notify developers.\n */\n clerkDevelopmentCache?.log({\n cacheKey: newOrReadKeys.publishableKey,\n msg: createKeylessModeMessage({ ...newOrReadKeys, claimUrl: claimUrl.href }),\n });\n\n output = <KeylessCookieSync {...newOrReadKeys}>{clientProvider}</KeylessCookieSync>;\n }\n } else {\n // When case keyless should run, but keys are not available, then fallback to throwing for missing keys\n output = (\n <ClientClerkProvider\n {...mergeNextClerkPropsWithEnv(rest)}\n nonce={await generateNonce()}\n initialState={await generateStatePromise()}\n disableKeyless\n >\n {children}\n </ClientClerkProvider>\n );\n }\n }\n\n if (dynamic) {\n return (\n // TODO: fix types so AuthObject is compatible with InitialState\n <PromisifiedAuthProvider authPromise={generateStatePromise() as unknown as Promise<InitialState>}>\n {output}\n </PromisifiedAuthProvider>\n );\n }\n\n return output;\n}\n"],"mappings":"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","names":["getDynamicClerkState","getNonceFromCSPHeader"]}