@c15t/backend 1.2.0-canary.8 → 1.2.0
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 +53 -52
- package/CHANGELOG.md +7 -0
- package/dist/__tests__/server.test.d.ts +2 -0
- package/dist/__tests__/server.test.d.ts.map +1 -0
- package/dist/contracts/index.d.ts +1 -1
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts.cjs +708 -0
- package/dist/contracts.js +661 -0
- package/dist/core.cjs +98 -47
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +98 -47
- package/dist/middleware/openapi/config.d.ts +1 -1
- package/dist/middleware/openapi/config.d.ts.map +1 -1
- package/dist/pkgs/data-model/index.cjs +57 -39
- package/dist/pkgs/data-model/index.js +57 -39
- package/dist/pkgs/data-model/schema/index.cjs +57 -39
- package/dist/pkgs/data-model/schema/index.js +57 -39
- package/dist/router.cjs +3 -1
- package/dist/router.js +3 -1
- package/dist/schema/consent-policy/registry.d.ts.map +1 -1
- package/dist/schema/create-registry.d.ts.map +1 -1
- package/dist/schema/index.cjs +57 -39
- package/dist/schema/index.js +57 -39
- package/package.json +9 -4
- package/rslib.config.ts +1 -0
- package/src/__tests__/server.test.ts +96 -0
- package/src/contracts/index.ts +2 -0
- package/src/core.ts +34 -1
- package/src/middleware/cors/cors.test.ts +0 -1
- package/src/middleware/openapi/config.ts +10 -7
- package/src/schema/consent-policy/registry.ts +74 -51
- package/.turbo/turbo-fmt.log +0 -7
- package/.turbo/turbo-test.log +0 -426
- package/coverage/coverage-final.json +0 -88
- package/coverage/coverage-summary.json +0 -89
- package/coverage/html/backend/index.html +0 -116
- package/coverage/html/backend/rslib.config.ts.html +0 -415
- package/coverage/html/backend/src/contracts/consent/index.html +0 -161
- package/coverage/html/backend/src/contracts/consent/index.ts.html +0 -112
- package/coverage/html/backend/src/contracts/consent/post.contract.ts.html +0 -550
- package/coverage/html/backend/src/contracts/consent/show-banner.contract.ts.html +0 -220
- package/coverage/html/backend/src/contracts/consent/verify.contract.ts.html +0 -463
- package/coverage/html/backend/src/contracts/index.html +0 -116
- package/coverage/html/backend/src/contracts/index.ts.html +0 -139
- package/coverage/html/backend/src/contracts/meta/index.html +0 -131
- package/coverage/html/backend/src/contracts/meta/index.ts.html +0 -100
- package/coverage/html/backend/src/contracts/meta/status.contract.ts.html +0 -196
- package/coverage/html/backend/src/contracts/shared/index.html +0 -116
- package/coverage/html/backend/src/contracts/shared/jurisdiction.schema.ts.html +0 -175
- package/coverage/html/backend/src/core.ts.html +0 -1342
- package/coverage/html/backend/src/handlers/consent/index.html +0 -161
- package/coverage/html/backend/src/handlers/consent/index.ts.html +0 -112
- package/coverage/html/backend/src/handlers/consent/post.handler.ts.html +0 -904
- package/coverage/html/backend/src/handlers/consent/show-banner.handler.ts.html +0 -532
- package/coverage/html/backend/src/handlers/consent/verify.handler.ts.html +0 -1000
- package/coverage/html/backend/src/handlers/meta/index.html +0 -131
- package/coverage/html/backend/src/handlers/meta/index.ts.html +0 -100
- package/coverage/html/backend/src/handlers/meta/status.handler.ts.html +0 -226
- package/coverage/html/backend/src/index.html +0 -161
- package/coverage/html/backend/src/init.ts.html +0 -1018
- package/coverage/html/backend/src/middleware/cors/cors.ts.html +0 -661
- package/coverage/html/backend/src/middleware/cors/index.html +0 -146
- package/coverage/html/backend/src/middleware/cors/is-origin-trusted.ts.html +0 -463
- package/coverage/html/backend/src/middleware/cors/process-cors.ts.html +0 -358
- package/coverage/html/backend/src/middleware/openapi/config.ts.html +0 -160
- package/coverage/html/backend/src/middleware/openapi/handlers.ts.html +0 -481
- package/coverage/html/backend/src/middleware/openapi/index.html +0 -131
- package/coverage/html/backend/src/pkgs/api-router/hooks/index.html +0 -116
- package/coverage/html/backend/src/pkgs/api-router/hooks/processor.ts.html +0 -544
- package/coverage/html/backend/src/pkgs/api-router/index.html +0 -116
- package/coverage/html/backend/src/pkgs/api-router/telemetry.ts.html +0 -334
- package/coverage/html/backend/src/pkgs/api-router/utils/index.html +0 -116
- package/coverage/html/backend/src/pkgs/api-router/utils/ip.ts.html +0 -361
- package/coverage/html/backend/src/pkgs/data-model/fields/field-factory.ts.html +0 -709
- package/coverage/html/backend/src/pkgs/data-model/fields/id-generator.ts.html +0 -256
- package/coverage/html/backend/src/pkgs/data-model/fields/index.html +0 -161
- package/coverage/html/backend/src/pkgs/data-model/fields/superjson-utils.ts.html +0 -136
- package/coverage/html/backend/src/pkgs/data-model/fields/zod-fields.ts.html +0 -496
- package/coverage/html/backend/src/pkgs/data-model/hooks/create-hooks.ts.html +0 -349
- package/coverage/html/backend/src/pkgs/data-model/hooks/index.html +0 -176
- package/coverage/html/backend/src/pkgs/data-model/hooks/update-hooks.ts.html +0 -358
- package/coverage/html/backend/src/pkgs/data-model/hooks/update-many-hooks.ts.html +0 -613
- package/coverage/html/backend/src/pkgs/data-model/hooks/utils.ts.html +0 -538
- package/coverage/html/backend/src/pkgs/data-model/hooks/with-hooks-factory.ts.html +0 -289
- package/coverage/html/backend/src/pkgs/db-adapters/adapter-factory.ts.html +0 -289
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.ts.html +0 -2203
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/drizzle-adapter/index.html +0 -116
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/index.html +0 -116
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/dialect.ts.html +0 -670
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/index.html +0 -131
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.ts.html +0 -3634
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/tests/index.html +0 -116
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.ts.html +0 -1417
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/memory-adapter/index.html +0 -116
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.ts.html +0 -2071
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/prisma-adapter/index.html +0 -116
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.ts.html +0 -1834
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/test.ts.html +0 -316
- package/coverage/html/backend/src/pkgs/db-adapters/index.html +0 -131
- package/coverage/html/backend/src/pkgs/db-adapters/utils.ts.html +0 -238
- package/coverage/html/backend/src/pkgs/migrations/get-migration.ts.html +0 -343
- package/coverage/html/backend/src/pkgs/migrations/get-schema/get-schema.ts.html +0 -217
- package/coverage/html/backend/src/pkgs/migrations/get-schema/index.html +0 -146
- package/coverage/html/backend/src/pkgs/migrations/get-schema/process-fields.ts.html +0 -280
- package/coverage/html/backend/src/pkgs/migrations/get-schema/process-tables.ts.html +0 -289
- package/coverage/html/backend/src/pkgs/migrations/index.html +0 -176
- package/coverage/html/backend/src/pkgs/migrations/migration-builders.ts.html +0 -595
- package/coverage/html/backend/src/pkgs/migrations/migration-execution.ts.html +0 -301
- package/coverage/html/backend/src/pkgs/migrations/schema-comparison.ts.html +0 -694
- package/coverage/html/backend/src/pkgs/migrations/type-mapping.ts.html +0 -817
- package/coverage/html/backend/src/pkgs/results/core/error-class.ts.html +0 -976
- package/coverage/html/backend/src/pkgs/results/core/error-codes.ts.html +0 -703
- package/coverage/html/backend/src/pkgs/results/core/index.html +0 -146
- package/coverage/html/backend/src/pkgs/results/core/tracing.ts.html +0 -280
- package/coverage/html/backend/src/pkgs/results/create-telemetry-options.ts.html +0 -271
- package/coverage/html/backend/src/pkgs/results/index.html +0 -131
- package/coverage/html/backend/src/pkgs/results/orpc-error-handler.ts.html +0 -496
- package/coverage/html/backend/src/pkgs/results/results/index.html +0 -131
- package/coverage/html/backend/src/pkgs/results/results/recovery-utils.ts.html +0 -628
- package/coverage/html/backend/src/pkgs/results/results/result-helpers.ts.html +0 -1234
- package/coverage/html/backend/src/pkgs/utils/env.ts.html +0 -337
- package/coverage/html/backend/src/pkgs/utils/index.html +0 -146
- package/coverage/html/backend/src/pkgs/utils/logger.ts.html +0 -199
- package/coverage/html/backend/src/pkgs/utils/url.ts.html +0 -400
- package/coverage/html/backend/src/router.ts.html +0 -109
- package/coverage/html/backend/src/schema/audit-log/index.html +0 -146
- package/coverage/html/backend/src/schema/audit-log/registry.ts.html +0 -436
- package/coverage/html/backend/src/schema/audit-log/schema.ts.html +0 -223
- package/coverage/html/backend/src/schema/audit-log/table.ts.html +0 -640
- package/coverage/html/backend/src/schema/consent/index.html +0 -146
- package/coverage/html/backend/src/schema/consent/registry.ts.html +0 -616
- package/coverage/html/backend/src/schema/consent/schema.ts.html +0 -238
- package/coverage/html/backend/src/schema/consent/table.ts.html +0 -748
- package/coverage/html/backend/src/schema/consent-policy/index.html +0 -146
- package/coverage/html/backend/src/schema/consent-policy/registry.ts.html +0 -1063
- package/coverage/html/backend/src/schema/consent-policy/schema.ts.html +0 -265
- package/coverage/html/backend/src/schema/consent-policy/table.ts.html +0 -535
- package/coverage/html/backend/src/schema/consent-purpose/index.html +0 -146
- package/coverage/html/backend/src/schema/consent-purpose/registry.ts.html +0 -589
- package/coverage/html/backend/src/schema/consent-purpose/schema.ts.html +0 -259
- package/coverage/html/backend/src/schema/consent-purpose/table.ts.html +0 -547
- package/coverage/html/backend/src/schema/consent-record/index.html +0 -131
- package/coverage/html/backend/src/schema/consent-record/schema.ts.html +0 -211
- package/coverage/html/backend/src/schema/consent-record/table.ts.html +0 -457
- package/coverage/html/backend/src/schema/create-registry.ts.html +0 -148
- package/coverage/html/backend/src/schema/definition.ts.html +0 -685
- package/coverage/html/backend/src/schema/domain/index.html +0 -146
- package/coverage/html/backend/src/schema/domain/registry.ts.html +0 -973
- package/coverage/html/backend/src/schema/domain/schema.ts.html +0 -214
- package/coverage/html/backend/src/schema/domain/table.ts.html +0 -496
- package/coverage/html/backend/src/schema/index.html +0 -146
- package/coverage/html/backend/src/schema/schemas.ts.html +0 -166
- package/coverage/html/backend/src/schema/subject/index.html +0 -146
- package/coverage/html/backend/src/schema/subject/registry.ts.html +0 -973
- package/coverage/html/backend/src/schema/subject/schema.ts.html +0 -208
- package/coverage/html/backend/src/schema/subject/table.ts.html +0 -499
- package/coverage/html/backend/src/server.ts.html +0 -463
- package/coverage/html/backend/src/testing/contract-testing.ts.html +0 -1396
- package/coverage/html/backend/src/testing/index.html +0 -116
- package/coverage/html/base.css +0 -224
- package/coverage/html/block-navigation.js +0 -87
- package/coverage/html/favicon.png +0 -0
- package/coverage/html/index.html +0 -656
- package/coverage/html/prettify.css +0 -1
- package/coverage/html/prettify.js +0 -2
- package/coverage/html/sort-arrow-sprite.png +0 -0
- package/coverage/html/sorter.js +0 -196
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@c15t/backend",
|
|
3
|
-
"version": "1.2.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"license": "GPL-3.0-only",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -19,6 +19,11 @@
|
|
|
19
19
|
"import": "./dist/schema/index.js",
|
|
20
20
|
"require": "./dist/schema/index.cjs"
|
|
21
21
|
},
|
|
22
|
+
"./contracts": {
|
|
23
|
+
"types": "./dist/contracts/index.d.ts",
|
|
24
|
+
"import": "./dist/contracts.js",
|
|
25
|
+
"require": "./dist/contracts.cjs"
|
|
26
|
+
},
|
|
22
27
|
"./pkgs/data-model/fields": {
|
|
23
28
|
"types": "./dist/pkgs/data-model/fields/index.d.ts",
|
|
24
29
|
"import": "./dist/pkgs/data-model/fields/index.js",
|
|
@@ -107,8 +112,8 @@
|
|
|
107
112
|
"msw": "^2.7.6",
|
|
108
113
|
"typescript": "^5.8.3",
|
|
109
114
|
"vitest": "^3.1.1",
|
|
110
|
-
"@c15t/
|
|
111
|
-
"@c15t/
|
|
115
|
+
"@c15t/typescript-config": "0.0.1-beta.1",
|
|
116
|
+
"@c15t/vitest-config": "1.0.0"
|
|
112
117
|
},
|
|
113
118
|
"publishConfig": {
|
|
114
119
|
"access": "public"
|
|
@@ -117,7 +122,7 @@
|
|
|
117
122
|
"build": "rslib build",
|
|
118
123
|
"check-types": "tsc --noEmit",
|
|
119
124
|
"dev": "rslib build --watch",
|
|
120
|
-
"fmt": "pnpm biome format --write . && biome check --formatter-enabled=false --linter-enabled=false --organize-imports-enabled=true --write",
|
|
125
|
+
"fmt": "pnpm biome format --write . && pnpm biome check --formatter-enabled=false --linter-enabled=false --organize-imports-enabled=true --write",
|
|
121
126
|
"knip": "knip",
|
|
122
127
|
"lint": "pnpm biome lint ./src",
|
|
123
128
|
"start": "node dist/server.cjs",
|
package/rslib.config.ts
CHANGED
|
@@ -62,6 +62,7 @@ export default defineConfig({
|
|
|
62
62
|
entry: {
|
|
63
63
|
core: ['./src/core.ts'],
|
|
64
64
|
router: ['./src/router.ts'],
|
|
65
|
+
contracts: ['./src/contracts/index.ts'],
|
|
65
66
|
'schema/index': ['./src/schema/index.ts'],
|
|
66
67
|
'pkgs/data-model/fields/index': ['./src/pkgs/data-model/fields/index.ts'],
|
|
67
68
|
'pkgs/data-model/index': ['./src/pkgs/data-model/index.ts'],
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { type C15TOptions, c15tInstance } from '../core';
|
|
3
|
+
|
|
4
|
+
const mockOptions: C15TOptions = {
|
|
5
|
+
appName: 'Consent.io Dashboard',
|
|
6
|
+
basePath: '/api/c15t',
|
|
7
|
+
trustedOrigins: [
|
|
8
|
+
'localhost',
|
|
9
|
+
'vercel.app',
|
|
10
|
+
'consent.io',
|
|
11
|
+
'https://test.consent.io',
|
|
12
|
+
],
|
|
13
|
+
cors: true,
|
|
14
|
+
advanced: {
|
|
15
|
+
cors: {
|
|
16
|
+
allowHeaders: ['content-type', 'x-request-id'],
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
logger: {
|
|
20
|
+
level: 'debug',
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const createTestRequest = (
|
|
25
|
+
path = '/api/c15t/status',
|
|
26
|
+
method = 'GET',
|
|
27
|
+
headers?: Record<string, string>
|
|
28
|
+
) => {
|
|
29
|
+
return new Request(`http://localhost${path}`, {
|
|
30
|
+
method,
|
|
31
|
+
headers: {
|
|
32
|
+
'content-type': 'application/json',
|
|
33
|
+
...(headers || {}),
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
describe('C15T /status endpoint', () => {
|
|
39
|
+
it('GET /api/c15t/status returns 200 and status payload', async () => {
|
|
40
|
+
const c15t = c15tInstance(mockOptions);
|
|
41
|
+
const request = createTestRequest();
|
|
42
|
+
const response = await c15t.handler(request);
|
|
43
|
+
expect(response.status).toBe(200);
|
|
44
|
+
const data = await response.json();
|
|
45
|
+
expect(data).toHaveProperty('status');
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('responds correctly to requests from allowed origins', async () => {
|
|
49
|
+
const c15t = c15tInstance(mockOptions);
|
|
50
|
+
const request = createTestRequest(undefined, undefined, {
|
|
51
|
+
origin: 'https://test.consent.io',
|
|
52
|
+
});
|
|
53
|
+
const response = await c15t.handler(request);
|
|
54
|
+
expect(response.status).toBe(200);
|
|
55
|
+
expect(response.headers.get('access-control-allow-origin')).toBe(
|
|
56
|
+
'https://test.consent.io'
|
|
57
|
+
);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('rejects requests from disallowed origins', async () => {
|
|
61
|
+
const c15t = c15tInstance(mockOptions);
|
|
62
|
+
const request = createTestRequest(undefined, undefined, {
|
|
63
|
+
origin: 'https://malicious-site.com',
|
|
64
|
+
});
|
|
65
|
+
const response = await c15t.handler(request);
|
|
66
|
+
expect(response.headers.get('access-control-allow-origin')).toBeNull();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('handles preflight requests correctly', async () => {
|
|
70
|
+
const c15t = c15tInstance(mockOptions);
|
|
71
|
+
const request = createTestRequest(undefined, 'OPTIONS', {
|
|
72
|
+
origin: 'https://test.consent.io',
|
|
73
|
+
'access-control-request-method': 'GET',
|
|
74
|
+
});
|
|
75
|
+
const response = await c15t.handler(request);
|
|
76
|
+
expect(response.status).toBe(204);
|
|
77
|
+
expect(response.headers.get('access-control-allow-origin')).toBe(
|
|
78
|
+
'https://test.consent.io'
|
|
79
|
+
);
|
|
80
|
+
expect(response.headers.get('access-control-allow-headers')).toContain(
|
|
81
|
+
'Content-Type, Authorization, x-request-id'
|
|
82
|
+
);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
describe('C15T /docs endpoint', () => {
|
|
87
|
+
it('GET /api/c15t/docs returns 200 and HTML', async () => {
|
|
88
|
+
const c15t = c15tInstance(mockOptions);
|
|
89
|
+
const request = createTestRequest('/api/c15t/docs');
|
|
90
|
+
const response = await c15t.handler(request);
|
|
91
|
+
expect(response.status).toBe(200);
|
|
92
|
+
const text = await response.text();
|
|
93
|
+
expect(text).toContain('<!doctype html>');
|
|
94
|
+
expect(response.headers.get('content-type')).toContain('text/html');
|
|
95
|
+
});
|
|
96
|
+
});
|
package/src/contracts/index.ts
CHANGED
package/src/core.ts
CHANGED
|
@@ -296,16 +296,31 @@ export const c15tInstance = <PluginTypes extends C15TPlugin[] = C15TPlugin[]>(
|
|
|
296
296
|
|
|
297
297
|
// Use oRPC handler to handle the request with our enhanced context
|
|
298
298
|
const handlerContext = orpcContext as Record<string, unknown>;
|
|
299
|
+
|
|
300
|
+
orpcContext.logger.debug?.('Handling prefix', {
|
|
301
|
+
prefix: (options.basePath as `/${string}`) || '/',
|
|
302
|
+
});
|
|
303
|
+
|
|
299
304
|
const { matched, response } = await rpcHandler.handle(request, {
|
|
300
|
-
prefix: '/',
|
|
305
|
+
prefix: (options.basePath as `/${string}`) || '/',
|
|
301
306
|
context: handlerContext,
|
|
302
307
|
});
|
|
303
308
|
|
|
304
309
|
// Return the response if handler matched
|
|
305
310
|
if (matched && response) {
|
|
311
|
+
orpcContext.logger.debug('Handler matched', {
|
|
312
|
+
request,
|
|
313
|
+
matched,
|
|
314
|
+
response,
|
|
315
|
+
});
|
|
306
316
|
return response;
|
|
307
317
|
}
|
|
308
318
|
|
|
319
|
+
orpcContext.logger.debug('No handler matched', {
|
|
320
|
+
request,
|
|
321
|
+
matched,
|
|
322
|
+
response,
|
|
323
|
+
});
|
|
309
324
|
// If no handler matched, return 404
|
|
310
325
|
return new Response('Not Found', { status: 404 });
|
|
311
326
|
};
|
|
@@ -316,6 +331,11 @@ export const c15tInstance = <PluginTypes extends C15TPlugin[] = C15TPlugin[]>(
|
|
|
316
331
|
const handler = async (request: Request): Promise<Response> => {
|
|
317
332
|
try {
|
|
318
333
|
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
|
+
});
|
|
319
339
|
|
|
320
340
|
// Check for OpenAPI spec or docs UI requests
|
|
321
341
|
const openApiResponse = await handleOpenApiSpecRequest(url);
|
|
@@ -335,6 +355,19 @@ export const c15tInstance = <PluginTypes extends C15TPlugin[] = C15TPlugin[]>(
|
|
|
335
355
|
}
|
|
336
356
|
const ctx = ctxResult.value;
|
|
337
357
|
|
|
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
|
+
|
|
338
371
|
// Handle API request
|
|
339
372
|
return await handleApiRequest(request, ctx);
|
|
340
373
|
} catch (error) {
|
|
@@ -4,12 +4,15 @@ import packageJson from '../../../package.json';
|
|
|
4
4
|
/**
|
|
5
5
|
* Default OpenAPI configuration
|
|
6
6
|
*/
|
|
7
|
-
export const createOpenAPIConfig = (options: C15TOptions) =>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
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
|
+
};
|
|
13
16
|
|
|
14
17
|
/**
|
|
15
18
|
* Default OpenAPI options
|
|
@@ -20,6 +23,6 @@ export const createDefaultOpenAPIOptions = (options: C15TOptions) => ({
|
|
|
20
23
|
version: packageJson.version,
|
|
21
24
|
description: 'API for consent management',
|
|
22
25
|
},
|
|
23
|
-
servers: [{ url: '/' }],
|
|
26
|
+
servers: [{ url: options.basePath || '/' }],
|
|
24
27
|
security: [{ bearerAuth: [] }],
|
|
25
28
|
});
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { getWithHooks } from '~/pkgs/data-model';
|
|
2
2
|
import type { Where } from '~/pkgs/db-adapters';
|
|
3
|
-
import type { GenericEndpointContext, RegistryContext } from '~/pkgs/types';
|
|
4
|
-
|
|
5
3
|
import { DoubleTieError, ERROR_CODES } from '~/pkgs/results';
|
|
4
|
+
import type { GenericEndpointContext, RegistryContext } from '~/pkgs/types';
|
|
6
5
|
import { validateEntityOutput } from '../definition';
|
|
7
6
|
import type { ConsentPolicy, PolicyType } from './schema';
|
|
8
7
|
|
|
@@ -31,12 +30,24 @@ import type { ConsentPolicy, PolicyType } from './schema';
|
|
|
31
30
|
*/
|
|
32
31
|
async function generatePolicyPlaceholder(name: string, date: Date) {
|
|
33
32
|
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()}`;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
.
|
|
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
|
+
|
|
40
51
|
return { content, contentHash };
|
|
41
52
|
}
|
|
42
53
|
|
|
@@ -271,55 +282,67 @@ export function policyRegistry({ adapter, ...ctx }: RegistryContext) {
|
|
|
271
282
|
// Use a transaction to prevent race conditions
|
|
272
283
|
return await adapter.transaction({
|
|
273
284
|
callback: async (txAdapter) => {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
285
|
+
try {
|
|
286
|
+
const now = new Date();
|
|
287
|
+
const txRegistry = policyRegistry({
|
|
288
|
+
adapter: txAdapter,
|
|
289
|
+
...ctx,
|
|
290
|
+
});
|
|
279
291
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
292
|
+
// Find latest policy with exact name match directly from database
|
|
293
|
+
const rawLatestPolicy = await txAdapter.findOne({
|
|
294
|
+
model: 'consentPolicy',
|
|
295
|
+
where: [
|
|
296
|
+
{ field: 'isActive', value: true },
|
|
297
|
+
{
|
|
298
|
+
field: 'type',
|
|
299
|
+
value: type,
|
|
300
|
+
},
|
|
301
|
+
],
|
|
302
|
+
sortBy: {
|
|
303
|
+
field: 'effectiveDate',
|
|
304
|
+
direction: 'desc',
|
|
288
305
|
},
|
|
289
|
-
|
|
290
|
-
sortBy: {
|
|
291
|
-
field: 'effectiveDate',
|
|
292
|
-
direction: 'desc',
|
|
293
|
-
},
|
|
294
|
-
});
|
|
306
|
+
});
|
|
295
307
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
308
|
+
const latestPolicy = rawLatestPolicy
|
|
309
|
+
? validateEntityOutput(
|
|
310
|
+
'consentPolicy',
|
|
311
|
+
rawLatestPolicy,
|
|
312
|
+
ctx.options
|
|
313
|
+
)
|
|
314
|
+
: null;
|
|
303
315
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
316
|
+
if (latestPolicy) {
|
|
317
|
+
return latestPolicy;
|
|
318
|
+
}
|
|
307
319
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
320
|
+
// Generate policy content and hash
|
|
321
|
+
const { content: defaultContent, contentHash } =
|
|
322
|
+
await generatePolicyPlaceholder(type, now);
|
|
311
323
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
324
|
+
return txRegistry.createConsentPolicy({
|
|
325
|
+
version: '1.0.0',
|
|
326
|
+
type,
|
|
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);
|
|
338
|
+
|
|
339
|
+
// Rethrow as a DoubleTieError with appropriate context
|
|
340
|
+
throw new DoubleTieError('Failed to find or create policy', {
|
|
341
|
+
code: ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
342
|
+
status: 500,
|
|
343
|
+
cause: error instanceof Error ? error : new Error(String(error)),
|
|
344
|
+
});
|
|
345
|
+
}
|
|
323
346
|
},
|
|
324
347
|
});
|
|
325
348
|
},
|
package/.turbo/turbo-fmt.log
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
> @c15t/backend@1.2.0-canary.7 fmt /Users/christopherburns/glados/k/c15t/packages/backend
|
|
4
|
-
> pnpm biome format --write . && biome check --formatter-enabled=false --linter-enabled=false --organize-imports-enabled=true --write
|
|
5
|
-
|
|
6
|
-
[0m[34mFormatted [0m[0m[34m162[0m[0m[34m [0m[0m[34mfiles[0m[0m[34m in [0m[0m[34m39[0m[0m[2m[34mms[0m[0m[34m.[0m[0m[34m No fixes applied.[0m
|
|
7
|
-
[0m[34mChecked [0m[0m[34m162[0m[0m[34m [0m[0m[34mfiles[0m[0m[34m in [0m[0m[34m15[0m[0m[2m[34mms[0m[0m[34m.[0m[0m[34m No fixes applied.[0m
|