@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
package/src/core.ts
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
import { createLogger } from '@doubletie/logger';
|
|
1
|
+
import { type Logger, createLogger } from '@doubletie/logger';
|
|
2
|
+
import { OpenAPIGenerator } from '@orpc/openapi';
|
|
2
3
|
import { OpenAPIHandler } from '@orpc/openapi/fetch';
|
|
3
4
|
import { CORSPlugin } from '@orpc/server/plugins';
|
|
5
|
+
import { ZodToJsonSchemaConverter } from '@orpc/zod';
|
|
4
6
|
import { DoubleTieError, ERROR_CODES } from '~/pkgs/results';
|
|
5
7
|
import type { C15TContext, C15TOptions, C15TPlugin } from '~/types';
|
|
8
|
+
import packageJson from '../package.json';
|
|
6
9
|
import { init } from './init';
|
|
7
|
-
import { createCORSOptions, processCors } from './middleware/cors';
|
|
8
|
-
import {
|
|
9
|
-
createDocsUI,
|
|
10
|
-
createOpenAPIConfig,
|
|
11
|
-
createOpenAPISpec,
|
|
12
|
-
} from './middleware/openapi';
|
|
13
10
|
import { withRequestSpan } from './pkgs/api-router/telemetry';
|
|
11
|
+
import { isOriginTrusted } from './pkgs/api-router/utils/cors';
|
|
14
12
|
import { getIp } from './pkgs/api-router/utils/ip';
|
|
15
13
|
import { router } from './router';
|
|
16
|
-
|
|
17
14
|
/**
|
|
18
15
|
* Type representing an API route
|
|
19
16
|
*/
|
|
@@ -95,6 +92,22 @@ export interface C15TInstance<PluginTypes extends C15TPlugin[] = C15TPlugin[]> {
|
|
|
95
92
|
getDocsUI: () => string;
|
|
96
93
|
}
|
|
97
94
|
|
|
95
|
+
// Define middleware context interface
|
|
96
|
+
interface MiddlewareContext {
|
|
97
|
+
logger?: Logger;
|
|
98
|
+
adapter: unknown;
|
|
99
|
+
registry: unknown;
|
|
100
|
+
generateId: unknown;
|
|
101
|
+
ipAddress?: string;
|
|
102
|
+
origin?: string;
|
|
103
|
+
trustedOrigin?: boolean;
|
|
104
|
+
path?: string;
|
|
105
|
+
method?: string;
|
|
106
|
+
headers?: Headers;
|
|
107
|
+
userAgent?: string;
|
|
108
|
+
[key: string]: unknown;
|
|
109
|
+
}
|
|
110
|
+
|
|
98
111
|
/**
|
|
99
112
|
* Creates a new c15t consent management instance.
|
|
100
113
|
*
|
|
@@ -106,22 +119,91 @@ export const c15tInstance = <PluginTypes extends C15TPlugin[] = C15TPlugin[]>(
|
|
|
106
119
|
// Initialize context
|
|
107
120
|
const contextPromise = init(options);
|
|
108
121
|
|
|
109
|
-
|
|
110
|
-
|
|
122
|
+
const corsOptions = options.trustedOrigins
|
|
123
|
+
? {
|
|
124
|
+
// When specific origins are configured
|
|
125
|
+
origin: options.trustedOrigins.includes('*')
|
|
126
|
+
? (origin: string) => origin // Return the actual origin
|
|
127
|
+
: options.trustedOrigins, // Otherwise use the specific list
|
|
128
|
+
credentials: true, // Allow cookies/auth headers
|
|
129
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH'],
|
|
130
|
+
allowedHeaders: ['Content-Type', 'Authorization', 'X-Request-ID'],
|
|
131
|
+
maxAge: 86400,
|
|
132
|
+
}
|
|
133
|
+
: {
|
|
134
|
+
// Default configuration when no origins specified
|
|
135
|
+
origin: '*', // Allow all origins
|
|
136
|
+
credentials: false, // Can't use credentials with wildcard origin
|
|
137
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH'],
|
|
138
|
+
allowedHeaders: ['Content-Type', 'Authorization', 'X-Request-ID'],
|
|
139
|
+
maxAge: 86400,
|
|
140
|
+
};
|
|
111
141
|
|
|
112
142
|
// Create the oRPC handler with plugins
|
|
113
143
|
const rpcHandler = new OpenAPIHandler(router, {
|
|
114
|
-
plugins: [
|
|
144
|
+
plugins: [
|
|
145
|
+
new CORSPlugin({
|
|
146
|
+
...corsOptions,
|
|
147
|
+
// Ensure these headers are always set
|
|
148
|
+
origin: (origin: string) => {
|
|
149
|
+
// If no origin, return null to deny the request
|
|
150
|
+
if (!origin) { return null; }
|
|
151
|
+
|
|
152
|
+
// If wildcard is allowed, return the actual origin
|
|
153
|
+
if (options.trustedOrigins?.includes('*')) {
|
|
154
|
+
return origin;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// If origin is in trusted list, return it
|
|
158
|
+
if (options.trustedOrigins?.includes(origin)) {
|
|
159
|
+
return origin;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Deny all other origins
|
|
163
|
+
return null;
|
|
164
|
+
},
|
|
165
|
+
credentials: true,
|
|
166
|
+
exposeHeaders: ['Content-Type', 'Authorization', 'X-Request-ID'],
|
|
167
|
+
}),
|
|
168
|
+
],
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// Initialize OpenAPI generator with schema converters
|
|
172
|
+
const openAPIGenerator = new OpenAPIGenerator({
|
|
173
|
+
schemaConverters: [new ZodToJsonSchemaConverter()],
|
|
115
174
|
});
|
|
116
175
|
|
|
117
|
-
// Set up OpenAPI configuration
|
|
118
|
-
const openApiConfig =
|
|
119
|
-
|
|
176
|
+
// Set up OpenAPI configuration with defaults
|
|
177
|
+
const openApiConfig = {
|
|
178
|
+
enabled: true,
|
|
179
|
+
specPath: '/spec.json',
|
|
180
|
+
docsPath: '/docs',
|
|
181
|
+
...(options.openapi || {}),
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
// Default OpenAPI options
|
|
185
|
+
const defaultOpenApiOptions = {
|
|
186
|
+
info: {
|
|
187
|
+
title: options.appName || 'c15t API',
|
|
188
|
+
version: packageJson.version,
|
|
189
|
+
description: 'API for consent management',
|
|
190
|
+
},
|
|
191
|
+
servers: [{ url: '/' }],
|
|
192
|
+
security: [{ bearerAuth: [] }],
|
|
193
|
+
// components: {
|
|
194
|
+
// securitySchemes: {
|
|
195
|
+
// bearerAuth: {
|
|
196
|
+
// type: 'http',
|
|
197
|
+
// scheme: 'bearer',
|
|
198
|
+
// },
|
|
199
|
+
// },
|
|
200
|
+
// },
|
|
201
|
+
};
|
|
120
202
|
|
|
121
203
|
/**
|
|
122
204
|
* Process IP tracking and add it to the context
|
|
123
205
|
*/
|
|
124
|
-
const processIp = (request: Request, context:
|
|
206
|
+
const processIp = (request: Request, context: MiddlewareContext) => {
|
|
125
207
|
const ip = getIp(request, options);
|
|
126
208
|
if (ip) {
|
|
127
209
|
context.ipAddress = ip;
|
|
@@ -129,10 +211,28 @@ export const c15tInstance = <PluginTypes extends C15TPlugin[] = C15TPlugin[]>(
|
|
|
129
211
|
return context;
|
|
130
212
|
};
|
|
131
213
|
|
|
214
|
+
/**
|
|
215
|
+
* Process CORS validation and add it to the context
|
|
216
|
+
*/
|
|
217
|
+
const processCors = (request: Request, context: MiddlewareContext) => {
|
|
218
|
+
const origin = request.headers.get('origin');
|
|
219
|
+
if (origin && options.trustedOrigins) {
|
|
220
|
+
const trusted = isOriginTrusted(
|
|
221
|
+
origin,
|
|
222
|
+
options.trustedOrigins,
|
|
223
|
+
context.logger
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
context.origin = origin;
|
|
227
|
+
context.trustedOrigin = trusted;
|
|
228
|
+
}
|
|
229
|
+
return context;
|
|
230
|
+
};
|
|
231
|
+
|
|
132
232
|
/**
|
|
133
233
|
* Add telemetry tracking to the context
|
|
134
234
|
*/
|
|
135
|
-
const processTelemetry = (request: Request, context:
|
|
235
|
+
const processTelemetry = (request: Request, context: MiddlewareContext) => {
|
|
136
236
|
const url = new URL(request.url);
|
|
137
237
|
const path = url.pathname;
|
|
138
238
|
const method = request.method;
|
|
@@ -158,6 +258,81 @@ export const c15tInstance = <PluginTypes extends C15TPlugin[] = C15TPlugin[]>(
|
|
|
158
258
|
return context;
|
|
159
259
|
};
|
|
160
260
|
|
|
261
|
+
/**
|
|
262
|
+
* Generate the OpenAPI specification document
|
|
263
|
+
*/
|
|
264
|
+
const getOpenAPISpec = (async (): Promise<Record<string, unknown>> => {
|
|
265
|
+
// Memoise once per process
|
|
266
|
+
if (getOpenAPISpec.cached) {
|
|
267
|
+
return getOpenAPISpec.cached;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Start with our defaults
|
|
271
|
+
const mergedOptions = { ...defaultOpenApiOptions };
|
|
272
|
+
|
|
273
|
+
// If user provided options, merge them with defaults
|
|
274
|
+
if (openApiConfig.options) {
|
|
275
|
+
// biome-ignore lint: OpenAPI options are dynamically merged
|
|
276
|
+
const userOptions = openApiConfig.options as Record<string, any>;
|
|
277
|
+
|
|
278
|
+
// Handle nested info object (title, description, version) specially
|
|
279
|
+
if (userOptions.info) {
|
|
280
|
+
mergedOptions.info = {
|
|
281
|
+
...defaultOpenApiOptions.info,
|
|
282
|
+
...userOptions.info,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// For all other top-level properties, override defaults with user settings
|
|
287
|
+
for (const [key, value] of Object.entries(userOptions)) {
|
|
288
|
+
if (key !== 'info') {
|
|
289
|
+
(mergedOptions as Record<string, unknown>)[key] = value;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// We need to cast to the expected type due to incompatibilities between the types
|
|
295
|
+
// This is safe as we control the options format and it's compatible with what the generator expects
|
|
296
|
+
const spec = await openAPIGenerator.generate(
|
|
297
|
+
router,
|
|
298
|
+
mergedOptions as Record<string, unknown>
|
|
299
|
+
);
|
|
300
|
+
getOpenAPISpec.cached = spec;
|
|
301
|
+
return spec;
|
|
302
|
+
}) as (() => Promise<Record<string, unknown>>) & {
|
|
303
|
+
cached?: Record<string, unknown>;
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Generate the default UI for API documentation
|
|
308
|
+
*/
|
|
309
|
+
const getDocsUI = () => {
|
|
310
|
+
// If a custom template is provided, use it
|
|
311
|
+
if (openApiConfig.customUiTemplate) {
|
|
312
|
+
return openApiConfig.customUiTemplate;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Otherwise, return the default Scalar UI
|
|
316
|
+
return `
|
|
317
|
+
<!doctype html>
|
|
318
|
+
<html>
|
|
319
|
+
<head>
|
|
320
|
+
<title>${options.appName || 'c15t API'} Documentation</title>
|
|
321
|
+
<meta charset="utf-8" />
|
|
322
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
323
|
+
<link rel="icon" type="image/svg+xml" href="https://orpc.unnoq.com/icon.svg" />
|
|
324
|
+
</head>
|
|
325
|
+
<body>
|
|
326
|
+
<script
|
|
327
|
+
id="api-reference"
|
|
328
|
+
data-url="${encodeURI(openApiConfig.specPath)}">
|
|
329
|
+
</script>
|
|
330
|
+
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
|
|
331
|
+
</body>
|
|
332
|
+
</html>
|
|
333
|
+
`;
|
|
334
|
+
};
|
|
335
|
+
|
|
161
336
|
/**
|
|
162
337
|
* Handle OpenAPI spec requests
|
|
163
338
|
*/
|
|
@@ -165,24 +340,6 @@ export const c15tInstance = <PluginTypes extends C15TPlugin[] = C15TPlugin[]>(
|
|
|
165
340
|
url: URL
|
|
166
341
|
): Promise<Response | null> => {
|
|
167
342
|
if (openApiConfig.enabled && url.pathname === openApiConfig.specPath) {
|
|
168
|
-
const ctxResult = await contextPromise;
|
|
169
|
-
if (!ctxResult.isOk()) {
|
|
170
|
-
throw ctxResult.error;
|
|
171
|
-
}
|
|
172
|
-
const ctx = ctxResult.value;
|
|
173
|
-
const orpcContext = {
|
|
174
|
-
adapter: ctx.adapter,
|
|
175
|
-
registry: ctx.registry,
|
|
176
|
-
logger: ctx.logger,
|
|
177
|
-
generateId: ctx.generateId,
|
|
178
|
-
headers: new Headers(),
|
|
179
|
-
appName: options.appName || 'c15t',
|
|
180
|
-
options,
|
|
181
|
-
trustedOrigins: options.trustedOrigins || [],
|
|
182
|
-
baseURL: options.baseURL || '/',
|
|
183
|
-
tables: ctx.tables,
|
|
184
|
-
};
|
|
185
|
-
const getOpenAPISpec = createOpenAPISpec(orpcContext, options);
|
|
186
343
|
const spec = await getOpenAPISpec();
|
|
187
344
|
return new Response(JSON.stringify(spec), {
|
|
188
345
|
status: 200,
|
|
@@ -275,52 +432,32 @@ export const c15tInstance = <PluginTypes extends C15TPlugin[] = C15TPlugin[]>(
|
|
|
275
432
|
ctx: C15TContext
|
|
276
433
|
): Promise<Response> => {
|
|
277
434
|
// Create context for the handler with c15t specifics
|
|
278
|
-
const orpcContext = {
|
|
435
|
+
const orpcContext: MiddlewareContext = {
|
|
279
436
|
adapter: ctx.adapter,
|
|
280
437
|
registry: ctx.registry,
|
|
281
438
|
logger: ctx.logger,
|
|
282
439
|
generateId: ctx.generateId,
|
|
283
440
|
headers: request.headers,
|
|
284
441
|
userAgent: request.headers.get('user-agent') || undefined,
|
|
285
|
-
appName: options.appName || 'c15t',
|
|
286
|
-
options,
|
|
287
|
-
trustedOrigins: options.trustedOrigins || [],
|
|
288
|
-
baseURL: options.baseURL || '/',
|
|
289
|
-
tables: ctx.tables,
|
|
290
442
|
};
|
|
291
443
|
|
|
292
444
|
// Apply middleware processing to enrich the context
|
|
293
445
|
processIp(request, orpcContext);
|
|
294
|
-
processCors(request, orpcContext
|
|
446
|
+
processCors(request, orpcContext);
|
|
295
447
|
processTelemetry(request, orpcContext);
|
|
296
448
|
|
|
297
449
|
// Use oRPC handler to handle the request with our enhanced context
|
|
298
450
|
const handlerContext = orpcContext as Record<string, unknown>;
|
|
299
|
-
|
|
300
|
-
orpcContext.logger.debug?.('Handling prefix', {
|
|
301
|
-
prefix: (options.basePath as `/${string}`) || '/',
|
|
302
|
-
});
|
|
303
|
-
|
|
304
451
|
const { matched, response } = await rpcHandler.handle(request, {
|
|
305
|
-
prefix:
|
|
452
|
+
prefix: '/',
|
|
306
453
|
context: handlerContext,
|
|
307
454
|
});
|
|
308
455
|
|
|
309
456
|
// Return the response if handler matched
|
|
310
457
|
if (matched && response) {
|
|
311
|
-
orpcContext.logger.debug('Handler matched', {
|
|
312
|
-
request,
|
|
313
|
-
matched,
|
|
314
|
-
response,
|
|
315
|
-
});
|
|
316
458
|
return response;
|
|
317
459
|
}
|
|
318
460
|
|
|
319
|
-
orpcContext.logger.debug('No handler matched', {
|
|
320
|
-
request,
|
|
321
|
-
matched,
|
|
322
|
-
response,
|
|
323
|
-
});
|
|
324
461
|
// If no handler matched, return 404
|
|
325
462
|
return new Response('Not Found', { status: 404 });
|
|
326
463
|
};
|
|
@@ -331,11 +468,6 @@ export const c15tInstance = <PluginTypes extends C15TPlugin[] = C15TPlugin[]>(
|
|
|
331
468
|
const handler = async (request: Request): Promise<Response> => {
|
|
332
469
|
try {
|
|
333
470
|
const url = new URL(request.url);
|
|
334
|
-
// Add this debug log:
|
|
335
|
-
createLogger(options.logger)?.debug?.('Incoming request', {
|
|
336
|
-
method: request.method,
|
|
337
|
-
pathname: url.pathname,
|
|
338
|
-
});
|
|
339
471
|
|
|
340
472
|
// Check for OpenAPI spec or docs UI requests
|
|
341
473
|
const openApiResponse = await handleOpenApiSpecRequest(url);
|
|
@@ -355,19 +487,6 @@ export const c15tInstance = <PluginTypes extends C15TPlugin[] = C15TPlugin[]>(
|
|
|
355
487
|
}
|
|
356
488
|
const ctx = ctxResult.value;
|
|
357
489
|
|
|
358
|
-
// After options/baseURL/basePath is set/used
|
|
359
|
-
const basePath = options.basePath || options.baseURL || '/';
|
|
360
|
-
createLogger(options.logger)?.debug?.('[c15t] Using basePath/baseURL', {
|
|
361
|
-
basePath,
|
|
362
|
-
});
|
|
363
|
-
|
|
364
|
-
// Add this debug log:
|
|
365
|
-
createLogger(options.logger)?.debug?.('[c15t] Routing request', {
|
|
366
|
-
method: request.method,
|
|
367
|
-
url: request.url,
|
|
368
|
-
prefix: basePath,
|
|
369
|
-
});
|
|
370
|
-
|
|
371
490
|
// Handle API request
|
|
372
491
|
return await handleApiRequest(request, ctx);
|
|
373
492
|
} catch (error) {
|
|
@@ -423,27 +542,7 @@ export const c15tInstance = <PluginTypes extends C15TPlugin[] = C15TPlugin[]>(
|
|
|
423
542
|
...createNextHandlers(),
|
|
424
543
|
|
|
425
544
|
// OpenAPI functionality
|
|
426
|
-
getOpenAPISpec
|
|
427
|
-
const ctxResult = await contextPromise;
|
|
428
|
-
if (!ctxResult.isOk()) {
|
|
429
|
-
throw ctxResult.error;
|
|
430
|
-
}
|
|
431
|
-
const ctx = ctxResult.value;
|
|
432
|
-
const orpcContext = {
|
|
433
|
-
adapter: ctx.adapter,
|
|
434
|
-
registry: ctx.registry,
|
|
435
|
-
logger: ctx.logger,
|
|
436
|
-
generateId: ctx.generateId,
|
|
437
|
-
headers: new Headers(),
|
|
438
|
-
appName: options.appName || 'c15t',
|
|
439
|
-
options,
|
|
440
|
-
trustedOrigins: options.trustedOrigins || [],
|
|
441
|
-
baseURL: options.baseURL || '/',
|
|
442
|
-
tables: ctx.tables,
|
|
443
|
-
};
|
|
444
|
-
const getOpenAPISpec = createOpenAPISpec(orpcContext, options);
|
|
445
|
-
return getOpenAPISpec();
|
|
446
|
-
},
|
|
545
|
+
getOpenAPISpec,
|
|
447
546
|
getDocsUI,
|
|
448
547
|
};
|
|
449
548
|
};
|
|
@@ -119,7 +119,7 @@ describe('Show Consent Banner Handler', () => {
|
|
|
119
119
|
createMockContext({ 'cf-ipcountry': 'US' })
|
|
120
120
|
);
|
|
121
121
|
|
|
122
|
-
expect(result.showConsentBanner).toBe(
|
|
122
|
+
expect(result.showConsentBanner).toBe(false);
|
|
123
123
|
expect(result.jurisdiction.code).toBe('NONE');
|
|
124
124
|
expect(result.jurisdiction.message).toBe(JurisdictionMessages.NONE);
|
|
125
125
|
});
|
|
@@ -110,7 +110,7 @@ export function checkJurisdiction(countryCode: string | null) {
|
|
|
110
110
|
};
|
|
111
111
|
|
|
112
112
|
// Default to no jurisdiction
|
|
113
|
-
|
|
113
|
+
let showConsentBanner = false;
|
|
114
114
|
let jurisdictionCode: JurisdictionCode = 'NONE';
|
|
115
115
|
|
|
116
116
|
// Check country code against jurisdiction sets
|
|
@@ -132,6 +132,7 @@ export function checkJurisdiction(countryCode: string | null) {
|
|
|
132
132
|
// Find matching jurisdiction
|
|
133
133
|
for (const { sets, code } of jurisdictionMap) {
|
|
134
134
|
if (sets.some((set) => set.has(countryCode))) {
|
|
135
|
+
showConsentBanner = true;
|
|
135
136
|
jurisdictionCode = code;
|
|
136
137
|
break;
|
|
137
138
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { Logger } from '@doubletie/logger';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Regex to strip protocol, trailing slashes, and port numbers from URLs
|
|
5
|
+
*/
|
|
6
|
+
export const STRIP_REGEX = /^(https?:\/\/)|(wss?:\/\/)|(\/+$)|:\d+/g;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Validates if a given origin matches a trusted domain pattern
|
|
10
|
+
*
|
|
11
|
+
* @param origin - The origin to validate
|
|
12
|
+
* @param trustedDomains - Array of trusted domain patterns (can include wildcard)
|
|
13
|
+
* @returns boolean indicating if the origin is trusted
|
|
14
|
+
*/
|
|
15
|
+
export function isOriginTrusted(
|
|
16
|
+
origin: string,
|
|
17
|
+
trustedDomains: string[],
|
|
18
|
+
logger?: Logger
|
|
19
|
+
): boolean {
|
|
20
|
+
try {
|
|
21
|
+
if (trustedDomains.length === 0) {
|
|
22
|
+
throw new Error('No trusted domains');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
logger?.debug(
|
|
26
|
+
`Checking if origin ${origin} is trusted in ${trustedDomains}`
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
// Special case: if "*" is in trusted domains, allow all origins
|
|
30
|
+
if (trustedDomains.includes('*')) {
|
|
31
|
+
logger?.debug('Allowing all origins');
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Parse the origin URL to get just the hostname
|
|
36
|
+
const url = new URL(origin);
|
|
37
|
+
const originHostname = url.hostname.toLowerCase();
|
|
38
|
+
logger?.debug(`Parsed origin hostname: ${originHostname}`);
|
|
39
|
+
|
|
40
|
+
return trustedDomains.some((domain) => {
|
|
41
|
+
// Handle empty domains (which might come from splitting empty strings)
|
|
42
|
+
if (!domain || domain.trim() === '') {
|
|
43
|
+
logger?.debug('Skipping empty domain');
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const strippedDomain = domain.replace(STRIP_REGEX, '').toLowerCase();
|
|
48
|
+
logger?.debug(`Checking against stripped domain: ${strippedDomain}`);
|
|
49
|
+
|
|
50
|
+
if (strippedDomain.startsWith('*.')) {
|
|
51
|
+
// For wildcard domains, ensure there is at least one subdomain
|
|
52
|
+
const wildcardDomain = strippedDomain.slice(2); // Remove *. prefix
|
|
53
|
+
const parts = originHostname.split('.');
|
|
54
|
+
|
|
55
|
+
const isValid =
|
|
56
|
+
parts.length > 2 && originHostname.endsWith(wildcardDomain);
|
|
57
|
+
logger?.debug(
|
|
58
|
+
`Wildcard match result: ${isValid} ${originHostname} ends with ${wildcardDomain} ${parts.length > 2} ${originHostname.endsWith(wildcardDomain)}`
|
|
59
|
+
);
|
|
60
|
+
return isValid;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const isMatch = originHostname === strippedDomain;
|
|
64
|
+
logger?.debug(
|
|
65
|
+
`Exact match result: ${isMatch} ${originHostname} === ${strippedDomain}`
|
|
66
|
+
);
|
|
67
|
+
return isMatch;
|
|
68
|
+
});
|
|
69
|
+
} catch (error) {
|
|
70
|
+
logger?.error('Error validating origin:', error);
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
|
|
1
3
|
import { getWithHooks } from '~/pkgs/data-model';
|
|
2
4
|
import type { Where } from '~/pkgs/db-adapters';
|
|
3
|
-
import { DoubleTieError, ERROR_CODES } from '~/pkgs/results';
|
|
4
5
|
import type { GenericEndpointContext, RegistryContext } from '~/pkgs/types';
|
|
6
|
+
|
|
7
|
+
import { DoubleTieError, ERROR_CODES } from '~/pkgs/results';
|
|
5
8
|
import { validateEntityOutput } from '../definition';
|
|
6
9
|
import type { ConsentPolicy, PolicyType } from './schema';
|
|
7
10
|
|
|
@@ -28,26 +31,9 @@ import type { ConsentPolicy, PolicyType } from './schema';
|
|
|
28
31
|
*
|
|
29
32
|
* @internal Used by findOrCreatePolicy to initialize placeholder content
|
|
30
33
|
*/
|
|
31
|
-
|
|
34
|
+
function generatePolicyPlaceholder(name: string, date: Date) {
|
|
32
35
|
const content = `[PLACEHOLDER] This is an automatically generated version of the ${name} policy.\n\nThis placeholder content should be replaced with actual policy terms before being presented to users.\n\nGenerated on: ${date.toISOString()}`;
|
|
33
|
-
|
|
34
|
-
let contentHash: string;
|
|
35
|
-
try {
|
|
36
|
-
// Use Web Crypto API which is available in both browsers and edge environments
|
|
37
|
-
const encoder = new TextEncoder();
|
|
38
|
-
const data = encoder.encode(content);
|
|
39
|
-
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
|
|
40
|
-
contentHash = Array.from(new Uint8Array(hashBuffer))
|
|
41
|
-
.map((b) => b.toString(16).padStart(2, '0'))
|
|
42
|
-
.join('');
|
|
43
|
-
} catch (error) {
|
|
44
|
-
throw new DoubleTieError('Failed to generate policy content hash', {
|
|
45
|
-
code: ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
46
|
-
status: 500,
|
|
47
|
-
cause: error instanceof Error ? error : new Error(String(error)),
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
|
|
36
|
+
const contentHash = createHash('sha256').update(content).digest('hex');
|
|
51
37
|
return { content, contentHash };
|
|
52
38
|
}
|
|
53
39
|
|
|
@@ -280,69 +266,57 @@ export function policyRegistry({ adapter, ...ctx }: RegistryContext) {
|
|
|
280
266
|
*/
|
|
281
267
|
findOrCreatePolicy: async (type: PolicyType) => {
|
|
282
268
|
// Use a transaction to prevent race conditions
|
|
283
|
-
return
|
|
269
|
+
return adapter.transaction({
|
|
284
270
|
callback: async (txAdapter) => {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
});
|
|
271
|
+
const now = new Date();
|
|
272
|
+
const txRegistry = policyRegistry({
|
|
273
|
+
adapter: txAdapter,
|
|
274
|
+
...ctx,
|
|
275
|
+
});
|
|
291
276
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
},
|
|
301
|
-
],
|
|
302
|
-
sortBy: {
|
|
303
|
-
field: 'effectiveDate',
|
|
304
|
-
direction: 'desc',
|
|
277
|
+
// Find latest policy with exact name match directly from database
|
|
278
|
+
const rawLatestPolicy = await txAdapter.findOne({
|
|
279
|
+
model: 'consentPolicy',
|
|
280
|
+
where: [
|
|
281
|
+
{ field: 'isActive', value: true },
|
|
282
|
+
{
|
|
283
|
+
field: 'type',
|
|
284
|
+
value: type,
|
|
305
285
|
},
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
ctx.options
|
|
313
|
-
)
|
|
314
|
-
: null;
|
|
286
|
+
],
|
|
287
|
+
sortBy: {
|
|
288
|
+
field: 'effectiveDate',
|
|
289
|
+
direction: 'desc',
|
|
290
|
+
},
|
|
291
|
+
});
|
|
315
292
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
293
|
+
const latestPolicy = rawLatestPolicy
|
|
294
|
+
? validateEntityOutput(
|
|
295
|
+
'consentPolicy',
|
|
296
|
+
rawLatestPolicy,
|
|
297
|
+
ctx.options
|
|
298
|
+
)
|
|
299
|
+
: null;
|
|
319
300
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
301
|
+
if (latestPolicy) {
|
|
302
|
+
return latestPolicy;
|
|
303
|
+
}
|
|
323
304
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
name: type,
|
|
328
|
-
effectiveDate: now,
|
|
329
|
-
content: defaultContent,
|
|
330
|
-
contentHash,
|
|
331
|
-
isActive: true,
|
|
332
|
-
updatedAt: now,
|
|
333
|
-
expirationDate: null,
|
|
334
|
-
});
|
|
335
|
-
} catch (error) {
|
|
336
|
-
// Log the error for debugging purposes
|
|
337
|
-
ctx.logger.error('Error in findOrCreatePolicy transaction:', error);
|
|
305
|
+
// Generate policy content and hash
|
|
306
|
+
const { content: defaultContent, contentHash } =
|
|
307
|
+
generatePolicyPlaceholder(type, now);
|
|
338
308
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
309
|
+
return txRegistry.createConsentPolicy({
|
|
310
|
+
version: '1.0.0',
|
|
311
|
+
type,
|
|
312
|
+
name: type,
|
|
313
|
+
effectiveDate: now,
|
|
314
|
+
content: defaultContent,
|
|
315
|
+
contentHash,
|
|
316
|
+
isActive: true,
|
|
317
|
+
updatedAt: now,
|
|
318
|
+
expirationDate: null,
|
|
319
|
+
});
|
|
346
320
|
},
|
|
347
321
|
});
|
|
348
322
|
},
|
package/src/server.ts
CHANGED
|
@@ -11,7 +11,11 @@ const logger = getLogger({
|
|
|
11
11
|
|
|
12
12
|
// Create the c15t instance with our configuration
|
|
13
13
|
const instance = c15tInstance({
|
|
14
|
-
|
|
14
|
+
advanced: {
|
|
15
|
+
cors: {
|
|
16
|
+
allowedOrigins: ['*'], // Allow all origins for development
|
|
17
|
+
},
|
|
18
|
+
},
|
|
15
19
|
// Add OpenAPI configuration
|
|
16
20
|
openapi: {
|
|
17
21
|
enabled: true, // Set to true to enable docs
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/server.test.ts"],"names":[],"mappings":""}
|