@c15t/backend 2.0.0-rc.4 → 2.0.0-rc.5
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/core.cjs +830 -74
- package/dist/core.js +807 -75
- package/dist/db/schema.cjs +37 -0
- package/dist/db/schema.js +33 -2
- package/dist/edge.cjs +1106 -0
- package/dist/edge.js +1069 -0
- package/dist/router.cjs +613 -64
- package/dist/router.js +613 -64
- package/{dist → dist-types}/cache/adapters/cloudflare-kv.d.ts +0 -1
- package/{dist → dist-types}/cache/adapters/index.d.ts +0 -1
- package/{dist → dist-types}/cache/adapters/memory.d.ts +0 -1
- package/{dist → dist-types}/cache/adapters/upstash-redis.d.ts +0 -1
- package/{dist → dist-types}/cache/gvl-resolver.d.ts +1 -2
- package/{dist → dist-types}/cache/index.d.ts +0 -1
- package/{dist → dist-types}/cache/keys.d.ts +0 -1
- package/{dist → dist-types}/cache/types.d.ts +0 -1
- package/{dist → dist-types}/core.d.ts +8 -1
- package/{dist → dist-types}/db/migrator/index.d.ts +0 -1
- package/{dist → dist-types}/db/registry/consent-policy.d.ts +0 -1
- package/{dist → dist-types}/db/registry/consent-purpose.d.ts +0 -1
- package/{dist → dist-types}/db/registry/domain.d.ts +0 -1
- package/{dist → dist-types}/db/registry/index.d.ts +22 -2
- package/dist-types/db/registry/runtime-policy-decision.d.ts +60 -0
- package/{dist → dist-types}/db/registry/subject.d.ts +0 -1
- package/{dist → dist-types}/db/registry/types.d.ts +1 -2
- package/{dist → dist-types}/db/registry/utils/generate-id.d.ts +0 -1
- package/{dist → dist-types}/db/registry/utils.d.ts +0 -1
- package/{dist → dist-types}/db/schema/1.0.0/audit-log.d.ts +0 -1
- package/{dist → dist-types}/db/schema/1.0.0/consent-policy.d.ts +0 -1
- package/{dist → dist-types}/db/schema/1.0.0/consent-purpose.d.ts +0 -1
- package/{dist → dist-types}/db/schema/1.0.0/consent-record.d.ts +0 -1
- package/{dist → dist-types}/db/schema/1.0.0/consent.d.ts +1 -2
- package/{dist → dist-types}/db/schema/1.0.0/domain.d.ts +0 -1
- package/{dist → dist-types}/db/schema/1.0.0/index.d.ts +0 -1
- package/{dist → dist-types}/db/schema/1.0.0/subject.d.ts +0 -1
- package/{dist → dist-types}/db/schema/2.0.0/audit-log.d.ts +1 -2
- package/{dist → dist-types}/db/schema/2.0.0/consent-policy.d.ts +1 -2
- package/{dist → dist-types}/db/schema/2.0.0/consent-purpose.d.ts +1 -2
- package/{dist → dist-types}/db/schema/2.0.0/consent.d.ts +5 -2
- package/{dist → dist-types}/db/schema/2.0.0/domain.d.ts +1 -2
- package/{dist → dist-types}/db/schema/2.0.0/index.d.ts +432 -17
- package/dist-types/db/schema/2.0.0/runtime-policy-decision.d.ts +23 -0
- package/{dist → dist-types}/db/schema/2.0.0/subject.d.ts +1 -2
- package/{dist → dist-types}/db/schema/index.d.ts +862 -33
- package/{dist → dist-types}/db/tenant-scope.d.ts +0 -1
- package/{dist → dist-types}/define-config.d.ts +0 -1
- package/dist-types/edge/index.d.ts +5 -0
- package/dist-types/edge/init-handler.d.ts +38 -0
- package/dist-types/edge/resolve-consent.d.ts +80 -0
- package/dist-types/edge/types.d.ts +13 -0
- package/{dist → dist-types}/handlers/consent/check.handler.d.ts +0 -1
- package/{src/handlers/consent/index.ts → dist-types/handlers/consent/index.d.ts} +0 -1
- package/{dist → dist-types}/handlers/init/geo.d.ts +2 -3
- package/{dist → dist-types}/handlers/init/index.d.ts +4 -5
- package/dist-types/handlers/init/policy.d.ts +26 -0
- package/dist-types/handlers/init/resolve-init.d.ts +44 -0
- package/dist-types/handlers/init/translations.d.ts +48 -0
- package/dist-types/handlers/policy/snapshot.d.ts +99 -0
- package/{src/handlers/status/index.ts → dist-types/handlers/status/index.d.ts} +0 -1
- package/{dist → dist-types}/handlers/status/status.handler.d.ts +0 -1
- package/{dist → dist-types}/handlers/subject/get.handler.d.ts +0 -1
- package/{src/handlers/subject/index.ts → dist-types/handlers/subject/index.d.ts} +0 -1
- package/{dist → dist-types}/handlers/subject/list.handler.d.ts +0 -1
- package/{dist → dist-types}/handlers/subject/patch.handler.d.ts +0 -1
- package/{dist → dist-types}/handlers/subject/post.handler.d.ts +12 -1
- package/{dist → dist-types}/handlers/utils/consent-enrichment.d.ts +0 -1
- package/{dist → dist-types}/init.d.ts +0 -1
- package/{dist → dist-types}/middleware/auth/index.d.ts +0 -1
- package/{dist → dist-types}/middleware/auth/validate-api-key.d.ts +0 -1
- package/{dist → dist-types}/middleware/cors/cors.d.ts +0 -1
- package/{src/middleware/cors/index.ts → dist-types/middleware/cors/index.d.ts} +0 -1
- package/{dist → dist-types}/middleware/cors/is-origin-trusted.d.ts +1 -2
- package/{dist → dist-types}/middleware/cors/process-cors.d.ts +0 -1
- package/{dist → dist-types}/middleware/openapi/config.d.ts +0 -1
- package/{dist → dist-types}/middleware/openapi/handlers.d.ts +0 -1
- package/{src/middleware/openapi/index.ts → dist-types/middleware/openapi/index.d.ts} +0 -1
- package/{dist → dist-types}/middleware/process-ip/index.d.ts +0 -1
- package/dist-types/policies/builder.d.ts +127 -0
- package/dist-types/policies/defaults.d.ts +2 -0
- package/dist-types/policies/matchers.d.ts +3 -0
- package/{dist → dist-types}/router.d.ts +0 -1
- package/{dist → dist-types}/routes/consent.d.ts +0 -1
- package/{src/routes/index.ts → dist-types/routes/index.d.ts} +0 -1
- package/{dist → dist-types}/routes/init.d.ts +0 -1
- package/{dist → dist-types}/routes/status.d.ts +0 -1
- package/{dist → dist-types}/routes/subject.d.ts +0 -1
- package/{dist → dist-types}/types/api.d.ts +0 -1
- package/{dist → dist-types}/types/index.d.ts +110 -6
- package/dist-types/utils/background.d.ts +6 -0
- package/{dist → dist-types}/utils/create-telemetry-options.d.ts +0 -1
- package/{dist → dist-types}/utils/env.d.ts +0 -1
- package/{dist → dist-types}/utils/extract-error-message.d.ts +0 -1
- package/{dist → dist-types}/utils/instrumentation.d.ts +0 -1
- package/{dist → dist-types}/utils/logger.d.ts +1 -2
- package/{dist → dist-types}/utils/metrics.d.ts +0 -1
- package/dist-types/version.d.ts +1 -0
- package/docs/README.md +49 -0
- package/docs/api/configuration.md +197 -0
- package/docs/api/endpoints.md +211 -0
- package/docs/guides/caching.md +85 -0
- package/docs/guides/database-setup.md +128 -0
- package/docs/guides/edge-deployment.md +248 -0
- package/docs/guides/framework-integration.md +142 -0
- package/docs/guides/iab-tcf.md +89 -0
- package/docs/guides/observability.md +96 -0
- package/docs/guides/policy-packs.md +396 -0
- package/docs/quickstart.md +129 -0
- package/package.json +33 -19
- package/.turbo/turbo-build.log +0 -49
- package/CHANGELOG.md +0 -123
- package/dist/cache/adapters/cloudflare-kv.d.ts.map +0 -1
- package/dist/cache/adapters/index.d.ts.map +0 -1
- package/dist/cache/adapters/memory.d.ts.map +0 -1
- package/dist/cache/adapters/upstash-redis.d.ts.map +0 -1
- package/dist/cache/gvl-resolver.d.ts.map +0 -1
- package/dist/cache/index.d.ts.map +0 -1
- package/dist/cache/keys.d.ts.map +0 -1
- package/dist/cache/types.d.ts.map +0 -1
- package/dist/core.d.ts.map +0 -1
- package/dist/db/adapters/drizzle.d.ts +0 -2
- package/dist/db/adapters/drizzle.d.ts.map +0 -1
- package/dist/db/adapters/index.d.ts +0 -2
- package/dist/db/adapters/index.d.ts.map +0 -1
- package/dist/db/adapters/kysely.d.ts +0 -2
- package/dist/db/adapters/kysely.d.ts.map +0 -1
- package/dist/db/adapters/mongo.d.ts +0 -2
- package/dist/db/adapters/mongo.d.ts.map +0 -1
- package/dist/db/adapters/prisma.d.ts +0 -2
- package/dist/db/adapters/prisma.d.ts.map +0 -1
- package/dist/db/adapters/typeorm.d.ts +0 -2
- package/dist/db/adapters/typeorm.d.ts.map +0 -1
- package/dist/db/migrator/index.d.ts.map +0 -1
- package/dist/db/registry/consent-policy.d.ts.map +0 -1
- package/dist/db/registry/consent-purpose.d.ts.map +0 -1
- package/dist/db/registry/domain.d.ts.map +0 -1
- package/dist/db/registry/index.d.ts.map +0 -1
- package/dist/db/registry/subject.d.ts.map +0 -1
- package/dist/db/registry/types.d.ts.map +0 -1
- package/dist/db/registry/utils/generate-id.d.ts.map +0 -1
- package/dist/db/registry/utils.d.ts.map +0 -1
- package/dist/db/schema/1.0.0/audit-log.d.ts.map +0 -1
- package/dist/db/schema/1.0.0/consent-policy.d.ts.map +0 -1
- package/dist/db/schema/1.0.0/consent-purpose.d.ts.map +0 -1
- package/dist/db/schema/1.0.0/consent-record.d.ts.map +0 -1
- package/dist/db/schema/1.0.0/consent.d.ts.map +0 -1
- package/dist/db/schema/1.0.0/domain.d.ts.map +0 -1
- package/dist/db/schema/1.0.0/index.d.ts.map +0 -1
- package/dist/db/schema/1.0.0/subject.d.ts.map +0 -1
- package/dist/db/schema/2.0.0/audit-log.d.ts.map +0 -1
- package/dist/db/schema/2.0.0/consent-policy.d.ts.map +0 -1
- package/dist/db/schema/2.0.0/consent-purpose.d.ts.map +0 -1
- package/dist/db/schema/2.0.0/consent.d.ts.map +0 -1
- package/dist/db/schema/2.0.0/domain.d.ts.map +0 -1
- package/dist/db/schema/2.0.0/index.d.ts.map +0 -1
- package/dist/db/schema/2.0.0/subject.d.ts.map +0 -1
- package/dist/db/schema/index.d.ts.map +0 -1
- package/dist/db/tenant-scope.d.ts.map +0 -1
- package/dist/define-config.d.ts.map +0 -1
- package/dist/handlers/consent/check.handler.d.ts.map +0 -1
- package/dist/handlers/consent/index.d.ts +0 -12
- package/dist/handlers/consent/index.d.ts.map +0 -1
- package/dist/handlers/init/geo.d.ts.map +0 -1
- package/dist/handlers/init/index.d.ts.map +0 -1
- package/dist/handlers/init/translations.d.ts +0 -26
- package/dist/handlers/init/translations.d.ts.map +0 -1
- package/dist/handlers/status/index.d.ts +0 -7
- package/dist/handlers/status/index.d.ts.map +0 -1
- package/dist/handlers/status/status.handler.d.ts.map +0 -1
- package/dist/handlers/subject/get.handler.d.ts.map +0 -1
- package/dist/handlers/subject/index.d.ts +0 -10
- package/dist/handlers/subject/index.d.ts.map +0 -1
- package/dist/handlers/subject/list.handler.d.ts.map +0 -1
- package/dist/handlers/subject/patch.handler.d.ts.map +0 -1
- package/dist/handlers/subject/post.handler.d.ts.map +0 -1
- package/dist/handlers/utils/consent-enrichment.d.ts.map +0 -1
- package/dist/init.d.ts.map +0 -1
- package/dist/middleware/auth/index.d.ts.map +0 -1
- package/dist/middleware/auth/validate-api-key.d.ts.map +0 -1
- package/dist/middleware/cors/cors.d.ts.map +0 -1
- package/dist/middleware/cors/index.d.ts +0 -30
- package/dist/middleware/cors/index.d.ts.map +0 -1
- package/dist/middleware/cors/is-origin-trusted.d.ts.map +0 -1
- package/dist/middleware/cors/process-cors.d.ts.map +0 -1
- package/dist/middleware/openapi/config.d.ts.map +0 -1
- package/dist/middleware/openapi/handlers.d.ts.map +0 -1
- package/dist/middleware/openapi/index.d.ts +0 -12
- package/dist/middleware/openapi/index.d.ts.map +0 -1
- package/dist/middleware/process-ip/index.d.ts.map +0 -1
- package/dist/router.d.ts.map +0 -1
- package/dist/routes/consent.d.ts.map +0 -1
- package/dist/routes/index.d.ts +0 -10
- package/dist/routes/index.d.ts.map +0 -1
- package/dist/routes/init.d.ts.map +0 -1
- package/dist/routes/status.d.ts.map +0 -1
- package/dist/routes/subject.d.ts.map +0 -1
- package/dist/types/api.d.ts.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/utils/create-telemetry-options.d.ts.map +0 -1
- package/dist/utils/env.d.ts.map +0 -1
- package/dist/utils/extract-error-message.d.ts.map +0 -1
- package/dist/utils/index.d.ts +0 -4
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/instrumentation.d.ts.map +0 -1
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/metrics.d.ts.map +0 -1
- package/dist/version.d.ts +0 -2
- package/dist/version.d.ts.map +0 -1
- package/knip.json +0 -31
- package/rslib.config.ts +0 -93
- package/src/cache/adapters/cloudflare-kv.ts +0 -71
- package/src/cache/adapters/index.ts +0 -22
- package/src/cache/adapters/memory.ts +0 -111
- package/src/cache/adapters/upstash-redis.ts +0 -113
- package/src/cache/gvl-resolver.ts +0 -289
- package/src/cache/index.ts +0 -34
- package/src/cache/keys.ts +0 -68
- package/src/cache/types.ts +0 -66
- package/src/core.ts +0 -369
- package/src/db/migrator/index.ts +0 -80
- package/src/db/registry/consent-policy.test.ts +0 -451
- package/src/db/registry/consent-policy.ts +0 -82
- package/src/db/registry/consent-purpose.test.ts +0 -428
- package/src/db/registry/consent-purpose.ts +0 -61
- package/src/db/registry/domain.test.ts +0 -445
- package/src/db/registry/domain.ts +0 -91
- package/src/db/registry/index.ts +0 -14
- package/src/db/registry/subject.test.ts +0 -371
- package/src/db/registry/subject.ts +0 -126
- package/src/db/registry/types.ts +0 -10
- package/src/db/registry/utils/generate-id.test.ts +0 -216
- package/src/db/registry/utils/generate-id.ts +0 -133
- package/src/db/registry/utils.ts +0 -133
- package/src/db/schema/1.0.0/audit-log.ts +0 -15
- package/src/db/schema/1.0.0/consent-policy.ts +0 -14
- package/src/db/schema/1.0.0/consent-purpose.ts +0 -14
- package/src/db/schema/1.0.0/consent-record.ts +0 -10
- package/src/db/schema/1.0.0/consent.ts +0 -20
- package/src/db/schema/1.0.0/domain.ts +0 -12
- package/src/db/schema/1.0.0/index.ts +0 -48
- package/src/db/schema/1.0.0/subject.ts +0 -11
- package/src/db/schema/2.0.0/audit-log.ts +0 -18
- package/src/db/schema/2.0.0/consent-policy.ts +0 -28
- package/src/db/schema/2.0.0/consent-purpose.ts +0 -12
- package/src/db/schema/2.0.0/consent.ts +0 -28
- package/src/db/schema/2.0.0/domain.ts +0 -12
- package/src/db/schema/2.0.0/index.ts +0 -47
- package/src/db/schema/2.0.0/subject.ts +0 -13
- package/src/db/schema/index.ts +0 -15
- package/src/db/tenant-scope.test.ts +0 -747
- package/src/db/tenant-scope.ts +0 -103
- package/src/define-config.ts +0 -19
- package/src/handlers/consent/check.handler.ts +0 -126
- package/src/handlers/init/geo.test.ts +0 -317
- package/src/handlers/init/geo.ts +0 -195
- package/src/handlers/init/index.test.ts +0 -205
- package/src/handlers/init/index.ts +0 -114
- package/src/handlers/init/translations.test.ts +0 -121
- package/src/handlers/init/translations.ts +0 -69
- package/src/handlers/status/status.handler.test.ts +0 -155
- package/src/handlers/status/status.handler.ts +0 -51
- package/src/handlers/subject/get.handler.ts +0 -92
- package/src/handlers/subject/list.handler.ts +0 -92
- package/src/handlers/subject/patch.handler.ts +0 -119
- package/src/handlers/subject/post.handler.test.ts +0 -294
- package/src/handlers/subject/post.handler.ts +0 -268
- package/src/handlers/utils/consent-enrichment.test.ts +0 -380
- package/src/handlers/utils/consent-enrichment.ts +0 -218
- package/src/init.test.ts +0 -122
- package/src/init.ts +0 -88
- package/src/middleware/auth/index.ts +0 -11
- package/src/middleware/auth/validate-api-key.test.ts +0 -86
- package/src/middleware/auth/validate-api-key.ts +0 -107
- package/src/middleware/cors/cors.test.ts +0 -135
- package/src/middleware/cors/cors.ts +0 -186
- package/src/middleware/cors/is-origin-trusted.test.ts +0 -164
- package/src/middleware/cors/is-origin-trusted.ts +0 -130
- package/src/middleware/cors/process-cors.ts +0 -91
- package/src/middleware/openapi/config.ts +0 -29
- package/src/middleware/openapi/handlers.ts +0 -34
- package/src/middleware/process-ip/index.test.ts +0 -193
- package/src/middleware/process-ip/index.ts +0 -199
- package/src/router.ts +0 -15
- package/src/routes/consent.ts +0 -52
- package/src/routes/init.ts +0 -105
- package/src/routes/status.ts +0 -46
- package/src/routes/subject.ts +0 -152
- package/src/types/api.ts +0 -48
- package/src/types/index.ts +0 -391
- package/src/utils/create-telemetry-options.test.ts +0 -286
- package/src/utils/create-telemetry-options.ts +0 -229
- package/src/utils/env.ts +0 -84
- package/src/utils/extract-error-message.ts +0 -21
- package/src/utils/instrumentation.test.ts +0 -183
- package/src/utils/instrumentation.ts +0 -194
- package/src/utils/logger.ts +0 -41
- package/src/utils/metrics.test.ts +0 -311
- package/src/utils/metrics.ts +0 -402
- package/src/utils/telemetry-pii.test.ts +0 -323
- package/src/version.ts +0 -2
- package/tsconfig.json +0 -11
- package/vitest.config.ts +0 -28
- /package/{src/db/adapters/drizzle.ts → dist-types/db/adapters/drizzle.d.ts} +0 -0
- /package/{src/db/adapters/index.ts → dist-types/db/adapters/index.d.ts} +0 -0
- /package/{src/db/adapters/kysely.ts → dist-types/db/adapters/kysely.d.ts} +0 -0
- /package/{src/db/adapters/mongo.ts → dist-types/db/adapters/mongo.d.ts} +0 -0
- /package/{src/db/adapters/prisma.ts → dist-types/db/adapters/prisma.d.ts} +0 -0
- /package/{src/db/adapters/typeorm.ts → dist-types/db/adapters/typeorm.d.ts} +0 -0
- /package/{src/utils/index.ts → dist-types/utils/index.d.ts} +0 -0
package/src/init.ts
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import type { C15TContext, C15TOptions } from '~/types';
|
|
2
|
-
import { createRegistry } from './db/registry';
|
|
3
|
-
import { DB } from './db/schema';
|
|
4
|
-
import { withTenantScope } from './db/tenant-scope';
|
|
5
|
-
import {
|
|
6
|
-
createTelemetryOptions,
|
|
7
|
-
isTelemetryEnabled,
|
|
8
|
-
} from './utils/create-telemetry-options';
|
|
9
|
-
import { initLogger } from './utils/logger';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Initializes the c15t backend context.
|
|
13
|
-
*
|
|
14
|
-
* Telemetry (tracing and metrics) is opt-in and disabled by default.
|
|
15
|
-
* Users must:
|
|
16
|
-
* 1. Set up their own OpenTelemetry SDK (Node.js, Bun, edge runtime, etc.)
|
|
17
|
-
* 2. Pass enabled: true and optionally a tracer/meter to the telemetry config
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* ```typescript
|
|
21
|
-
* // User sets up their own SDK before calling init
|
|
22
|
-
* import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
23
|
-
* const sdk = new NodeSDK({ ... });
|
|
24
|
-
* sdk.start();
|
|
25
|
-
*
|
|
26
|
-
* // Then pass telemetry config
|
|
27
|
-
* const instance = c15tInstance({
|
|
28
|
-
* telemetry: {
|
|
29
|
-
* enabled: true,
|
|
30
|
-
* tracer: trace.getTracer('my-app'),
|
|
31
|
-
* meter: metrics.getMeter('my-app'),
|
|
32
|
-
* },
|
|
33
|
-
* });
|
|
34
|
-
* ```
|
|
35
|
-
*/
|
|
36
|
-
export const init = (options: C15TOptions): C15TContext => {
|
|
37
|
-
const appName = options.appName || 'c15t';
|
|
38
|
-
|
|
39
|
-
const logger = initLogger({
|
|
40
|
-
...options.logger,
|
|
41
|
-
appName: String(appName),
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
// Create telemetry options (validates and merges with defaults)
|
|
45
|
-
const telemetryOptions = createTelemetryOptions(
|
|
46
|
-
String(appName),
|
|
47
|
-
options.telemetry,
|
|
48
|
-
options.tenantId
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
// Log telemetry status
|
|
52
|
-
if (isTelemetryEnabled(options)) {
|
|
53
|
-
logger.debug('Telemetry is enabled', {
|
|
54
|
-
hasTracer: !!telemetryOptions?.tracer,
|
|
55
|
-
hasMeter: !!telemetryOptions?.meter,
|
|
56
|
-
attributes: telemetryOptions?.defaultAttributes,
|
|
57
|
-
});
|
|
58
|
-
} else {
|
|
59
|
-
logger.debug('Telemetry is disabled (opt-in required)');
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Initialize core components
|
|
63
|
-
const db = options.tablePrefix ? DB.names.prefix(options.tablePrefix) : DB;
|
|
64
|
-
const client = db.client(options.adapter);
|
|
65
|
-
|
|
66
|
-
const rawOrm = client.orm('2.0.0');
|
|
67
|
-
const orm = options.tenantId
|
|
68
|
-
? withTenantScope(rawOrm, options.tenantId)
|
|
69
|
-
: rawOrm;
|
|
70
|
-
|
|
71
|
-
// Destructure ipAddress config to avoid type conflict with C15TContext.ipAddress (resolved string)
|
|
72
|
-
const { ipAddress: _ipAddressConfig, ...baseOptions } = options;
|
|
73
|
-
|
|
74
|
-
const context: C15TContext = {
|
|
75
|
-
...baseOptions,
|
|
76
|
-
appName,
|
|
77
|
-
logger,
|
|
78
|
-
db: orm,
|
|
79
|
-
registry: createRegistry({
|
|
80
|
-
db: orm,
|
|
81
|
-
ctx: {
|
|
82
|
-
logger,
|
|
83
|
-
},
|
|
84
|
-
}),
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
return context;
|
|
88
|
-
};
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import {
|
|
3
|
-
extractBearerToken,
|
|
4
|
-
validateApiKey,
|
|
5
|
-
validateRequestAuth,
|
|
6
|
-
} from './validate-api-key';
|
|
7
|
-
|
|
8
|
-
describe('extractBearerToken', () => {
|
|
9
|
-
it('should extract token from valid Bearer header', () => {
|
|
10
|
-
expect(extractBearerToken('Bearer sk_live_abc123')).toBe('sk_live_abc123');
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
it('should return null for non-Bearer auth', () => {
|
|
14
|
-
expect(extractBearerToken('Basic abc123')).toBeNull();
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
it('should return null for missing Bearer prefix', () => {
|
|
18
|
-
expect(extractBearerToken('sk_live_abc123')).toBeNull();
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it('should return null for null header', () => {
|
|
22
|
-
expect(extractBearerToken(null)).toBeNull();
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it('should return null for empty header', () => {
|
|
26
|
-
expect(extractBearerToken('')).toBeNull();
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('should handle extra spaces', () => {
|
|
30
|
-
expect(extractBearerToken('Bearer abc123')).toBeNull(); // Two spaces
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
describe('validateApiKey', () => {
|
|
35
|
-
const validKeys = ['sk_live_abc123', 'sk_live_def456'];
|
|
36
|
-
|
|
37
|
-
it('should return true for valid key', () => {
|
|
38
|
-
expect(validateApiKey('sk_live_abc123', validKeys)).toBe(true);
|
|
39
|
-
expect(validateApiKey('sk_live_def456', validKeys)).toBe(true);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('should return false for invalid key', () => {
|
|
43
|
-
expect(validateApiKey('sk_live_invalid', validKeys)).toBe(false);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('should return false for null token', () => {
|
|
47
|
-
expect(validateApiKey(null, validKeys)).toBe(false);
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('should return false for undefined keys', () => {
|
|
51
|
-
expect(validateApiKey('sk_live_abc123', undefined)).toBe(false);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('should return false for empty keys array', () => {
|
|
55
|
-
expect(validateApiKey('sk_live_abc123', [])).toBe(false);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it('should be case-sensitive', () => {
|
|
59
|
-
expect(validateApiKey('SK_LIVE_ABC123', validKeys)).toBe(false);
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
describe('validateRequestAuth', () => {
|
|
64
|
-
const validKeys = ['sk_live_abc123'];
|
|
65
|
-
|
|
66
|
-
it('should return true for valid Authorization header', () => {
|
|
67
|
-
const headers = new Headers();
|
|
68
|
-
headers.set('Authorization', 'Bearer sk_live_abc123');
|
|
69
|
-
expect(validateRequestAuth(headers, validKeys)).toBe(true);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('should return false for invalid token', () => {
|
|
73
|
-
const headers = new Headers();
|
|
74
|
-
headers.set('Authorization', 'Bearer sk_live_invalid');
|
|
75
|
-
expect(validateRequestAuth(headers, validKeys)).toBe(false);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('should return false for missing Authorization header', () => {
|
|
79
|
-
const headers = new Headers();
|
|
80
|
-
expect(validateRequestAuth(headers, validKeys)).toBe(false);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('should return false for undefined headers', () => {
|
|
84
|
-
expect(validateRequestAuth(undefined, validKeys)).toBe(false);
|
|
85
|
-
});
|
|
86
|
-
});
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* API key validation utilities.
|
|
3
|
-
*
|
|
4
|
-
* @packageDocumentation
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Extracts the Bearer token from an Authorization header.
|
|
9
|
-
*
|
|
10
|
-
* @param authHeader - The Authorization header value
|
|
11
|
-
* @returns The token if valid Bearer format, null otherwise
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```typescript
|
|
15
|
-
* extractBearerToken('Bearer sk_live_abc123'); // 'sk_live_abc123'
|
|
16
|
-
* extractBearerToken('Basic abc123'); // null
|
|
17
|
-
* extractBearerToken('sk_live_abc123'); // null
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
export function extractBearerToken(authHeader: string | null): string | null {
|
|
21
|
-
if (!authHeader) {
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const parts = authHeader.split(' ');
|
|
26
|
-
if (parts.length !== 2 || parts[0] !== 'Bearer') {
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return parts[1] || null;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Validates an API key against the configured keys.
|
|
35
|
-
*
|
|
36
|
-
* @param token - The token to validate
|
|
37
|
-
* @param validKeys - Array of valid API keys
|
|
38
|
-
* @returns True if the token is valid
|
|
39
|
-
*
|
|
40
|
-
* @remarks
|
|
41
|
-
* Uses timing-safe comparison to prevent timing attacks.
|
|
42
|
-
* If no keys are configured, returns false.
|
|
43
|
-
*/
|
|
44
|
-
export function validateApiKey(
|
|
45
|
-
token: string | null,
|
|
46
|
-
validKeys: string[] | undefined
|
|
47
|
-
): boolean {
|
|
48
|
-
if (!token || !validKeys || validKeys.length === 0) {
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Use timing-safe comparison to prevent timing attacks
|
|
53
|
-
return validKeys.some((key) => timingSafeEqual(token, key));
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Timing-safe string comparison to prevent timing attacks.
|
|
58
|
-
*
|
|
59
|
-
* @param a - First string
|
|
60
|
-
* @param b - Second string
|
|
61
|
-
* @returns True if strings are equal
|
|
62
|
-
*/
|
|
63
|
-
function timingSafeEqual(a: string, b: string): boolean {
|
|
64
|
-
if (a.length !== b.length) {
|
|
65
|
-
// Still do comparison to maintain constant time
|
|
66
|
-
let result = 0;
|
|
67
|
-
for (let i = 0; i < a.length; i++) {
|
|
68
|
-
result |= a.charCodeAt(i) ^ (b.charCodeAt(i % b.length) || 0);
|
|
69
|
-
}
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
let result = 0;
|
|
74
|
-
for (let i = 0; i < a.length; i++) {
|
|
75
|
-
result |= a.charCodeAt(i) ^ b.charCodeAt(i);
|
|
76
|
-
}
|
|
77
|
-
return result === 0;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Validates authentication from request headers.
|
|
82
|
-
*
|
|
83
|
-
* @param headers - Request headers
|
|
84
|
-
* @param validKeys - Array of valid API keys
|
|
85
|
-
* @returns True if the request has a valid API key
|
|
86
|
-
*
|
|
87
|
-
* @example
|
|
88
|
-
* ```typescript
|
|
89
|
-
* const headers = new Headers();
|
|
90
|
-
* headers.set('Authorization', 'Bearer sk_live_abc123');
|
|
91
|
-
*
|
|
92
|
-
* validateRequestAuth(headers, ['sk_live_abc123']); // true
|
|
93
|
-
* validateRequestAuth(headers, ['sk_live_other']); // false
|
|
94
|
-
* ```
|
|
95
|
-
*/
|
|
96
|
-
export function validateRequestAuth(
|
|
97
|
-
headers: Headers | undefined,
|
|
98
|
-
validKeys: string[] | undefined
|
|
99
|
-
): boolean {
|
|
100
|
-
if (!headers) {
|
|
101
|
-
return false;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const authHeader = headers.get('Authorization');
|
|
105
|
-
const token = extractBearerToken(authHeader);
|
|
106
|
-
return validateApiKey(token, validKeys);
|
|
107
|
-
}
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { createCORSOptions } from './cors';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Helper to call the origin function or return a default value
|
|
6
|
-
*/
|
|
7
|
-
const callOrigin = async (
|
|
8
|
-
origin: string | string[] | ((origin: string) => string | null) | undefined,
|
|
9
|
-
value: string
|
|
10
|
-
): Promise<string | null> => {
|
|
11
|
-
if (typeof origin === 'function') {
|
|
12
|
-
return origin(value);
|
|
13
|
-
}
|
|
14
|
-
if (origin === '*') {
|
|
15
|
-
return value || '*';
|
|
16
|
-
}
|
|
17
|
-
if (Array.isArray(origin)) {
|
|
18
|
-
return origin.includes(value) ? value : null;
|
|
19
|
-
}
|
|
20
|
-
return origin === value ? value : null;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
describe('createCORSOptions (unit)', () => {
|
|
24
|
-
describe('configuration shape', () => {
|
|
25
|
-
it('returns expected defaults when no trustedOrigins provided', async () => {
|
|
26
|
-
const config = createCORSOptions();
|
|
27
|
-
expect(config.credentials).toBe(true);
|
|
28
|
-
expect(config.maxAge).toBe(600);
|
|
29
|
-
expect(config.allowHeaders).toEqual([
|
|
30
|
-
'Content-Type',
|
|
31
|
-
'Authorization',
|
|
32
|
-
'x-request-id',
|
|
33
|
-
'x-c15t-country',
|
|
34
|
-
'x-c15t-region',
|
|
35
|
-
'accept-language',
|
|
36
|
-
]);
|
|
37
|
-
expect(config.methods).toEqual([
|
|
38
|
-
'GET',
|
|
39
|
-
'POST',
|
|
40
|
-
'PUT',
|
|
41
|
-
'DELETE',
|
|
42
|
-
'PATCH',
|
|
43
|
-
'OPTIONS',
|
|
44
|
-
]);
|
|
45
|
-
// For default config, origin is '*' string
|
|
46
|
-
expect(config.origin).toBe('*');
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
describe('wildcard "*"', () => {
|
|
51
|
-
it('allows any concrete origin and echoes it back', async () => {
|
|
52
|
-
const config = createCORSOptions(['*']);
|
|
53
|
-
expect(await callOrigin(config.origin, 'http://localhost:3002')).toBe(
|
|
54
|
-
'http://localhost:3002'
|
|
55
|
-
);
|
|
56
|
-
// missing origin -> '*'
|
|
57
|
-
expect(await callOrigin(config.origin, '')).toBe('*');
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
describe('specific origins', () => {
|
|
62
|
-
it('allows trusted origin and rejects untrusted', async () => {
|
|
63
|
-
const config = createCORSOptions(['http://localhost:3002']);
|
|
64
|
-
expect(await callOrigin(config.origin, 'http://localhost:3002')).toBe(
|
|
65
|
-
'http://localhost:3002'
|
|
66
|
-
);
|
|
67
|
-
expect(
|
|
68
|
-
await callOrigin(config.origin, 'http://malicious-site.com')
|
|
69
|
-
).toBeNull();
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('treats localhost variants (ports, IPs) as trusted when "localhost" provided', async () => {
|
|
73
|
-
const config = createCORSOptions(['localhost']);
|
|
74
|
-
expect(await callOrigin(config.origin, 'http://localhost:1234')).toBe(
|
|
75
|
-
'http://localhost:1234'
|
|
76
|
-
);
|
|
77
|
-
expect(await callOrigin(config.origin, 'http://127.0.0.1:3000')).toBe(
|
|
78
|
-
'http://127.0.0.1:3000'
|
|
79
|
-
);
|
|
80
|
-
expect(await callOrigin(config.origin, 'http://[::1]:3000')).toBe(
|
|
81
|
-
'http://[::1]:3000'
|
|
82
|
-
);
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
describe('www and non-www variants', () => {
|
|
87
|
-
it('allows www when non-www is trusted', async () => {
|
|
88
|
-
const config = createCORSOptions(['http://c15t.com']);
|
|
89
|
-
expect(await callOrigin(config.origin, 'http://www.c15t.com')).toBe(
|
|
90
|
-
'http://www.c15t.com'
|
|
91
|
-
);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('allows non-www when www is trusted', async () => {
|
|
95
|
-
const config = createCORSOptions(['http://www.c15t.com']);
|
|
96
|
-
expect(await callOrigin(config.origin, 'http://c15t.com')).toBe(
|
|
97
|
-
'http://c15t.com'
|
|
98
|
-
);
|
|
99
|
-
});
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
describe('ports and protocols', () => {
|
|
103
|
-
it('matches with exact port when provided', async () => {
|
|
104
|
-
const config = createCORSOptions(['localhost:3002']);
|
|
105
|
-
expect(await callOrigin(config.origin, 'http://localhost:3002')).toBe(
|
|
106
|
-
'http://localhost:3002'
|
|
107
|
-
);
|
|
108
|
-
expect(
|
|
109
|
-
await callOrigin(config.origin, 'http://localhost:4000')
|
|
110
|
-
).toBeNull();
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it('is protocol-agnostic for host comparison', async () => {
|
|
114
|
-
const config = createCORSOptions(['example.com']);
|
|
115
|
-
expect(await callOrigin(config.origin, 'http://example.com')).toBe(
|
|
116
|
-
'http://example.com'
|
|
117
|
-
);
|
|
118
|
-
expect(await callOrigin(config.origin, 'https://www.example.com')).toBe(
|
|
119
|
-
'https://www.example.com'
|
|
120
|
-
);
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
describe('invalid or missing origins', () => {
|
|
125
|
-
it('returns null for clearly invalid origins', async () => {
|
|
126
|
-
const config = createCORSOptions(['example.com']);
|
|
127
|
-
expect(await callOrigin(config.origin, '::::invalid::::')).toBeNull();
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
it('returns "*" when origin header is missing/empty', async () => {
|
|
131
|
-
const config = createCORSOptions(['*']);
|
|
132
|
-
expect(await callOrigin(config.origin, '')).toBe('*');
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
});
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CORS middleware utility for c15t that handles origin validation and CORS headers
|
|
3
|
-
*
|
|
4
|
-
* @packageDocumentation
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* CORS configuration options compatible with Hono's cors middleware
|
|
9
|
-
*/
|
|
10
|
-
export interface CorsOptions {
|
|
11
|
-
origin: string | string[] | ((origin: string) => string | null);
|
|
12
|
-
methods?: string[];
|
|
13
|
-
allowMethods?: string[];
|
|
14
|
-
allowHeaders?: string[];
|
|
15
|
-
maxAge?: number;
|
|
16
|
-
credentials?: boolean;
|
|
17
|
-
exposeHeaders?: string[];
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/** Regular expression to match www prefix in domain names */
|
|
21
|
-
const WWW_REGEX = /^www\./;
|
|
22
|
-
|
|
23
|
-
/** Regular expression to match protocol and www prefix in URLs */
|
|
24
|
-
const PROTOCOL_WWW_REGEX = /^https?:\/\/(www\.)?/;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Supported HTTP methods for CORS
|
|
28
|
-
*/
|
|
29
|
-
const SUPPORTED_METHODS = [
|
|
30
|
-
'GET',
|
|
31
|
-
'POST',
|
|
32
|
-
'PUT',
|
|
33
|
-
'DELETE',
|
|
34
|
-
'PATCH',
|
|
35
|
-
'OPTIONS',
|
|
36
|
-
] as const;
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Supported headers for CORS requests
|
|
40
|
-
*/
|
|
41
|
-
const SUPPORTED_HEADERS = [
|
|
42
|
-
'Content-Type',
|
|
43
|
-
'Authorization',
|
|
44
|
-
'x-request-id',
|
|
45
|
-
'x-c15t-country',
|
|
46
|
-
'x-c15t-region',
|
|
47
|
-
'accept-language',
|
|
48
|
-
] as const;
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Normalizes an origin string by removing protocol and www prefix
|
|
52
|
-
*
|
|
53
|
-
* @param origin - The origin URL to normalize
|
|
54
|
-
* @returns Normalized origin string without protocol and www prefix
|
|
55
|
-
*/
|
|
56
|
-
function normalizeOrigin(origin: string): string {
|
|
57
|
-
try {
|
|
58
|
-
// Handle bare domains like 'localhost' or 'example.com'
|
|
59
|
-
if (
|
|
60
|
-
!origin.includes('://') &&
|
|
61
|
-
!origin.includes(':') &&
|
|
62
|
-
!origin.includes('/')
|
|
63
|
-
) {
|
|
64
|
-
return origin.toLowerCase();
|
|
65
|
-
}
|
|
66
|
-
// Add protocol if missing
|
|
67
|
-
const originWithProtocol =
|
|
68
|
-
origin.startsWith('http://') ||
|
|
69
|
-
origin.startsWith('https://') ||
|
|
70
|
-
origin.startsWith('ws://') ||
|
|
71
|
-
origin.startsWith('wss://')
|
|
72
|
-
? origin
|
|
73
|
-
: `http://${origin}`;
|
|
74
|
-
const url = new URL(originWithProtocol);
|
|
75
|
-
const hostname = url.hostname.replace(WWW_REGEX, '');
|
|
76
|
-
// Return without protocol to match both http and https
|
|
77
|
-
return `${hostname}${url.port ? `:${url.port}` : ''}`;
|
|
78
|
-
} catch {
|
|
79
|
-
// Fallback: remove www manually and protocol
|
|
80
|
-
return origin.replace(PROTOCOL_WWW_REGEX, '').replace(WWW_REGEX, '');
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Expands a list of origins to include www variants
|
|
86
|
-
*
|
|
87
|
-
* @param origins - Array of origin strings to expand
|
|
88
|
-
* @returns Array of origins including www variants
|
|
89
|
-
*/
|
|
90
|
-
function expandWithWWW(origins: string[]): string[] {
|
|
91
|
-
const expanded = new Set<string>();
|
|
92
|
-
for (const origin of origins) {
|
|
93
|
-
if (origin === '*') {
|
|
94
|
-
expanded.add('*');
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
const normalized = normalizeOrigin(origin);
|
|
98
|
-
expanded.add(normalized);
|
|
99
|
-
// Add www version if not already present
|
|
100
|
-
if (!normalized.includes('www.')) {
|
|
101
|
-
expanded.add(`www.${normalized}`);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
return Array.from(expanded);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Creates CORS options configuration for Hono's cors middleware
|
|
109
|
-
*
|
|
110
|
-
* @param trustedOrigins - Array of allowed origin patterns or single string. Can include wildcards ('*').
|
|
111
|
-
* If undefined, defaults to allowing all origins without credentials.
|
|
112
|
-
*
|
|
113
|
-
* @returns Hono CORS configuration object
|
|
114
|
-
*
|
|
115
|
-
* @example
|
|
116
|
-
* ```ts
|
|
117
|
-
* const corsOptions = createCORSOptions(['http://localhost:3000', 'https://example.com']);
|
|
118
|
-
* app.use('*', cors(corsOptions));
|
|
119
|
-
* ```
|
|
120
|
-
*/
|
|
121
|
-
export function createCORSOptions(
|
|
122
|
-
trustedOrigins?: string[] | string
|
|
123
|
-
): CorsOptions {
|
|
124
|
-
// If trustedOrigins is undefined or empty, return default config that allows all origins
|
|
125
|
-
if (!trustedOrigins) {
|
|
126
|
-
return {
|
|
127
|
-
origin: '*',
|
|
128
|
-
credentials: true,
|
|
129
|
-
allowHeaders: [...SUPPORTED_HEADERS],
|
|
130
|
-
maxAge: 600,
|
|
131
|
-
allowMethods: [...SUPPORTED_METHODS],
|
|
132
|
-
methods: [...SUPPORTED_METHODS],
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Convert string to array if needed
|
|
137
|
-
const origins = Array.isArray(trustedOrigins)
|
|
138
|
-
? trustedOrigins
|
|
139
|
-
: [trustedOrigins];
|
|
140
|
-
if (origins.length === 0) {
|
|
141
|
-
return {
|
|
142
|
-
origin: '*',
|
|
143
|
-
credentials: true,
|
|
144
|
-
allowHeaders: [...SUPPORTED_HEADERS],
|
|
145
|
-
maxAge: 600,
|
|
146
|
-
allowMethods: [...SUPPORTED_METHODS],
|
|
147
|
-
methods: [...SUPPORTED_METHODS],
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const expandedTrusted = expandWithWWW(origins);
|
|
152
|
-
|
|
153
|
-
return {
|
|
154
|
-
origin: (origin) => {
|
|
155
|
-
if (!origin) {
|
|
156
|
-
return '*';
|
|
157
|
-
}
|
|
158
|
-
const normalizedOrigin = normalizeOrigin(origin);
|
|
159
|
-
if (expandedTrusted.includes('*')) {
|
|
160
|
-
return origin;
|
|
161
|
-
}
|
|
162
|
-
// Check if the origin matches any trusted origin
|
|
163
|
-
const isTrusted = expandedTrusted.some((trusted) => {
|
|
164
|
-
const normalizedTrusted = normalizeOrigin(trusted);
|
|
165
|
-
// For localhost, match both with and without port
|
|
166
|
-
if (normalizedTrusted === 'localhost') {
|
|
167
|
-
return (
|
|
168
|
-
normalizedOrigin === 'localhost' ||
|
|
169
|
-
normalizedOrigin.startsWith('localhost:') ||
|
|
170
|
-
normalizedOrigin === '127.0.0.1' ||
|
|
171
|
-
normalizedOrigin.startsWith('127.0.0.1:') ||
|
|
172
|
-
normalizedOrigin === '[::1]' ||
|
|
173
|
-
normalizedOrigin.startsWith('[::1]:')
|
|
174
|
-
);
|
|
175
|
-
}
|
|
176
|
-
return normalizedTrusted === normalizedOrigin;
|
|
177
|
-
});
|
|
178
|
-
return isTrusted ? origin : null;
|
|
179
|
-
},
|
|
180
|
-
credentials: true,
|
|
181
|
-
allowHeaders: [...SUPPORTED_HEADERS],
|
|
182
|
-
maxAge: 600,
|
|
183
|
-
allowMethods: [...SUPPORTED_METHODS],
|
|
184
|
-
methods: [...SUPPORTED_METHODS],
|
|
185
|
-
};
|
|
186
|
-
}
|