@clerk/express 2.1.49 → 2.1.50-canary.v20260731161424

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { i as ExpressRequestWithAuth, n as ClerkMiddlewareOptions, r as ClerkMiddlewareOptionsCallback, t as AuthenticateRequestParams } from "./types-CRXNc42W.mjs";
1
+ import { i as ExpressRequestWithAuth, n as ClerkMiddlewareOptions, r as ClerkMiddlewareOptionsCallback, t as AuthenticateRequestParams } from "./types-D9OHSDSA.mjs";
2
2
  import { ClerkClient } from "@clerk/backend";
3
3
  import { GetAuthFn, RequestState } from "@clerk/backend/internal";
4
4
  import { Request, RequestHandler } from "express";
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { i as ExpressRequestWithAuth, n as ClerkMiddlewareOptions, r as ClerkMiddlewareOptionsCallback, t as AuthenticateRequestParams } from "./types-CRXNc42W.js";
1
+ import { i as ExpressRequestWithAuth, n as ClerkMiddlewareOptions, r as ClerkMiddlewareOptionsCallback, t as AuthenticateRequestParams } from "./types-D9OHSDSA.js";
2
2
  import { ClerkClient } from "@clerk/backend";
3
3
  import { GetAuthFn, RequestState } from "@clerk/backend/internal";
4
4
  import { Request, RequestHandler } from "express";
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_utils = require('./utils-BKrEOl3y.js');
2
+ const require_utils = require('./utils-8eqSXbcQ.js');
3
3
  let _clerk_backend = require("@clerk/backend");
4
4
  let stream = require("stream");
5
5
  let _clerk_backend_internal = require("@clerk/backend/internal");
