@clerk/nextjs 7.5.21-snapshot.v20260720201619 → 7.5.21

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.
@@ -58,7 +58,7 @@ const SIGN_IN_URL = process.env.NEXT_PUBLIC_CLERK_SIGN_IN_URL || "";
58
58
  const SIGN_UP_URL = process.env.NEXT_PUBLIC_CLERK_SIGN_UP_URL || "";
59
59
  const SDK_METADATA = {
60
60
  name: "@clerk/nextjs",
61
- version: "7.5.21-snapshot.v20260720201619",
61
+ version: "7.5.21",
62
62
  environment: process.env.NODE_ENV
63
63
  };
64
64
  const TELEMETRY_DISABLED = (0, import_underscore.isTruthy)(process.env.NEXT_PUBLIC_CLERK_TELEMETRY_DISABLED);
@@ -23,6 +23,7 @@ __export(content_security_policy_exports, {
23
23
  });
24
24
  module.exports = __toCommonJS(content_security_policy_exports);
25
25
  var import_internal = require("@clerk/backend/internal");
26
+ const clerkProtectionOrigins = ["https://*.protect.clerk.com", "https://*.client.protect.clerk.com"];
26
27
  class ContentSecurityPolicyDirectiveManager {
27
28
  /**
28
29
  * Creates a new ContentSecurityPolicyDirectiveSet with default values
@@ -84,7 +85,8 @@ ContentSecurityPolicyDirectiveManager.DEFAULT_DIRECTIVES = {
84
85
  "https://api.stripe.com",
85
86
  "https://maps.googleapis.com",
86
87
  "https://img.clerk.com",
87
- "https://images.clerkstage.dev"
88
+ "https://images.clerkstage.dev",
89
+ ...clerkProtectionOrigins
88
90
  ],
89
91
  "default-src": ["self"],
90
92
  "form-action": ["self"],
@@ -93,7 +95,8 @@ ContentSecurityPolicyDirectiveManager.DEFAULT_DIRECTIVES = {
93
95
  "https://challenges.cloudflare.com",
94
96
  "https://*.js.stripe.com",
95
97
  "https://js.stripe.com",
96
- "https://hooks.stripe.com"
98
+ "https://hooks.stripe.com",
99
+ ...clerkProtectionOrigins
97
100
  ],
98
101
  "img-src": ["self", "https://img.clerk.com"],
99
102
  "script-src": [
@@ -104,7 +107,8 @@ ContentSecurityPolicyDirectiveManager.DEFAULT_DIRECTIVES = {
104
107
  "http:",
105
108
  "https://*.js.stripe.com",
106
109
  "https://js.stripe.com",
107
- "https://maps.googleapis.com"
110
+ "https://maps.googleapis.com",
111
+ ...clerkProtectionOrigins
108
112
  ],
109
113
  "style-src": ["self", "unsafe-inline"],
110
114
  "worker-src": ["self", "blob:"]
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/server/content-security-policy.ts"],"sourcesContent":["import { constants } from '@clerk/backend/internal';\n\n/**\n * Valid CSP directives according to the CSP Level 3 specification\n */\nexport type ContentSecurityPolicyDirective =\n // Default resource directives\n | 'connect-src'\n | 'default-src'\n | 'font-src'\n | 'img-src'\n | 'media-src'\n | 'object-src'\n | 'script-src'\n | 'style-src'\n // Framing and navigation directives\n | 'base-uri'\n | 'child-src'\n | 'form-action'\n | 'frame-ancestors'\n | 'frame-src'\n | 'manifest-src'\n | 'navigate-to'\n | 'prefetch-src'\n | 'worker-src'\n // Sandbox and plugin directives\n | 'plugin-types'\n | 'require-sri-for'\n | 'sandbox'\n // Trusted types and upgrade directives\n | 'block-all-mixed-content'\n | 'require-trusted-types-for'\n | 'trusted-types'\n | 'upgrade-insecure-requests'\n // Reporting directives\n | 'report-to'\n | 'report-uri'\n // CSP Level 3 additional directives\n | 'script-src-attr'\n | 'script-src-elem'\n | 'style-src-attr'\n | 'style-src-elem';\n\n/**\n * Partial record of directives and their values\n */\ntype ContentSecurityPolicyValues = Partial<Record<ContentSecurityPolicyDirective, string[]>>;\n\n/**\n * Directives and their values\n */\ntype ContentSecurityPolicyDirectiveSet = Record<ContentSecurityPolicyDirective, Set<string>>;\n\nexport interface ContentSecurityPolicyHeaders {\n /**\n * Array of formatted headers to be added to the response.\n *\n * Includes both standard and report-only headers when applicable.\n * Includes nonce when strict mode is enabled.\n */\n headers: [string, string][];\n}\n\nexport interface ContentSecurityPolicyOptions {\n /**\n * When set to true, enhances security by applying the `strict-dynamic` attribute to the `script-src` CSP directive\n */\n strict?: boolean;\n /**\n * Custom CSP directives to merge with Clerk's default directives\n */\n directives?: Partial<Record<ContentSecurityPolicyDirective, string[]>>;\n /**\n * When set to true, the Content-Security-Policy-Report-Only header will be used instead of\n * Content-Security-Policy. This allows monitoring policy violations without blocking content.\n */\n reportOnly?: boolean;\n /**\n * Specifies a reporting endpoint for CSP violations. This value will be used in the\n * 'report-to' directive of the Content-Security-Policy header.\n */\n reportTo?: string;\n}\n\nclass ContentSecurityPolicyDirectiveManager {\n /** Set of special keywords that require quoting in CSP directives */\n private static readonly KEYWORDS = new Set([\n 'none',\n 'self',\n 'strict-dynamic',\n 'unsafe-eval',\n 'unsafe-hashes',\n 'unsafe-inline',\n ]);\n\n /** Default CSP directives and their values */\n static readonly DEFAULT_DIRECTIVES: ContentSecurityPolicyValues = {\n 'connect-src': [\n 'self',\n 'https://clerk-telemetry.com',\n 'https://*.clerk-telemetry.com',\n 'https://api.stripe.com',\n 'https://maps.googleapis.com',\n 'https://img.clerk.com',\n 'https://images.clerkstage.dev',\n ],\n 'default-src': ['self'],\n 'form-action': ['self'],\n 'frame-src': [\n 'self',\n 'https://challenges.cloudflare.com',\n 'https://*.js.stripe.com',\n 'https://js.stripe.com',\n 'https://hooks.stripe.com',\n ],\n 'img-src': ['self', 'https://img.clerk.com'],\n 'script-src': [\n 'self',\n ...(process.env.NODE_ENV !== 'production' ? ['unsafe-eval'] : []),\n 'unsafe-inline',\n 'https:',\n 'http:',\n 'https://*.js.stripe.com',\n 'https://js.stripe.com',\n 'https://maps.googleapis.com',\n ],\n 'style-src': ['self', 'unsafe-inline'],\n 'worker-src': ['self', 'blob:'],\n };\n\n /**\n * Creates a new ContentSecurityPolicyDirectiveSet with default values\n * @returns A new ContentSecurityPolicyDirectiveSet with default values\n */\n static createDefaultDirectives(): ContentSecurityPolicyDirectiveSet {\n return Object.entries(this.DEFAULT_DIRECTIVES).reduce((acc, [key, values]) => {\n acc[key as ContentSecurityPolicyDirective] = new Set(values);\n return acc;\n }, {} as ContentSecurityPolicyDirectiveSet);\n }\n\n /**\n * Checks if a value is a special keyword that requires quoting\n * @param value - The value to check\n * @returns True if the value is a special keyword\n */\n static isKeyword(value: string): boolean {\n return this.KEYWORDS.has(value.replace(/^'|'$/g, ''));\n }\n\n /**\n * Formats a value according to CSP rules, adding quotes for special keywords\n * @param value - The value to format\n * @returns The formatted value\n */\n static formatValue(value: string): string {\n const unquoted = value.replace(/^'|'$/g, '');\n return this.isKeyword(unquoted) ? `'${unquoted}'` : value;\n }\n\n /**\n * Handles directive values, ensuring proper formatting and special case handling\n * @param values - Array of values to process\n * @returns Set of formatted values\n */\n static handleDirectiveValues(values: string[]): Set<string> {\n const result = new Set<string>();\n\n if (values.includes(\"'none'\") || values.includes('none')) {\n result.add(\"'none'\");\n return result;\n }\n\n values.forEach(v => result.add(this.formatValue(v)));\n return result;\n }\n}\n\n/**\n * Handles merging of existing directives with new values\n * @param mergedCSP - The current merged CSP state\n * @param key - The directive key to handle\n * @param values - New values to merge\n */\nfunction handleExistingDirective(\n mergedCSP: ContentSecurityPolicyDirectiveSet,\n key: ContentSecurityPolicyDirective,\n values: string[],\n) {\n // None overrides all other values\n if (values.includes(\"'none'\") || values.includes('none')) {\n mergedCSP[key] = new Set([\"'none'\"]);\n return;\n }\n\n // For existing directives, merge the values rather than replacing\n const deduplicatedSet = new Set<string>();\n\n mergedCSP[key].forEach(value => {\n deduplicatedSet.add(ContentSecurityPolicyDirectiveManager.formatValue(value));\n });\n\n values.forEach(value => {\n deduplicatedSet.add(ContentSecurityPolicyDirectiveManager.formatValue(value));\n });\n\n mergedCSP[key] = deduplicatedSet;\n}\n\n/**\n * Handles custom directives that are not part of the default set\n * @param customDirectives - Map of custom directives\n * @param key - The directive key\n * @param values - Values for the directive\n */\nfunction handleCustomDirective(customDirectives: Map<string, Set<string>>, key: string, values: string[]) {\n // None overrides all other values\n if (values.includes(\"'none'\") || values.includes('none')) {\n customDirectives.set(key, new Set([\"'none'\"]));\n return;\n }\n\n const formattedValues = new Set<string>();\n values.forEach(value => {\n const formattedValue = ContentSecurityPolicyDirectiveManager.formatValue(value);\n formattedValues.add(formattedValue);\n });\n\n customDirectives.set(key, formattedValues);\n}\n\n/**\n * Applies formatting to the CSP header\n * @param mergedCSP - The merged CSP state to format\n * @returns Formatted CSP header string\n */\nfunction formatCSPHeader(mergedCSP: Record<string, Set<string>>): string {\n return Object.entries(mergedCSP)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, values]) => {\n const valueObjs = Array.from(values).map(v => ({\n raw: v,\n formatted: ContentSecurityPolicyDirectiveManager.formatValue(v),\n }));\n\n return `${key} ${valueObjs.map(item => item.formatted).join(' ')}`;\n })\n .join('; ');\n}\n\n/**\n * Generates a secure random nonce for CSP headers\n * @returns A base64-encoded random nonce\n */\nexport function generateNonce(): string {\n const randomBytes = new Uint8Array(16);\n crypto.getRandomValues(randomBytes);\n const binaryString = Array.from(randomBytes, byte => String.fromCharCode(byte)).join('');\n return btoa(binaryString);\n}\n\n/**\n * Builds a complete set of CSP directives by combining defaults with custom directives,\n * applying special configurations like strict mode and nonce, and formatting them into a valid CSP string.\n */\nfunction buildContentSecurityPolicyDirectives(\n strict: boolean,\n host: string,\n customDirectives?: Partial<Record<ContentSecurityPolicyDirective, string[]>>,\n nonce?: string,\n): string {\n const directives = Object.entries(ContentSecurityPolicyDirectiveManager.DEFAULT_DIRECTIVES).reduce(\n (acc, [key, values]) => {\n acc[key as ContentSecurityPolicyDirective] = new Set(values);\n return acc;\n },\n {} as ContentSecurityPolicyDirectiveSet,\n );\n\n directives['connect-src'].add(host);\n\n if (strict) {\n directives['script-src'].delete('http:');\n directives['script-src'].delete('https:');\n directives['script-src'].add(\"'strict-dynamic'\");\n if (nonce) {\n directives['script-src'].add(`'nonce-${nonce}'`);\n }\n }\n\n if (customDirectives) {\n const customDirectivesMap = new Map<string, Set<string>>();\n Object.entries(customDirectives).forEach(([key, values]) => {\n const valuesArray = Array.isArray(values) ? values : [values];\n if (ContentSecurityPolicyDirectiveManager.DEFAULT_DIRECTIVES[key as ContentSecurityPolicyDirective]) {\n handleExistingDirective(directives, key as ContentSecurityPolicyDirective, valuesArray);\n } else {\n handleCustomDirective(customDirectivesMap, key, valuesArray);\n }\n });\n\n // Merge all custom directives into the final directives object\n customDirectivesMap.forEach((values, key) => {\n directives[key as ContentSecurityPolicyDirective] = values;\n });\n }\n\n return formatCSPHeader(directives);\n}\n\n/**\n * Creates Content Security Policy (CSP) headers with the specified configuration\n * @returns Object containing the formatted CSP headers\n */\nexport function createContentSecurityPolicyHeaders(\n host: string,\n options: ContentSecurityPolicyOptions,\n): ContentSecurityPolicyHeaders {\n const headers: [string, string][] = [];\n\n const nonce = options.strict ? generateNonce() : undefined;\n\n let cspHeader = buildContentSecurityPolicyDirectives(options.strict ?? false, host, options.directives, nonce);\n\n if (options.reportTo) {\n cspHeader += '; report-to csp-endpoint';\n headers.push([constants.Headers.ReportingEndpoints, `csp-endpoint=\"${options.reportTo}\"`]);\n }\n\n if (options.reportOnly) {\n headers.push([constants.Headers.ContentSecurityPolicyReportOnly, cspHeader]);\n } else {\n headers.push([constants.Headers.ContentSecurityPolicy, cspHeader]);\n }\n\n if (nonce) {\n headers.push([constants.Headers.Nonce, nonce]);\n }\n\n return {\n headers,\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/server/content-security-policy.ts"],"sourcesContent":["import { constants } from '@clerk/backend/internal';\n\nconst clerkProtectionOrigins = ['https://*.protect.clerk.com', 'https://*.client.protect.clerk.com'];\n\n/**\n * Valid CSP directives according to the CSP Level 3 specification\n */\nexport type ContentSecurityPolicyDirective =\n // Default resource directives\n | 'connect-src'\n | 'default-src'\n | 'font-src'\n | 'img-src'\n | 'media-src'\n | 'object-src'\n | 'script-src'\n | 'style-src'\n // Framing and navigation directives\n | 'base-uri'\n | 'child-src'\n | 'form-action'\n | 'frame-ancestors'\n | 'frame-src'\n | 'manifest-src'\n | 'navigate-to'\n | 'prefetch-src'\n | 'worker-src'\n // Sandbox and plugin directives\n | 'plugin-types'\n | 'require-sri-for'\n | 'sandbox'\n // Trusted types and upgrade directives\n | 'block-all-mixed-content'\n | 'require-trusted-types-for'\n | 'trusted-types'\n | 'upgrade-insecure-requests'\n // Reporting directives\n | 'report-to'\n | 'report-uri'\n // CSP Level 3 additional directives\n | 'script-src-attr'\n | 'script-src-elem'\n | 'style-src-attr'\n | 'style-src-elem';\n\n/**\n * Partial record of directives and their values\n */\ntype ContentSecurityPolicyValues = Partial<Record<ContentSecurityPolicyDirective, string[]>>;\n\n/**\n * Directives and their values\n */\ntype ContentSecurityPolicyDirectiveSet = Record<ContentSecurityPolicyDirective, Set<string>>;\n\nexport interface ContentSecurityPolicyHeaders {\n /**\n * Array of formatted headers to be added to the response.\n *\n * Includes both standard and report-only headers when applicable.\n * Includes nonce when strict mode is enabled.\n */\n headers: [string, string][];\n}\n\nexport interface ContentSecurityPolicyOptions {\n /**\n * When set to true, enhances security by applying the `strict-dynamic` attribute to the `script-src` CSP directive\n */\n strict?: boolean;\n /**\n * Custom CSP directives to merge with Clerk's default directives\n */\n directives?: Partial<Record<ContentSecurityPolicyDirective, string[]>>;\n /**\n * When set to true, the Content-Security-Policy-Report-Only header will be used instead of\n * Content-Security-Policy. This allows monitoring policy violations without blocking content.\n */\n reportOnly?: boolean;\n /**\n * Specifies a reporting endpoint for CSP violations. This value will be used in the\n * 'report-to' directive of the Content-Security-Policy header.\n */\n reportTo?: string;\n}\n\nclass ContentSecurityPolicyDirectiveManager {\n /** Set of special keywords that require quoting in CSP directives */\n private static readonly KEYWORDS = new Set([\n 'none',\n 'self',\n 'strict-dynamic',\n 'unsafe-eval',\n 'unsafe-hashes',\n 'unsafe-inline',\n ]);\n\n /** Default CSP directives and their values */\n static readonly DEFAULT_DIRECTIVES: ContentSecurityPolicyValues = {\n 'connect-src': [\n 'self',\n 'https://clerk-telemetry.com',\n 'https://*.clerk-telemetry.com',\n 'https://api.stripe.com',\n 'https://maps.googleapis.com',\n 'https://img.clerk.com',\n 'https://images.clerkstage.dev',\n ...clerkProtectionOrigins,\n ],\n 'default-src': ['self'],\n 'form-action': ['self'],\n 'frame-src': [\n 'self',\n 'https://challenges.cloudflare.com',\n 'https://*.js.stripe.com',\n 'https://js.stripe.com',\n 'https://hooks.stripe.com',\n ...clerkProtectionOrigins,\n ],\n 'img-src': ['self', 'https://img.clerk.com'],\n 'script-src': [\n 'self',\n ...(process.env.NODE_ENV !== 'production' ? ['unsafe-eval'] : []),\n 'unsafe-inline',\n 'https:',\n 'http:',\n 'https://*.js.stripe.com',\n 'https://js.stripe.com',\n 'https://maps.googleapis.com',\n ...clerkProtectionOrigins,\n ],\n 'style-src': ['self', 'unsafe-inline'],\n 'worker-src': ['self', 'blob:'],\n };\n\n /**\n * Creates a new ContentSecurityPolicyDirectiveSet with default values\n * @returns A new ContentSecurityPolicyDirectiveSet with default values\n */\n static createDefaultDirectives(): ContentSecurityPolicyDirectiveSet {\n return Object.entries(this.DEFAULT_DIRECTIVES).reduce((acc, [key, values]) => {\n acc[key as ContentSecurityPolicyDirective] = new Set(values);\n return acc;\n }, {} as ContentSecurityPolicyDirectiveSet);\n }\n\n /**\n * Checks if a value is a special keyword that requires quoting\n * @param value - The value to check\n * @returns True if the value is a special keyword\n */\n static isKeyword(value: string): boolean {\n return this.KEYWORDS.has(value.replace(/^'|'$/g, ''));\n }\n\n /**\n * Formats a value according to CSP rules, adding quotes for special keywords\n * @param value - The value to format\n * @returns The formatted value\n */\n static formatValue(value: string): string {\n const unquoted = value.replace(/^'|'$/g, '');\n return this.isKeyword(unquoted) ? `'${unquoted}'` : value;\n }\n\n /**\n * Handles directive values, ensuring proper formatting and special case handling\n * @param values - Array of values to process\n * @returns Set of formatted values\n */\n static handleDirectiveValues(values: string[]): Set<string> {\n const result = new Set<string>();\n\n if (values.includes(\"'none'\") || values.includes('none')) {\n result.add(\"'none'\");\n return result;\n }\n\n values.forEach(v => result.add(this.formatValue(v)));\n return result;\n }\n}\n\n/**\n * Handles merging of existing directives with new values\n * @param mergedCSP - The current merged CSP state\n * @param key - The directive key to handle\n * @param values - New values to merge\n */\nfunction handleExistingDirective(\n mergedCSP: ContentSecurityPolicyDirectiveSet,\n key: ContentSecurityPolicyDirective,\n values: string[],\n) {\n // None overrides all other values\n if (values.includes(\"'none'\") || values.includes('none')) {\n mergedCSP[key] = new Set([\"'none'\"]);\n return;\n }\n\n // For existing directives, merge the values rather than replacing\n const deduplicatedSet = new Set<string>();\n\n mergedCSP[key].forEach(value => {\n deduplicatedSet.add(ContentSecurityPolicyDirectiveManager.formatValue(value));\n });\n\n values.forEach(value => {\n deduplicatedSet.add(ContentSecurityPolicyDirectiveManager.formatValue(value));\n });\n\n mergedCSP[key] = deduplicatedSet;\n}\n\n/**\n * Handles custom directives that are not part of the default set\n * @param customDirectives - Map of custom directives\n * @param key - The directive key\n * @param values - Values for the directive\n */\nfunction handleCustomDirective(customDirectives: Map<string, Set<string>>, key: string, values: string[]) {\n // None overrides all other values\n if (values.includes(\"'none'\") || values.includes('none')) {\n customDirectives.set(key, new Set([\"'none'\"]));\n return;\n }\n\n const formattedValues = new Set<string>();\n values.forEach(value => {\n const formattedValue = ContentSecurityPolicyDirectiveManager.formatValue(value);\n formattedValues.add(formattedValue);\n });\n\n customDirectives.set(key, formattedValues);\n}\n\n/**\n * Applies formatting to the CSP header\n * @param mergedCSP - The merged CSP state to format\n * @returns Formatted CSP header string\n */\nfunction formatCSPHeader(mergedCSP: Record<string, Set<string>>): string {\n return Object.entries(mergedCSP)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, values]) => {\n const valueObjs = Array.from(values).map(v => ({\n raw: v,\n formatted: ContentSecurityPolicyDirectiveManager.formatValue(v),\n }));\n\n return `${key} ${valueObjs.map(item => item.formatted).join(' ')}`;\n })\n .join('; ');\n}\n\n/**\n * Generates a secure random nonce for CSP headers\n * @returns A base64-encoded random nonce\n */\nexport function generateNonce(): string {\n const randomBytes = new Uint8Array(16);\n crypto.getRandomValues(randomBytes);\n const binaryString = Array.from(randomBytes, byte => String.fromCharCode(byte)).join('');\n return btoa(binaryString);\n}\n\n/**\n * Builds a complete set of CSP directives by combining defaults with custom directives,\n * applying special configurations like strict mode and nonce, and formatting them into a valid CSP string.\n */\nfunction buildContentSecurityPolicyDirectives(\n strict: boolean,\n host: string,\n customDirectives?: Partial<Record<ContentSecurityPolicyDirective, string[]>>,\n nonce?: string,\n): string {\n const directives = Object.entries(ContentSecurityPolicyDirectiveManager.DEFAULT_DIRECTIVES).reduce(\n (acc, [key, values]) => {\n acc[key as ContentSecurityPolicyDirective] = new Set(values);\n return acc;\n },\n {} as ContentSecurityPolicyDirectiveSet,\n );\n\n directives['connect-src'].add(host);\n\n if (strict) {\n directives['script-src'].delete('http:');\n directives['script-src'].delete('https:');\n directives['script-src'].add(\"'strict-dynamic'\");\n if (nonce) {\n directives['script-src'].add(`'nonce-${nonce}'`);\n }\n }\n\n if (customDirectives) {\n const customDirectivesMap = new Map<string, Set<string>>();\n Object.entries(customDirectives).forEach(([key, values]) => {\n const valuesArray = Array.isArray(values) ? values : [values];\n if (ContentSecurityPolicyDirectiveManager.DEFAULT_DIRECTIVES[key as ContentSecurityPolicyDirective]) {\n handleExistingDirective(directives, key as ContentSecurityPolicyDirective, valuesArray);\n } else {\n handleCustomDirective(customDirectivesMap, key, valuesArray);\n }\n });\n\n // Merge all custom directives into the final directives object\n customDirectivesMap.forEach((values, key) => {\n directives[key as ContentSecurityPolicyDirective] = values;\n });\n }\n\n return formatCSPHeader(directives);\n}\n\n/**\n * Creates Content Security Policy (CSP) headers with the specified configuration\n * @returns Object containing the formatted CSP headers\n */\nexport function createContentSecurityPolicyHeaders(\n host: string,\n options: ContentSecurityPolicyOptions,\n): ContentSecurityPolicyHeaders {\n const headers: [string, string][] = [];\n\n const nonce = options.strict ? generateNonce() : undefined;\n\n let cspHeader = buildContentSecurityPolicyDirectives(options.strict ?? false, host, options.directives, nonce);\n\n if (options.reportTo) {\n cspHeader += '; report-to csp-endpoint';\n headers.push([constants.Headers.ReportingEndpoints, `csp-endpoint=\"${options.reportTo}\"`]);\n }\n\n if (options.reportOnly) {\n headers.push([constants.Headers.ContentSecurityPolicyReportOnly, cspHeader]);\n } else {\n headers.push([constants.Headers.ContentSecurityPolicy, cspHeader]);\n }\n\n if (nonce) {\n headers.push([constants.Headers.Nonce, nonce]);\n }\n\n return {\n headers,\n };\n}\n"],"mappings":"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","names":[]}
@@ -28,7 +28,7 @@ const clerkClientDefaultOptions = {
28
28
  publishableKey: import_constants.PUBLISHABLE_KEY,
29
29
  apiUrl: import_constants.API_URL,
30
30
  apiVersion: import_constants.API_VERSION,
31
- userAgent: `${"@clerk/nextjs"}@${"7.5.21-snapshot.v20260720201619"}`,
31
+ userAgent: `${"@clerk/nextjs"}@${"7.5.21"}`,
32
32
  proxyUrl: import_constants.PROXY_URL,
33
33
  domain: import_constants.DOMAIN,
34
34
  isSatellite: import_constants.IS_SATELLITE,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/server/createClerkClient.ts"],"sourcesContent":["import { createClerkClient } from '@clerk/backend';\n\nimport {\n API_URL,\n API_VERSION,\n DOMAIN,\n IS_SATELLITE,\n MACHINE_SECRET_KEY,\n PROXY_URL,\n PUBLISHABLE_KEY,\n SDK_METADATA,\n SECRET_KEY,\n TELEMETRY_DEBUG,\n TELEMETRY_DISABLED,\n} from './constants';\n\nconst clerkClientDefaultOptions = {\n secretKey: SECRET_KEY,\n publishableKey: PUBLISHABLE_KEY,\n apiUrl: API_URL,\n apiVersion: API_VERSION,\n userAgent: `${PACKAGE_NAME}@${PACKAGE_VERSION}`,\n proxyUrl: PROXY_URL,\n domain: DOMAIN,\n isSatellite: IS_SATELLITE,\n machineSecretKey: MACHINE_SECRET_KEY,\n sdkMetadata: SDK_METADATA,\n telemetry: {\n disabled: TELEMETRY_DISABLED,\n debug: TELEMETRY_DEBUG,\n },\n};\n\nexport const createClerkClientWithOptions: typeof createClerkClient = options =>\n createClerkClient({ ...clerkClientDefaultOptions, ...options });\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAkC;AAElC,uBAYO;AAEP,MAAM,4BAA4B;AAAA,EAChC,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,WAAW,GAAG,eAAY,IAAI,iCAAe;AAAA,EAC7C,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,WAAW;AAAA,IACT,UAAU;AAAA,IACV,OAAO;AAAA,EACT;AACF;AAEO,MAAM,+BAAyD,iBACpE,kCAAkB,EAAE,GAAG,2BAA2B,GAAG,QAAQ,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../../src/server/createClerkClient.ts"],"sourcesContent":["import { createClerkClient } from '@clerk/backend';\n\nimport {\n API_URL,\n API_VERSION,\n DOMAIN,\n IS_SATELLITE,\n MACHINE_SECRET_KEY,\n PROXY_URL,\n PUBLISHABLE_KEY,\n SDK_METADATA,\n SECRET_KEY,\n TELEMETRY_DEBUG,\n TELEMETRY_DISABLED,\n} from './constants';\n\nconst clerkClientDefaultOptions = {\n secretKey: SECRET_KEY,\n publishableKey: PUBLISHABLE_KEY,\n apiUrl: API_URL,\n apiVersion: API_VERSION,\n userAgent: `${PACKAGE_NAME}@${PACKAGE_VERSION}`,\n proxyUrl: PROXY_URL,\n domain: DOMAIN,\n isSatellite: IS_SATELLITE,\n machineSecretKey: MACHINE_SECRET_KEY,\n sdkMetadata: SDK_METADATA,\n telemetry: {\n disabled: TELEMETRY_DISABLED,\n debug: TELEMETRY_DEBUG,\n },\n};\n\nexport const createClerkClientWithOptions: typeof createClerkClient = options =>\n createClerkClient({ ...clerkClientDefaultOptions, ...options });\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAkC;AAElC,uBAYO;AAEP,MAAM,4BAA4B;AAAA,EAChC,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,WAAW,GAAG,eAAY,IAAI,QAAe;AAAA,EAC7C,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,WAAW;AAAA,IACT,UAAU;AAAA,IACV,OAAO;AAAA,EACT;AACF;AAEO,MAAM,+BAAyD,iBACpE,kCAAkB,EAAE,GAAG,2BAA2B,GAAG,QAAQ,CAAC;","names":[]}
@@ -90,7 +90,7 @@ function debugLogHeader(name) {
90
90
  return `[clerk debug start: ${name}]`;
91
91
  }
92
92
  function debugLogFooter(name) {
93
- return `[clerk debug end: ${name}] (@clerk/nextjs=${"7.5.21-snapshot.v20260720201619"},next=${import_package.default.version},timestamp=${Math.round((/* @__PURE__ */ new Date()).getTime() / 1e3)})`;
93
+ return `[clerk debug end: ${name}] (@clerk/nextjs=${"7.5.21"},next=${import_package.default.version},timestamp=${Math.round((/* @__PURE__ */ new Date()).getTime() / 1e3)})`;
94
94
  }
95
95
  function truncate(str, maxLength) {
96
96
  const encoder = new TextEncoder();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/debugLogger.ts"],"sourcesContent":["// TODO: Replace with a more sophisticated logging solution\n\nimport nextPkg from 'next/package.json';\n\nimport { logFormatter } from './logFormatter';\n\nexport type Log = string | Record<string, unknown>;\nexport type LogEntry = Log | Log[];\nexport type Logger<L = Log> = {\n commit: () => void;\n debug: (...args: Array<L | (() => L)>) => void;\n enable: () => void;\n};\nexport type LoggerNoCommit<L = Logger> = Omit<L, 'commit'>;\n\nexport const createDebugLogger = (name: string, formatter: (val: LogEntry) => string) => (): Logger => {\n const entries: LogEntry[] = [];\n let isEnabled = false;\n\n return {\n enable: () => {\n isEnabled = true;\n },\n debug: (...args) => {\n if (isEnabled) {\n entries.push(args.map(arg => (typeof arg === 'function' ? arg() : arg)));\n }\n },\n commit: () => {\n if (isEnabled) {\n console.log(debugLogHeader(name));\n\n /**\n * We buffer each collected log entry so we can format them and log them all at once.\n * Individual console.log calls are used to ensure we don't hit platform-specific log limits (Vercel and Netlify are 4kb).\n */\n for (const log of entries) {\n let output = formatter(log);\n\n output = output\n .split('\\n')\n .map(l => ` ${l}`)\n .join('\\n');\n\n // Vercel errors if the output is > 4kb, so we truncate it\n if (process.env.VERCEL) {\n output = truncate(output, 4096);\n }\n\n console.log(output);\n }\n\n console.log(debugLogFooter(name));\n }\n },\n };\n};\n\ntype WithLogger = <L extends Logger, H extends (...args: any[]) => any>(\n loggerFactoryOrName: string | (() => L),\n handlerCtor: (logger: LoggerNoCommit<L>) => H,\n) => H;\n\nexport const withLogger: WithLogger = (loggerFactoryOrName, handlerCtor) => {\n return ((...args: any) => {\n const factory =\n typeof loggerFactoryOrName === 'string'\n ? createDebugLogger(loggerFactoryOrName, logFormatter)\n : loggerFactoryOrName;\n\n const logger = factory();\n const handler = handlerCtor(logger as any);\n\n try {\n const res = handler(...args);\n if (typeof res === 'object' && 'then' in res && typeof res.then === 'function') {\n return res\n .then((val: any) => {\n logger.commit();\n return val;\n })\n .catch((err: any) => {\n logger.commit();\n throw err;\n });\n }\n // handle sync methods\n logger.commit();\n return res;\n } catch (err: any) {\n logger.commit();\n throw err;\n }\n }) as ReturnType<typeof handlerCtor>;\n};\n\nfunction debugLogHeader(name: string) {\n return `[clerk debug start: ${name}]`;\n}\n\nfunction debugLogFooter(name: string) {\n return `[clerk debug end: ${name}] (@clerk/nextjs=${PACKAGE_VERSION},next=${nextPkg.version},timestamp=${Math.round(new Date().getTime() / 1_000)})`;\n}\n\n// ref: https://stackoverflow.com/questions/57769465/javascript-truncate-text-by-bytes-length\nfunction truncate(str: string, maxLength: number) {\n const encoder = new TextEncoder();\n const decoder = new TextDecoder('utf-8');\n\n const encodedString = encoder.encode(str);\n const truncatedString = encodedString.slice(0, maxLength);\n\n // return the truncated string, removing any replacement characters that result from partially truncated characters\n return decoder.decode(truncatedString).replace(/\\uFFFD/g, '');\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,qBAAoB;AAEpB,0BAA6B;AAWtB,MAAM,oBAAoB,CAAC,MAAc,cAAyC,MAAc;AACrG,QAAM,UAAsB,CAAC;AAC7B,MAAI,YAAY;AAEhB,SAAO;AAAA,IACL,QAAQ,MAAM;AACZ,kBAAY;AAAA,IACd;AAAA,IACA,OAAO,IAAI,SAAS;AAClB,UAAI,WAAW;AACb,gBAAQ,KAAK,KAAK,IAAI,SAAQ,OAAO,QAAQ,aAAa,IAAI,IAAI,GAAI,CAAC;AAAA,MACzE;AAAA,IACF;AAAA,IACA,QAAQ,MAAM;AACZ,UAAI,WAAW;AACb,gBAAQ,IAAI,eAAe,IAAI,CAAC;AAMhC,mBAAW,OAAO,SAAS;AACzB,cAAI,SAAS,UAAU,GAAG;AAE1B,mBAAS,OACN,MAAM,IAAI,EACV,IAAI,OAAK,KAAK,CAAC,EAAE,EACjB,KAAK,IAAI;AAGZ,cAAI,QAAQ,IAAI,QAAQ;AACtB,qBAAS,SAAS,QAAQ,IAAI;AAAA,UAChC;AAEA,kBAAQ,IAAI,MAAM;AAAA,QACpB;AAEA,gBAAQ,IAAI,eAAe,IAAI,CAAC;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AACF;AAOO,MAAM,aAAyB,CAAC,qBAAqB,gBAAgB;AAC1E,UAAQ,IAAI,SAAc;AACxB,UAAM,UACJ,OAAO,wBAAwB,WAC3B,kBAAkB,qBAAqB,gCAAY,IACnD;AAEN,UAAM,SAAS,QAAQ;AACvB,UAAM,UAAU,YAAY,MAAa;AAEzC,QAAI;AACF,YAAM,MAAM,QAAQ,GAAG,IAAI;AAC3B,UAAI,OAAO,QAAQ,YAAY,UAAU,OAAO,OAAO,IAAI,SAAS,YAAY;AAC9E,eAAO,IACJ,KAAK,CAAC,QAAa;AAClB,iBAAO,OAAO;AACd,iBAAO;AAAA,QACT,CAAC,EACA,MAAM,CAAC,QAAa;AACnB,iBAAO,OAAO;AACd,gBAAM;AAAA,QACR,CAAC;AAAA,MACL;AAEA,aAAO,OAAO;AACd,aAAO;AAAA,IACT,SAAS,KAAU;AACjB,aAAO,OAAO;AACd,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,SAAS,eAAe,MAAc;AACpC,SAAO,uBAAuB,IAAI;AACpC;AAEA,SAAS,eAAe,MAAc;AACpC,SAAO,qBAAqB,IAAI,oBAAoB,iCAAe,SAAS,eAAAA,QAAQ,OAAO,cAAc,KAAK,OAAM,oBAAI,KAAK,GAAE,QAAQ,IAAI,GAAK,CAAC;AACnJ;AAGA,SAAS,SAAS,KAAa,WAAmB;AAChD,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,UAAU,IAAI,YAAY,OAAO;AAEvC,QAAM,gBAAgB,QAAQ,OAAO,GAAG;AACxC,QAAM,kBAAkB,cAAc,MAAM,GAAG,SAAS;AAGxD,SAAO,QAAQ,OAAO,eAAe,EAAE,QAAQ,WAAW,EAAE;AAC9D;","names":["nextPkg"]}
1
+ {"version":3,"sources":["../../../src/utils/debugLogger.ts"],"sourcesContent":["// TODO: Replace with a more sophisticated logging solution\n\nimport nextPkg from 'next/package.json';\n\nimport { logFormatter } from './logFormatter';\n\nexport type Log = string | Record<string, unknown>;\nexport type LogEntry = Log | Log[];\nexport type Logger<L = Log> = {\n commit: () => void;\n debug: (...args: Array<L | (() => L)>) => void;\n enable: () => void;\n};\nexport type LoggerNoCommit<L = Logger> = Omit<L, 'commit'>;\n\nexport const createDebugLogger = (name: string, formatter: (val: LogEntry) => string) => (): Logger => {\n const entries: LogEntry[] = [];\n let isEnabled = false;\n\n return {\n enable: () => {\n isEnabled = true;\n },\n debug: (...args) => {\n if (isEnabled) {\n entries.push(args.map(arg => (typeof arg === 'function' ? arg() : arg)));\n }\n },\n commit: () => {\n if (isEnabled) {\n console.log(debugLogHeader(name));\n\n /**\n * We buffer each collected log entry so we can format them and log them all at once.\n * Individual console.log calls are used to ensure we don't hit platform-specific log limits (Vercel and Netlify are 4kb).\n */\n for (const log of entries) {\n let output = formatter(log);\n\n output = output\n .split('\\n')\n .map(l => ` ${l}`)\n .join('\\n');\n\n // Vercel errors if the output is > 4kb, so we truncate it\n if (process.env.VERCEL) {\n output = truncate(output, 4096);\n }\n\n console.log(output);\n }\n\n console.log(debugLogFooter(name));\n }\n },\n };\n};\n\ntype WithLogger = <L extends Logger, H extends (...args: any[]) => any>(\n loggerFactoryOrName: string | (() => L),\n handlerCtor: (logger: LoggerNoCommit<L>) => H,\n) => H;\n\nexport const withLogger: WithLogger = (loggerFactoryOrName, handlerCtor) => {\n return ((...args: any) => {\n const factory =\n typeof loggerFactoryOrName === 'string'\n ? createDebugLogger(loggerFactoryOrName, logFormatter)\n : loggerFactoryOrName;\n\n const logger = factory();\n const handler = handlerCtor(logger as any);\n\n try {\n const res = handler(...args);\n if (typeof res === 'object' && 'then' in res && typeof res.then === 'function') {\n return res\n .then((val: any) => {\n logger.commit();\n return val;\n })\n .catch((err: any) => {\n logger.commit();\n throw err;\n });\n }\n // handle sync methods\n logger.commit();\n return res;\n } catch (err: any) {\n logger.commit();\n throw err;\n }\n }) as ReturnType<typeof handlerCtor>;\n};\n\nfunction debugLogHeader(name: string) {\n return `[clerk debug start: ${name}]`;\n}\n\nfunction debugLogFooter(name: string) {\n return `[clerk debug end: ${name}] (@clerk/nextjs=${PACKAGE_VERSION},next=${nextPkg.version},timestamp=${Math.round(new Date().getTime() / 1_000)})`;\n}\n\n// ref: https://stackoverflow.com/questions/57769465/javascript-truncate-text-by-bytes-length\nfunction truncate(str: string, maxLength: number) {\n const encoder = new TextEncoder();\n const decoder = new TextDecoder('utf-8');\n\n const encodedString = encoder.encode(str);\n const truncatedString = encodedString.slice(0, maxLength);\n\n // return the truncated string, removing any replacement characters that result from partially truncated characters\n return decoder.decode(truncatedString).replace(/\\uFFFD/g, '');\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,qBAAoB;AAEpB,0BAA6B;AAWtB,MAAM,oBAAoB,CAAC,MAAc,cAAyC,MAAc;AACrG,QAAM,UAAsB,CAAC;AAC7B,MAAI,YAAY;AAEhB,SAAO;AAAA,IACL,QAAQ,MAAM;AACZ,kBAAY;AAAA,IACd;AAAA,IACA,OAAO,IAAI,SAAS;AAClB,UAAI,WAAW;AACb,gBAAQ,KAAK,KAAK,IAAI,SAAQ,OAAO,QAAQ,aAAa,IAAI,IAAI,GAAI,CAAC;AAAA,MACzE;AAAA,IACF;AAAA,IACA,QAAQ,MAAM;AACZ,UAAI,WAAW;AACb,gBAAQ,IAAI,eAAe,IAAI,CAAC;AAMhC,mBAAW,OAAO,SAAS;AACzB,cAAI,SAAS,UAAU,GAAG;AAE1B,mBAAS,OACN,MAAM,IAAI,EACV,IAAI,OAAK,KAAK,CAAC,EAAE,EACjB,KAAK,IAAI;AAGZ,cAAI,QAAQ,IAAI,QAAQ;AACtB,qBAAS,SAAS,QAAQ,IAAI;AAAA,UAChC;AAEA,kBAAQ,IAAI,MAAM;AAAA,QACpB;AAEA,gBAAQ,IAAI,eAAe,IAAI,CAAC;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AACF;AAOO,MAAM,aAAyB,CAAC,qBAAqB,gBAAgB;AAC1E,UAAQ,IAAI,SAAc;AACxB,UAAM,UACJ,OAAO,wBAAwB,WAC3B,kBAAkB,qBAAqB,gCAAY,IACnD;AAEN,UAAM,SAAS,QAAQ;AACvB,UAAM,UAAU,YAAY,MAAa;AAEzC,QAAI;AACF,YAAM,MAAM,QAAQ,GAAG,IAAI;AAC3B,UAAI,OAAO,QAAQ,YAAY,UAAU,OAAO,OAAO,IAAI,SAAS,YAAY;AAC9E,eAAO,IACJ,KAAK,CAAC,QAAa;AAClB,iBAAO,OAAO;AACd,iBAAO;AAAA,QACT,CAAC,EACA,MAAM,CAAC,QAAa;AACnB,iBAAO,OAAO;AACd,gBAAM;AAAA,QACR,CAAC;AAAA,MACL;AAEA,aAAO,OAAO;AACd,aAAO;AAAA,IACT,SAAS,KAAU;AACjB,aAAO,OAAO;AACd,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,SAAS,eAAe,MAAc;AACpC,SAAO,uBAAuB,IAAI;AACpC;AAEA,SAAS,eAAe,MAAc;AACpC,SAAO,qBAAqB,IAAI,oBAAoB,QAAe,SAAS,eAAAA,QAAQ,OAAO,cAAc,KAAK,OAAM,oBAAI,KAAK,GAAE,QAAQ,IAAI,GAAK,CAAC;AACnJ;AAGA,SAAS,SAAS,KAAa,WAAmB;AAChD,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,UAAU,IAAI,YAAY,OAAO;AAEvC,QAAM,gBAAgB,QAAQ,OAAO,GAAG;AACxC,QAAM,kBAAkB,cAAc,MAAM,GAAG,SAAS;AAGxD,SAAO,QAAQ,OAAO,eAAe,EAAE,QAAQ,WAAW,EAAE;AAC9D;","names":["nextPkg"]}
@@ -18,7 +18,7 @@ const SIGN_IN_URL = process.env.NEXT_PUBLIC_CLERK_SIGN_IN_URL || "";
18
18
  const SIGN_UP_URL = process.env.NEXT_PUBLIC_CLERK_SIGN_UP_URL || "";
19
19
  const SDK_METADATA = {
20
20
  name: "@clerk/nextjs",
21
- version: "7.5.21-snapshot.v20260720201619",
21
+ version: "7.5.21",
22
22
  environment: process.env.NODE_ENV
23
23
  };
24
24
  const TELEMETRY_DISABLED = isTruthy(process.env.NEXT_PUBLIC_CLERK_TELEMETRY_DISABLED);
@@ -1,5 +1,6 @@
1
1
  import "../chunk-BUSYA2B4.js";
2
2
  import { constants } from "@clerk/backend/internal";
3
+ const clerkProtectionOrigins = ["https://*.protect.clerk.com", "https://*.client.protect.clerk.com"];
3
4
  class ContentSecurityPolicyDirectiveManager {
4
5
  /**
5
6
  * Creates a new ContentSecurityPolicyDirectiveSet with default values
@@ -61,7 +62,8 @@ ContentSecurityPolicyDirectiveManager.DEFAULT_DIRECTIVES = {
61
62
  "https://api.stripe.com",
62
63
  "https://maps.googleapis.com",
63
64
  "https://img.clerk.com",
64
- "https://images.clerkstage.dev"
65
+ "https://images.clerkstage.dev",
66
+ ...clerkProtectionOrigins
65
67
  ],
66
68
  "default-src": ["self"],
67
69
  "form-action": ["self"],
@@ -70,7 +72,8 @@ ContentSecurityPolicyDirectiveManager.DEFAULT_DIRECTIVES = {
70
72
  "https://challenges.cloudflare.com",
71
73
  "https://*.js.stripe.com",
72
74
  "https://js.stripe.com",
73
- "https://hooks.stripe.com"
75
+ "https://hooks.stripe.com",
76
+ ...clerkProtectionOrigins
74
77
  ],
75
78
  "img-src": ["self", "https://img.clerk.com"],
76
79
  "script-src": [
@@ -81,7 +84,8 @@ ContentSecurityPolicyDirectiveManager.DEFAULT_DIRECTIVES = {
81
84
  "http:",
82
85
  "https://*.js.stripe.com",
83
86
  "https://js.stripe.com",
84
- "https://maps.googleapis.com"
87
+ "https://maps.googleapis.com",
88
+ ...clerkProtectionOrigins
85
89
  ],
86
90
  "style-src": ["self", "unsafe-inline"],
87
91
  "worker-src": ["self", "blob:"]
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/server/content-security-policy.ts"],"sourcesContent":["import { constants } from '@clerk/backend/internal';\n\n/**\n * Valid CSP directives according to the CSP Level 3 specification\n */\nexport type ContentSecurityPolicyDirective =\n // Default resource directives\n | 'connect-src'\n | 'default-src'\n | 'font-src'\n | 'img-src'\n | 'media-src'\n | 'object-src'\n | 'script-src'\n | 'style-src'\n // Framing and navigation directives\n | 'base-uri'\n | 'child-src'\n | 'form-action'\n | 'frame-ancestors'\n | 'frame-src'\n | 'manifest-src'\n | 'navigate-to'\n | 'prefetch-src'\n | 'worker-src'\n // Sandbox and plugin directives\n | 'plugin-types'\n | 'require-sri-for'\n | 'sandbox'\n // Trusted types and upgrade directives\n | 'block-all-mixed-content'\n | 'require-trusted-types-for'\n | 'trusted-types'\n | 'upgrade-insecure-requests'\n // Reporting directives\n | 'report-to'\n | 'report-uri'\n // CSP Level 3 additional directives\n | 'script-src-attr'\n | 'script-src-elem'\n | 'style-src-attr'\n | 'style-src-elem';\n\n/**\n * Partial record of directives and their values\n */\ntype ContentSecurityPolicyValues = Partial<Record<ContentSecurityPolicyDirective, string[]>>;\n\n/**\n * Directives and their values\n */\ntype ContentSecurityPolicyDirectiveSet = Record<ContentSecurityPolicyDirective, Set<string>>;\n\nexport interface ContentSecurityPolicyHeaders {\n /**\n * Array of formatted headers to be added to the response.\n *\n * Includes both standard and report-only headers when applicable.\n * Includes nonce when strict mode is enabled.\n */\n headers: [string, string][];\n}\n\nexport interface ContentSecurityPolicyOptions {\n /**\n * When set to true, enhances security by applying the `strict-dynamic` attribute to the `script-src` CSP directive\n */\n strict?: boolean;\n /**\n * Custom CSP directives to merge with Clerk's default directives\n */\n directives?: Partial<Record<ContentSecurityPolicyDirective, string[]>>;\n /**\n * When set to true, the Content-Security-Policy-Report-Only header will be used instead of\n * Content-Security-Policy. This allows monitoring policy violations without blocking content.\n */\n reportOnly?: boolean;\n /**\n * Specifies a reporting endpoint for CSP violations. This value will be used in the\n * 'report-to' directive of the Content-Security-Policy header.\n */\n reportTo?: string;\n}\n\nclass ContentSecurityPolicyDirectiveManager {\n /** Set of special keywords that require quoting in CSP directives */\n private static readonly KEYWORDS = new Set([\n 'none',\n 'self',\n 'strict-dynamic',\n 'unsafe-eval',\n 'unsafe-hashes',\n 'unsafe-inline',\n ]);\n\n /** Default CSP directives and their values */\n static readonly DEFAULT_DIRECTIVES: ContentSecurityPolicyValues = {\n 'connect-src': [\n 'self',\n 'https://clerk-telemetry.com',\n 'https://*.clerk-telemetry.com',\n 'https://api.stripe.com',\n 'https://maps.googleapis.com',\n 'https://img.clerk.com',\n 'https://images.clerkstage.dev',\n ],\n 'default-src': ['self'],\n 'form-action': ['self'],\n 'frame-src': [\n 'self',\n 'https://challenges.cloudflare.com',\n 'https://*.js.stripe.com',\n 'https://js.stripe.com',\n 'https://hooks.stripe.com',\n ],\n 'img-src': ['self', 'https://img.clerk.com'],\n 'script-src': [\n 'self',\n ...(process.env.NODE_ENV !== 'production' ? ['unsafe-eval'] : []),\n 'unsafe-inline',\n 'https:',\n 'http:',\n 'https://*.js.stripe.com',\n 'https://js.stripe.com',\n 'https://maps.googleapis.com',\n ],\n 'style-src': ['self', 'unsafe-inline'],\n 'worker-src': ['self', 'blob:'],\n };\n\n /**\n * Creates a new ContentSecurityPolicyDirectiveSet with default values\n * @returns A new ContentSecurityPolicyDirectiveSet with default values\n */\n static createDefaultDirectives(): ContentSecurityPolicyDirectiveSet {\n return Object.entries(this.DEFAULT_DIRECTIVES).reduce((acc, [key, values]) => {\n acc[key as ContentSecurityPolicyDirective] = new Set(values);\n return acc;\n }, {} as ContentSecurityPolicyDirectiveSet);\n }\n\n /**\n * Checks if a value is a special keyword that requires quoting\n * @param value - The value to check\n * @returns True if the value is a special keyword\n */\n static isKeyword(value: string): boolean {\n return this.KEYWORDS.has(value.replace(/^'|'$/g, ''));\n }\n\n /**\n * Formats a value according to CSP rules, adding quotes for special keywords\n * @param value - The value to format\n * @returns The formatted value\n */\n static formatValue(value: string): string {\n const unquoted = value.replace(/^'|'$/g, '');\n return this.isKeyword(unquoted) ? `'${unquoted}'` : value;\n }\n\n /**\n * Handles directive values, ensuring proper formatting and special case handling\n * @param values - Array of values to process\n * @returns Set of formatted values\n */\n static handleDirectiveValues(values: string[]): Set<string> {\n const result = new Set<string>();\n\n if (values.includes(\"'none'\") || values.includes('none')) {\n result.add(\"'none'\");\n return result;\n }\n\n values.forEach(v => result.add(this.formatValue(v)));\n return result;\n }\n}\n\n/**\n * Handles merging of existing directives with new values\n * @param mergedCSP - The current merged CSP state\n * @param key - The directive key to handle\n * @param values - New values to merge\n */\nfunction handleExistingDirective(\n mergedCSP: ContentSecurityPolicyDirectiveSet,\n key: ContentSecurityPolicyDirective,\n values: string[],\n) {\n // None overrides all other values\n if (values.includes(\"'none'\") || values.includes('none')) {\n mergedCSP[key] = new Set([\"'none'\"]);\n return;\n }\n\n // For existing directives, merge the values rather than replacing\n const deduplicatedSet = new Set<string>();\n\n mergedCSP[key].forEach(value => {\n deduplicatedSet.add(ContentSecurityPolicyDirectiveManager.formatValue(value));\n });\n\n values.forEach(value => {\n deduplicatedSet.add(ContentSecurityPolicyDirectiveManager.formatValue(value));\n });\n\n mergedCSP[key] = deduplicatedSet;\n}\n\n/**\n * Handles custom directives that are not part of the default set\n * @param customDirectives - Map of custom directives\n * @param key - The directive key\n * @param values - Values for the directive\n */\nfunction handleCustomDirective(customDirectives: Map<string, Set<string>>, key: string, values: string[]) {\n // None overrides all other values\n if (values.includes(\"'none'\") || values.includes('none')) {\n customDirectives.set(key, new Set([\"'none'\"]));\n return;\n }\n\n const formattedValues = new Set<string>();\n values.forEach(value => {\n const formattedValue = ContentSecurityPolicyDirectiveManager.formatValue(value);\n formattedValues.add(formattedValue);\n });\n\n customDirectives.set(key, formattedValues);\n}\n\n/**\n * Applies formatting to the CSP header\n * @param mergedCSP - The merged CSP state to format\n * @returns Formatted CSP header string\n */\nfunction formatCSPHeader(mergedCSP: Record<string, Set<string>>): string {\n return Object.entries(mergedCSP)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, values]) => {\n const valueObjs = Array.from(values).map(v => ({\n raw: v,\n formatted: ContentSecurityPolicyDirectiveManager.formatValue(v),\n }));\n\n return `${key} ${valueObjs.map(item => item.formatted).join(' ')}`;\n })\n .join('; ');\n}\n\n/**\n * Generates a secure random nonce for CSP headers\n * @returns A base64-encoded random nonce\n */\nexport function generateNonce(): string {\n const randomBytes = new Uint8Array(16);\n crypto.getRandomValues(randomBytes);\n const binaryString = Array.from(randomBytes, byte => String.fromCharCode(byte)).join('');\n return btoa(binaryString);\n}\n\n/**\n * Builds a complete set of CSP directives by combining defaults with custom directives,\n * applying special configurations like strict mode and nonce, and formatting them into a valid CSP string.\n */\nfunction buildContentSecurityPolicyDirectives(\n strict: boolean,\n host: string,\n customDirectives?: Partial<Record<ContentSecurityPolicyDirective, string[]>>,\n nonce?: string,\n): string {\n const directives = Object.entries(ContentSecurityPolicyDirectiveManager.DEFAULT_DIRECTIVES).reduce(\n (acc, [key, values]) => {\n acc[key as ContentSecurityPolicyDirective] = new Set(values);\n return acc;\n },\n {} as ContentSecurityPolicyDirectiveSet,\n );\n\n directives['connect-src'].add(host);\n\n if (strict) {\n directives['script-src'].delete('http:');\n directives['script-src'].delete('https:');\n directives['script-src'].add(\"'strict-dynamic'\");\n if (nonce) {\n directives['script-src'].add(`'nonce-${nonce}'`);\n }\n }\n\n if (customDirectives) {\n const customDirectivesMap = new Map<string, Set<string>>();\n Object.entries(customDirectives).forEach(([key, values]) => {\n const valuesArray = Array.isArray(values) ? values : [values];\n if (ContentSecurityPolicyDirectiveManager.DEFAULT_DIRECTIVES[key as ContentSecurityPolicyDirective]) {\n handleExistingDirective(directives, key as ContentSecurityPolicyDirective, valuesArray);\n } else {\n handleCustomDirective(customDirectivesMap, key, valuesArray);\n }\n });\n\n // Merge all custom directives into the final directives object\n customDirectivesMap.forEach((values, key) => {\n directives[key as ContentSecurityPolicyDirective] = values;\n });\n }\n\n return formatCSPHeader(directives);\n}\n\n/**\n * Creates Content Security Policy (CSP) headers with the specified configuration\n * @returns Object containing the formatted CSP headers\n */\nexport function createContentSecurityPolicyHeaders(\n host: string,\n options: ContentSecurityPolicyOptions,\n): ContentSecurityPolicyHeaders {\n const headers: [string, string][] = [];\n\n const nonce = options.strict ? generateNonce() : undefined;\n\n let cspHeader = buildContentSecurityPolicyDirectives(options.strict ?? false, host, options.directives, nonce);\n\n if (options.reportTo) {\n cspHeader += '; report-to csp-endpoint';\n headers.push([constants.Headers.ReportingEndpoints, `csp-endpoint=\"${options.reportTo}\"`]);\n }\n\n if (options.reportOnly) {\n headers.push([constants.Headers.ContentSecurityPolicyReportOnly, cspHeader]);\n } else {\n headers.push([constants.Headers.ContentSecurityPolicy, cspHeader]);\n }\n\n if (nonce) {\n headers.push([constants.Headers.Nonce, nonce]);\n }\n\n return {\n headers,\n };\n}\n"],"mappings":";AAAA,SAAS,iBAAiB;AAoF1B,MAAM,sCAAsC;AAAA;AAAA;AAAA;AAAA;AAAA,EAkD1C,OAAO,0BAA6D;AAClE,WAAO,OAAO,QAAQ,KAAK,kBAAkB,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,MAAM,MAAM;AAC5E,UAAI,GAAqC,IAAI,IAAI,IAAI,MAAM;AAC3D,aAAO;AAAA,IACT,GAAG,CAAC,CAAsC;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,UAAU,OAAwB;AACvC,WAAO,KAAK,SAAS,IAAI,MAAM,QAAQ,UAAU,EAAE,CAAC;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,YAAY,OAAuB;AACxC,UAAM,WAAW,MAAM,QAAQ,UAAU,EAAE;AAC3C,WAAO,KAAK,UAAU,QAAQ,IAAI,IAAI,QAAQ,MAAM;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,sBAAsB,QAA+B;AAC1D,UAAM,SAAS,oBAAI,IAAY;AAE/B,QAAI,OAAO,SAAS,QAAQ,KAAK,OAAO,SAAS,MAAM,GAAG;AACxD,aAAO,IAAI,QAAQ;AACnB,aAAO;AAAA,IACT;AAEA,WAAO,QAAQ,OAAK,OAAO,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC;AACnD,WAAO;AAAA,EACT;AACF;AAAA;AA5FM,sCAEoB,WAAW,oBAAI,IAAI;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAAA;AATG,sCAYY,qBAAkD;AAAA,EAChE,eAAe;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,eAAe,CAAC,MAAM;AAAA,EACtB,eAAe,CAAC,MAAM;AAAA,EACtB,aAAa;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,WAAW,CAAC,QAAQ,uBAAuB;AAAA,EAC3C,cAAc;AAAA,IACZ;AAAA,IACA,GAAI,QAAQ,IAAI,aAAa,eAAe,CAAC,aAAa,IAAI,CAAC;AAAA,IAC/D;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,aAAa,CAAC,QAAQ,eAAe;AAAA,EACrC,cAAc,CAAC,QAAQ,OAAO;AAChC;AAwDF,SAAS,wBACP,WACA,KACA,QACA;AAEA,MAAI,OAAO,SAAS,QAAQ,KAAK,OAAO,SAAS,MAAM,GAAG;AACxD,cAAU,GAAG,IAAI,oBAAI,IAAI,CAAC,QAAQ,CAAC;AACnC;AAAA,EACF;AAGA,QAAM,kBAAkB,oBAAI,IAAY;AAExC,YAAU,GAAG,EAAE,QAAQ,WAAS;AAC9B,oBAAgB,IAAI,sCAAsC,YAAY,KAAK,CAAC;AAAA,EAC9E,CAAC;AAED,SAAO,QAAQ,WAAS;AACtB,oBAAgB,IAAI,sCAAsC,YAAY,KAAK,CAAC;AAAA,EAC9E,CAAC;AAED,YAAU,GAAG,IAAI;AACnB;AAQA,SAAS,sBAAsB,kBAA4C,KAAa,QAAkB;AAExG,MAAI,OAAO,SAAS,QAAQ,KAAK,OAAO,SAAS,MAAM,GAAG;AACxD,qBAAiB,IAAI,KAAK,oBAAI,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC7C;AAAA,EACF;AAEA,QAAM,kBAAkB,oBAAI,IAAY;AACxC,SAAO,QAAQ,WAAS;AACtB,UAAM,iBAAiB,sCAAsC,YAAY,KAAK;AAC9E,oBAAgB,IAAI,cAAc;AAAA,EACpC,CAAC;AAED,mBAAiB,IAAI,KAAK,eAAe;AAC3C;AAOA,SAAS,gBAAgB,WAAgD;AACvE,SAAO,OAAO,QAAQ,SAAS,EAC5B,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EACrC,IAAI,CAAC,CAAC,KAAK,MAAM,MAAM;AACtB,UAAM,YAAY,MAAM,KAAK,MAAM,EAAE,IAAI,QAAM;AAAA,MAC7C,KAAK;AAAA,MACL,WAAW,sCAAsC,YAAY,CAAC;AAAA,IAChE,EAAE;AAEF,WAAO,GAAG,GAAG,IAAI,UAAU,IAAI,UAAQ,KAAK,SAAS,EAAE,KAAK,GAAG,CAAC;AAAA,EAClE,CAAC,EACA,KAAK,IAAI;AACd;AAMO,SAAS,gBAAwB;AACtC,QAAM,cAAc,IAAI,WAAW,EAAE;AACrC,SAAO,gBAAgB,WAAW;AAClC,QAAM,eAAe,MAAM,KAAK,aAAa,UAAQ,OAAO,aAAa,IAAI,CAAC,EAAE,KAAK,EAAE;AACvF,SAAO,KAAK,YAAY;AAC1B;AAMA,SAAS,qCACP,QACA,MACA,kBACA,OACQ;AACR,QAAM,aAAa,OAAO,QAAQ,sCAAsC,kBAAkB,EAAE;AAAA,IAC1F,CAAC,KAAK,CAAC,KAAK,MAAM,MAAM;AACtB,UAAI,GAAqC,IAAI,IAAI,IAAI,MAAM;AAC3D,aAAO;AAAA,IACT;AAAA,IACA,CAAC;AAAA,EACH;AAEA,aAAW,aAAa,EAAE,IAAI,IAAI;AAElC,MAAI,QAAQ;AACV,eAAW,YAAY,EAAE,OAAO,OAAO;AACvC,eAAW,YAAY,EAAE,OAAO,QAAQ;AACxC,eAAW,YAAY,EAAE,IAAI,kBAAkB;AAC/C,QAAI,OAAO;AACT,iBAAW,YAAY,EAAE,IAAI,UAAU,KAAK,GAAG;AAAA,IACjD;AAAA,EACF;AAEA,MAAI,kBAAkB;AACpB,UAAM,sBAAsB,oBAAI,IAAyB;AACzD,WAAO,QAAQ,gBAAgB,EAAE,QAAQ,CAAC,CAAC,KAAK,MAAM,MAAM;AAC1D,YAAM,cAAc,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;AAC5D,UAAI,sCAAsC,mBAAmB,GAAqC,GAAG;AACnG,gCAAwB,YAAY,KAAuC,WAAW;AAAA,MACxF,OAAO;AACL,8BAAsB,qBAAqB,KAAK,WAAW;AAAA,MAC7D;AAAA,IACF,CAAC;AAGD,wBAAoB,QAAQ,CAAC,QAAQ,QAAQ;AAC3C,iBAAW,GAAqC,IAAI;AAAA,IACtD,CAAC;AAAA,EACH;AAEA,SAAO,gBAAgB,UAAU;AACnC;AAMO,SAAS,mCACd,MACA,SAC8B;AA7ThC;AA8TE,QAAM,UAA8B,CAAC;AAErC,QAAM,QAAQ,QAAQ,SAAS,cAAc,IAAI;AAEjD,MAAI,YAAY,sCAAqC,aAAQ,WAAR,YAAkB,OAAO,MAAM,QAAQ,YAAY,KAAK;AAE7G,MAAI,QAAQ,UAAU;AACpB,iBAAa;AACb,YAAQ,KAAK,CAAC,UAAU,QAAQ,oBAAoB,iBAAiB,QAAQ,QAAQ,GAAG,CAAC;AAAA,EAC3F;AAEA,MAAI,QAAQ,YAAY;AACtB,YAAQ,KAAK,CAAC,UAAU,QAAQ,iCAAiC,SAAS,CAAC;AAAA,EAC7E,OAAO;AACL,YAAQ,KAAK,CAAC,UAAU,QAAQ,uBAAuB,SAAS,CAAC;AAAA,EACnE;AAEA,MAAI,OAAO;AACT,YAAQ,KAAK,CAAC,UAAU,QAAQ,OAAO,KAAK,CAAC;AAAA,EAC/C;AAEA,SAAO;AAAA,IACL;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/server/content-security-policy.ts"],"sourcesContent":["import { constants } from '@clerk/backend/internal';\n\nconst clerkProtectionOrigins = ['https://*.protect.clerk.com', 'https://*.client.protect.clerk.com'];\n\n/**\n * Valid CSP directives according to the CSP Level 3 specification\n */\nexport type ContentSecurityPolicyDirective =\n // Default resource directives\n | 'connect-src'\n | 'default-src'\n | 'font-src'\n | 'img-src'\n | 'media-src'\n | 'object-src'\n | 'script-src'\n | 'style-src'\n // Framing and navigation directives\n | 'base-uri'\n | 'child-src'\n | 'form-action'\n | 'frame-ancestors'\n | 'frame-src'\n | 'manifest-src'\n | 'navigate-to'\n | 'prefetch-src'\n | 'worker-src'\n // Sandbox and plugin directives\n | 'plugin-types'\n | 'require-sri-for'\n | 'sandbox'\n // Trusted types and upgrade directives\n | 'block-all-mixed-content'\n | 'require-trusted-types-for'\n | 'trusted-types'\n | 'upgrade-insecure-requests'\n // Reporting directives\n | 'report-to'\n | 'report-uri'\n // CSP Level 3 additional directives\n | 'script-src-attr'\n | 'script-src-elem'\n | 'style-src-attr'\n | 'style-src-elem';\n\n/**\n * Partial record of directives and their values\n */\ntype ContentSecurityPolicyValues = Partial<Record<ContentSecurityPolicyDirective, string[]>>;\n\n/**\n * Directives and their values\n */\ntype ContentSecurityPolicyDirectiveSet = Record<ContentSecurityPolicyDirective, Set<string>>;\n\nexport interface ContentSecurityPolicyHeaders {\n /**\n * Array of formatted headers to be added to the response.\n *\n * Includes both standard and report-only headers when applicable.\n * Includes nonce when strict mode is enabled.\n */\n headers: [string, string][];\n}\n\nexport interface ContentSecurityPolicyOptions {\n /**\n * When set to true, enhances security by applying the `strict-dynamic` attribute to the `script-src` CSP directive\n */\n strict?: boolean;\n /**\n * Custom CSP directives to merge with Clerk's default directives\n */\n directives?: Partial<Record<ContentSecurityPolicyDirective, string[]>>;\n /**\n * When set to true, the Content-Security-Policy-Report-Only header will be used instead of\n * Content-Security-Policy. This allows monitoring policy violations without blocking content.\n */\n reportOnly?: boolean;\n /**\n * Specifies a reporting endpoint for CSP violations. This value will be used in the\n * 'report-to' directive of the Content-Security-Policy header.\n */\n reportTo?: string;\n}\n\nclass ContentSecurityPolicyDirectiveManager {\n /** Set of special keywords that require quoting in CSP directives */\n private static readonly KEYWORDS = new Set([\n 'none',\n 'self',\n 'strict-dynamic',\n 'unsafe-eval',\n 'unsafe-hashes',\n 'unsafe-inline',\n ]);\n\n /** Default CSP directives and their values */\n static readonly DEFAULT_DIRECTIVES: ContentSecurityPolicyValues = {\n 'connect-src': [\n 'self',\n 'https://clerk-telemetry.com',\n 'https://*.clerk-telemetry.com',\n 'https://api.stripe.com',\n 'https://maps.googleapis.com',\n 'https://img.clerk.com',\n 'https://images.clerkstage.dev',\n ...clerkProtectionOrigins,\n ],\n 'default-src': ['self'],\n 'form-action': ['self'],\n 'frame-src': [\n 'self',\n 'https://challenges.cloudflare.com',\n 'https://*.js.stripe.com',\n 'https://js.stripe.com',\n 'https://hooks.stripe.com',\n ...clerkProtectionOrigins,\n ],\n 'img-src': ['self', 'https://img.clerk.com'],\n 'script-src': [\n 'self',\n ...(process.env.NODE_ENV !== 'production' ? ['unsafe-eval'] : []),\n 'unsafe-inline',\n 'https:',\n 'http:',\n 'https://*.js.stripe.com',\n 'https://js.stripe.com',\n 'https://maps.googleapis.com',\n ...clerkProtectionOrigins,\n ],\n 'style-src': ['self', 'unsafe-inline'],\n 'worker-src': ['self', 'blob:'],\n };\n\n /**\n * Creates a new ContentSecurityPolicyDirectiveSet with default values\n * @returns A new ContentSecurityPolicyDirectiveSet with default values\n */\n static createDefaultDirectives(): ContentSecurityPolicyDirectiveSet {\n return Object.entries(this.DEFAULT_DIRECTIVES).reduce((acc, [key, values]) => {\n acc[key as ContentSecurityPolicyDirective] = new Set(values);\n return acc;\n }, {} as ContentSecurityPolicyDirectiveSet);\n }\n\n /**\n * Checks if a value is a special keyword that requires quoting\n * @param value - The value to check\n * @returns True if the value is a special keyword\n */\n static isKeyword(value: string): boolean {\n return this.KEYWORDS.has(value.replace(/^'|'$/g, ''));\n }\n\n /**\n * Formats a value according to CSP rules, adding quotes for special keywords\n * @param value - The value to format\n * @returns The formatted value\n */\n static formatValue(value: string): string {\n const unquoted = value.replace(/^'|'$/g, '');\n return this.isKeyword(unquoted) ? `'${unquoted}'` : value;\n }\n\n /**\n * Handles directive values, ensuring proper formatting and special case handling\n * @param values - Array of values to process\n * @returns Set of formatted values\n */\n static handleDirectiveValues(values: string[]): Set<string> {\n const result = new Set<string>();\n\n if (values.includes(\"'none'\") || values.includes('none')) {\n result.add(\"'none'\");\n return result;\n }\n\n values.forEach(v => result.add(this.formatValue(v)));\n return result;\n }\n}\n\n/**\n * Handles merging of existing directives with new values\n * @param mergedCSP - The current merged CSP state\n * @param key - The directive key to handle\n * @param values - New values to merge\n */\nfunction handleExistingDirective(\n mergedCSP: ContentSecurityPolicyDirectiveSet,\n key: ContentSecurityPolicyDirective,\n values: string[],\n) {\n // None overrides all other values\n if (values.includes(\"'none'\") || values.includes('none')) {\n mergedCSP[key] = new Set([\"'none'\"]);\n return;\n }\n\n // For existing directives, merge the values rather than replacing\n const deduplicatedSet = new Set<string>();\n\n mergedCSP[key].forEach(value => {\n deduplicatedSet.add(ContentSecurityPolicyDirectiveManager.formatValue(value));\n });\n\n values.forEach(value => {\n deduplicatedSet.add(ContentSecurityPolicyDirectiveManager.formatValue(value));\n });\n\n mergedCSP[key] = deduplicatedSet;\n}\n\n/**\n * Handles custom directives that are not part of the default set\n * @param customDirectives - Map of custom directives\n * @param key - The directive key\n * @param values - Values for the directive\n */\nfunction handleCustomDirective(customDirectives: Map<string, Set<string>>, key: string, values: string[]) {\n // None overrides all other values\n if (values.includes(\"'none'\") || values.includes('none')) {\n customDirectives.set(key, new Set([\"'none'\"]));\n return;\n }\n\n const formattedValues = new Set<string>();\n values.forEach(value => {\n const formattedValue = ContentSecurityPolicyDirectiveManager.formatValue(value);\n formattedValues.add(formattedValue);\n });\n\n customDirectives.set(key, formattedValues);\n}\n\n/**\n * Applies formatting to the CSP header\n * @param mergedCSP - The merged CSP state to format\n * @returns Formatted CSP header string\n */\nfunction formatCSPHeader(mergedCSP: Record<string, Set<string>>): string {\n return Object.entries(mergedCSP)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, values]) => {\n const valueObjs = Array.from(values).map(v => ({\n raw: v,\n formatted: ContentSecurityPolicyDirectiveManager.formatValue(v),\n }));\n\n return `${key} ${valueObjs.map(item => item.formatted).join(' ')}`;\n })\n .join('; ');\n}\n\n/**\n * Generates a secure random nonce for CSP headers\n * @returns A base64-encoded random nonce\n */\nexport function generateNonce(): string {\n const randomBytes = new Uint8Array(16);\n crypto.getRandomValues(randomBytes);\n const binaryString = Array.from(randomBytes, byte => String.fromCharCode(byte)).join('');\n return btoa(binaryString);\n}\n\n/**\n * Builds a complete set of CSP directives by combining defaults with custom directives,\n * applying special configurations like strict mode and nonce, and formatting them into a valid CSP string.\n */\nfunction buildContentSecurityPolicyDirectives(\n strict: boolean,\n host: string,\n customDirectives?: Partial<Record<ContentSecurityPolicyDirective, string[]>>,\n nonce?: string,\n): string {\n const directives = Object.entries(ContentSecurityPolicyDirectiveManager.DEFAULT_DIRECTIVES).reduce(\n (acc, [key, values]) => {\n acc[key as ContentSecurityPolicyDirective] = new Set(values);\n return acc;\n },\n {} as ContentSecurityPolicyDirectiveSet,\n );\n\n directives['connect-src'].add(host);\n\n if (strict) {\n directives['script-src'].delete('http:');\n directives['script-src'].delete('https:');\n directives['script-src'].add(\"'strict-dynamic'\");\n if (nonce) {\n directives['script-src'].add(`'nonce-${nonce}'`);\n }\n }\n\n if (customDirectives) {\n const customDirectivesMap = new Map<string, Set<string>>();\n Object.entries(customDirectives).forEach(([key, values]) => {\n const valuesArray = Array.isArray(values) ? values : [values];\n if (ContentSecurityPolicyDirectiveManager.DEFAULT_DIRECTIVES[key as ContentSecurityPolicyDirective]) {\n handleExistingDirective(directives, key as ContentSecurityPolicyDirective, valuesArray);\n } else {\n handleCustomDirective(customDirectivesMap, key, valuesArray);\n }\n });\n\n // Merge all custom directives into the final directives object\n customDirectivesMap.forEach((values, key) => {\n directives[key as ContentSecurityPolicyDirective] = values;\n });\n }\n\n return formatCSPHeader(directives);\n}\n\n/**\n * Creates Content Security Policy (CSP) headers with the specified configuration\n * @returns Object containing the formatted CSP headers\n */\nexport function createContentSecurityPolicyHeaders(\n host: string,\n options: ContentSecurityPolicyOptions,\n): ContentSecurityPolicyHeaders {\n const headers: [string, string][] = [];\n\n const nonce = options.strict ? generateNonce() : undefined;\n\n let cspHeader = buildContentSecurityPolicyDirectives(options.strict ?? false, host, options.directives, nonce);\n\n if (options.reportTo) {\n cspHeader += '; report-to csp-endpoint';\n headers.push([constants.Headers.ReportingEndpoints, `csp-endpoint=\"${options.reportTo}\"`]);\n }\n\n if (options.reportOnly) {\n headers.push([constants.Headers.ContentSecurityPolicyReportOnly, cspHeader]);\n } else {\n headers.push([constants.Headers.ContentSecurityPolicy, cspHeader]);\n }\n\n if (nonce) {\n headers.push([constants.Headers.Nonce, nonce]);\n }\n\n return {\n headers,\n };\n}\n"],"mappings":"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","names":[]}
@@ -18,7 +18,7 @@ const clerkClientDefaultOptions = {
18
18
  publishableKey: PUBLISHABLE_KEY,
19
19
  apiUrl: API_URL,
20
20
  apiVersion: API_VERSION,
21
- userAgent: `${"@clerk/nextjs"}@${"7.5.21-snapshot.v20260720201619"}`,
21
+ userAgent: `${"@clerk/nextjs"}@${"7.5.21"}`,
22
22
  proxyUrl: PROXY_URL,
23
23
  domain: DOMAIN,
24
24
  isSatellite: IS_SATELLITE,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/server/createClerkClient.ts"],"sourcesContent":["import { createClerkClient } from '@clerk/backend';\n\nimport {\n API_URL,\n API_VERSION,\n DOMAIN,\n IS_SATELLITE,\n MACHINE_SECRET_KEY,\n PROXY_URL,\n PUBLISHABLE_KEY,\n SDK_METADATA,\n SECRET_KEY,\n TELEMETRY_DEBUG,\n TELEMETRY_DISABLED,\n} from './constants';\n\nconst clerkClientDefaultOptions = {\n secretKey: SECRET_KEY,\n publishableKey: PUBLISHABLE_KEY,\n apiUrl: API_URL,\n apiVersion: API_VERSION,\n userAgent: `${PACKAGE_NAME}@${PACKAGE_VERSION}`,\n proxyUrl: PROXY_URL,\n domain: DOMAIN,\n isSatellite: IS_SATELLITE,\n machineSecretKey: MACHINE_SECRET_KEY,\n sdkMetadata: SDK_METADATA,\n telemetry: {\n disabled: TELEMETRY_DISABLED,\n debug: TELEMETRY_DEBUG,\n },\n};\n\nexport const createClerkClientWithOptions: typeof createClerkClient = options =>\n createClerkClient({ ...clerkClientDefaultOptions, ...options });\n"],"mappings":";AAAA,SAAS,yBAAyB;AAElC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,MAAM,4BAA4B;AAAA,EAChC,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,WAAW,GAAG,eAAY,IAAI,iCAAe;AAAA,EAC7C,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,WAAW;AAAA,IACT,UAAU;AAAA,IACV,OAAO;AAAA,EACT;AACF;AAEO,MAAM,+BAAyD,aACpE,kBAAkB,EAAE,GAAG,2BAA2B,GAAG,QAAQ,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../../src/server/createClerkClient.ts"],"sourcesContent":["import { createClerkClient } from '@clerk/backend';\n\nimport {\n API_URL,\n API_VERSION,\n DOMAIN,\n IS_SATELLITE,\n MACHINE_SECRET_KEY,\n PROXY_URL,\n PUBLISHABLE_KEY,\n SDK_METADATA,\n SECRET_KEY,\n TELEMETRY_DEBUG,\n TELEMETRY_DISABLED,\n} from './constants';\n\nconst clerkClientDefaultOptions = {\n secretKey: SECRET_KEY,\n publishableKey: PUBLISHABLE_KEY,\n apiUrl: API_URL,\n apiVersion: API_VERSION,\n userAgent: `${PACKAGE_NAME}@${PACKAGE_VERSION}`,\n proxyUrl: PROXY_URL,\n domain: DOMAIN,\n isSatellite: IS_SATELLITE,\n machineSecretKey: MACHINE_SECRET_KEY,\n sdkMetadata: SDK_METADATA,\n telemetry: {\n disabled: TELEMETRY_DISABLED,\n debug: TELEMETRY_DEBUG,\n },\n};\n\nexport const createClerkClientWithOptions: typeof createClerkClient = options =>\n createClerkClient({ ...clerkClientDefaultOptions, ...options });\n"],"mappings":";AAAA,SAAS,yBAAyB;AAElC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,MAAM,4BAA4B;AAAA,EAChC,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,WAAW,GAAG,eAAY,IAAI,QAAe;AAAA,EAC7C,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,WAAW;AAAA,IACT,UAAU;AAAA,IACV,OAAO;AAAA,EACT;AACF;AAEO,MAAM,+BAAyD,aACpE,kBAAkB,EAAE,GAAG,2BAA2B,GAAG,QAAQ,CAAC;","names":[]}
@@ -57,7 +57,7 @@ function debugLogHeader(name) {
57
57
  return `[clerk debug start: ${name}]`;
58
58
  }
59
59
  function debugLogFooter(name) {
60
- return `[clerk debug end: ${name}] (@clerk/nextjs=${"7.5.21-snapshot.v20260720201619"},next=${nextPkg.version},timestamp=${Math.round((/* @__PURE__ */ new Date()).getTime() / 1e3)})`;
60
+ return `[clerk debug end: ${name}] (@clerk/nextjs=${"7.5.21"},next=${nextPkg.version},timestamp=${Math.round((/* @__PURE__ */ new Date()).getTime() / 1e3)})`;
61
61
  }
62
62
  function truncate(str, maxLength) {
63
63
  const encoder = new TextEncoder();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/debugLogger.ts"],"sourcesContent":["// TODO: Replace with a more sophisticated logging solution\n\nimport nextPkg from 'next/package.json';\n\nimport { logFormatter } from './logFormatter';\n\nexport type Log = string | Record<string, unknown>;\nexport type LogEntry = Log | Log[];\nexport type Logger<L = Log> = {\n commit: () => void;\n debug: (...args: Array<L | (() => L)>) => void;\n enable: () => void;\n};\nexport type LoggerNoCommit<L = Logger> = Omit<L, 'commit'>;\n\nexport const createDebugLogger = (name: string, formatter: (val: LogEntry) => string) => (): Logger => {\n const entries: LogEntry[] = [];\n let isEnabled = false;\n\n return {\n enable: () => {\n isEnabled = true;\n },\n debug: (...args) => {\n if (isEnabled) {\n entries.push(args.map(arg => (typeof arg === 'function' ? arg() : arg)));\n }\n },\n commit: () => {\n if (isEnabled) {\n console.log(debugLogHeader(name));\n\n /**\n * We buffer each collected log entry so we can format them and log them all at once.\n * Individual console.log calls are used to ensure we don't hit platform-specific log limits (Vercel and Netlify are 4kb).\n */\n for (const log of entries) {\n let output = formatter(log);\n\n output = output\n .split('\\n')\n .map(l => ` ${l}`)\n .join('\\n');\n\n // Vercel errors if the output is > 4kb, so we truncate it\n if (process.env.VERCEL) {\n output = truncate(output, 4096);\n }\n\n console.log(output);\n }\n\n console.log(debugLogFooter(name));\n }\n },\n };\n};\n\ntype WithLogger = <L extends Logger, H extends (...args: any[]) => any>(\n loggerFactoryOrName: string | (() => L),\n handlerCtor: (logger: LoggerNoCommit<L>) => H,\n) => H;\n\nexport const withLogger: WithLogger = (loggerFactoryOrName, handlerCtor) => {\n return ((...args: any) => {\n const factory =\n typeof loggerFactoryOrName === 'string'\n ? createDebugLogger(loggerFactoryOrName, logFormatter)\n : loggerFactoryOrName;\n\n const logger = factory();\n const handler = handlerCtor(logger as any);\n\n try {\n const res = handler(...args);\n if (typeof res === 'object' && 'then' in res && typeof res.then === 'function') {\n return res\n .then((val: any) => {\n logger.commit();\n return val;\n })\n .catch((err: any) => {\n logger.commit();\n throw err;\n });\n }\n // handle sync methods\n logger.commit();\n return res;\n } catch (err: any) {\n logger.commit();\n throw err;\n }\n }) as ReturnType<typeof handlerCtor>;\n};\n\nfunction debugLogHeader(name: string) {\n return `[clerk debug start: ${name}]`;\n}\n\nfunction debugLogFooter(name: string) {\n return `[clerk debug end: ${name}] (@clerk/nextjs=${PACKAGE_VERSION},next=${nextPkg.version},timestamp=${Math.round(new Date().getTime() / 1_000)})`;\n}\n\n// ref: https://stackoverflow.com/questions/57769465/javascript-truncate-text-by-bytes-length\nfunction truncate(str: string, maxLength: number) {\n const encoder = new TextEncoder();\n const decoder = new TextDecoder('utf-8');\n\n const encodedString = encoder.encode(str);\n const truncatedString = encodedString.slice(0, maxLength);\n\n // return the truncated string, removing any replacement characters that result from partially truncated characters\n return decoder.decode(truncatedString).replace(/\\uFFFD/g, '');\n}\n"],"mappings":";AAEA,OAAO,aAAa;AAEpB,SAAS,oBAAoB;AAWtB,MAAM,oBAAoB,CAAC,MAAc,cAAyC,MAAc;AACrG,QAAM,UAAsB,CAAC;AAC7B,MAAI,YAAY;AAEhB,SAAO;AAAA,IACL,QAAQ,MAAM;AACZ,kBAAY;AAAA,IACd;AAAA,IACA,OAAO,IAAI,SAAS;AAClB,UAAI,WAAW;AACb,gBAAQ,KAAK,KAAK,IAAI,SAAQ,OAAO,QAAQ,aAAa,IAAI,IAAI,GAAI,CAAC;AAAA,MACzE;AAAA,IACF;AAAA,IACA,QAAQ,MAAM;AACZ,UAAI,WAAW;AACb,gBAAQ,IAAI,eAAe,IAAI,CAAC;AAMhC,mBAAW,OAAO,SAAS;AACzB,cAAI,SAAS,UAAU,GAAG;AAE1B,mBAAS,OACN,MAAM,IAAI,EACV,IAAI,OAAK,KAAK,CAAC,EAAE,EACjB,KAAK,IAAI;AAGZ,cAAI,QAAQ,IAAI,QAAQ;AACtB,qBAAS,SAAS,QAAQ,IAAI;AAAA,UAChC;AAEA,kBAAQ,IAAI,MAAM;AAAA,QACpB;AAEA,gBAAQ,IAAI,eAAe,IAAI,CAAC;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AACF;AAOO,MAAM,aAAyB,CAAC,qBAAqB,gBAAgB;AAC1E,UAAQ,IAAI,SAAc;AACxB,UAAM,UACJ,OAAO,wBAAwB,WAC3B,kBAAkB,qBAAqB,YAAY,IACnD;AAEN,UAAM,SAAS,QAAQ;AACvB,UAAM,UAAU,YAAY,MAAa;AAEzC,QAAI;AACF,YAAM,MAAM,QAAQ,GAAG,IAAI;AAC3B,UAAI,OAAO,QAAQ,YAAY,UAAU,OAAO,OAAO,IAAI,SAAS,YAAY;AAC9E,eAAO,IACJ,KAAK,CAAC,QAAa;AAClB,iBAAO,OAAO;AACd,iBAAO;AAAA,QACT,CAAC,EACA,MAAM,CAAC,QAAa;AACnB,iBAAO,OAAO;AACd,gBAAM;AAAA,QACR,CAAC;AAAA,MACL;AAEA,aAAO,OAAO;AACd,aAAO;AAAA,IACT,SAAS,KAAU;AACjB,aAAO,OAAO;AACd,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,SAAS,eAAe,MAAc;AACpC,SAAO,uBAAuB,IAAI;AACpC;AAEA,SAAS,eAAe,MAAc;AACpC,SAAO,qBAAqB,IAAI,oBAAoB,iCAAe,SAAS,QAAQ,OAAO,cAAc,KAAK,OAAM,oBAAI,KAAK,GAAE,QAAQ,IAAI,GAAK,CAAC;AACnJ;AAGA,SAAS,SAAS,KAAa,WAAmB;AAChD,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,UAAU,IAAI,YAAY,OAAO;AAEvC,QAAM,gBAAgB,QAAQ,OAAO,GAAG;AACxC,QAAM,kBAAkB,cAAc,MAAM,GAAG,SAAS;AAGxD,SAAO,QAAQ,OAAO,eAAe,EAAE,QAAQ,WAAW,EAAE;AAC9D;","names":[]}
1
+ {"version":3,"sources":["../../../src/utils/debugLogger.ts"],"sourcesContent":["// TODO: Replace with a more sophisticated logging solution\n\nimport nextPkg from 'next/package.json';\n\nimport { logFormatter } from './logFormatter';\n\nexport type Log = string | Record<string, unknown>;\nexport type LogEntry = Log | Log[];\nexport type Logger<L = Log> = {\n commit: () => void;\n debug: (...args: Array<L | (() => L)>) => void;\n enable: () => void;\n};\nexport type LoggerNoCommit<L = Logger> = Omit<L, 'commit'>;\n\nexport const createDebugLogger = (name: string, formatter: (val: LogEntry) => string) => (): Logger => {\n const entries: LogEntry[] = [];\n let isEnabled = false;\n\n return {\n enable: () => {\n isEnabled = true;\n },\n debug: (...args) => {\n if (isEnabled) {\n entries.push(args.map(arg => (typeof arg === 'function' ? arg() : arg)));\n }\n },\n commit: () => {\n if (isEnabled) {\n console.log(debugLogHeader(name));\n\n /**\n * We buffer each collected log entry so we can format them and log them all at once.\n * Individual console.log calls are used to ensure we don't hit platform-specific log limits (Vercel and Netlify are 4kb).\n */\n for (const log of entries) {\n let output = formatter(log);\n\n output = output\n .split('\\n')\n .map(l => ` ${l}`)\n .join('\\n');\n\n // Vercel errors if the output is > 4kb, so we truncate it\n if (process.env.VERCEL) {\n output = truncate(output, 4096);\n }\n\n console.log(output);\n }\n\n console.log(debugLogFooter(name));\n }\n },\n };\n};\n\ntype WithLogger = <L extends Logger, H extends (...args: any[]) => any>(\n loggerFactoryOrName: string | (() => L),\n handlerCtor: (logger: LoggerNoCommit<L>) => H,\n) => H;\n\nexport const withLogger: WithLogger = (loggerFactoryOrName, handlerCtor) => {\n return ((...args: any) => {\n const factory =\n typeof loggerFactoryOrName === 'string'\n ? createDebugLogger(loggerFactoryOrName, logFormatter)\n : loggerFactoryOrName;\n\n const logger = factory();\n const handler = handlerCtor(logger as any);\n\n try {\n const res = handler(...args);\n if (typeof res === 'object' && 'then' in res && typeof res.then === 'function') {\n return res\n .then((val: any) => {\n logger.commit();\n return val;\n })\n .catch((err: any) => {\n logger.commit();\n throw err;\n });\n }\n // handle sync methods\n logger.commit();\n return res;\n } catch (err: any) {\n logger.commit();\n throw err;\n }\n }) as ReturnType<typeof handlerCtor>;\n};\n\nfunction debugLogHeader(name: string) {\n return `[clerk debug start: ${name}]`;\n}\n\nfunction debugLogFooter(name: string) {\n return `[clerk debug end: ${name}] (@clerk/nextjs=${PACKAGE_VERSION},next=${nextPkg.version},timestamp=${Math.round(new Date().getTime() / 1_000)})`;\n}\n\n// ref: https://stackoverflow.com/questions/57769465/javascript-truncate-text-by-bytes-length\nfunction truncate(str: string, maxLength: number) {\n const encoder = new TextEncoder();\n const decoder = new TextDecoder('utf-8');\n\n const encodedString = encoder.encode(str);\n const truncatedString = encodedString.slice(0, maxLength);\n\n // return the truncated string, removing any replacement characters that result from partially truncated characters\n return decoder.decode(truncatedString).replace(/\\uFFFD/g, '');\n}\n"],"mappings":";AAEA,OAAO,aAAa;AAEpB,SAAS,oBAAoB;AAWtB,MAAM,oBAAoB,CAAC,MAAc,cAAyC,MAAc;AACrG,QAAM,UAAsB,CAAC;AAC7B,MAAI,YAAY;AAEhB,SAAO;AAAA,IACL,QAAQ,MAAM;AACZ,kBAAY;AAAA,IACd;AAAA,IACA,OAAO,IAAI,SAAS;AAClB,UAAI,WAAW;AACb,gBAAQ,KAAK,KAAK,IAAI,SAAQ,OAAO,QAAQ,aAAa,IAAI,IAAI,GAAI,CAAC;AAAA,MACzE;AAAA,IACF;AAAA,IACA,QAAQ,MAAM;AACZ,UAAI,WAAW;AACb,gBAAQ,IAAI,eAAe,IAAI,CAAC;AAMhC,mBAAW,OAAO,SAAS;AACzB,cAAI,SAAS,UAAU,GAAG;AAE1B,mBAAS,OACN,MAAM,IAAI,EACV,IAAI,OAAK,KAAK,CAAC,EAAE,EACjB,KAAK,IAAI;AAGZ,cAAI,QAAQ,IAAI,QAAQ;AACtB,qBAAS,SAAS,QAAQ,IAAI;AAAA,UAChC;AAEA,kBAAQ,IAAI,MAAM;AAAA,QACpB;AAEA,gBAAQ,IAAI,eAAe,IAAI,CAAC;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AACF;AAOO,MAAM,aAAyB,CAAC,qBAAqB,gBAAgB;AAC1E,UAAQ,IAAI,SAAc;AACxB,UAAM,UACJ,OAAO,wBAAwB,WAC3B,kBAAkB,qBAAqB,YAAY,IACnD;AAEN,UAAM,SAAS,QAAQ;AACvB,UAAM,UAAU,YAAY,MAAa;AAEzC,QAAI;AACF,YAAM,MAAM,QAAQ,GAAG,IAAI;AAC3B,UAAI,OAAO,QAAQ,YAAY,UAAU,OAAO,OAAO,IAAI,SAAS,YAAY;AAC9E,eAAO,IACJ,KAAK,CAAC,QAAa;AAClB,iBAAO,OAAO;AACd,iBAAO;AAAA,QACT,CAAC,EACA,MAAM,CAAC,QAAa;AACnB,iBAAO,OAAO;AACd,gBAAM;AAAA,QACR,CAAC;AAAA,MACL;AAEA,aAAO,OAAO;AACd,aAAO;AAAA,IACT,SAAS,KAAU;AACjB,aAAO,OAAO;AACd,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,SAAS,eAAe,MAAc;AACpC,SAAO,uBAAuB,IAAI;AACpC;AAEA,SAAS,eAAe,MAAc;AACpC,SAAO,qBAAqB,IAAI,oBAAoB,QAAe,SAAS,QAAQ,OAAO,cAAc,KAAK,OAAM,oBAAI,KAAK,GAAE,QAAQ,IAAI,GAAK,CAAC;AACnJ;AAGA,SAAS,SAAS,KAAa,WAAmB;AAChD,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,UAAU,IAAI,YAAY,OAAO;AAEvC,QAAM,gBAAgB,QAAQ,OAAO,GAAG;AACxC,QAAM,kBAAkB,cAAc,MAAM,GAAG,SAAS;AAGxD,SAAO,QAAQ,OAAO,eAAe,EAAE,QAAQ,WAAW,EAAE;AAC9D;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"content-security-policy.d.ts","sourceRoot":"","sources":["../../../src/server/content-security-policy.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,8BAA8B,GAEtC,aAAa,GACb,aAAa,GACb,UAAU,GACV,SAAS,GACT,WAAW,GACX,YAAY,GACZ,YAAY,GACZ,WAAW,GAEX,UAAU,GACV,WAAW,GACX,aAAa,GACb,iBAAiB,GACjB,WAAW,GACX,cAAc,GACd,aAAa,GACb,cAAc,GACd,YAAY,GAEZ,cAAc,GACd,iBAAiB,GACjB,SAAS,GAET,yBAAyB,GACzB,2BAA2B,GAC3B,eAAe,GACf,2BAA2B,GAE3B,WAAW,GACX,YAAY,GAEZ,iBAAiB,GACjB,iBAAiB,GACjB,gBAAgB,GAChB,gBAAgB,CAAC;AAYrB,MAAM,WAAW,4BAA4B;IAC3C;;;;;OAKG;IACH,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,4BAA4B;IAC3C;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,8BAA8B,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IACvE;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAwKD;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAKtC;AAmDD;;;GAGG;AACH,wBAAgB,kCAAkC,CAChD,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,4BAA4B,GACpC,4BAA4B,CAyB9B"}
1
+ {"version":3,"file":"content-security-policy.d.ts","sourceRoot":"","sources":["../../../src/server/content-security-policy.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,MAAM,8BAA8B,GAEtC,aAAa,GACb,aAAa,GACb,UAAU,GACV,SAAS,GACT,WAAW,GACX,YAAY,GACZ,YAAY,GACZ,WAAW,GAEX,UAAU,GACV,WAAW,GACX,aAAa,GACb,iBAAiB,GACjB,WAAW,GACX,cAAc,GACd,aAAa,GACb,cAAc,GACd,YAAY,GAEZ,cAAc,GACd,iBAAiB,GACjB,SAAS,GAET,yBAAyB,GACzB,2BAA2B,GAC3B,eAAe,GACf,2BAA2B,GAE3B,WAAW,GACX,YAAY,GAEZ,iBAAiB,GACjB,iBAAiB,GACjB,gBAAgB,GAChB,gBAAgB,CAAC;AAYrB,MAAM,WAAW,4BAA4B;IAC3C;;;;;OAKG;IACH,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,4BAA4B;IAC3C;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,8BAA8B,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IACvE;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA2KD;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAKtC;AAmDD;;;GAGG;AACH,wBAAgB,kCAAkC,CAChD,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,4BAA4B,GACpC,4BAA4B,CAyB9B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clerk/nextjs",
3
- "version": "7.5.21-snapshot.v20260720201619",
3
+ "version": "7.5.21",
4
4
  "description": "Clerk SDK for NextJS",
5
5
  "keywords": [
6
6
  "clerk",
@@ -72,9 +72,9 @@
72
72
  "dependencies": {
73
73
  "server-only": "0.0.1",
74
74
  "tslib": "2.8.1",
75
- "@clerk/react": "6.12.6-snapshot.v20260720201619",
76
- "@clerk/shared": "4.25.6-snapshot.v20260720201619",
77
- "@clerk/backend": "3.12.0-snapshot.v20260720201619"
75
+ "@clerk/backend": "^3.12.0",
76
+ "@clerk/react": "^6.12.6",
77
+ "@clerk/shared": "^4.25.6"
78
78
  },
79
79
  "devDependencies": {
80
80
  "crypto-es": "^2.1.0",