@c15t/backend 1.2.0-canary.13 → 1.2.0-canary.2
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/.turbo/turbo-build.log +20 -22
- package/.turbo/turbo-fmt.log +4 -4
- package/.turbo/turbo-test.log +531 -0
- package/coverage/coverage-final.json +84 -0
- package/coverage/coverage-summary.json +85 -0
- package/coverage/html/backend/index.html +116 -0
- package/coverage/html/backend/rslib.config.ts.html +415 -0
- package/coverage/html/backend/src/contracts/consent/index.html +161 -0
- package/coverage/html/backend/src/contracts/consent/index.ts.html +112 -0
- package/coverage/html/backend/src/contracts/consent/post.contract.ts.html +559 -0
- package/coverage/html/backend/src/contracts/consent/show-banner.contract.ts.html +220 -0
- package/coverage/html/backend/src/contracts/consent/verify.contract.ts.html +463 -0
- package/coverage/html/backend/src/contracts/index.html +116 -0
- package/coverage/html/backend/src/contracts/index.ts.html +139 -0
- package/coverage/html/backend/src/contracts/meta/index.html +131 -0
- package/coverage/html/backend/src/contracts/meta/index.ts.html +100 -0
- package/coverage/html/backend/src/contracts/meta/status.contract.ts.html +196 -0
- package/coverage/html/backend/src/contracts/shared/index.html +116 -0
- package/coverage/html/backend/src/contracts/shared/jurisdiction.schema.ts.html +175 -0
- package/coverage/html/backend/src/core.ts.html +1624 -0
- package/coverage/html/backend/src/handlers/consent/index.html +161 -0
- package/coverage/html/backend/src/handlers/consent/index.ts.html +112 -0
- package/coverage/html/backend/src/handlers/consent/post.handler.ts.html +889 -0
- package/coverage/html/backend/src/handlers/consent/show-banner.handler.ts.html +535 -0
- package/coverage/html/backend/src/handlers/consent/verify.handler.ts.html +1000 -0
- package/coverage/html/backend/src/handlers/meta/index.html +131 -0
- package/coverage/html/backend/src/handlers/meta/index.ts.html +100 -0
- package/coverage/html/backend/src/handlers/meta/status.handler.ts.html +226 -0
- package/coverage/html/backend/src/index.html +161 -0
- package/coverage/html/backend/src/init.ts.html +1018 -0
- package/coverage/html/backend/src/pkgs/api-router/hooks/index.html +116 -0
- package/coverage/html/backend/src/pkgs/api-router/hooks/processor.ts.html +544 -0
- package/coverage/html/backend/src/pkgs/api-router/index.html +116 -0
- package/coverage/html/backend/src/pkgs/api-router/telemetry.ts.html +334 -0
- package/coverage/html/backend/src/pkgs/api-router/utils/cors.ts.html +304 -0
- package/coverage/html/backend/src/pkgs/api-router/utils/index.html +131 -0
- package/coverage/html/backend/src/pkgs/api-router/utils/ip.ts.html +361 -0
- package/coverage/html/backend/src/pkgs/data-model/fields/field-factory.ts.html +709 -0
- package/coverage/html/backend/src/pkgs/data-model/fields/id-generator.ts.html +256 -0
- package/coverage/html/backend/src/pkgs/data-model/fields/index.html +161 -0
- package/coverage/html/backend/src/pkgs/data-model/fields/superjson-utils.ts.html +136 -0
- package/coverage/html/backend/src/pkgs/data-model/fields/zod-fields.ts.html +496 -0
- package/coverage/html/backend/src/pkgs/data-model/hooks/create-hooks.ts.html +349 -0
- package/coverage/html/backend/src/pkgs/data-model/hooks/index.html +176 -0
- package/coverage/html/backend/src/pkgs/data-model/hooks/update-hooks.ts.html +358 -0
- package/coverage/html/backend/src/pkgs/data-model/hooks/update-many-hooks.ts.html +613 -0
- package/coverage/html/backend/src/pkgs/data-model/hooks/utils.ts.html +538 -0
- package/coverage/html/backend/src/pkgs/data-model/hooks/with-hooks-factory.ts.html +289 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapter-factory.ts.html +289 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.ts.html +2203 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/drizzle-adapter/index.html +116 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/index.html +116 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/dialect.ts.html +670 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/index.html +131 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.ts.html +3634 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/tests/index.html +116 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.ts.html +1417 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/memory-adapter/index.html +116 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.ts.html +2071 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/prisma-adapter/index.html +116 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.ts.html +1834 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/test.ts.html +316 -0
- package/coverage/html/backend/src/pkgs/db-adapters/index.html +131 -0
- package/coverage/html/backend/src/pkgs/db-adapters/utils.ts.html +238 -0
- package/coverage/html/backend/src/pkgs/migrations/get-migration.ts.html +343 -0
- package/coverage/html/backend/src/pkgs/migrations/get-schema/get-schema.ts.html +217 -0
- package/coverage/html/backend/src/pkgs/migrations/get-schema/index.html +146 -0
- package/coverage/html/backend/src/pkgs/migrations/get-schema/process-fields.ts.html +280 -0
- package/coverage/html/backend/src/pkgs/migrations/get-schema/process-tables.ts.html +289 -0
- package/coverage/html/backend/src/pkgs/migrations/index.html +176 -0
- package/coverage/html/backend/src/pkgs/migrations/migration-builders.ts.html +595 -0
- package/coverage/html/backend/src/pkgs/migrations/migration-execution.ts.html +301 -0
- package/coverage/html/backend/src/pkgs/migrations/schema-comparison.ts.html +694 -0
- package/coverage/html/backend/src/pkgs/migrations/type-mapping.ts.html +817 -0
- package/coverage/html/backend/src/pkgs/results/core/error-class.ts.html +976 -0
- package/coverage/html/backend/src/pkgs/results/core/error-codes.ts.html +703 -0
- package/coverage/html/backend/src/pkgs/results/core/index.html +146 -0
- package/coverage/html/backend/src/pkgs/results/core/tracing.ts.html +280 -0
- package/coverage/html/backend/src/pkgs/results/create-telemetry-options.ts.html +271 -0
- package/coverage/html/backend/src/pkgs/results/index.html +131 -0
- package/coverage/html/backend/src/pkgs/results/orpc-error-handler.ts.html +496 -0
- package/coverage/html/backend/src/pkgs/results/results/index.html +131 -0
- package/coverage/html/backend/src/pkgs/results/results/recovery-utils.ts.html +628 -0
- package/coverage/html/backend/src/pkgs/results/results/result-helpers.ts.html +1234 -0
- package/coverage/html/backend/src/pkgs/utils/env.ts.html +337 -0
- package/coverage/html/backend/src/pkgs/utils/index.html +146 -0
- package/coverage/html/backend/src/pkgs/utils/logger.ts.html +199 -0
- package/coverage/html/backend/src/pkgs/utils/url.ts.html +400 -0
- package/coverage/html/backend/src/router.ts.html +109 -0
- package/coverage/html/backend/src/schema/audit-log/index.html +146 -0
- package/coverage/html/backend/src/schema/audit-log/registry.ts.html +436 -0
- package/coverage/html/backend/src/schema/audit-log/schema.ts.html +223 -0
- package/coverage/html/backend/src/schema/audit-log/table.ts.html +640 -0
- package/coverage/html/backend/src/schema/consent/index.html +146 -0
- package/coverage/html/backend/src/schema/consent/registry.ts.html +616 -0
- package/coverage/html/backend/src/schema/consent/schema.ts.html +238 -0
- package/coverage/html/backend/src/schema/consent/table.ts.html +748 -0
- package/coverage/html/backend/src/schema/consent-policy/index.html +146 -0
- package/coverage/html/backend/src/schema/consent-policy/registry.ts.html +1063 -0
- package/coverage/html/backend/src/schema/consent-policy/schema.ts.html +265 -0
- package/coverage/html/backend/src/schema/consent-policy/table.ts.html +535 -0
- package/coverage/html/backend/src/schema/consent-purpose/index.html +146 -0
- package/coverage/html/backend/src/schema/consent-purpose/registry.ts.html +589 -0
- package/coverage/html/backend/src/schema/consent-purpose/schema.ts.html +259 -0
- package/coverage/html/backend/src/schema/consent-purpose/table.ts.html +547 -0
- package/coverage/html/backend/src/schema/consent-record/index.html +131 -0
- package/coverage/html/backend/src/schema/consent-record/schema.ts.html +211 -0
- package/coverage/html/backend/src/schema/consent-record/table.ts.html +457 -0
- package/coverage/html/backend/src/schema/create-registry.ts.html +148 -0
- package/coverage/html/backend/src/schema/definition.ts.html +685 -0
- package/coverage/html/backend/src/schema/domain/index.html +146 -0
- package/coverage/html/backend/src/schema/domain/registry.ts.html +973 -0
- package/coverage/html/backend/src/schema/domain/schema.ts.html +214 -0
- package/coverage/html/backend/src/schema/domain/table.ts.html +496 -0
- package/coverage/html/backend/src/schema/index.html +146 -0
- package/coverage/html/backend/src/schema/schemas.ts.html +166 -0
- package/coverage/html/backend/src/schema/subject/index.html +146 -0
- package/coverage/html/backend/src/schema/subject/registry.ts.html +973 -0
- package/coverage/html/backend/src/schema/subject/schema.ts.html +208 -0
- package/coverage/html/backend/src/schema/subject/table.ts.html +499 -0
- package/coverage/html/backend/src/server.ts.html +475 -0
- package/coverage/html/backend/src/testing/contract-testing.ts.html +1348 -0
- package/coverage/html/backend/src/testing/index.html +116 -0
- package/coverage/html/base.css +224 -0
- package/coverage/html/block-navigation.js +87 -0
- package/coverage/html/favicon.png +0 -0
- package/coverage/html/index.html +626 -0
- package/coverage/html/prettify.css +1 -0
- package/coverage/html/prettify.js +2 -0
- package/coverage/html/sort-arrow-sprite.png +0 -0
- package/coverage/html/sorter.js +196 -0
- package/dist/contracts/consent/index.d.ts +2 -2
- package/dist/contracts/consent/post.contract.d.ts +2 -2
- package/dist/contracts/consent/post.contract.d.ts.map +1 -1
- package/dist/contracts/index.d.ts +5 -5
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/core.cjs +244 -388
- package/dist/core.d.ts +5 -3
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +244 -388
- package/dist/handlers/consent/index.d.ts +2 -2
- package/dist/handlers/consent/post.handler.d.ts +2 -2
- package/dist/handlers/consent/show-banner.handler.d.ts.map +1 -1
- package/dist/pkgs/api-router/utils/core.test.d.ts +2 -0
- package/dist/pkgs/api-router/utils/core.test.d.ts.map +1 -0
- package/dist/pkgs/api-router/utils/cors.d.ts +14 -0
- package/dist/pkgs/api-router/utils/cors.d.ts.map +1 -0
- package/dist/pkgs/data-model/fields/zod-fields.d.ts +32 -32
- package/dist/pkgs/data-model/index.cjs +39 -59
- package/dist/pkgs/data-model/index.js +39 -59
- package/dist/pkgs/data-model/schema/index.cjs +39 -59
- package/dist/pkgs/data-model/schema/index.js +39 -59
- package/dist/pkgs/db-adapters/adapters/drizzle-adapter/index.cjs +1 -0
- package/dist/pkgs/db-adapters/adapters/drizzle-adapter/index.js +1 -0
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/index.cjs +1 -0
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/index.js +1 -0
- package/dist/pkgs/db-adapters/adapters/memory-adapter/index.cjs +1 -0
- package/dist/pkgs/db-adapters/adapters/memory-adapter/index.js +1 -0
- package/dist/pkgs/db-adapters/adapters/prisma-adapter/index.cjs +1 -0
- package/dist/pkgs/db-adapters/adapters/prisma-adapter/index.js +1 -0
- package/dist/pkgs/db-adapters/index.cjs +1 -0
- package/dist/pkgs/db-adapters/index.js +1 -0
- package/dist/pkgs/migrations/index.cjs +1 -0
- package/dist/pkgs/migrations/index.js +1 -0
- package/dist/router.cjs +5 -3
- package/dist/router.d.ts +2 -2
- package/dist/router.js +5 -3
- package/dist/schema/consent-policy/registry.d.ts +4 -4
- package/dist/schema/consent-policy/registry.d.ts.map +1 -1
- package/dist/schema/consent-policy/schema.d.ts +2 -2
- package/dist/schema/consent-policy/table.d.ts +2 -2
- package/dist/schema/consent-purpose/registry.d.ts +2 -2
- package/dist/schema/consent-purpose/schema.d.ts +2 -2
- package/dist/schema/consent-purpose/table.d.ts +2 -2
- package/dist/schema/create-registry.d.ts +6 -6
- package/dist/schema/create-registry.d.ts.map +1 -1
- package/dist/schema/definition.d.ts +4 -4
- package/dist/schema/index.cjs +39 -59
- package/dist/schema/index.js +39 -59
- package/dist/schema/schemas.d.ts +4 -4
- package/package.json +2 -8
- package/rslib.config.ts +0 -1
- package/src/contracts/consent/post.contract.ts +6 -1
- package/src/contracts/index.ts +0 -2
- package/src/core.ts +195 -96
- package/src/handlers/consent/show-banner.handler.test.ts +1 -1
- package/src/handlers/consent/show-banner.handler.ts +2 -1
- package/src/{middleware/cors/is-origin-trusted.test.ts → pkgs/api-router/utils/core.test.ts} +1 -1
- package/src/pkgs/api-router/utils/cors.ts +73 -0
- package/src/schema/consent-policy/registry.ts +50 -76
- package/src/server.ts +5 -1
- package/dist/__tests__/server.test.d.ts +0 -2
- package/dist/__tests__/server.test.d.ts.map +0 -1
- package/dist/contracts.cjs +0 -708
- package/dist/contracts.js +0 -661
- package/dist/middleware/cors/cors.d.ts +0 -37
- package/dist/middleware/cors/cors.d.ts.map +0 -1
- package/dist/middleware/cors/cors.test.d.ts +0 -2
- package/dist/middleware/cors/cors.test.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 +0 -49
- package/dist/middleware/cors/is-origin-trusted.d.ts.map +0 -1
- package/dist/middleware/cors/is-origin-trusted.test.d.ts +0 -2
- package/dist/middleware/cors/is-origin-trusted.test.d.ts.map +0 -1
- package/dist/middleware/cors/process-cors.d.ts +0 -31
- package/dist/middleware/cors/process-cors.d.ts.map +0 -1
- package/dist/middleware/openapi/config.d.ts +0 -28
- package/dist/middleware/openapi/config.d.ts.map +0 -1
- package/dist/middleware/openapi/handlers.d.ts +0 -29
- package/dist/middleware/openapi/handlers.d.ts.map +0 -1
- package/dist/middleware/openapi/index.d.ts +0 -11
- package/dist/middleware/openapi/index.d.ts.map +0 -1
- package/src/__tests__/server.test.ts +0 -96
- package/src/middleware/cors/cors.test.ts +0 -419
- package/src/middleware/cors/cors.ts +0 -192
- package/src/middleware/cors/index.ts +0 -30
- package/src/middleware/cors/is-origin-trusted.ts +0 -126
- package/src/middleware/cors/process-cors.ts +0 -91
- package/src/middleware/openapi/config.ts +0 -28
- package/src/middleware/openapi/handlers.ts +0 -132
- package/src/middleware/openapi/index.ts +0 -11
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Origin validation utilities for CORS security
|
|
3
|
-
*
|
|
4
|
-
* @packageDocumentation
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { Logger } from '@doubletie/logger';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Regular expression to strip protocol, trailing slashes, and port numbers from URLs
|
|
11
|
-
* Matches:
|
|
12
|
-
* - http:// or https:// protocol
|
|
13
|
-
* - ws:// or wss:// protocol
|
|
14
|
-
* - trailing slashes
|
|
15
|
-
* - port numbers with colon
|
|
16
|
-
*
|
|
17
|
-
* @internal
|
|
18
|
-
*/
|
|
19
|
-
export const STRIP_REGEX = /^(https?:\/\/)|(wss?:\/\/)|(\/+$)|:\d+/g;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Checks if a domain matches a wildcard pattern
|
|
23
|
-
*
|
|
24
|
-
* @param hostname - The hostname to check
|
|
25
|
-
* @param wildcardPattern - The wildcard pattern (e.g. *.example.com)
|
|
26
|
-
* @param logger - Optional logger for debugging
|
|
27
|
-
* @returns true if the hostname matches the wildcard pattern
|
|
28
|
-
*
|
|
29
|
-
* @internal
|
|
30
|
-
*/
|
|
31
|
-
function matchesWildcard(
|
|
32
|
-
hostname: string,
|
|
33
|
-
wildcardPattern: string,
|
|
34
|
-
logger?: Logger
|
|
35
|
-
): boolean {
|
|
36
|
-
const wildcardDomain = wildcardPattern.slice(2); // Remove *. prefix
|
|
37
|
-
const parts = hostname.split('.');
|
|
38
|
-
const isValid = parts.length > 2 && hostname.endsWith(wildcardDomain);
|
|
39
|
-
|
|
40
|
-
logger?.debug(
|
|
41
|
-
`Wildcard match result: ${isValid} ${hostname} ends with ${wildcardDomain} ${parts.length > 2} ${hostname.endsWith(wildcardDomain)}`
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
return isValid;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Validates if a given origin matches any of the trusted domain patterns
|
|
49
|
-
*
|
|
50
|
-
* Supports:
|
|
51
|
-
* - Exact domain matches
|
|
52
|
-
* - Wildcard subdomains (e.g. *.example.com)
|
|
53
|
-
* - Protocol-agnostic matching
|
|
54
|
-
* - Case-insensitive comparison
|
|
55
|
-
*
|
|
56
|
-
* @param origin - The origin URL to validate (e.g. https://example.com)
|
|
57
|
-
* @param trustedDomains - Array of trusted domain patterns. Can include wildcards (e.g. *.example.com)
|
|
58
|
-
* @param logger - Optional logger for debugging validation process
|
|
59
|
-
*
|
|
60
|
-
* @returns `true` if the origin matches any trusted domain pattern, `false` otherwise
|
|
61
|
-
*
|
|
62
|
-
* @throws {Error} When trustedDomains array is empty
|
|
63
|
-
* @throws {TypeError} When origin URL is invalid
|
|
64
|
-
*
|
|
65
|
-
* @example
|
|
66
|
-
* ```ts
|
|
67
|
-
* // Simple domain matching
|
|
68
|
-
* isOriginTrusted('https://example.com', ['example.com']); // true
|
|
69
|
-
*
|
|
70
|
-
* // Wildcard subdomain matching
|
|
71
|
-
* isOriginTrusted('https://api.example.com', ['*.example.com']); // true
|
|
72
|
-
*
|
|
73
|
-
* // Allow all origins
|
|
74
|
-
* isOriginTrusted('https://any-domain.com', ['*']); // true
|
|
75
|
-
* ```
|
|
76
|
-
*/
|
|
77
|
-
export function isOriginTrusted(
|
|
78
|
-
origin: string,
|
|
79
|
-
trustedDomains: string[],
|
|
80
|
-
logger?: Logger
|
|
81
|
-
): boolean {
|
|
82
|
-
try {
|
|
83
|
-
if (trustedDomains.length === 0) {
|
|
84
|
-
throw new Error('No trusted domains');
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
logger?.debug(
|
|
88
|
-
`Checking if origin ${origin} is trusted in ${trustedDomains}`
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
// Special case: if "*" is in trusted domains, allow all origins
|
|
92
|
-
if (trustedDomains.includes('*')) {
|
|
93
|
-
logger?.debug('Allowing all origins');
|
|
94
|
-
return true;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Parse the origin URL to get just the hostname
|
|
98
|
-
const url = new URL(origin);
|
|
99
|
-
const originHostname = url.hostname.toLowerCase();
|
|
100
|
-
logger?.debug(`Parsed origin hostname: ${originHostname}`);
|
|
101
|
-
|
|
102
|
-
return trustedDomains.some((domain) => {
|
|
103
|
-
// Handle empty domains (which might come from splitting empty strings)
|
|
104
|
-
if (!domain || domain.trim() === '') {
|
|
105
|
-
logger?.debug('Skipping empty domain');
|
|
106
|
-
return false;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const strippedDomain = domain.replace(STRIP_REGEX, '').toLowerCase();
|
|
110
|
-
logger?.debug(`Checking against stripped domain: ${strippedDomain}`);
|
|
111
|
-
|
|
112
|
-
if (strippedDomain.startsWith('*.')) {
|
|
113
|
-
return matchesWildcard(originHostname, strippedDomain, logger);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const isMatch = originHostname === strippedDomain;
|
|
117
|
-
logger?.debug(
|
|
118
|
-
`Exact match result: ${isMatch} ${originHostname} === ${strippedDomain}`
|
|
119
|
-
);
|
|
120
|
-
return isMatch;
|
|
121
|
-
});
|
|
122
|
-
} catch (error) {
|
|
123
|
-
logger?.error('Error validating origin:', error);
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CORS processing middleware for c15t
|
|
3
|
-
* Handles origin validation and context enrichment
|
|
4
|
-
*
|
|
5
|
-
* @packageDocumentation
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { C15TContext } from '~/types/context';
|
|
9
|
-
import { isOriginTrusted } from './is-origin-trusted';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Result of CORS processing
|
|
13
|
-
* @internal
|
|
14
|
-
*/
|
|
15
|
-
interface CORSProcessingResult {
|
|
16
|
-
/** The origin from the request */
|
|
17
|
-
origin: string | null;
|
|
18
|
-
/** Whether the origin is trusted */
|
|
19
|
-
isTrusted: boolean;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Extracts and validates CORS information from a request
|
|
24
|
-
*
|
|
25
|
-
* @param request - The request to process
|
|
26
|
-
* @param trustedOrigins - Array of trusted origins
|
|
27
|
-
* @param logger - Optional logger for debugging
|
|
28
|
-
* @returns CORS processing result
|
|
29
|
-
*
|
|
30
|
-
* @internal
|
|
31
|
-
*/
|
|
32
|
-
function extractCORSInfo(
|
|
33
|
-
request: Request,
|
|
34
|
-
trustedOrigins?: string[],
|
|
35
|
-
logger?: C15TContext['logger']
|
|
36
|
-
): CORSProcessingResult {
|
|
37
|
-
const origin = request.headers.get('origin');
|
|
38
|
-
|
|
39
|
-
if (!origin || !trustedOrigins) {
|
|
40
|
-
return {
|
|
41
|
-
origin: origin,
|
|
42
|
-
isTrusted: false,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return {
|
|
47
|
-
origin,
|
|
48
|
-
isTrusted: isOriginTrusted(origin, trustedOrigins, logger),
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Processes CORS validation for an incoming request and enriches the context
|
|
54
|
-
* with origin information. This middleware function validates the origin against
|
|
55
|
-
* trusted patterns and updates the context with the validation results.
|
|
56
|
-
*
|
|
57
|
-
* @param request - The incoming HTTP request to process
|
|
58
|
-
* @param context - The c15t middleware context to enrich
|
|
59
|
-
* @param trustedOrigins - Array of trusted origin patterns. Can include wildcards ('*')
|
|
60
|
-
*
|
|
61
|
-
* @returns The enriched context with origin validation results
|
|
62
|
-
*
|
|
63
|
-
* @example
|
|
64
|
-
* ```ts
|
|
65
|
-
* const enrichedContext = processCors(
|
|
66
|
-
* request,
|
|
67
|
-
* context,
|
|
68
|
-
* ['https://example.com', '*.trusted-domain.com']
|
|
69
|
-
* );
|
|
70
|
-
* ```
|
|
71
|
-
*
|
|
72
|
-
* @see {@link isOriginTrusted} for origin validation details
|
|
73
|
-
*/
|
|
74
|
-
export const processCors = (
|
|
75
|
-
request: Request,
|
|
76
|
-
context: C15TContext,
|
|
77
|
-
trustedOrigins?: string[]
|
|
78
|
-
): C15TContext => {
|
|
79
|
-
const { origin, isTrusted } = extractCORSInfo(
|
|
80
|
-
request,
|
|
81
|
-
trustedOrigins,
|
|
82
|
-
context.logger
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
if (origin) {
|
|
86
|
-
context.origin = origin;
|
|
87
|
-
context.trustedOrigin = isTrusted;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return context;
|
|
91
|
-
};
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { C15TOptions } from '~/types';
|
|
2
|
-
import packageJson from '../../../package.json';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Default OpenAPI configuration
|
|
6
|
-
*/
|
|
7
|
-
export const createOpenAPIConfig = (options: C15TOptions) => {
|
|
8
|
-
const basePath = options.basePath || '';
|
|
9
|
-
return {
|
|
10
|
-
enabled: true,
|
|
11
|
-
specPath: `${basePath}/spec.json`,
|
|
12
|
-
docsPath: `${basePath}/docs`,
|
|
13
|
-
...(options.openapi || {}),
|
|
14
|
-
};
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Default OpenAPI options
|
|
19
|
-
*/
|
|
20
|
-
export const createDefaultOpenAPIOptions = (options: C15TOptions) => ({
|
|
21
|
-
info: {
|
|
22
|
-
title: options.appName || 'c15t API',
|
|
23
|
-
version: packageJson.version,
|
|
24
|
-
description: 'API for consent management',
|
|
25
|
-
},
|
|
26
|
-
servers: [{ url: options.basePath || '/' }],
|
|
27
|
-
security: [{ bearerAuth: [] }],
|
|
28
|
-
});
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import { OpenAPIGenerator } from '@orpc/openapi';
|
|
2
|
-
import { ZodToJsonSchemaConverter } from '@orpc/zod';
|
|
3
|
-
import { router } from '~/router';
|
|
4
|
-
import type { C15TContext, C15TOptions } from '~/types';
|
|
5
|
-
import { createDefaultOpenAPIOptions, createOpenAPIConfig } from './config';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Type for the memoized OpenAPI spec function
|
|
9
|
-
*/
|
|
10
|
-
type MemoizedSpecFunction = {
|
|
11
|
-
(): Promise<Record<string, unknown>>;
|
|
12
|
-
cached?: Record<string, unknown>;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Merges user OpenAPI options with default options
|
|
17
|
-
*/
|
|
18
|
-
const mergeOpenAPIOptions = (
|
|
19
|
-
defaultOptions: Record<string, unknown>,
|
|
20
|
-
userOptions: Record<string, unknown>
|
|
21
|
-
): Record<string, unknown> => {
|
|
22
|
-
const merged = { ...defaultOptions };
|
|
23
|
-
|
|
24
|
-
// Handle nested info object specially
|
|
25
|
-
if (userOptions.info && typeof userOptions.info === 'object') {
|
|
26
|
-
merged.info = {
|
|
27
|
-
...(merged.info as Record<string, unknown>),
|
|
28
|
-
...userOptions.info,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// For all other top-level properties, override defaults
|
|
33
|
-
for (const [key, value] of Object.entries(userOptions)) {
|
|
34
|
-
if (key !== 'info') {
|
|
35
|
-
merged[key] = value;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return merged;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Generate the OpenAPI specification document
|
|
44
|
-
*
|
|
45
|
-
* @param options - Configuration options for the OpenAPI spec generation
|
|
46
|
-
* @returns A memoized function that generates and caches the OpenAPI spec
|
|
47
|
-
*
|
|
48
|
-
* @throws {Error} When the OpenAPI generator fails to create a valid spec
|
|
49
|
-
*
|
|
50
|
-
* @example
|
|
51
|
-
* ```ts
|
|
52
|
-
* const getSpec = createOpenAPISpec(options);
|
|
53
|
-
* const spec = await getSpec();
|
|
54
|
-
* ```
|
|
55
|
-
*/
|
|
56
|
-
export const createOpenAPISpec = (
|
|
57
|
-
context: C15TContext,
|
|
58
|
-
options: C15TOptions
|
|
59
|
-
) => {
|
|
60
|
-
// Initialize OpenAPI generator with schema converters
|
|
61
|
-
const openAPIGenerator = new OpenAPIGenerator({
|
|
62
|
-
schemaConverters: [new ZodToJsonSchemaConverter()],
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
// Memoise once per process
|
|
66
|
-
const getOpenAPISpec = (async (): Promise<Record<string, unknown>> => {
|
|
67
|
-
if (getOpenAPISpec.cached) {
|
|
68
|
-
return getOpenAPISpec.cached;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const defaultOptions = createDefaultOpenAPIOptions(options);
|
|
72
|
-
const mergedOptions = options.openapi?.options
|
|
73
|
-
? mergeOpenAPIOptions(
|
|
74
|
-
defaultOptions,
|
|
75
|
-
options.openapi.options as Record<string, unknown>
|
|
76
|
-
)
|
|
77
|
-
: defaultOptions;
|
|
78
|
-
|
|
79
|
-
try {
|
|
80
|
-
// We need to cast to the expected type due to incompatibilities between the types
|
|
81
|
-
// This is safe as we control the options format and it's compatible with what the generator expects
|
|
82
|
-
const spec = await openAPIGenerator.generate(
|
|
83
|
-
router,
|
|
84
|
-
mergedOptions as Record<string, unknown>
|
|
85
|
-
);
|
|
86
|
-
getOpenAPISpec.cached = spec;
|
|
87
|
-
return spec;
|
|
88
|
-
} catch (error) {
|
|
89
|
-
context.logger?.error('Failed to generate OpenAPI spec:', error);
|
|
90
|
-
// Return a minimal valid spec to prevent UI errors
|
|
91
|
-
return {
|
|
92
|
-
openapi: '3.0.0',
|
|
93
|
-
info: { title: options.appName || 'c15t API', version: '0.0.0' },
|
|
94
|
-
paths: {},
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
}) as MemoizedSpecFunction;
|
|
98
|
-
|
|
99
|
-
return getOpenAPISpec;
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Generate the default UI for API documentation
|
|
104
|
-
*/
|
|
105
|
-
export const createDocsUI = (options: C15TOptions) => {
|
|
106
|
-
const config = createOpenAPIConfig(options);
|
|
107
|
-
|
|
108
|
-
// If a custom template is provided, use it
|
|
109
|
-
if (config.customUiTemplate) {
|
|
110
|
-
return config.customUiTemplate;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Otherwise, return the default Scalar UI
|
|
114
|
-
return `
|
|
115
|
-
<!doctype html>
|
|
116
|
-
<html>
|
|
117
|
-
<head>
|
|
118
|
-
<title>${options.appName || 'c15t API'} Documentation</title>
|
|
119
|
-
<meta charset="utf-8" />
|
|
120
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
121
|
-
<link rel="icon" type="image/svg+xml" href="https://c15t.com/icon.svg" />
|
|
122
|
-
</head>
|
|
123
|
-
<body>
|
|
124
|
-
<script
|
|
125
|
-
id="api-reference"
|
|
126
|
-
data-url="${encodeURI(config.specPath)}">
|
|
127
|
-
</script>
|
|
128
|
-
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
|
|
129
|
-
</body>
|
|
130
|
-
</html>
|
|
131
|
-
`;
|
|
132
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OpenAPI middleware for c15t
|
|
3
|
-
*
|
|
4
|
-
* This module provides OpenAPI functionality including:
|
|
5
|
-
* - Configuration management
|
|
6
|
-
* - Specification generation
|
|
7
|
-
* - Documentation UI
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
export { createOpenAPIConfig, createDefaultOpenAPIOptions } from './config';
|
|
11
|
-
export { createOpenAPISpec, createDocsUI } from './handlers';
|