@@ -21,7 +21,7 @@ const clerkClient = new Proxy(clerkClientSingleton, {
21
21
  };
22
22
  const client = (0, _clerk_backend.createClerkClient)({
23
23
  ...env,
24
- userAgent: `@clerk/express@2.1.49`
24
+ userAgent: `@clerk/express@2.1.50-canary.v20260731161424`
25
25
  });
26
26
  if (env.secretKey) clerkClientSingleton = client;
27
27
  return client[property];
@@ -69,7 +69,7 @@ Check if signInUrl is missing from your configuration or if it is not an absolut
69
69
  const authenticateRequest = (opts) => {
70
70
  const { clerkClient, request, options } = opts;
71
71
  const { clerkClient: _clerkClient, debug: _debug, frontendApiProxy: _frontendApiProxy, isSatellite: isSatelliteInput, domain: domainInput, signInUrl: signInUrlInput, proxyUrl: proxyUrlInput, secretKey: secretKeyInput, machineSecretKey: machineSecretKeyInput, publishableKey: publishableKeyInput, ...restOptions } = options || {};
72
- const clerkRequest = (0, _clerk_backend_internal.createClerkRequest)(require_utils.incomingMessageToRequest(request));
72
+ const clerkRequest = opts.clerkRequest ?? (0, _clerk_backend_internal.createClerkRequest)(require_utils.incomingMessageToRequest(request));
73
73
  const env = {
74
74
  ...require_utils.loadApiEnv(),
75
75
  ...require_utils.loadClientEnv()
@@ -121,7 +121,7 @@ const resolveDefaultClerkClient = (options) => {
121
121
  ...require_utils.loadClientEnv(),
122
122
  ...options.apiUrl ? { apiUrl: options.apiUrl } : {},
123
123
  ...options.apiVersion ? { apiVersion: options.apiVersion } : {},
124
- userAgent: `@clerk/express@2.1.49`
124
+ userAgent: `@clerk/express@2.1.50-canary.v20260731161424`
125
125
  });
126
126
  };
127
127
  const authenticateAndDecorateRequest = (options = {}) => {
@@ -131,6 +131,13 @@ const authenticateAndDecorateRequest = (options = {}) => {
131
131
  const middleware = async (request, response, next) => {
132
132
  if (require_utils.requestHasAuthObject(request)) return next();
133
133
  if ("auth" in request) _clerk_shared_logger.logger.warnOnce("Clerk: another middleware has already set `req.auth` on this request. Clerk authentication will run anyway and overwrite it. To use another auth library alongside Clerk, configure it to store its state on a different request property.");
134
+ let clerkRequest;
135
+ try {
136
+ clerkRequest = (0, _clerk_backend_internal.createClerkRequest)(require_utils.incomingMessageToRequest(request));
137
+ } catch {
138
+ response.status(400).end();
139
+ return;
140
+ }
134
141
  const env = {
135
142
  ...require_utils.loadApiEnv(),
136
143
  ...require_utils.loadClientEnv()
@@ -138,9 +145,22 @@ const authenticateAndDecorateRequest = (options = {}) => {
138
145
  const publishableKey = options.publishableKey || env.publishableKey;
139
146
  const secretKey = options.secretKey || env.secretKey;
140
147
  if (frontendApiProxy) {
141
- const requestUrl = new URL(request.originalUrl || request.url, `http://${request.headers.host}`);
148
+ let requestUrl;
149
+ try {
150
+ requestUrl = new URL(request.originalUrl || request.url, `http://${request.headers.host}`);
151
+ } catch {
152
+ response.status(400).end();
153
+ return;
154
+ }
142
155
  if ((typeof frontendApiProxy.enabled === "function" ? frontendApiProxy.enabled(requestUrl) : frontendApiProxy.enabled) && (requestUrl.pathname === proxyPath || requestUrl.pathname.startsWith(proxyPath + "/"))) {
143
- const proxyResponse = await (0, _clerk_backend_proxy.clerkFrontendApiProxy)(require_utils.requestToProxyRequest(request), {
156
+ let proxyRequest;
157
+ try {
158
+ proxyRequest = require_utils.requestToProxyRequest(request);
159
+ } catch {
160
+ response.status(400).end();
161
+ return;
162
+ }
163
+ const proxyResponse = await (0, _clerk_backend_proxy.clerkFrontendApiProxy)(proxyRequest, {
144
164
  proxyPath,
145
165
  publishableKey,
146
166
  secretKey
@@ -166,7 +186,13 @@ const authenticateAndDecorateRequest = (options = {}) => {
166
186
  }
167
187
  let resolvedOptions = options;
168
188
  if (frontendApiProxy && !options.proxyUrl) {
169
- const requestUrl = new URL(request.originalUrl || request.url, `http://${request.headers.host}`);
189
+ let requestUrl;
190
+ try {
191
+ requestUrl = new URL(request.originalUrl || request.url, `http://${request.headers.host}`);
192
+ } catch {
193
+ response.status(400).end();
194
+ return;
195
+ }
170
196
  if (typeof frontendApiProxy.enabled === "function" ? frontendApiProxy.enabled(requestUrl) : frontendApiProxy.enabled) resolvedOptions = {
171
197
  ...options,
172
198
  proxyUrl: proxyPath
@@ -176,7 +202,8 @@ const authenticateAndDecorateRequest = (options = {}) => {
176
202
  const requestState = await authenticateRequest({
177
203
  clerkClient,
178
204
  request,
179
- options: resolvedOptions
205
+ options: resolvedOptions,
206
+ clerkRequest
180
207
  });
181
208
  const err = setResponseHeaders(requestState, response);
182
209
  if (err) return next(err);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["loadApiEnv","loadClientEnv","incomingMessageToRequest","loadApiEnv","loadClientEnv","AuthStatus","defaultClerkClient","DEFAULT_PROXY_PATH","requestHasAuthObject","requestToProxyRequest","Readable","brandRequestAuth","requestHasAuthObject"],"sources":["../src/clerkClient.ts","../src/errors.ts","../src/authenticateRequest.ts","../src/clerkMiddleware.ts","../src/getAuth.ts","../src/requireAuth.ts"],"sourcesContent":["import type { ClerkClient } from '@clerk/backend';\nimport { createClerkClient } from '@clerk/backend';\n\nimport { loadApiEnv, loadClientEnv } from './utils';\n\nlet clerkClientSingleton = {} as unknown as ClerkClient;\n\nexport const clerkClient = new Proxy(clerkClientSingleton, {\n get(_target, property: keyof ClerkClient) {\n if (property in clerkClientSingleton) {\n return clerkClientSingleton[property];\n }\n\n const env = { ...loadApiEnv(), ...loadClientEnv() };\n const client = createClerkClient({ ...env, userAgent: `${PACKAGE_NAME}@${PACKAGE_VERSION}` });\n\n // if the client is initialized properly, cache it to a singleton instance variable\n // in the next invocation the guard at the top will be triggered instead of creating another instance\n if (env.secretKey) {\n clerkClientSingleton = client;\n }\n\n return client[property];\n },\n set() {\n return false;\n },\n});\n","const createErrorMessage = (msg: string) => {\n return `🔒 Clerk: ${msg.trim()}\n\n For more info, check out the docs: https://clerk.com/docs,\n or come say hi in our discord server: https://clerk.com/discord\n `;\n};\n\nexport const middlewareRequired = (fnName: string) =>\n createErrorMessage(`The \"clerkMiddleware\" should be registered before using \"${fnName}\".\nExample:\n\nimport express from 'express';\nimport { clerkMiddleware } from '@clerk/express';\n\nconst app = express();\napp.use(clerkMiddleware());\n`);\n\nexport const satelliteAndMissingProxyUrlAndDomain =\n 'Missing domain and proxyUrl. A satellite application needs to specify a domain or a proxyUrl';\nexport const satelliteAndMissingSignInUrl = `\nInvalid signInUrl. A satellite application requires a signInUrl for development instances.\nCheck if signInUrl is missing from your configuration or if it is not an absolute URL.`;\n","import { createClerkClient } from '@clerk/backend';\nimport type { RequestState } from '@clerk/backend/internal';\nimport { AuthStatus, createClerkRequest } from '@clerk/backend/internal';\nimport { clerkFrontendApiProxy, DEFAULT_PROXY_PATH, stripTrailingSlashes } from '@clerk/backend/proxy';\nimport { isDevelopmentFromSecretKey } from '@clerk/shared/keys';\nimport { logger } from '@clerk/shared/logger';\nimport { isHttpOrHttps, isProxyUrlRelative, isValidProxyUrl } from '@clerk/shared/proxy';\nimport { handleValueOrFn } from '@clerk/shared/utils';\nimport type { RequestHandler, Response } from 'express';\nimport { Readable } from 'stream';\n\nimport { clerkClient as defaultClerkClient } from './clerkClient';\nimport { satelliteAndMissingProxyUrlAndDomain, satelliteAndMissingSignInUrl } from './errors';\nimport type { AuthenticateRequestParams, ClerkMiddlewareOptions } from './types';\nimport {\n brandRequestAuth,\n incomingMessageToRequest,\n loadApiEnv,\n loadClientEnv,\n requestHasAuthObject,\n requestToProxyRequest,\n} from './utils';\n\n/**\n * @internal\n * Authenticates an Express request by wrapping clerkClient.authenticateRequest and\n * converts the express request object into a standard web request object\n *\n * @param opts - Configuration options for request authentication\n * @param opts.clerkClient - The Clerk client instance to use for authentication\n * @param opts.request - The Express request object to authenticate\n * @param opts.options - Optional middleware configuration options\n */\nexport const authenticateRequest = (opts: AuthenticateRequestParams) => {\n const { clerkClient, request, options } = opts;\n // Peel off middleware-only keys and the few options that need middleware-side\n // resolution (env fallbacks, URL normalization). Everything else is spread\n // straight through, so new AuthenticateRequestOptions/VerifyTokenOptions\n // fields flow to the backend without another code change here.\n const {\n clerkClient: _clerkClient,\n debug: _debug,\n frontendApiProxy: _frontendApiProxy,\n isSatellite: isSatelliteInput,\n domain: domainInput,\n signInUrl: signInUrlInput,\n proxyUrl: proxyUrlInput,\n secretKey: secretKeyInput,\n machineSecretKey: machineSecretKeyInput,\n publishableKey: publishableKeyInput,\n ...restOptions\n } = options || {};\n\n const clerkRequest = createClerkRequest(incomingMessageToRequest(request));\n const env = { ...loadApiEnv(), ...loadClientEnv() };\n\n const secretKey = secretKeyInput || env.secretKey;\n const machineSecretKey = machineSecretKeyInput || env.machineSecretKey;\n const publishableKey = publishableKeyInput || env.publishableKey;\n\n const isSatellite = handleValueOrFn(isSatelliteInput, clerkRequest.clerkUrl, env.isSatellite);\n const domain = handleValueOrFn(domainInput, clerkRequest.clerkUrl) || env.domain;\n const signInUrl = signInUrlInput || env.signInUrl;\n const proxyUrl = absoluteProxyUrl(\n handleValueOrFn(proxyUrlInput, clerkRequest.clerkUrl, env.proxyUrl),\n clerkRequest.clerkUrl.toString(),\n );\n\n if (isSatellite && !proxyUrl && !domain) {\n throw new Error(satelliteAndMissingProxyUrlAndDomain);\n }\n\n if (isSatellite && !isHttpOrHttps(signInUrl) && isDevelopmentFromSecretKey(secretKey || '')) {\n throw new Error(satelliteAndMissingSignInUrl);\n }\n\n return clerkClient.authenticateRequest(clerkRequest, {\n ...restOptions,\n secretKey,\n machineSecretKey,\n publishableKey,\n proxyUrl,\n isSatellite,\n domain,\n signInUrl,\n });\n};\n\nconst setResponseHeaders = (requestState: RequestState, res: Response): Error | undefined => {\n if (requestState.headers) {\n requestState.headers.forEach((value, key) => res.appendHeader(key, value));\n }\n return setResponseForHandshake(requestState, res);\n};\n\n/**\n * Depending on the auth state of the request, handles applying redirects and validating that a handshake state was properly handled.\n *\n * Returns an error if state is handshake without a redirect, otherwise returns undefined. res.writableEnded should be checked after this method is called.\n */\nconst setResponseForHandshake = (requestState: RequestState, res: Response): Error | undefined => {\n const hasLocationHeader = requestState.headers.get('location');\n if (hasLocationHeader) {\n // triggering a handshake redirect\n res.status(307).end();\n return;\n }\n\n if (requestState.status === AuthStatus.Handshake) {\n return new Error('Clerk: unexpected handshake without redirect');\n }\n\n return;\n};\n\nconst absoluteProxyUrl = (relativeOrAbsoluteUrl: string, baseUrl: string): string => {\n if (!relativeOrAbsoluteUrl || !isValidProxyUrl(relativeOrAbsoluteUrl) || !isProxyUrlRelative(relativeOrAbsoluteUrl)) {\n return relativeOrAbsoluteUrl;\n }\n return new URL(relativeOrAbsoluteUrl, baseUrl).toString();\n};\n\n// `apiUrl` and `apiVersion` are pinned at client construction time inside\n// `@clerk/backend`'s `createAuthenticateRequest` factory (build-time values\n// override runtime ones). The default singleton in `./clerkClient` is built\n// from env only, so passing these via `clerkMiddleware()` would be silently\n// ignored. When the caller hasn't supplied their own `clerkClient` but did\n// pass `apiUrl`/`apiVersion`, build a per-middleware client with those values.\nconst resolveDefaultClerkClient = (options: ClerkMiddlewareOptions) => {\n if (!options.apiUrl && !options.apiVersion) {\n return defaultClerkClient;\n }\n const env = { ...loadApiEnv(), ...loadClientEnv() };\n return createClerkClient({\n ...env,\n ...(options.apiUrl ? { apiUrl: options.apiUrl } : {}),\n ...(options.apiVersion ? { apiVersion: options.apiVersion } : {}),\n userAgent: `${PACKAGE_NAME}@${PACKAGE_VERSION}`,\n });\n};\n\nexport const authenticateAndDecorateRequest = (options: ClerkMiddlewareOptions = {}): RequestHandler => {\n const clerkClient = options.clerkClient || resolveDefaultClerkClient(options);\n\n // Extract proxy configuration\n const frontendApiProxy = options.frontendApiProxy;\n const proxyPath = stripTrailingSlashes(frontendApiProxy?.path ?? DEFAULT_PROXY_PATH) || DEFAULT_PROXY_PATH;\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n const middleware: RequestHandler = async (request, response, next) => {\n // Skip authentication only when a Clerk middleware has already processed\n // this request. The brand check matters: a truthy `req.auth` is not proof\n // of that, since express-jwt, passport and other libraries set the same\n // property, and treating their value as ours would silently disable Clerk\n // authentication.\n if (requestHasAuthObject(request)) {\n return next();\n }\n\n if ('auth' in request) {\n logger.warnOnce(\n 'Clerk: another middleware has already set `req.auth` on this request. Clerk authentication will run anyway and overwrite it. To use another auth library alongside Clerk, configure it to store its state on a different request property.',\n );\n }\n\n const env = { ...loadApiEnv(), ...loadClientEnv() };\n const publishableKey = options.publishableKey || env.publishableKey;\n const secretKey = options.secretKey || env.secretKey;\n\n // Handle Frontend API proxy requests early, before authentication\n if (frontendApiProxy) {\n const requestUrl = new URL(request.originalUrl || request.url, `http://${request.headers.host}`);\n const isEnabled =\n typeof frontendApiProxy.enabled === 'function'\n ? frontendApiProxy.enabled(requestUrl)\n : frontendApiProxy.enabled;\n\n if (isEnabled && (requestUrl.pathname === proxyPath || requestUrl.pathname.startsWith(proxyPath + '/'))) {\n // Convert Express request to Fetch API Request\n const proxyRequest = requestToProxyRequest(request);\n\n // Call the core proxy function\n const proxyResponse = await clerkFrontendApiProxy(proxyRequest, {\n proxyPath,\n publishableKey,\n secretKey,\n });\n\n // Send the proxy response back to the client\n response.status(proxyResponse.status);\n proxyResponse.headers.forEach((value, key) => {\n response.setHeader(key, value);\n });\n\n if (proxyResponse.body) {\n const reader = proxyResponse.body.getReader();\n const stream = new Readable({\n async read() {\n try {\n const { done, value } = await reader.read();\n if (done) {\n this.push(null);\n } else {\n this.push(Buffer.from(value));\n }\n } catch (error) {\n this.destroy(error instanceof Error ? error : new Error(String(error)));\n }\n },\n });\n stream.pipe(response);\n } else {\n response.end();\n }\n return;\n }\n }\n\n // Pass the proxy path to authenticateRequest - the backend resolves it\n // against the request's public origin (from x-forwarded-* headers).\n let resolvedOptions = options;\n if (frontendApiProxy && !options.proxyUrl) {\n const requestUrl = new URL(request.originalUrl || request.url, `http://${request.headers.host}`);\n const isProxyEnabled =\n typeof frontendApiProxy.enabled === 'function'\n ? frontendApiProxy.enabled(requestUrl)\n : frontendApiProxy.enabled;\n if (isProxyEnabled) {\n resolvedOptions = { ...options, proxyUrl: proxyPath };\n }\n }\n\n try {\n const requestState = await authenticateRequest({\n clerkClient,\n request,\n options: resolvedOptions,\n });\n\n const err = setResponseHeaders(requestState, response);\n if (err) {\n return next(err);\n }\n if (response.writableEnded) {\n return;\n }\n\n const auth = brandRequestAuth((opts: Parameters<typeof requestState.toAuth>[0]) => requestState.toAuth(opts));\n\n Object.assign(request, { auth });\n\n next();\n } catch (err) {\n next(err);\n }\n };\n\n return middleware;\n};\n","import type { RequestHandler } from 'express';\n\nimport { authenticateAndDecorateRequest } from './authenticateRequest';\nimport type { ClerkMiddlewareOptions, ClerkMiddlewareOptionsCallback } from './types';\n\n/**\n * Middleware that integrates Clerk authentication into your Express application.\n * It checks the request's cookies and headers for a session JWT and, if found,\n * attaches the Auth object to the request object under the `auth` key.\n *\n * Accepts either a static options object or a callback that receives the request\n * and returns options. The callback form is useful for multi-domain setups where\n * the publishable key differs per domain.\n *\n * @example\n * app.use(clerkMiddleware(options));\n *\n * @example\n * const clerkClient = createClerkClient({ ... });\n * app.use(clerkMiddleware({ clerkClient }));\n *\n * @example\n * app.use(clerkMiddleware());\n *\n * @example\n * // Dynamic keys per domain\n * app.use(clerkMiddleware((req) => ({\n * publishableKey: req.hostname === 'example.com' ? PK_A : PK_B,\n * })));\n */\nexport const clerkMiddleware = (\n options: ClerkMiddlewareOptions | ClerkMiddlewareOptionsCallback = {},\n): RequestHandler => {\n if (typeof options !== 'function') {\n const authMiddleware = authenticateAndDecorateRequest({\n ...options,\n acceptsToken: 'any',\n });\n return (request, response, next) => {\n authMiddleware(request, response, next);\n };\n }\n\n return async (request, response, next) => {\n try {\n const resolvedOptions = await options(request);\n const handler = authenticateAndDecorateRequest({\n ...resolvedOptions,\n acceptsToken: 'any',\n });\n handler(request, response, next);\n } catch (err) {\n next(err);\n }\n };\n};\n","import type { AuthOptions, GetAuthFn } from '@clerk/backend/internal';\nimport { getAuthObjectForAcceptedToken } from '@clerk/backend/internal';\nimport type { Request as ExpressRequest } from 'express';\n\nimport { middlewareRequired } from './errors';\nimport { requestHasAuthObject } from './utils';\n\n/**\n * Retrieves the Clerk AuthObject using the current request object.\n *\n * @param {GetAuthOptions} options - Optional configuration for retrieving auth object.\n * @returns {AuthObject} Object with information about the request state and claims.\n * @throws {Error} `clerkMiddleware` or `requireAuth` is required to be set in the middleware chain before this util is used.\n */\nexport const getAuth: GetAuthFn<ExpressRequest> = ((req: ExpressRequest, options?: AuthOptions) => {\n if (!requestHasAuthObject(req)) {\n throw new Error(middlewareRequired('getAuth'));\n }\n\n const authObject = req.auth(options);\n\n return getAuthObjectForAcceptedToken({ authObject, acceptsToken: options?.acceptsToken });\n}) as GetAuthFn<ExpressRequest>;\n","import { deprecated } from '@clerk/shared/deprecated';\nimport type { RequestHandler } from 'express';\n\nimport { authenticateAndDecorateRequest } from './authenticateRequest';\nimport type { ClerkMiddlewareOptions, ExpressRequestWithAuth } from './types';\n\n/**\n * Middleware to require authentication for user requests.\n * Redirects unauthenticated requests to the sign-in url.\n *\n * @deprecated Use `clerkMiddleware()` with `getAuth()` instead.\n * `requireAuth` will be removed in the next major version.\n *\n * @example\n * // Before (deprecated)\n * import { requireAuth } from '@clerk/express'\n * router.get('/path', requireAuth(), getHandler)\n *\n * @example\n * // After (recommended)\n * import { clerkMiddleware, getAuth } from '@clerk/express'\n *\n * app.use(clerkMiddleware())\n *\n * app.get('/api/protected', (req, res) => {\n * const { userId } = getAuth(req);\n * if (!userId) {\n * return res.status(401).json({ error: 'Unauthorized' });\n * }\n * // handle authenticated request\n * })\n */\nexport const requireAuth = (options: ClerkMiddlewareOptions = {}): RequestHandler => {\n const authMiddleware = authenticateAndDecorateRequest({\n ...options,\n acceptsToken: 'any',\n });\n\n return (request, response, next) => {\n deprecated(\n 'requireAuth',\n 'Use `clerkMiddleware()` with `getAuth()` instead. `requireAuth` will be removed in the next major version.',\n );\n\n authMiddleware(request, response, err => {\n if (err) {\n return next(err);\n }\n\n const signInUrl = options.signInUrl || process.env.CLERK_SIGN_IN_URL || '/';\n\n if (!(request as ExpressRequestWithAuth).auth()?.userId) {\n return response.redirect(signInUrl);\n }\n\n next();\n });\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["loadApiEnv","loadClientEnv","incomingMessageToRequest","loadApiEnv","loadClientEnv","AuthStatus","defaultClerkClient","DEFAULT_PROXY_PATH","requestHasAuthObject","requestToProxyRequest","Readable","brandRequestAuth","requestHasAuthObject"],"sources":["../src/clerkClient.ts","../src/errors.ts","../src/authenticateRequest.ts","../src/clerkMiddleware.ts","../src/getAuth.ts","../src/requireAuth.ts"],"sourcesContent":["import type { ClerkClient } from '@clerk/backend';\nimport { createClerkClient } from '@clerk/backend';\n\nimport { loadApiEnv, loadClientEnv } from './utils';\n\nlet clerkClientSingleton = {} as unknown as ClerkClient;\n\nexport const clerkClient = new Proxy(clerkClientSingleton, {\n get(_target, property: keyof ClerkClient) {\n if (property in clerkClientSingleton) {\n return clerkClientSingleton[property];\n }\n\n const env = { ...loadApiEnv(), ...loadClientEnv() };\n const client = createClerkClient({ ...env, userAgent: `${PACKAGE_NAME}@${PACKAGE_VERSION}` });\n\n // if the client is initialized properly, cache it to a singleton instance variable\n // in the next invocation the guard at the top will be triggered instead of creating another instance\n if (env.secretKey) {\n clerkClientSingleton = client;\n }\n\n return client[property];\n },\n set() {\n return false;\n },\n});\n","const createErrorMessage = (msg: string) => {\n return `🔒 Clerk: ${msg.trim()}\n\n For more info, check out the docs: https://clerk.com/docs,\n or come say hi in our discord server: https://clerk.com/discord\n `;\n};\n\nexport const middlewareRequired = (fnName: string) =>\n createErrorMessage(`The \"clerkMiddleware\" should be registered before using \"${fnName}\".\nExample:\n\nimport express from 'express';\nimport { clerkMiddleware } from '@clerk/express';\n\nconst app = express();\napp.use(clerkMiddleware());\n`);\n\nexport const satelliteAndMissingProxyUrlAndDomain =\n 'Missing domain and proxyUrl. A satellite application needs to specify a domain or a proxyUrl';\nexport const satelliteAndMissingSignInUrl = `\nInvalid signInUrl. A satellite application requires a signInUrl for development instances.\nCheck if signInUrl is missing from your configuration or if it is not an absolute URL.`;\n","import { createClerkClient } from '@clerk/backend';\nimport type { ClerkRequest, RequestState } from '@clerk/backend/internal';\nimport { AuthStatus, createClerkRequest } from '@clerk/backend/internal';\nimport { clerkFrontendApiProxy, DEFAULT_PROXY_PATH, stripTrailingSlashes } from '@clerk/backend/proxy';\nimport { isDevelopmentFromSecretKey } from '@clerk/shared/keys';\nimport { logger } from '@clerk/shared/logger';\nimport { isHttpOrHttps, isProxyUrlRelative, isValidProxyUrl } from '@clerk/shared/proxy';\nimport { handleValueOrFn } from '@clerk/shared/utils';\nimport type { RequestHandler, Response } from 'express';\nimport { Readable } from 'stream';\n\nimport { clerkClient as defaultClerkClient } from './clerkClient';\nimport { satelliteAndMissingProxyUrlAndDomain, satelliteAndMissingSignInUrl } from './errors';\nimport type { AuthenticateRequestParams, ClerkMiddlewareOptions } from './types';\nimport {\n brandRequestAuth,\n incomingMessageToRequest,\n loadApiEnv,\n loadClientEnv,\n requestHasAuthObject,\n requestToProxyRequest,\n} from './utils';\n\n/**\n * @internal\n * Authenticates an Express request by wrapping clerkClient.authenticateRequest and\n * converts the express request object into a standard web request object\n *\n * @param opts - Configuration options for request authentication\n * @param opts.clerkClient - The Clerk client instance to use for authentication\n * @param opts.request - The Express request object to authenticate\n * @param opts.options - Optional middleware configuration options\n */\nexport const authenticateRequest = (opts: AuthenticateRequestParams) => {\n const { clerkClient, request, options } = opts;\n // Peel off middleware-only keys and the few options that need middleware-side\n // resolution (env fallbacks, URL normalization). Everything else is spread\n // straight through, so new AuthenticateRequestOptions/VerifyTokenOptions\n // fields flow to the backend without another code change here.\n const {\n clerkClient: _clerkClient,\n debug: _debug,\n frontendApiProxy: _frontendApiProxy,\n isSatellite: isSatelliteInput,\n domain: domainInput,\n signInUrl: signInUrlInput,\n proxyUrl: proxyUrlInput,\n secretKey: secretKeyInput,\n machineSecretKey: machineSecretKeyInput,\n publishableKey: publishableKeyInput,\n ...restOptions\n } = options || {};\n\n const clerkRequest = opts.clerkRequest ?? createClerkRequest(incomingMessageToRequest(request));\n const env = { ...loadApiEnv(), ...loadClientEnv() };\n\n const secretKey = secretKeyInput || env.secretKey;\n const machineSecretKey = machineSecretKeyInput || env.machineSecretKey;\n const publishableKey = publishableKeyInput || env.publishableKey;\n\n const isSatellite = handleValueOrFn(isSatelliteInput, clerkRequest.clerkUrl, env.isSatellite);\n const domain = handleValueOrFn(domainInput, clerkRequest.clerkUrl) || env.domain;\n const signInUrl = signInUrlInput || env.signInUrl;\n const proxyUrl = absoluteProxyUrl(\n handleValueOrFn(proxyUrlInput, clerkRequest.clerkUrl, env.proxyUrl),\n clerkRequest.clerkUrl.toString(),\n );\n\n if (isSatellite && !proxyUrl && !domain) {\n throw new Error(satelliteAndMissingProxyUrlAndDomain);\n }\n\n if (isSatellite && !isHttpOrHttps(signInUrl) && isDevelopmentFromSecretKey(secretKey || '')) {\n throw new Error(satelliteAndMissingSignInUrl);\n }\n\n return clerkClient.authenticateRequest(clerkRequest, {\n ...restOptions,\n secretKey,\n machineSecretKey,\n publishableKey,\n proxyUrl,\n isSatellite,\n domain,\n signInUrl,\n });\n};\n\nconst setResponseHeaders = (requestState: RequestState, res: Response): Error | undefined => {\n if (requestState.headers) {\n requestState.headers.forEach((value, key) => res.appendHeader(key, value));\n }\n return setResponseForHandshake(requestState, res);\n};\n\n/**\n * Depending on the auth state of the request, handles applying redirects and validating that a handshake state was properly handled.\n *\n * Returns an error if state is handshake without a redirect, otherwise returns undefined. res.writableEnded should be checked after this method is called.\n */\nconst setResponseForHandshake = (requestState: RequestState, res: Response): Error | undefined => {\n const hasLocationHeader = requestState.headers.get('location');\n if (hasLocationHeader) {\n // triggering a handshake redirect\n res.status(307).end();\n return;\n }\n\n if (requestState.status === AuthStatus.Handshake) {\n return new Error('Clerk: unexpected handshake without redirect');\n }\n\n return;\n};\n\nconst absoluteProxyUrl = (relativeOrAbsoluteUrl: string, baseUrl: string): string => {\n if (!relativeOrAbsoluteUrl || !isValidProxyUrl(relativeOrAbsoluteUrl) || !isProxyUrlRelative(relativeOrAbsoluteUrl)) {\n return relativeOrAbsoluteUrl;\n }\n return new URL(relativeOrAbsoluteUrl, baseUrl).toString();\n};\n\n// `apiUrl` and `apiVersion` are pinned at client construction time inside\n// `@clerk/backend`'s `createAuthenticateRequest` factory (build-time values\n// override runtime ones). The default singleton in `./clerkClient` is built\n// from env only, so passing these via `clerkMiddleware()` would be silently\n// ignored. When the caller hasn't supplied their own `clerkClient` but did\n// pass `apiUrl`/`apiVersion`, build a per-middleware client with those values.\nconst resolveDefaultClerkClient = (options: ClerkMiddlewareOptions) => {\n if (!options.apiUrl && !options.apiVersion) {\n return defaultClerkClient;\n }\n const env = { ...loadApiEnv(), ...loadClientEnv() };\n return createClerkClient({\n ...env,\n ...(options.apiUrl ? { apiUrl: options.apiUrl } : {}),\n ...(options.apiVersion ? { apiVersion: options.apiVersion } : {}),\n userAgent: `${PACKAGE_NAME}@${PACKAGE_VERSION}`,\n });\n};\n\nexport const authenticateAndDecorateRequest = (options: ClerkMiddlewareOptions = {}): RequestHandler => {\n const clerkClient = options.clerkClient || resolveDefaultClerkClient(options);\n\n // Extract proxy configuration\n const frontendApiProxy = options.frontendApiProxy;\n const proxyPath = stripTrailingSlashes(frontendApiProxy?.path ?? DEFAULT_PROXY_PATH) || DEFAULT_PROXY_PATH;\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n const middleware: RequestHandler = async (request, response, next) => {\n // Skip authentication only when a Clerk middleware has already processed\n // this request. The brand check matters: a truthy `req.auth` is not proof\n // of that, since express-jwt, passport and other libraries set the same\n // property, and treating their value as ours would silently disable Clerk\n // authentication.\n if (requestHasAuthObject(request)) {\n return next();\n }\n\n if ('auth' in request) {\n logger.warnOnce(\n 'Clerk: another middleware has already set `req.auth` on this request. Clerk authentication will run anyway and overwrite it. To use another auth library alongside Clerk, configure it to store its state on a different request property.',\n );\n }\n\n // Node accepts request targets/methods (`//`, TRACE) the fetch spec cannot represent; reject those instead of 500ing.\n let clerkRequest: ClerkRequest;\n try {\n clerkRequest = createClerkRequest(incomingMessageToRequest(request));\n } catch {\n response.status(400).end();\n return;\n }\n\n const env = { ...loadApiEnv(), ...loadClientEnv() };\n const publishableKey = options.publishableKey || env.publishableKey;\n const secretKey = options.secretKey || env.secretKey;\n\n // Handle Frontend API proxy requests early, before authentication\n if (frontendApiProxy) {\n let requestUrl: URL;\n try {\n requestUrl = new URL(request.originalUrl || request.url, `http://${request.headers.host}`);\n } catch {\n response.status(400).end();\n return;\n }\n const isEnabled =\n typeof frontendApiProxy.enabled === 'function'\n ? frontendApiProxy.enabled(requestUrl)\n : frontendApiProxy.enabled;\n\n if (isEnabled && (requestUrl.pathname === proxyPath || requestUrl.pathname.startsWith(proxyPath + '/'))) {\n // Convert Express request to Fetch API Request\n let proxyRequest: Request;\n try {\n proxyRequest = requestToProxyRequest(request);\n } catch {\n response.status(400).end();\n return;\n }\n\n // Call the core proxy function\n const proxyResponse = await clerkFrontendApiProxy(proxyRequest, {\n proxyPath,\n publishableKey,\n secretKey,\n });\n\n // Send the proxy response back to the client\n response.status(proxyResponse.status);\n proxyResponse.headers.forEach((value, key) => {\n response.setHeader(key, value);\n });\n\n if (proxyResponse.body) {\n const reader = proxyResponse.body.getReader();\n const stream = new Readable({\n async read() {\n try {\n const { done, value } = await reader.read();\n if (done) {\n this.push(null);\n } else {\n this.push(Buffer.from(value));\n }\n } catch (error) {\n this.destroy(error instanceof Error ? error : new Error(String(error)));\n }\n },\n });\n stream.pipe(response);\n } else {\n response.end();\n }\n return;\n }\n }\n\n // Pass the proxy path to authenticateRequest - the backend resolves it\n // against the request's public origin (from x-forwarded-* headers).\n let resolvedOptions = options;\n if (frontendApiProxy && !options.proxyUrl) {\n let requestUrl: URL;\n try {\n requestUrl = new URL(request.originalUrl || request.url, `http://${request.headers.host}`);\n } catch {\n response.status(400).end();\n return;\n }\n const isProxyEnabled =\n typeof frontendApiProxy.enabled === 'function'\n ? frontendApiProxy.enabled(requestUrl)\n : frontendApiProxy.enabled;\n if (isProxyEnabled) {\n resolvedOptions = { ...options, proxyUrl: proxyPath };\n }\n }\n\n try {\n const requestState = await authenticateRequest({\n clerkClient,\n request,\n options: resolvedOptions,\n clerkRequest,\n });\n\n const err = setResponseHeaders(requestState, response);\n if (err) {\n return next(err);\n }\n if (response.writableEnded) {\n return;\n }\n\n const auth = brandRequestAuth((opts: Parameters<typeof requestState.toAuth>[0]) => requestState.toAuth(opts));\n\n Object.assign(request, { auth });\n\n next();\n } catch (err) {\n next(err);\n }\n };\n\n return middleware;\n};\n","import type { RequestHandler } from 'express';\n\nimport { authenticateAndDecorateRequest } from './authenticateRequest';\nimport type { ClerkMiddlewareOptions, ClerkMiddlewareOptionsCallback } from './types';\n\n/**\n * Middleware that integrates Clerk authentication into your Express application.\n * It checks the request's cookies and headers for a session JWT and, if found,\n * attaches the Auth object to the request object under the `auth` key.\n *\n * Accepts either a static options object or a callback that receives the request\n * and returns options. The callback form is useful for multi-domain setups where\n * the publishable key differs per domain.\n *\n * @example\n * app.use(clerkMiddleware(options));\n *\n * @example\n * const clerkClient = createClerkClient({ ... });\n * app.use(clerkMiddleware({ clerkClient }));\n *\n * @example\n * app.use(clerkMiddleware());\n *\n * @example\n * // Dynamic keys per domain\n * app.use(clerkMiddleware((req) => ({\n * publishableKey: req.hostname === 'example.com' ? PK_A : PK_B,\n * })));\n */\nexport const clerkMiddleware = (\n options: ClerkMiddlewareOptions | ClerkMiddlewareOptionsCallback = {},\n): RequestHandler => {\n if (typeof options !== 'function') {\n const authMiddleware = authenticateAndDecorateRequest({\n ...options,\n acceptsToken: 'any',\n });\n return (request, response, next) => {\n authMiddleware(request, response, next);\n };\n }\n\n return async (request, response, next) => {\n try {\n const resolvedOptions = await options(request);\n const handler = authenticateAndDecorateRequest({\n ...resolvedOptions,\n acceptsToken: 'any',\n });\n handler(request, response, next);\n } catch (err) {\n next(err);\n }\n };\n};\n","import type { AuthOptions, GetAuthFn } from '@clerk/backend/internal';\nimport { getAuthObjectForAcceptedToken } from '@clerk/backend/internal';\nimport type { Request as ExpressRequest } from 'express';\n\nimport { middlewareRequired } from './errors';\nimport { requestHasAuthObject } from './utils';\n\n/**\n * Retrieves the Clerk AuthObject using the current request object.\n *\n * @param {GetAuthOptions} options - Optional configuration for retrieving auth object.\n * @returns {AuthObject} Object with information about the request state and claims.\n * @throws {Error} `clerkMiddleware` or `requireAuth` is required to be set in the middleware chain before this util is used.\n */\nexport const getAuth: GetAuthFn<ExpressRequest> = ((req: ExpressRequest, options?: AuthOptions) => {\n if (!requestHasAuthObject(req)) {\n throw new Error(middlewareRequired('getAuth'));\n }\n\n const authObject = req.auth(options);\n\n return getAuthObjectForAcceptedToken({ authObject, acceptsToken: options?.acceptsToken });\n}) as GetAuthFn<ExpressRequest>;\n","import { deprecated } from '@clerk/shared/deprecated';\nimport type { RequestHandler } from 'express';\n\nimport { authenticateAndDecorateRequest } from './authenticateRequest';\nimport type { ClerkMiddlewareOptions, ExpressRequestWithAuth } from './types';\n\n/**\n * Middleware to require authentication for user requests.\n * Redirects unauthenticated requests to the sign-in url.\n *\n * @deprecated Use `clerkMiddleware()` with `getAuth()` instead.\n * `requireAuth` will be removed in the next major version.\n *\n * @example\n * // Before (deprecated)\n * import { requireAuth } from '@clerk/express'\n * router.get('/path', requireAuth(), getHandler)\n *\n * @example\n * // After (recommended)\n * import { clerkMiddleware, getAuth } from '@clerk/express'\n *\n * app.use(clerkMiddleware())\n *\n * app.get('/api/protected', (req, res) => {\n * const { userId } = getAuth(req);\n * if (!userId) {\n * return res.status(401).json({ error: 'Unauthorized' });\n * }\n * // handle authenticated request\n * })\n */\nexport const requireAuth = (options: ClerkMiddlewareOptions = {}): RequestHandler => {\n const authMiddleware = authenticateAndDecorateRequest({\n ...options,\n acceptsToken: 'any',\n });\n\n return (request, response, next) => {\n deprecated(\n 'requireAuth',\n 'Use `clerkMiddleware()` with `getAuth()` instead. `requireAuth` will be removed in the next major version.',\n );\n\n authMiddleware(request, response, err => {\n if (err) {\n return next(err);\n }\n\n const signInUrl = options.signInUrl || process.env.CLERK_SIGN_IN_URL || '/';\n\n if (!(request as ExpressRequestWithAuth).auth()?.userId) {\n return response.redirect(signInUrl);\n }\n\n next();\n });\n };\n};\n"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as requestHasAuthObject, i as loadClientEnv, n as incomingMessageToRequest, o as requestToProxyRequest, r as loadApiEnv, t as brandRequestAuth } from "./utils-CW7I2k9m.mjs";
1
+ import { a as requestHasAuthObject, i as loadClientEnv, n as incomingMessageToRequest, o as requestToProxyRequest, r as loadApiEnv, t as brandRequestAuth } from "./utils-DnpNAWof.mjs";
2
2
  import { createClerkClient } from "@clerk/backend";
3
3
  import { Readable } from "stream";
4
4
  import { AuthStatus, createClerkRequest, getAuthObjectForAcceptedToken } from "@clerk/backend/internal";
@@ -22,7 +22,7 @@ const clerkClient = new Proxy(clerkClientSingleton, {
22
22
  };
23
23
  const client = createClerkClient({
24
24
  ...env,
25
- userAgent: `@clerk/express@2.1.49`
25
+ userAgent: `@clerk/express@2.1.50-canary.v20260731161424`
26
26
  });
27
27
  if (env.secretKey) clerkClientSingleton = client;
28
28
  return client[property];
@@ -70,7 +70,7 @@ Check if signInUrl is missing from your configuration or if it is not an absolut
70
70
  const authenticateRequest = (opts) => {
71
71
  const { clerkClient, request, options } = opts;
72
72
  const { clerkClient: _clerkClient, debug: _debug, frontendApiProxy: _frontendApiProxy, isSatellite: isSatelliteInput, domain: domainInput, signInUrl: signInUrlInput, proxyUrl: proxyUrlInput, secretKey: secretKeyInput, machineSecretKey: machineSecretKeyInput, publishableKey: publishableKeyInput, ...restOptions } = options || {};
73
- const clerkRequest = createClerkRequest(incomingMessageToRequest(request));
73
+ const clerkRequest = opts.clerkRequest ?? createClerkRequest(incomingMessageToRequest(request));
74
74
  const env = {
75
75
  ...loadApiEnv(),
76
76
  ...loadClientEnv()
@@ -122,7 +122,7 @@ const resolveDefaultClerkClient = (options) => {
122
122
  ...loadClientEnv(),
123
123
  ...options.apiUrl ? { apiUrl: options.apiUrl } : {},
124
124
  ...options.apiVersion ? { apiVersion: options.apiVersion } : {},
125
- userAgent: `@clerk/express@2.1.49`
125
+ userAgent: `@clerk/express@2.1.50-canary.v20260731161424`
126
126
  });
127
127
  };
128
128
  const authenticateAndDecorateRequest = (options = {}) => {
@@ -132,6 +132,13 @@ const authenticateAndDecorateRequest = (options = {}) => {
132
132
  const middleware = async (request, response, next) => {
133
133
  if (requestHasAuthObject(request)) return next();
134
134
  if ("auth" in request) logger.warnOnce("Clerk: another middleware has already set `req.auth` on this request. Clerk authentication will run anyway and overwrite it. To use another auth library alongside Clerk, configure it to store its state on a different request property.");
135
+ let clerkRequest;
136
+ try {
137
+ clerkRequest = createClerkRequest(incomingMessageToRequest(request));
138
+ } catch {
139
+ response.status(400).end();
140
+ return;
141
+ }
135
142
  const env = {
136
143
  ...loadApiEnv(),
137
144
  ...loadClientEnv()
@@ -139,9 +146,22 @@ const authenticateAndDecorateRequest = (options = {}) => {
139
146
  const publishableKey = options.publishableKey || env.publishableKey;
140
147
  const secretKey = options.secretKey || env.secretKey;
141
148
  if (frontendApiProxy) {
142
- const requestUrl = new URL(request.originalUrl || request.url, `http://${request.headers.host}`);
149
+ let requestUrl;
150
+ try {
151
+ requestUrl = new URL(request.originalUrl || request.url, `http://${request.headers.host}`);
152
+ } catch {
153
+ response.status(400).end();
154
+ return;
155
+ }
143
156
  if ((typeof frontendApiProxy.enabled === "function" ? frontendApiProxy.enabled(requestUrl) : frontendApiProxy.enabled) && (requestUrl.pathname === proxyPath || requestUrl.pathname.startsWith(proxyPath + "/"))) {
144
- const proxyResponse = await clerkFrontendApiProxy(requestToProxyRequest(request), {
157
+ let proxyRequest;
158
+ try {
159
+ proxyRequest = requestToProxyRequest(request);
160
+ } catch {
161
+ response.status(400).end();
162
+ return;
163
+ }
164
+ const proxyResponse = await clerkFrontendApiProxy(proxyRequest, {
145
165
  proxyPath,
146
166
  publishableKey,
147
167
  secretKey
@@ -167,7 +187,13 @@ const authenticateAndDecorateRequest = (options = {}) => {
167
187
  }
168
188
  let resolvedOptions = options;
169
189
  if (frontendApiProxy && !options.proxyUrl) {
170
- const requestUrl = new URL(request.originalUrl || request.url, `http://${request.headers.host}`);
190
+ let requestUrl;
191
+ try {
192
+ requestUrl = new URL(request.originalUrl || request.url, `http://${request.headers.host}`);
193
+ } catch {
194
+ response.status(400).end();
195
+ return;
196
+ }
171
197
  if (typeof frontendApiProxy.enabled === "function" ? frontendApiProxy.enabled(requestUrl) : frontendApiProxy.enabled) resolvedOptions = {
172
198
  ...options,
173
199
  proxyUrl: proxyPath
@@ -177,7 +203,8 @@ const authenticateAndDecorateRequest = (options = {}) => {
177
203
  const requestState = await authenticateRequest({
178
204
  clerkClient,
179
205
  request,
180
- options: resolvedOptions
206
+ options: resolvedOptions,
207
+ clerkRequest
181
208
  });
182
209
  const err = setResponseHeaders(requestState, response);
183
210
  if (err) return next(err);
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["defaultClerkClient"],"sources":["../src/clerkClient.ts","../src/errors.ts","../src/authenticateRequest.ts","../src/clerkMiddleware.ts","../src/getAuth.ts","../src/requireAuth.ts"],"sourcesContent":["import type { ClerkClient } from '@clerk/backend';\nimport { createClerkClient } from '@clerk/backend';\n\nimport { loadApiEnv, loadClientEnv } from './utils';\n\nlet clerkClientSingleton = {} as unknown as ClerkClient;\n\nexport const clerkClient = new Proxy(clerkClientSingleton, {\n get(_target, property: keyof ClerkClient) {\n if (property in clerkClientSingleton) {\n return clerkClientSingleton[property];\n }\n\n const env = { ...loadApiEnv(), ...loadClientEnv() };\n const client = createClerkClient({ ...env, userAgent: `${PACKAGE_NAME}@${PACKAGE_VERSION}` });\n\n // if the client is initialized properly, cache it to a singleton instance variable\n // in the next invocation the guard at the top will be triggered instead of creating another instance\n if (env.secretKey) {\n clerkClientSingleton = client;\n }\n\n return client[property];\n },\n set() {\n return false;\n },\n});\n","const createErrorMessage = (msg: string) => {\n return `🔒 Clerk: ${msg.trim()}\n\n For more info, check out the docs: https://clerk.com/docs,\n or come say hi in our discord server: https://clerk.com/discord\n `;\n};\n\nexport const middlewareRequired = (fnName: string) =>\n createErrorMessage(`The \"clerkMiddleware\" should be registered before using \"${fnName}\".\nExample:\n\nimport express from 'express';\nimport { clerkMiddleware } from '@clerk/express';\n\nconst app = express();\napp.use(clerkMiddleware());\n`);\n\nexport const satelliteAndMissingProxyUrlAndDomain =\n 'Missing domain and proxyUrl. A satellite application needs to specify a domain or a proxyUrl';\nexport const satelliteAndMissingSignInUrl = `\nInvalid signInUrl. A satellite application requires a signInUrl for development instances.\nCheck if signInUrl is missing from your configuration or if it is not an absolute URL.`;\n","import { createClerkClient } from '@clerk/backend';\nimport type { RequestState } from '@clerk/backend/internal';\nimport { AuthStatus, createClerkRequest } from '@clerk/backend/internal';\nimport { clerkFrontendApiProxy, DEFAULT_PROXY_PATH, stripTrailingSlashes } from '@clerk/backend/proxy';\nimport { isDevelopmentFromSecretKey } from '@clerk/shared/keys';\nimport { logger } from '@clerk/shared/logger';\nimport { isHttpOrHttps, isProxyUrlRelative, isValidProxyUrl } from '@clerk/shared/proxy';\nimport { handleValueOrFn } from '@clerk/shared/utils';\nimport type { RequestHandler, Response } from 'express';\nimport { Readable } from 'stream';\n\nimport { clerkClient as defaultClerkClient } from './clerkClient';\nimport { satelliteAndMissingProxyUrlAndDomain, satelliteAndMissingSignInUrl } from './errors';\nimport type { AuthenticateRequestParams, ClerkMiddlewareOptions } from './types';\nimport {\n brandRequestAuth,\n incomingMessageToRequest,\n loadApiEnv,\n loadClientEnv,\n requestHasAuthObject,\n requestToProxyRequest,\n} from './utils';\n\n/**\n * @internal\n * Authenticates an Express request by wrapping clerkClient.authenticateRequest and\n * converts the express request object into a standard web request object\n *\n * @param opts - Configuration options for request authentication\n * @param opts.clerkClient - The Clerk client instance to use for authentication\n * @param opts.request - The Express request object to authenticate\n * @param opts.options - Optional middleware configuration options\n */\nexport const authenticateRequest = (opts: AuthenticateRequestParams) => {\n const { clerkClient, request, options } = opts;\n // Peel off middleware-only keys and the few options that need middleware-side\n // resolution (env fallbacks, URL normalization). Everything else is spread\n // straight through, so new AuthenticateRequestOptions/VerifyTokenOptions\n // fields flow to the backend without another code change here.\n const {\n clerkClient: _clerkClient,\n debug: _debug,\n frontendApiProxy: _frontendApiProxy,\n isSatellite: isSatelliteInput,\n domain: domainInput,\n signInUrl: signInUrlInput,\n proxyUrl: proxyUrlInput,\n secretKey: secretKeyInput,\n machineSecretKey: machineSecretKeyInput,\n publishableKey: publishableKeyInput,\n ...restOptions\n } = options || {};\n\n const clerkRequest = createClerkRequest(incomingMessageToRequest(request));\n const env = { ...loadApiEnv(), ...loadClientEnv() };\n\n const secretKey = secretKeyInput || env.secretKey;\n const machineSecretKey = machineSecretKeyInput || env.machineSecretKey;\n const publishableKey = publishableKeyInput || env.publishableKey;\n\n const isSatellite = handleValueOrFn(isSatelliteInput, clerkRequest.clerkUrl, env.isSatellite);\n const domain = handleValueOrFn(domainInput, clerkRequest.clerkUrl) || env.domain;\n const signInUrl = signInUrlInput || env.signInUrl;\n const proxyUrl = absoluteProxyUrl(\n handleValueOrFn(proxyUrlInput, clerkRequest.clerkUrl, env.proxyUrl),\n clerkRequest.clerkUrl.toString(),\n );\n\n if (isSatellite && !proxyUrl && !domain) {\n throw new Error(satelliteAndMissingProxyUrlAndDomain);\n }\n\n if (isSatellite && !isHttpOrHttps(signInUrl) && isDevelopmentFromSecretKey(secretKey || '')) {\n throw new Error(satelliteAndMissingSignInUrl);\n }\n\n return clerkClient.authenticateRequest(clerkRequest, {\n ...restOptions,\n secretKey,\n machineSecretKey,\n publishableKey,\n proxyUrl,\n isSatellite,\n domain,\n signInUrl,\n });\n};\n\nconst setResponseHeaders = (requestState: RequestState, res: Response): Error | undefined => {\n if (requestState.headers) {\n requestState.headers.forEach((value, key) => res.appendHeader(key, value));\n }\n return setResponseForHandshake(requestState, res);\n};\n\n/**\n * Depending on the auth state of the request, handles applying redirects and validating that a handshake state was properly handled.\n *\n * Returns an error if state is handshake without a redirect, otherwise returns undefined. res.writableEnded should be checked after this method is called.\n */\nconst setResponseForHandshake = (requestState: RequestState, res: Response): Error | undefined => {\n const hasLocationHeader = requestState.headers.get('location');\n if (hasLocationHeader) {\n // triggering a handshake redirect\n res.status(307).end();\n return;\n }\n\n if (requestState.status === AuthStatus.Handshake) {\n return new Error('Clerk: unexpected handshake without redirect');\n }\n\n return;\n};\n\nconst absoluteProxyUrl = (relativeOrAbsoluteUrl: string, baseUrl: string): string => {\n if (!relativeOrAbsoluteUrl || !isValidProxyUrl(relativeOrAbsoluteUrl) || !isProxyUrlRelative(relativeOrAbsoluteUrl)) {\n return relativeOrAbsoluteUrl;\n }\n return new URL(relativeOrAbsoluteUrl, baseUrl).toString();\n};\n\n// `apiUrl` and `apiVersion` are pinned at client construction time inside\n// `@clerk/backend`'s `createAuthenticateRequest` factory (build-time values\n// override runtime ones). The default singleton in `./clerkClient` is built\n// from env only, so passing these via `clerkMiddleware()` would be silently\n// ignored. When the caller hasn't supplied their own `clerkClient` but did\n// pass `apiUrl`/`apiVersion`, build a per-middleware client with those values.\nconst resolveDefaultClerkClient = (options: ClerkMiddlewareOptions) => {\n if (!options.apiUrl && !options.apiVersion) {\n return defaultClerkClient;\n }\n const env = { ...loadApiEnv(), ...loadClientEnv() };\n return createClerkClient({\n ...env,\n ...(options.apiUrl ? { apiUrl: options.apiUrl } : {}),\n ...(options.apiVersion ? { apiVersion: options.apiVersion } : {}),\n userAgent: `${PACKAGE_NAME}@${PACKAGE_VERSION}`,\n });\n};\n\nexport const authenticateAndDecorateRequest = (options: ClerkMiddlewareOptions = {}): RequestHandler => {\n const clerkClient = options.clerkClient || resolveDefaultClerkClient(options);\n\n // Extract proxy configuration\n const frontendApiProxy = options.frontendApiProxy;\n const proxyPath = stripTrailingSlashes(frontendApiProxy?.path ?? DEFAULT_PROXY_PATH) || DEFAULT_PROXY_PATH;\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n const middleware: RequestHandler = async (request, response, next) => {\n // Skip authentication only when a Clerk middleware has already processed\n // this request. The brand check matters: a truthy `req.auth` is not proof\n // of that, since express-jwt, passport and other libraries set the same\n // property, and treating their value as ours would silently disable Clerk\n // authentication.\n if (requestHasAuthObject(request)) {\n return next();\n }\n\n if ('auth' in request) {\n logger.warnOnce(\n 'Clerk: another middleware has already set `req.auth` on this request. Clerk authentication will run anyway and overwrite it. To use another auth library alongside Clerk, configure it to store its state on a different request property.',\n );\n }\n\n const env = { ...loadApiEnv(), ...loadClientEnv() };\n const publishableKey = options.publishableKey || env.publishableKey;\n const secretKey = options.secretKey || env.secretKey;\n\n // Handle Frontend API proxy requests early, before authentication\n if (frontendApiProxy) {\n const requestUrl = new URL(request.originalUrl || request.url, `http://${request.headers.host}`);\n const isEnabled =\n typeof frontendApiProxy.enabled === 'function'\n ? frontendApiProxy.enabled(requestUrl)\n : frontendApiProxy.enabled;\n\n if (isEnabled && (requestUrl.pathname === proxyPath || requestUrl.pathname.startsWith(proxyPath + '/'))) {\n // Convert Express request to Fetch API Request\n const proxyRequest = requestToProxyRequest(request);\n\n // Call the core proxy function\n const proxyResponse = await clerkFrontendApiProxy(proxyRequest, {\n proxyPath,\n publishableKey,\n secretKey,\n });\n\n // Send the proxy response back to the client\n response.status(proxyResponse.status);\n proxyResponse.headers.forEach((value, key) => {\n response.setHeader(key, value);\n });\n\n if (proxyResponse.body) {\n const reader = proxyResponse.body.getReader();\n const stream = new Readable({\n async read() {\n try {\n const { done, value } = await reader.read();\n if (done) {\n this.push(null);\n } else {\n this.push(Buffer.from(value));\n }\n } catch (error) {\n this.destroy(error instanceof Error ? error : new Error(String(error)));\n }\n },\n });\n stream.pipe(response);\n } else {\n response.end();\n }\n return;\n }\n }\n\n // Pass the proxy path to authenticateRequest - the backend resolves it\n // against the request's public origin (from x-forwarded-* headers).\n let resolvedOptions = options;\n if (frontendApiProxy && !options.proxyUrl) {\n const requestUrl = new URL(request.originalUrl || request.url, `http://${request.headers.host}`);\n const isProxyEnabled =\n typeof frontendApiProxy.enabled === 'function'\n ? frontendApiProxy.enabled(requestUrl)\n : frontendApiProxy.enabled;\n if (isProxyEnabled) {\n resolvedOptions = { ...options, proxyUrl: proxyPath };\n }\n }\n\n try {\n const requestState = await authenticateRequest({\n clerkClient,\n request,\n options: resolvedOptions,\n });\n\n const err = setResponseHeaders(requestState, response);\n if (err) {\n return next(err);\n }\n if (response.writableEnded) {\n return;\n }\n\n const auth = brandRequestAuth((opts: Parameters<typeof requestState.toAuth>[0]) => requestState.toAuth(opts));\n\n Object.assign(request, { auth });\n\n next();\n } catch (err) {\n next(err);\n }\n };\n\n return middleware;\n};\n","import type { RequestHandler } from 'express';\n\nimport { authenticateAndDecorateRequest } from './authenticateRequest';\nimport type { ClerkMiddlewareOptions, ClerkMiddlewareOptionsCallback } from './types';\n\n/**\n * Middleware that integrates Clerk authentication into your Express application.\n * It checks the request's cookies and headers for a session JWT and, if found,\n * attaches the Auth object to the request object under the `auth` key.\n *\n * Accepts either a static options object or a callback that receives the request\n * and returns options. The callback form is useful for multi-domain setups where\n * the publishable key differs per domain.\n *\n * @example\n * app.use(clerkMiddleware(options));\n *\n * @example\n * const clerkClient = createClerkClient({ ... });\n * app.use(clerkMiddleware({ clerkClient }));\n *\n * @example\n * app.use(clerkMiddleware());\n *\n * @example\n * // Dynamic keys per domain\n * app.use(clerkMiddleware((req) => ({\n * publishableKey: req.hostname === 'example.com' ? PK_A : PK_B,\n * })));\n */\nexport const clerkMiddleware = (\n options: ClerkMiddlewareOptions | ClerkMiddlewareOptionsCallback = {},\n): RequestHandler => {\n if (typeof options !== 'function') {\n const authMiddleware = authenticateAndDecorateRequest({\n ...options,\n acceptsToken: 'any',\n });\n return (request, response, next) => {\n authMiddleware(request, response, next);\n };\n }\n\n return async (request, response, next) => {\n try {\n const resolvedOptions = await options(request);\n const handler = authenticateAndDecorateRequest({\n ...resolvedOptions,\n acceptsToken: 'any',\n });\n handler(request, response, next);\n } catch (err) {\n next(err);\n }\n };\n};\n","import type { AuthOptions, GetAuthFn } from '@clerk/backend/internal';\nimport { getAuthObjectForAcceptedToken } from '@clerk/backend/internal';\nimport type { Request as ExpressRequest } from 'express';\n\nimport { middlewareRequired } from './errors';\nimport { requestHasAuthObject } from './utils';\n\n/**\n * Retrieves the Clerk AuthObject using the current request object.\n *\n * @param {GetAuthOptions} options - Optional configuration for retrieving auth object.\n * @returns {AuthObject} Object with information about the request state and claims.\n * @throws {Error} `clerkMiddleware` or `requireAuth` is required to be set in the middleware chain before this util is used.\n */\nexport const getAuth: GetAuthFn<ExpressRequest> = ((req: ExpressRequest, options?: AuthOptions) => {\n if (!requestHasAuthObject(req)) {\n throw new Error(middlewareRequired('getAuth'));\n }\n\n const authObject = req.auth(options);\n\n return getAuthObjectForAcceptedToken({ authObject, acceptsToken: options?.acceptsToken });\n}) as GetAuthFn<ExpressRequest>;\n","import { deprecated } from '@clerk/shared/deprecated';\nimport type { RequestHandler } from 'express';\n\nimport { authenticateAndDecorateRequest } from './authenticateRequest';\nimport type { ClerkMiddlewareOptions, ExpressRequestWithAuth } from './types';\n\n/**\n * Middleware to require authentication for user requests.\n * Redirects unauthenticated requests to the sign-in url.\n *\n * @deprecated Use `clerkMiddleware()` with `getAuth()` instead.\n * `requireAuth` will be removed in the next major version.\n *\n * @example\n * // Before (deprecated)\n * import { requireAuth } from '@clerk/express'\n * router.get('/path', requireAuth(), getHandler)\n *\n * @example\n * // After (recommended)\n * import { clerkMiddleware, getAuth } from '@clerk/express'\n *\n * app.use(clerkMiddleware())\n *\n * app.get('/api/protected', (req, res) => {\n * const { userId } = getAuth(req);\n * if (!userId) {\n * return res.status(401).json({ error: 'Unauthorized' });\n * }\n * // handle authenticated request\n * })\n */\nexport const requireAuth = (options: ClerkMiddlewareOptions = {}): RequestHandler => {\n const authMiddleware = authenticateAndDecorateRequest({\n ...options,\n acceptsToken: 'any',\n });\n\n return (request, response, next) => {\n deprecated(\n 'requireAuth',\n 'Use `clerkMiddleware()` with `getAuth()` instead. `requireAuth` will be removed in the next major version.',\n );\n\n authMiddleware(request, response, err => {\n if (err) {\n return next(err);\n }\n\n const signInUrl = options.signInUrl || process.env.CLERK_SIGN_IN_URL || '/';\n\n if (!(request as ExpressRequestWithAuth).auth()?.userId) {\n return response.redirect(signInUrl);\n }\n\n next();\n });\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["defaultClerkClient"],"sources":["../src/clerkClient.ts","../src/errors.ts","../src/authenticateRequest.ts","../src/clerkMiddleware.ts","../src/getAuth.ts","../src/requireAuth.ts"],"sourcesContent":["import type { ClerkClient } from '@clerk/backend';\nimport { createClerkClient } from '@clerk/backend';\n\nimport { loadApiEnv, loadClientEnv } from './utils';\n\nlet clerkClientSingleton = {} as unknown as ClerkClient;\n\nexport const clerkClient = new Proxy(clerkClientSingleton, {\n get(_target, property: keyof ClerkClient) {\n if (property in clerkClientSingleton) {\n return clerkClientSingleton[property];\n }\n\n const env = { ...loadApiEnv(), ...loadClientEnv() };\n const client = createClerkClient({ ...env, userAgent: `${PACKAGE_NAME}@${PACKAGE_VERSION}` });\n\n // if the client is initialized properly, cache it to a singleton instance variable\n // in the next invocation the guard at the top will be triggered instead of creating another instance\n if (env.secretKey) {\n clerkClientSingleton = client;\n }\n\n return client[property];\n },\n set() {\n return false;\n },\n});\n","const createErrorMessage = (msg: string) => {\n return `🔒 Clerk: ${msg.trim()}\n\n For more info, check out the docs: https://clerk.com/docs,\n or come say hi in our discord server: https://clerk.com/discord\n `;\n};\n\nexport const middlewareRequired = (fnName: string) =>\n createErrorMessage(`The \"clerkMiddleware\" should be registered before using \"${fnName}\".\nExample:\n\nimport express from 'express';\nimport { clerkMiddleware } from '@clerk/express';\n\nconst app = express();\napp.use(clerkMiddleware());\n`);\n\nexport const satelliteAndMissingProxyUrlAndDomain =\n 'Missing domain and proxyUrl. A satellite application needs to specify a domain or a proxyUrl';\nexport const satelliteAndMissingSignInUrl = `\nInvalid signInUrl. A satellite application requires a signInUrl for development instances.\nCheck if signInUrl is missing from your configuration or if it is not an absolute URL.`;\n","import { createClerkClient } from '@clerk/backend';\nimport type { ClerkRequest, RequestState } from '@clerk/backend/internal';\nimport { AuthStatus, createClerkRequest } from '@clerk/backend/internal';\nimport { clerkFrontendApiProxy, DEFAULT_PROXY_PATH, stripTrailingSlashes } from '@clerk/backend/proxy';\nimport { isDevelopmentFromSecretKey } from '@clerk/shared/keys';\nimport { logger } from '@clerk/shared/logger';\nimport { isHttpOrHttps, isProxyUrlRelative, isValidProxyUrl } from '@clerk/shared/proxy';\nimport { handleValueOrFn } from '@clerk/shared/utils';\nimport type { RequestHandler, Response } from 'express';\nimport { Readable } from 'stream';\n\nimport { clerkClient as defaultClerkClient } from './clerkClient';\nimport { satelliteAndMissingProxyUrlAndDomain, satelliteAndMissingSignInUrl } from './errors';\nimport type { AuthenticateRequestParams, ClerkMiddlewareOptions } from './types';\nimport {\n brandRequestAuth,\n incomingMessageToRequest,\n loadApiEnv,\n loadClientEnv,\n requestHasAuthObject,\n requestToProxyRequest,\n} from './utils';\n\n/**\n * @internal\n * Authenticates an Express request by wrapping clerkClient.authenticateRequest and\n * converts the express request object into a standard web request object\n *\n * @param opts - Configuration options for request authentication\n * @param opts.clerkClient - The Clerk client instance to use for authentication\n * @param opts.request - The Express request object to authenticate\n * @param opts.options - Optional middleware configuration options\n */\nexport const authenticateRequest = (opts: AuthenticateRequestParams) => {\n const { clerkClient, request, options } = opts;\n // Peel off middleware-only keys and the few options that need middleware-side\n // resolution (env fallbacks, URL normalization). Everything else is spread\n // straight through, so new AuthenticateRequestOptions/VerifyTokenOptions\n // fields flow to the backend without another code change here.\n const {\n clerkClient: _clerkClient,\n debug: _debug,\n frontendApiProxy: _frontendApiProxy,\n isSatellite: isSatelliteInput,\n domain: domainInput,\n signInUrl: signInUrlInput,\n proxyUrl: proxyUrlInput,\n secretKey: secretKeyInput,\n machineSecretKey: machineSecretKeyInput,\n publishableKey: publishableKeyInput,\n ...restOptions\n } = options || {};\n\n const clerkRequest = opts.clerkRequest ?? createClerkRequest(incomingMessageToRequest(request));\n const env = { ...loadApiEnv(), ...loadClientEnv() };\n\n const secretKey = secretKeyInput || env.secretKey;\n const machineSecretKey = machineSecretKeyInput || env.machineSecretKey;\n const publishableKey = publishableKeyInput || env.publishableKey;\n\n const isSatellite = handleValueOrFn(isSatelliteInput, clerkRequest.clerkUrl, env.isSatellite);\n const domain = handleValueOrFn(domainInput, clerkRequest.clerkUrl) || env.domain;\n const signInUrl = signInUrlInput || env.signInUrl;\n const proxyUrl = absoluteProxyUrl(\n handleValueOrFn(proxyUrlInput, clerkRequest.clerkUrl, env.proxyUrl),\n clerkRequest.clerkUrl.toString(),\n );\n\n if (isSatellite && !proxyUrl && !domain) {\n throw new Error(satelliteAndMissingProxyUrlAndDomain);\n }\n\n if (isSatellite && !isHttpOrHttps(signInUrl) && isDevelopmentFromSecretKey(secretKey || '')) {\n throw new Error(satelliteAndMissingSignInUrl);\n }\n\n return clerkClient.authenticateRequest(clerkRequest, {\n ...restOptions,\n secretKey,\n machineSecretKey,\n publishableKey,\n proxyUrl,\n isSatellite,\n domain,\n signInUrl,\n });\n};\n\nconst setResponseHeaders = (requestState: RequestState, res: Response): Error | undefined => {\n if (requestState.headers) {\n requestState.headers.forEach((value, key) => res.appendHeader(key, value));\n }\n return setResponseForHandshake(requestState, res);\n};\n\n/**\n * Depending on the auth state of the request, handles applying redirects and validating that a handshake state was properly handled.\n *\n * Returns an error if state is handshake without a redirect, otherwise returns undefined. res.writableEnded should be checked after this method is called.\n */\nconst setResponseForHandshake = (requestState: RequestState, res: Response): Error | undefined => {\n const hasLocationHeader = requestState.headers.get('location');\n if (hasLocationHeader) {\n // triggering a handshake redirect\n res.status(307).end();\n return;\n }\n\n if (requestState.status === AuthStatus.Handshake) {\n return new Error('Clerk: unexpected handshake without redirect');\n }\n\n return;\n};\n\nconst absoluteProxyUrl = (relativeOrAbsoluteUrl: string, baseUrl: string): string => {\n if (!relativeOrAbsoluteUrl || !isValidProxyUrl(relativeOrAbsoluteUrl) || !isProxyUrlRelative(relativeOrAbsoluteUrl)) {\n return relativeOrAbsoluteUrl;\n }\n return new URL(relativeOrAbsoluteUrl, baseUrl).toString();\n};\n\n// `apiUrl` and `apiVersion` are pinned at client construction time inside\n// `@clerk/backend`'s `createAuthenticateRequest` factory (build-time values\n// override runtime ones). The default singleton in `./clerkClient` is built\n// from env only, so passing these via `clerkMiddleware()` would be silently\n// ignored. When the caller hasn't supplied their own `clerkClient` but did\n// pass `apiUrl`/`apiVersion`, build a per-middleware client with those values.\nconst resolveDefaultClerkClient = (options: ClerkMiddlewareOptions) => {\n if (!options.apiUrl && !options.apiVersion) {\n return defaultClerkClient;\n }\n const env = { ...loadApiEnv(), ...loadClientEnv() };\n return createClerkClient({\n ...env,\n ...(options.apiUrl ? { apiUrl: options.apiUrl } : {}),\n ...(options.apiVersion ? { apiVersion: options.apiVersion } : {}),\n userAgent: `${PACKAGE_NAME}@${PACKAGE_VERSION}`,\n });\n};\n\nexport const authenticateAndDecorateRequest = (options: ClerkMiddlewareOptions = {}): RequestHandler => {\n const clerkClient = options.clerkClient || resolveDefaultClerkClient(options);\n\n // Extract proxy configuration\n const frontendApiProxy = options.frontendApiProxy;\n const proxyPath = stripTrailingSlashes(frontendApiProxy?.path ?? DEFAULT_PROXY_PATH) || DEFAULT_PROXY_PATH;\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n const middleware: RequestHandler = async (request, response, next) => {\n // Skip authentication only when a Clerk middleware has already processed\n // this request. The brand check matters: a truthy `req.auth` is not proof\n // of that, since express-jwt, passport and other libraries set the same\n // property, and treating their value as ours would silently disable Clerk\n // authentication.\n if (requestHasAuthObject(request)) {\n return next();\n }\n\n if ('auth' in request) {\n logger.warnOnce(\n 'Clerk: another middleware has already set `req.auth` on this request. Clerk authentication will run anyway and overwrite it. To use another auth library alongside Clerk, configure it to store its state on a different request property.',\n );\n }\n\n // Node accepts request targets/methods (`//`, TRACE) the fetch spec cannot represent; reject those instead of 500ing.\n let clerkRequest: ClerkRequest;\n try {\n clerkRequest = createClerkRequest(incomingMessageToRequest(request));\n } catch {\n response.status(400).end();\n return;\n }\n\n const env = { ...loadApiEnv(), ...loadClientEnv() };\n const publishableKey = options.publishableKey || env.publishableKey;\n const secretKey = options.secretKey || env.secretKey;\n\n // Handle Frontend API proxy requests early, before authentication\n if (frontendApiProxy) {\n let requestUrl: URL;\n try {\n requestUrl = new URL(request.originalUrl || request.url, `http://${request.headers.host}`);\n } catch {\n response.status(400).end();\n return;\n }\n const isEnabled =\n typeof frontendApiProxy.enabled === 'function'\n ? frontendApiProxy.enabled(requestUrl)\n : frontendApiProxy.enabled;\n\n if (isEnabled && (requestUrl.pathname === proxyPath || requestUrl.pathname.startsWith(proxyPath + '/'))) {\n // Convert Express request to Fetch API Request\n let proxyRequest: Request;\n try {\n proxyRequest = requestToProxyRequest(request);\n } catch {\n response.status(400).end();\n return;\n }\n\n // Call the core proxy function\n const proxyResponse = await clerkFrontendApiProxy(proxyRequest, {\n proxyPath,\n publishableKey,\n secretKey,\n });\n\n // Send the proxy response back to the client\n response.status(proxyResponse.status);\n proxyResponse.headers.forEach((value, key) => {\n response.setHeader(key, value);\n });\n\n if (proxyResponse.body) {\n const reader = proxyResponse.body.getReader();\n const stream = new Readable({\n async read() {\n try {\n const { done, value } = await reader.read();\n if (done) {\n this.push(null);\n } else {\n this.push(Buffer.from(value));\n }\n } catch (error) {\n this.destroy(error instanceof Error ? error : new Error(String(error)));\n }\n },\n });\n stream.pipe(response);\n } else {\n response.end();\n }\n return;\n }\n }\n\n // Pass the proxy path to authenticateRequest - the backend resolves it\n // against the request's public origin (from x-forwarded-* headers).\n let resolvedOptions = options;\n if (frontendApiProxy && !options.proxyUrl) {\n let requestUrl: URL;\n try {\n requestUrl = new URL(request.originalUrl || request.url, `http://${request.headers.host}`);\n } catch {\n response.status(400).end();\n return;\n }\n const isProxyEnabled =\n typeof frontendApiProxy.enabled === 'function'\n ? frontendApiProxy.enabled(requestUrl)\n : frontendApiProxy.enabled;\n if (isProxyEnabled) {\n resolvedOptions = { ...options, proxyUrl: proxyPath };\n }\n }\n\n try {\n const requestState = await authenticateRequest({\n clerkClient,\n request,\n options: resolvedOptions,\n clerkRequest,\n });\n\n const err = setResponseHeaders(requestState, response);\n if (err) {\n return next(err);\n }\n if (response.writableEnded) {\n return;\n }\n\n const auth = brandRequestAuth((opts: Parameters<typeof requestState.toAuth>[0]) => requestState.toAuth(opts));\n\n Object.assign(request, { auth });\n\n next();\n } catch (err) {\n next(err);\n }\n };\n\n return middleware;\n};\n","import type { RequestHandler } from 'express';\n\nimport { authenticateAndDecorateRequest } from './authenticateRequest';\nimport type { ClerkMiddlewareOptions, ClerkMiddlewareOptionsCallback } from './types';\n\n/**\n * Middleware that integrates Clerk authentication into your Express application.\n * It checks the request's cookies and headers for a session JWT and, if found,\n * attaches the Auth object to the request object under the `auth` key.\n *\n * Accepts either a static options object or a callback that receives the request\n * and returns options. The callback form is useful for multi-domain setups where\n * the publishable key differs per domain.\n *\n * @example\n * app.use(clerkMiddleware(options));\n *\n * @example\n * const clerkClient = createClerkClient({ ... });\n * app.use(clerkMiddleware({ clerkClient }));\n *\n * @example\n * app.use(clerkMiddleware());\n *\n * @example\n * // Dynamic keys per domain\n * app.use(clerkMiddleware((req) => ({\n * publishableKey: req.hostname === 'example.com' ? PK_A : PK_B,\n * })));\n */\nexport const clerkMiddleware = (\n options: ClerkMiddlewareOptions | ClerkMiddlewareOptionsCallback = {},\n): RequestHandler => {\n if (typeof options !== 'function') {\n const authMiddleware = authenticateAndDecorateRequest({\n ...options,\n acceptsToken: 'any',\n });\n return (request, response, next) => {\n authMiddleware(request, response, next);\n };\n }\n\n return async (request, response, next) => {\n try {\n const resolvedOptions = await options(request);\n const handler = authenticateAndDecorateRequest({\n ...resolvedOptions,\n acceptsToken: 'any',\n });\n handler(request, response, next);\n } catch (err) {\n next(err);\n }\n };\n};\n","import type { AuthOptions, GetAuthFn } from '@clerk/backend/internal';\nimport { getAuthObjectForAcceptedToken } from '@clerk/backend/internal';\nimport type { Request as ExpressRequest } from 'express';\n\nimport { middlewareRequired } from './errors';\nimport { requestHasAuthObject } from './utils';\n\n/**\n * Retrieves the Clerk AuthObject using the current request object.\n *\n * @param {GetAuthOptions} options - Optional configuration for retrieving auth object.\n * @returns {AuthObject} Object with information about the request state and claims.\n * @throws {Error} `clerkMiddleware` or `requireAuth` is required to be set in the middleware chain before this util is used.\n */\nexport const getAuth: GetAuthFn<ExpressRequest> = ((req: ExpressRequest, options?: AuthOptions) => {\n if (!requestHasAuthObject(req)) {\n throw new Error(middlewareRequired('getAuth'));\n }\n\n const authObject = req.auth(options);\n\n return getAuthObjectForAcceptedToken({ authObject, acceptsToken: options?.acceptsToken });\n}) as GetAuthFn<ExpressRequest>;\n","import { deprecated } from '@clerk/shared/deprecated';\nimport type { RequestHandler } from 'express';\n\nimport { authenticateAndDecorateRequest } from './authenticateRequest';\nimport type { ClerkMiddlewareOptions, ExpressRequestWithAuth } from './types';\n\n/**\n * Middleware to require authentication for user requests.\n * Redirects unauthenticated requests to the sign-in url.\n *\n * @deprecated Use `clerkMiddleware()` with `getAuth()` instead.\n * `requireAuth` will be removed in the next major version.\n *\n * @example\n * // Before (deprecated)\n * import { requireAuth } from '@clerk/express'\n * router.get('/path', requireAuth(), getHandler)\n *\n * @example\n * // After (recommended)\n * import { clerkMiddleware, getAuth } from '@clerk/express'\n *\n * app.use(clerkMiddleware())\n *\n * app.get('/api/protected', (req, res) => {\n * const { userId } = getAuth(req);\n * if (!userId) {\n * return res.status(401).json({ error: 'Unauthorized' });\n * }\n * // handle authenticated request\n * })\n */\nexport const requireAuth = (options: ClerkMiddlewareOptions = {}): RequestHandler => {\n const authMiddleware = authenticateAndDecorateRequest({\n ...options,\n acceptsToken: 'any',\n });\n\n return (request, response, next) => {\n deprecated(\n 'requireAuth',\n 'Use `clerkMiddleware()` with `getAuth()` instead. `requireAuth` will be removed in the next major version.',\n );\n\n authMiddleware(request, response, err => {\n if (err) {\n return next(err);\n }\n\n const signInUrl = options.signInUrl || process.env.CLERK_SIGN_IN_URL || '/';\n\n if (!(request as ExpressRequestWithAuth).auth()?.userId) {\n return response.redirect(signInUrl);\n }\n\n next();\n });\n };\n};\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { createClerkClient } from "@clerk/backend";
2
- import { AuthenticateRequestOptions, SignedInAuthObject, SignedOutAuthObject } from "@clerk/backend/internal";
2
+ import { AuthenticateRequestOptions, ClerkRequest, SignedInAuthObject, SignedOutAuthObject } from "@clerk/backend/internal";
3
3
  import { ShouldProxyFn } from "@clerk/shared/proxy";
4
4
  import { PendingSessionOptions } from "@clerk/shared/types";
5
5
  import { Request } from "express";
@@ -53,8 +53,9 @@ type ClerkClient$1 = ReturnType<typeof createClerkClient>;
53
53
  type AuthenticateRequestParams = {
54
54
  clerkClient: ClerkClient$1;
55
55
  request: Request;
56
- options?: ClerkMiddlewareOptions;
56
+ options?: ClerkMiddlewareOptions; /** Prebuilt ClerkRequest, so callers that already converted the request can skip re-conversion. */
57
+ clerkRequest?: ClerkRequest;
57
58
  };
58
59
  //#endregion
59
60
  export { ExpressRequestWithAuth as i, ClerkMiddlewareOptions as n, ClerkMiddlewareOptionsCallback as r, AuthenticateRequestParams as t };
60
- //# sourceMappingURL=types-CRXNc42W.d.ts.map
61
+ //# sourceMappingURL=types-D9OHSDSA.d.mts.map
@@ -1,5 +1,5 @@
1
1
  import { createClerkClient } from "@clerk/backend";
2
- import { AuthenticateRequestOptions, SignedInAuthObject, SignedOutAuthObject } from "@clerk/backend/internal";
2
+ import { AuthenticateRequestOptions, ClerkRequest, SignedInAuthObject, SignedOutAuthObject } from "@clerk/backend/internal";
3
3
  import { ShouldProxyFn } from "@clerk/shared/proxy";
4
4
  import { PendingSessionOptions } from "@clerk/shared/types";
5
5
  import { Request } from "express";
@@ -53,8 +53,9 @@ type ClerkClient$1 = ReturnType<typeof createClerkClient>;
53
53
  type AuthenticateRequestParams = {
54
54
  clerkClient: ClerkClient$1;
55
55
  request: Request;
56
- options?: ClerkMiddlewareOptions;
56
+ options?: ClerkMiddlewareOptions; /** Prebuilt ClerkRequest, so callers that already converted the request can skip re-conversion. */
57
+ clerkRequest?: ClerkRequest;
57
58
  };
58
59
  //#endregion
59
60
  export { ExpressRequestWithAuth as i, ClerkMiddlewareOptions as n, ClerkMiddlewareOptionsCallback as r, AuthenticateRequestParams as t };
60
- //# sourceMappingURL=types-CRXNc42W.d.mts.map
61
+ //# sourceMappingURL=types-D9OHSDSA.d.ts.map
package/dist/types.d.mts CHANGED
@@ -1,3 +1,3 @@
1
- import { i as ExpressRequestWithAuth, n as ClerkMiddlewareOptions, t as AuthenticateRequestParams } from "./types-CRXNc42W.mjs";
1
+ import { i as ExpressRequestWithAuth, n as ClerkMiddlewareOptions, t as AuthenticateRequestParams } from "./types-D9OHSDSA.mjs";
2
2
  export type * from "@clerk/shared/types";
3
3
  export type { AuthenticateRequestParams, ClerkMiddlewareOptions, ExpressRequestWithAuth };
package/dist/types.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { i as ExpressRequestWithAuth, n as ClerkMiddlewareOptions, t as AuthenticateRequestParams } from "./types-CRXNc42W.js";
1
+ import { i as ExpressRequestWithAuth, n as ClerkMiddlewareOptions, t as AuthenticateRequestParams } from "./types-D9OHSDSA.js";
2
2
  export type * from "@clerk/shared/types";
3
3
  export type { AuthenticateRequestParams, ClerkMiddlewareOptions, ExpressRequestWithAuth };
@@ -39,7 +39,7 @@ const loadApiEnv = () => {
39
39
  jwtKey: process.env.CLERK_JWT_KEY || "",
40
40
  sdkMetadata: {
41
41
  name: "@clerk/express",
42
- version: "2.1.49",
42
+ version: "2.1.50-canary.v20260731161424",
43
43
  environment: process.env.NODE_ENV
44
44
  },
45
45
  telemetry: {
@@ -119,4 +119,4 @@ Object.defineProperty(exports, 'requestToProxyRequest', {
119
119
  return requestToProxyRequest;
120
120
  }
121
121
  });
122
- //# sourceMappingURL=utils-BKrEOl3y.js.map
122
+ //# sourceMappingURL=utils-8eqSXbcQ.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils-BKrEOl3y.js","names":["Readable"],"sources":["../src/utils.ts"],"sourcesContent":["import { isTruthy } from '@clerk/shared/underscore';\nimport type { Request as ExpressRequest } from 'express';\nimport { Readable } from 'stream';\n\nimport type { ExpressRequestWithAuth } from './types';\n\n/**\n * Brand attached to the `req.auth` handler installed by Clerk middleware.\n * `req.auth` is a property name shared with other auth libraries (express-jwt,\n * passport, express-openid-connect), so its mere presence proves nothing about\n * whether Clerk authenticated the request. `Symbol.for` registers the brand\n * globally so it stays stable across multiple copies of this package loaded in\n * the same process.\n */\nconst clerkAuthBrand = Symbol.for('@clerk/express.auth');\n\nexport const brandRequestAuth = <T extends (...args: never[]) => unknown>(authHandler: T): T =>\n Object.assign(authHandler, { [clerkAuthBrand]: true });\n\nexport const requestHasAuthObject = (req: ExpressRequest): req is ExpressRequestWithAuth => {\n const auth = (req as Partial<ExpressRequestWithAuth>).auth;\n return typeof auth === 'function' && (auth as unknown as Record<symbol, unknown>)[clerkAuthBrand] === true;\n};\n\nexport const loadClientEnv = () => {\n return {\n publishableKey: process.env.CLERK_PUBLISHABLE_KEY || '',\n __internal_clerkJSUrl: process.env.CLERK_JS || process.env.CLERK_JS_URL || '',\n __internal_clerkJSVersion: process.env.CLERK_JS_VERSION || '',\n __internal_clerkUIUrl: process.env.CLERK_UI_URL || '',\n __internal_clerkUIVersion: process.env.CLERK_UI_VERSION || '',\n prefetchUI: process.env.CLERK_PREFETCH_UI === 'false' ? false : undefined,\n };\n};\n\nexport const loadApiEnv = () => {\n return {\n secretKey: process.env.CLERK_SECRET_KEY || '',\n machineSecretKey: process.env.CLERK_MACHINE_SECRET_KEY || '',\n apiUrl: process.env.CLERK_API_URL || 'https://api.clerk.com',\n apiVersion: process.env.CLERK_API_VERSION || 'v1',\n domain: process.env.CLERK_DOMAIN || '',\n proxyUrl: process.env.CLERK_PROXY_URL || '',\n signInUrl: process.env.CLERK_SIGN_IN_URL || '',\n isSatellite: isTruthy(process.env.CLERK_IS_SATELLITE),\n jwtKey: process.env.CLERK_JWT_KEY || '',\n sdkMetadata: {\n name: PACKAGE_NAME,\n version: PACKAGE_VERSION,\n environment: process.env.NODE_ENV,\n },\n telemetry: {\n disabled: isTruthy(process.env.CLERK_TELEMETRY_DISABLED),\n debug: isTruthy(process.env.CLERK_TELEMETRY_DEBUG),\n },\n };\n};\n\nexport const incomingMessageToRequest = (req: ExpressRequest): Request => {\n const headers = Object.keys(req.headers).reduce((acc, key) => Object.assign(acc, { [key]: req?.headers[key] }), {});\n // @ts-ignore Optimistic attempt to get the protocol in case\n // req extends IncomingMessage in a useful way. No guarantee\n // it'll work.\n const protocol = req.connection?.encrypted ? 'https' : 'http';\n const dummyOriginReqUrl = new URL(req.originalUrl || req.url || '', `${protocol}://clerk-dummy`);\n return new Request(dummyOriginReqUrl, {\n method: req.method,\n headers: new Headers(headers),\n });\n};\n\n/**\n * Converts an Express request to a Fetch API Request with body streaming support.\n * This is used for proxying requests where the body needs to be forwarded.\n */\nexport const requestToProxyRequest = (req: ExpressRequest): Request => {\n const headers = new Headers();\n Object.entries(req.headers).forEach(([key, value]) => {\n if (value) {\n headers.set(key, Array.isArray(value) ? value.join(', ') : value);\n }\n });\n\n const protocol = req.protocol || (req.secure ? 'https' : 'http');\n const host = req.get('host') || 'localhost';\n const url = new URL(req.originalUrl || req.url, `${protocol}://${host}`);\n\n const hasBody = ['POST', 'PUT', 'PATCH'].includes(req.method);\n\n return new Request(url.toString(), {\n method: req.method,\n headers,\n body: hasBody ? (Readable.toWeb(req) as ReadableStream) : undefined,\n // @ts-expect-error - duplex required for streaming bodies but not in all TS definitions\n duplex: hasBody ? 'half' : undefined,\n });\n};\n"],"mappings":";;;;;;;;;;;;AAcA,MAAM,iBAAiB,OAAO,IAAI,qBAAqB;AAEvD,MAAa,oBAA6D,gBACxE,OAAO,OAAO,aAAa,GAAG,iBAAiB,KAAK,CAAC;AAEvD,MAAa,wBAAwB,QAAuD;CAC1F,MAAM,OAAQ,IAAwC;CACtD,OAAO,OAAO,SAAS,cAAe,KAA4C,oBAAoB;AACxG;AAEA,MAAa,sBAAsB;CACjC,OAAO;EACL,gBAAgB,QAAQ,IAAI,yBAAyB;EACrD,uBAAuB,QAAQ,IAAI,YAAY,QAAQ,IAAI,gBAAgB;EAC3E,2BAA2B,QAAQ,IAAI,oBAAoB;EAC3D,uBAAuB,QAAQ,IAAI,gBAAgB;EACnD,2BAA2B,QAAQ,IAAI,oBAAoB;EAC3D,YAAY,QAAQ,IAAI,sBAAsB,UAAU,QAAQ;CAClE;AACF;AAEA,MAAa,mBAAmB;CAC9B,OAAO;EACL,WAAW,QAAQ,IAAI,oBAAoB;EAC3C,kBAAkB,QAAQ,IAAI,4BAA4B;EAC1D,QAAQ,QAAQ,IAAI,iBAAiB;EACrC,YAAY,QAAQ,IAAI,qBAAqB;EAC7C,QAAQ,QAAQ,IAAI,gBAAgB;EACpC,UAAU,QAAQ,IAAI,mBAAmB;EACzC,WAAW,QAAQ,IAAI,qBAAqB;EAC5C,oDAAsB,QAAQ,IAAI,kBAAkB;EACpD,QAAQ,QAAQ,IAAI,iBAAiB;EACrC,aAAa;GACX;GACA;GACA,aAAa,QAAQ,IAAI;EAC3B;EACA,WAAW;GACT,iDAAmB,QAAQ,IAAI,wBAAwB;GACvD,8CAAgB,QAAQ,IAAI,qBAAqB;EACnD;CACF;AACF;AAEA,MAAa,4BAA4B,QAAiC;CACxE,MAAM,UAAU,OAAO,KAAK,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,OAAO,OAAO,KAAK,GAAG,MAAM,KAAK,QAAQ,KAAK,CAAC,GAAG,CAAC,CAAC;CAIlH,MAAM,WAAW,IAAI,YAAY,YAAY,UAAU;CACvD,MAAM,oBAAoB,IAAI,IAAI,IAAI,eAAe,IAAI,OAAO,IAAI,GAAG,SAAS,eAAe;CAC/F,OAAO,IAAI,QAAQ,mBAAmB;EACpC,QAAQ,IAAI;EACZ,SAAS,IAAI,QAAQ,OAAO;CAC9B,CAAC;AACH;;;;;AAMA,MAAa,yBAAyB,QAAiC;CACrE,MAAM,UAAU,IAAI,QAAQ;CAC5B,OAAO,QAAQ,IAAI,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,WAAW;EACpD,IAAI,OACF,QAAQ,IAAI,KAAK,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK;CAEpE,CAAC;CAED,MAAM,WAAW,IAAI,aAAa,IAAI,SAAS,UAAU;CACzD,MAAM,OAAO,IAAI,IAAI,MAAM,KAAK;CAChC,MAAM,MAAM,IAAI,IAAI,IAAI,eAAe,IAAI,KAAK,GAAG,SAAS,KAAK,MAAM;CAEvE,MAAM,UAAU;EAAC;EAAQ;EAAO;CAAO,CAAC,CAAC,SAAS,IAAI,MAAM;CAE5D,OAAO,IAAI,QAAQ,IAAI,SAAS,GAAG;EACjC,QAAQ,IAAI;EACZ;EACA,MAAM,UAAWA,gBAAS,MAAM,GAAG,IAAuB;EAE1D,QAAQ,UAAU,SAAS;CAC7B,CAAC;AACH"}
1
+ {"version":3,"file":"utils-8eqSXbcQ.js","names":["Readable"],"sources":["../src/utils.ts"],"sourcesContent":["import { isTruthy } from '@clerk/shared/underscore';\nimport type { Request as ExpressRequest } from 'express';\nimport { Readable } from 'stream';\n\nimport type { ExpressRequestWithAuth } from './types';\n\n/**\n * Brand attached to the `req.auth` handler installed by Clerk middleware.\n * `req.auth` is a property name shared with other auth libraries (express-jwt,\n * passport, express-openid-connect), so its mere presence proves nothing about\n * whether Clerk authenticated the request. `Symbol.for` registers the brand\n * globally so it stays stable across multiple copies of this package loaded in\n * the same process.\n */\nconst clerkAuthBrand = Symbol.for('@clerk/express.auth');\n\nexport const brandRequestAuth = <T extends (...args: never[]) => unknown>(authHandler: T): T =>\n Object.assign(authHandler, { [clerkAuthBrand]: true });\n\nexport const requestHasAuthObject = (req: ExpressRequest): req is ExpressRequestWithAuth => {\n const auth = (req as Partial<ExpressRequestWithAuth>).auth;\n return typeof auth === 'function' && (auth as unknown as Record<symbol, unknown>)[clerkAuthBrand] === true;\n};\n\nexport const loadClientEnv = () => {\n return {\n publishableKey: process.env.CLERK_PUBLISHABLE_KEY || '',\n __internal_clerkJSUrl: process.env.CLERK_JS || process.env.CLERK_JS_URL || '',\n __internal_clerkJSVersion: process.env.CLERK_JS_VERSION || '',\n __internal_clerkUIUrl: process.env.CLERK_UI_URL || '',\n __internal_clerkUIVersion: process.env.CLERK_UI_VERSION || '',\n prefetchUI: process.env.CLERK_PREFETCH_UI === 'false' ? false : undefined,\n };\n};\n\nexport const loadApiEnv = () => {\n return {\n secretKey: process.env.CLERK_SECRET_KEY || '',\n machineSecretKey: process.env.CLERK_MACHINE_SECRET_KEY || '',\n apiUrl: process.env.CLERK_API_URL || 'https://api.clerk.com',\n apiVersion: process.env.CLERK_API_VERSION || 'v1',\n domain: process.env.CLERK_DOMAIN || '',\n proxyUrl: process.env.CLERK_PROXY_URL || '',\n signInUrl: process.env.CLERK_SIGN_IN_URL || '',\n isSatellite: isTruthy(process.env.CLERK_IS_SATELLITE),\n jwtKey: process.env.CLERK_JWT_KEY || '',\n sdkMetadata: {\n name: PACKAGE_NAME,\n version: PACKAGE_VERSION,\n environment: process.env.NODE_ENV,\n },\n telemetry: {\n disabled: isTruthy(process.env.CLERK_TELEMETRY_DISABLED),\n debug: isTruthy(process.env.CLERK_TELEMETRY_DEBUG),\n },\n };\n};\n\nexport const incomingMessageToRequest = (req: ExpressRequest): Request => {\n const headers = Object.keys(req.headers).reduce((acc, key) => Object.assign(acc, { [key]: req?.headers[key] }), {});\n // @ts-ignore Optimistic attempt to get the protocol in case\n // req extends IncomingMessage in a useful way. No guarantee\n // it'll work.\n const protocol = req.connection?.encrypted ? 'https' : 'http';\n const dummyOriginReqUrl = new URL(req.originalUrl || req.url || '', `${protocol}://clerk-dummy`);\n return new Request(dummyOriginReqUrl, {\n method: req.method,\n headers: new Headers(headers),\n });\n};\n\n/**\n * Converts an Express request to a Fetch API Request with body streaming support.\n * This is used for proxying requests where the body needs to be forwarded.\n */\nexport const requestToProxyRequest = (req: ExpressRequest): Request => {\n const headers = new Headers();\n Object.entries(req.headers).forEach(([key, value]) => {\n if (value) {\n headers.set(key, Array.isArray(value) ? value.join(', ') : value);\n }\n });\n\n const protocol = req.protocol || (req.secure ? 'https' : 'http');\n const host = req.get('host') || 'localhost';\n const url = new URL(req.originalUrl || req.url, `${protocol}://${host}`);\n\n const hasBody = ['POST', 'PUT', 'PATCH'].includes(req.method);\n\n return new Request(url.toString(), {\n method: req.method,\n headers,\n body: hasBody ? (Readable.toWeb(req) as ReadableStream) : undefined,\n // @ts-expect-error - duplex required for streaming bodies but not in all TS definitions\n duplex: hasBody ? 'half' : undefined,\n });\n};\n"],"mappings":";;;;;;;;;;;;AAcA,MAAM,iBAAiB,OAAO,IAAI,qBAAqB;AAEvD,MAAa,oBAA6D,gBACxE,OAAO,OAAO,aAAa,GAAG,iBAAiB,KAAK,CAAC;AAEvD,MAAa,wBAAwB,QAAuD;CAC1F,MAAM,OAAQ,IAAwC;CACtD,OAAO,OAAO,SAAS,cAAe,KAA4C,oBAAoB;AACxG;AAEA,MAAa,sBAAsB;CACjC,OAAO;EACL,gBAAgB,QAAQ,IAAI,yBAAyB;EACrD,uBAAuB,QAAQ,IAAI,YAAY,QAAQ,IAAI,gBAAgB;EAC3E,2BAA2B,QAAQ,IAAI,oBAAoB;EAC3D,uBAAuB,QAAQ,IAAI,gBAAgB;EACnD,2BAA2B,QAAQ,IAAI,oBAAoB;EAC3D,YAAY,QAAQ,IAAI,sBAAsB,UAAU,QAAQ;CAClE;AACF;AAEA,MAAa,mBAAmB;CAC9B,OAAO;EACL,WAAW,QAAQ,IAAI,oBAAoB;EAC3C,kBAAkB,QAAQ,IAAI,4BAA4B;EAC1D,QAAQ,QAAQ,IAAI,iBAAiB;EACrC,YAAY,QAAQ,IAAI,qBAAqB;EAC7C,QAAQ,QAAQ,IAAI,gBAAgB;EACpC,UAAU,QAAQ,IAAI,mBAAmB;EACzC,WAAW,QAAQ,IAAI,qBAAqB;EAC5C,oDAAsB,QAAQ,IAAI,kBAAkB;EACpD,QAAQ,QAAQ,IAAI,iBAAiB;EACrC,aAAa;GACX;GACA;GACA,aAAa,QAAQ,IAAI;EAC3B;EACA,WAAW;GACT,iDAAmB,QAAQ,IAAI,wBAAwB;GACvD,8CAAgB,QAAQ,IAAI,qBAAqB;EACnD;CACF;AACF;AAEA,MAAa,4BAA4B,QAAiC;CACxE,MAAM,UAAU,OAAO,KAAK,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,OAAO,OAAO,KAAK,GAAG,MAAM,KAAK,QAAQ,KAAK,CAAC,GAAG,CAAC,CAAC;CAIlH,MAAM,WAAW,IAAI,YAAY,YAAY,UAAU;CACvD,MAAM,oBAAoB,IAAI,IAAI,IAAI,eAAe,IAAI,OAAO,IAAI,GAAG,SAAS,eAAe;CAC/F,OAAO,IAAI,QAAQ,mBAAmB;EACpC,QAAQ,IAAI;EACZ,SAAS,IAAI,QAAQ,OAAO;CAC9B,CAAC;AACH;;;;;AAMA,MAAa,yBAAyB,QAAiC;CACrE,MAAM,UAAU,IAAI,QAAQ;CAC5B,OAAO,QAAQ,IAAI,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,WAAW;EACpD,IAAI,OACF,QAAQ,IAAI,KAAK,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK;CAEpE,CAAC;CAED,MAAM,WAAW,IAAI,aAAa,IAAI,SAAS,UAAU;CACzD,MAAM,OAAO,IAAI,IAAI,MAAM,KAAK;CAChC,MAAM,MAAM,IAAI,IAAI,IAAI,eAAe,IAAI,KAAK,GAAG,SAAS,KAAK,MAAM;CAEvE,MAAM,UAAU;EAAC;EAAQ;EAAO;CAAO,CAAC,CAAC,SAAS,IAAI,MAAM;CAE5D,OAAO,IAAI,QAAQ,IAAI,SAAS,GAAG;EACjC,QAAQ,IAAI;EACZ;EACA,MAAM,UAAWA,gBAAS,MAAM,GAAG,IAAuB;EAE1D,QAAQ,UAAU,SAAS;CAC7B,CAAC;AACH"}
@@ -39,7 +39,7 @@ const loadApiEnv = () => {
39
39
  jwtKey: process.env.CLERK_JWT_KEY || "",
40
40
  sdkMetadata: {
41
41
  name: "@clerk/express",
42
- version: "2.1.49",
42
+ version: "2.1.50-canary.v20260731161424",
43
43
  environment: process.env.NODE_ENV
44
44
  },
45
45
  telemetry: {
@@ -84,4 +84,4 @@ const requestToProxyRequest = (req) => {
84
84
 
85
85
  //#endregion
86
86
  export { requestHasAuthObject as a, loadClientEnv as i, incomingMessageToRequest as n, requestToProxyRequest as o, loadApiEnv as r, brandRequestAuth as t };
87
- //# sourceMappingURL=utils-CW7I2k9m.mjs.map
87
+ //# sourceMappingURL=utils-DnpNAWof.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils-CW7I2k9m.mjs","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import { isTruthy } from '@clerk/shared/underscore';\nimport type { Request as ExpressRequest } from 'express';\nimport { Readable } from 'stream';\n\nimport type { ExpressRequestWithAuth } from './types';\n\n/**\n * Brand attached to the `req.auth` handler installed by Clerk middleware.\n * `req.auth` is a property name shared with other auth libraries (express-jwt,\n * passport, express-openid-connect), so its mere presence proves nothing about\n * whether Clerk authenticated the request. `Symbol.for` registers the brand\n * globally so it stays stable across multiple copies of this package loaded in\n * the same process.\n */\nconst clerkAuthBrand = Symbol.for('@clerk/express.auth');\n\nexport const brandRequestAuth = <T extends (...args: never[]) => unknown>(authHandler: T): T =>\n Object.assign(authHandler, { [clerkAuthBrand]: true });\n\nexport const requestHasAuthObject = (req: ExpressRequest): req is ExpressRequestWithAuth => {\n const auth = (req as Partial<ExpressRequestWithAuth>).auth;\n return typeof auth === 'function' && (auth as unknown as Record<symbol, unknown>)[clerkAuthBrand] === true;\n};\n\nexport const loadClientEnv = () => {\n return {\n publishableKey: process.env.CLERK_PUBLISHABLE_KEY || '',\n __internal_clerkJSUrl: process.env.CLERK_JS || process.env.CLERK_JS_URL || '',\n __internal_clerkJSVersion: process.env.CLERK_JS_VERSION || '',\n __internal_clerkUIUrl: process.env.CLERK_UI_URL || '',\n __internal_clerkUIVersion: process.env.CLERK_UI_VERSION || '',\n prefetchUI: process.env.CLERK_PREFETCH_UI === 'false' ? false : undefined,\n };\n};\n\nexport const loadApiEnv = () => {\n return {\n secretKey: process.env.CLERK_SECRET_KEY || '',\n machineSecretKey: process.env.CLERK_MACHINE_SECRET_KEY || '',\n apiUrl: process.env.CLERK_API_URL || 'https://api.clerk.com',\n apiVersion: process.env.CLERK_API_VERSION || 'v1',\n domain: process.env.CLERK_DOMAIN || '',\n proxyUrl: process.env.CLERK_PROXY_URL || '',\n signInUrl: process.env.CLERK_SIGN_IN_URL || '',\n isSatellite: isTruthy(process.env.CLERK_IS_SATELLITE),\n jwtKey: process.env.CLERK_JWT_KEY || '',\n sdkMetadata: {\n name: PACKAGE_NAME,\n version: PACKAGE_VERSION,\n environment: process.env.NODE_ENV,\n },\n telemetry: {\n disabled: isTruthy(process.env.CLERK_TELEMETRY_DISABLED),\n debug: isTruthy(process.env.CLERK_TELEMETRY_DEBUG),\n },\n };\n};\n\nexport const incomingMessageToRequest = (req: ExpressRequest): Request => {\n const headers = Object.keys(req.headers).reduce((acc, key) => Object.assign(acc, { [key]: req?.headers[key] }), {});\n // @ts-ignore Optimistic attempt to get the protocol in case\n // req extends IncomingMessage in a useful way. No guarantee\n // it'll work.\n const protocol = req.connection?.encrypted ? 'https' : 'http';\n const dummyOriginReqUrl = new URL(req.originalUrl || req.url || '', `${protocol}://clerk-dummy`);\n return new Request(dummyOriginReqUrl, {\n method: req.method,\n headers: new Headers(headers),\n });\n};\n\n/**\n * Converts an Express request to a Fetch API Request with body streaming support.\n * This is used for proxying requests where the body needs to be forwarded.\n */\nexport const requestToProxyRequest = (req: ExpressRequest): Request => {\n const headers = new Headers();\n Object.entries(req.headers).forEach(([key, value]) => {\n if (value) {\n headers.set(key, Array.isArray(value) ? value.join(', ') : value);\n }\n });\n\n const protocol = req.protocol || (req.secure ? 'https' : 'http');\n const host = req.get('host') || 'localhost';\n const url = new URL(req.originalUrl || req.url, `${protocol}://${host}`);\n\n const hasBody = ['POST', 'PUT', 'PATCH'].includes(req.method);\n\n return new Request(url.toString(), {\n method: req.method,\n headers,\n body: hasBody ? (Readable.toWeb(req) as ReadableStream) : undefined,\n // @ts-expect-error - duplex required for streaming bodies but not in all TS definitions\n duplex: hasBody ? 'half' : undefined,\n });\n};\n"],"mappings":";;;;;;;;;;;;AAcA,MAAM,iBAAiB,OAAO,IAAI,qBAAqB;AAEvD,MAAa,oBAA6D,gBACxE,OAAO,OAAO,aAAa,GAAG,iBAAiB,KAAK,CAAC;AAEvD,MAAa,wBAAwB,QAAuD;CAC1F,MAAM,OAAQ,IAAwC;CACtD,OAAO,OAAO,SAAS,cAAe,KAA4C,oBAAoB;AACxG;AAEA,MAAa,sBAAsB;CACjC,OAAO;EACL,gBAAgB,QAAQ,IAAI,yBAAyB;EACrD,uBAAuB,QAAQ,IAAI,YAAY,QAAQ,IAAI,gBAAgB;EAC3E,2BAA2B,QAAQ,IAAI,oBAAoB;EAC3D,uBAAuB,QAAQ,IAAI,gBAAgB;EACnD,2BAA2B,QAAQ,IAAI,oBAAoB;EAC3D,YAAY,QAAQ,IAAI,sBAAsB,UAAU,QAAQ;CAClE;AACF;AAEA,MAAa,mBAAmB;CAC9B,OAAO;EACL,WAAW,QAAQ,IAAI,oBAAoB;EAC3C,kBAAkB,QAAQ,IAAI,4BAA4B;EAC1D,QAAQ,QAAQ,IAAI,iBAAiB;EACrC,YAAY,QAAQ,IAAI,qBAAqB;EAC7C,QAAQ,QAAQ,IAAI,gBAAgB;EACpC,UAAU,QAAQ,IAAI,mBAAmB;EACzC,WAAW,QAAQ,IAAI,qBAAqB;EAC5C,aAAa,SAAS,QAAQ,IAAI,kBAAkB;EACpD,QAAQ,QAAQ,IAAI,iBAAiB;EACrC,aAAa;GACX;GACA;GACA,aAAa,QAAQ,IAAI;EAC3B;EACA,WAAW;GACT,UAAU,SAAS,QAAQ,IAAI,wBAAwB;GACvD,OAAO,SAAS,QAAQ,IAAI,qBAAqB;EACnD;CACF;AACF;AAEA,MAAa,4BAA4B,QAAiC;CACxE,MAAM,UAAU,OAAO,KAAK,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,OAAO,OAAO,KAAK,GAAG,MAAM,KAAK,QAAQ,KAAK,CAAC,GAAG,CAAC,CAAC;CAIlH,MAAM,WAAW,IAAI,YAAY,YAAY,UAAU;CACvD,MAAM,oBAAoB,IAAI,IAAI,IAAI,eAAe,IAAI,OAAO,IAAI,GAAG,SAAS,eAAe;CAC/F,OAAO,IAAI,QAAQ,mBAAmB;EACpC,QAAQ,IAAI;EACZ,SAAS,IAAI,QAAQ,OAAO;CAC9B,CAAC;AACH;;;;;AAMA,MAAa,yBAAyB,QAAiC;CACrE,MAAM,UAAU,IAAI,QAAQ;CAC5B,OAAO,QAAQ,IAAI,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,WAAW;EACpD,IAAI,OACF,QAAQ,IAAI,KAAK,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK;CAEpE,CAAC;CAED,MAAM,WAAW,IAAI,aAAa,IAAI,SAAS,UAAU;CACzD,MAAM,OAAO,IAAI,IAAI,MAAM,KAAK;CAChC,MAAM,MAAM,IAAI,IAAI,IAAI,eAAe,IAAI,KAAK,GAAG,SAAS,KAAK,MAAM;CAEvE,MAAM,UAAU;EAAC;EAAQ;EAAO;CAAO,CAAC,CAAC,SAAS,IAAI,MAAM;CAE5D,OAAO,IAAI,QAAQ,IAAI,SAAS,GAAG;EACjC,QAAQ,IAAI;EACZ;EACA,MAAM,UAAW,SAAS,MAAM,GAAG,IAAuB;EAE1D,QAAQ,UAAU,SAAS;CAC7B,CAAC;AACH"}
1
+ {"version":3,"file":"utils-DnpNAWof.mjs","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import { isTruthy } from '@clerk/shared/underscore';\nimport type { Request as ExpressRequest } from 'express';\nimport { Readable } from 'stream';\n\nimport type { ExpressRequestWithAuth } from './types';\n\n/**\n * Brand attached to the `req.auth` handler installed by Clerk middleware.\n * `req.auth` is a property name shared with other auth libraries (express-jwt,\n * passport, express-openid-connect), so its mere presence proves nothing about\n * whether Clerk authenticated the request. `Symbol.for` registers the brand\n * globally so it stays stable across multiple copies of this package loaded in\n * the same process.\n */\nconst clerkAuthBrand = Symbol.for('@clerk/express.auth');\n\nexport const brandRequestAuth = <T extends (...args: never[]) => unknown>(authHandler: T): T =>\n Object.assign(authHandler, { [clerkAuthBrand]: true });\n\nexport const requestHasAuthObject = (req: ExpressRequest): req is ExpressRequestWithAuth => {\n const auth = (req as Partial<ExpressRequestWithAuth>).auth;\n return typeof auth === 'function' && (auth as unknown as Record<symbol, unknown>)[clerkAuthBrand] === true;\n};\n\nexport const loadClientEnv = () => {\n return {\n publishableKey: process.env.CLERK_PUBLISHABLE_KEY || '',\n __internal_clerkJSUrl: process.env.CLERK_JS || process.env.CLERK_JS_URL || '',\n __internal_clerkJSVersion: process.env.CLERK_JS_VERSION || '',\n __internal_clerkUIUrl: process.env.CLERK_UI_URL || '',\n __internal_clerkUIVersion: process.env.CLERK_UI_VERSION || '',\n prefetchUI: process.env.CLERK_PREFETCH_UI === 'false' ? false : undefined,\n };\n};\n\nexport const loadApiEnv = () => {\n return {\n secretKey: process.env.CLERK_SECRET_KEY || '',\n machineSecretKey: process.env.CLERK_MACHINE_SECRET_KEY || '',\n apiUrl: process.env.CLERK_API_URL || 'https://api.clerk.com',\n apiVersion: process.env.CLERK_API_VERSION || 'v1',\n domain: process.env.CLERK_DOMAIN || '',\n proxyUrl: process.env.CLERK_PROXY_URL || '',\n signInUrl: process.env.CLERK_SIGN_IN_URL || '',\n isSatellite: isTruthy(process.env.CLERK_IS_SATELLITE),\n jwtKey: process.env.CLERK_JWT_KEY || '',\n sdkMetadata: {\n name: PACKAGE_NAME,\n version: PACKAGE_VERSION,\n environment: process.env.NODE_ENV,\n },\n telemetry: {\n disabled: isTruthy(process.env.CLERK_TELEMETRY_DISABLED),\n debug: isTruthy(process.env.CLERK_TELEMETRY_DEBUG),\n },\n };\n};\n\nexport const incomingMessageToRequest = (req: ExpressRequest): Request => {\n const headers = Object.keys(req.headers).reduce((acc, key) => Object.assign(acc, { [key]: req?.headers[key] }), {});\n // @ts-ignore Optimistic attempt to get the protocol in case\n // req extends IncomingMessage in a useful way. No guarantee\n // it'll work.\n const protocol = req.connection?.encrypted ? 'https' : 'http';\n const dummyOriginReqUrl = new URL(req.originalUrl || req.url || '', `${protocol}://clerk-dummy`);\n return new Request(dummyOriginReqUrl, {\n method: req.method,\n headers: new Headers(headers),\n });\n};\n\n/**\n * Converts an Express request to a Fetch API Request with body streaming support.\n * This is used for proxying requests where the body needs to be forwarded.\n */\nexport const requestToProxyRequest = (req: ExpressRequest): Request => {\n const headers = new Headers();\n Object.entries(req.headers).forEach(([key, value]) => {\n if (value) {\n headers.set(key, Array.isArray(value) ? value.join(', ') : value);\n }\n });\n\n const protocol = req.protocol || (req.secure ? 'https' : 'http');\n const host = req.get('host') || 'localhost';\n const url = new URL(req.originalUrl || req.url, `${protocol}://${host}`);\n\n const hasBody = ['POST', 'PUT', 'PATCH'].includes(req.method);\n\n return new Request(url.toString(), {\n method: req.method,\n headers,\n body: hasBody ? (Readable.toWeb(req) as ReadableStream) : undefined,\n // @ts-expect-error - duplex required for streaming bodies but not in all TS definitions\n duplex: hasBody ? 'half' : undefined,\n });\n};\n"],"mappings":";;;;;;;;;;;;AAcA,MAAM,iBAAiB,OAAO,IAAI,qBAAqB;AAEvD,MAAa,oBAA6D,gBACxE,OAAO,OAAO,aAAa,GAAG,iBAAiB,KAAK,CAAC;AAEvD,MAAa,wBAAwB,QAAuD;CAC1F,MAAM,OAAQ,IAAwC;CACtD,OAAO,OAAO,SAAS,cAAe,KAA4C,oBAAoB;AACxG;AAEA,MAAa,sBAAsB;CACjC,OAAO;EACL,gBAAgB,QAAQ,IAAI,yBAAyB;EACrD,uBAAuB,QAAQ,IAAI,YAAY,QAAQ,IAAI,gBAAgB;EAC3E,2BAA2B,QAAQ,IAAI,oBAAoB;EAC3D,uBAAuB,QAAQ,IAAI,gBAAgB;EACnD,2BAA2B,QAAQ,IAAI,oBAAoB;EAC3D,YAAY,QAAQ,IAAI,sBAAsB,UAAU,QAAQ;CAClE;AACF;AAEA,MAAa,mBAAmB;CAC9B,OAAO;EACL,WAAW,QAAQ,IAAI,oBAAoB;EAC3C,kBAAkB,QAAQ,IAAI,4BAA4B;EAC1D,QAAQ,QAAQ,IAAI,iBAAiB;EACrC,YAAY,QAAQ,IAAI,qBAAqB;EAC7C,QAAQ,QAAQ,IAAI,gBAAgB;EACpC,UAAU,QAAQ,IAAI,mBAAmB;EACzC,WAAW,QAAQ,IAAI,qBAAqB;EAC5C,aAAa,SAAS,QAAQ,IAAI,kBAAkB;EACpD,QAAQ,QAAQ,IAAI,iBAAiB;EACrC,aAAa;GACX;GACA;GACA,aAAa,QAAQ,IAAI;EAC3B;EACA,WAAW;GACT,UAAU,SAAS,QAAQ,IAAI,wBAAwB;GACvD,OAAO,SAAS,QAAQ,IAAI,qBAAqB;EACnD;CACF;AACF;AAEA,MAAa,4BAA4B,QAAiC;CACxE,MAAM,UAAU,OAAO,KAAK,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,OAAO,OAAO,KAAK,GAAG,MAAM,KAAK,QAAQ,KAAK,CAAC,GAAG,CAAC,CAAC;CAIlH,MAAM,WAAW,IAAI,YAAY,YAAY,UAAU;CACvD,MAAM,oBAAoB,IAAI,IAAI,IAAI,eAAe,IAAI,OAAO,IAAI,GAAG,SAAS,eAAe;CAC/F,OAAO,IAAI,QAAQ,mBAAmB;EACpC,QAAQ,IAAI;EACZ,SAAS,IAAI,QAAQ,OAAO;CAC9B,CAAC;AACH;;;;;AAMA,MAAa,yBAAyB,QAAiC;CACrE,MAAM,UAAU,IAAI,QAAQ;CAC5B,OAAO,QAAQ,IAAI,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,WAAW;EACpD,IAAI,OACF,QAAQ,IAAI,KAAK,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK;CAEpE,CAAC;CAED,MAAM,WAAW,IAAI,aAAa,IAAI,SAAS,UAAU;CACzD,MAAM,OAAO,IAAI,IAAI,MAAM,KAAK;CAChC,MAAM,MAAM,IAAI,IAAI,IAAI,eAAe,IAAI,KAAK,GAAG,SAAS,KAAK,MAAM;CAEvE,MAAM,UAAU;EAAC;EAAQ;EAAO;CAAO,CAAC,CAAC,SAAS,IAAI,MAAM;CAE5D,OAAO,IAAI,QAAQ,IAAI,SAAS,GAAG;EACjC,QAAQ,IAAI;EACZ;EACA,MAAM,UAAW,SAAS,MAAM,GAAG,IAAuB;EAE1D,QAAQ,UAAU,SAAS;CAC7B,CAAC;AACH"}
package/dist/webhooks.js CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_utils = require('./utils-BKrEOl3y.js');
2
+ const require_utils = require('./utils-8eqSXbcQ.js');
3
3
  let _clerk_backend_webhooks = require("@clerk/backend/webhooks");
4
4
 
5
5
  //#region src/webhooks.ts
package/dist/webhooks.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { n as incomingMessageToRequest } from "./utils-CW7I2k9m.mjs";
1
+ import { n as incomingMessageToRequest } from "./utils-DnpNAWof.mjs";
2
2
  import { verifyWebhook as verifyWebhook$1 } from "@clerk/backend/webhooks";
3
3
 
4
4
  export * from "@clerk/backend/webhooks"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clerk/express",
3
- "version": "2.1.49",
3
+ "version": "2.1.50-canary.v20260731161424",
4
4
  "description": "Clerk server SDK for usage with Express",
5
5
  "keywords": [
6
6
  "clerk",
@@ -62,8 +62,8 @@
62
62
  ],
63
63
  "dependencies": {
64
64
  "tslib": "2.8.1",
65
- "@clerk/backend": "^3.15.0",
66
- "@clerk/shared": "^4.25.10"
65
+ "@clerk/backend": "3.15.1-canary.v20260731161424",
66
+ "@clerk/shared": "4.25.11-canary.v20260731161424"
67
67
  },
68
68
  "devDependencies": {
69
69
  "@types/express": "^4.17.25",