@c15t/backend 1.2.0-canary.9 → 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 +94 -47
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +94 -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 +7 -2
- 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 +29 -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
|
@@ -1256,10 +1256,19 @@ function consentRegistry({ adapter, ...ctx }) {
|
|
|
1256
1256
|
}
|
|
1257
1257
|
async function generatePolicyPlaceholder(name, date) {
|
|
1258
1258
|
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()}`;
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1259
|
+
let contentHash;
|
|
1260
|
+
try {
|
|
1261
|
+
const encoder = new TextEncoder();
|
|
1262
|
+
const data = encoder.encode(content);
|
|
1263
|
+
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
|
|
1264
|
+
contentHash = Array.from(new Uint8Array(hashBuffer)).map((b)=>b.toString(16).padStart(2, '0')).join('');
|
|
1265
|
+
} catch (error) {
|
|
1266
|
+
throw new error_class_DoubleTieError('Failed to generate policy content hash', {
|
|
1267
|
+
code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
1268
|
+
status: 500,
|
|
1269
|
+
cause: error instanceof Error ? error : new Error(String(error))
|
|
1270
|
+
});
|
|
1271
|
+
}
|
|
1263
1272
|
return {
|
|
1264
1273
|
content,
|
|
1265
1274
|
contentHash
|
|
@@ -1321,42 +1330,51 @@ function policyRegistry({ adapter, ...ctx }) {
|
|
|
1321
1330
|
},
|
|
1322
1331
|
findOrCreatePolicy: async (type)=>await adapter.transaction({
|
|
1323
1332
|
callback: async (txAdapter)=>{
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1333
|
+
try {
|
|
1334
|
+
const now = new Date();
|
|
1335
|
+
const txRegistry = policyRegistry({
|
|
1336
|
+
adapter: txAdapter,
|
|
1337
|
+
...ctx
|
|
1338
|
+
});
|
|
1339
|
+
const rawLatestPolicy = await txAdapter.findOne({
|
|
1340
|
+
model: 'consentPolicy',
|
|
1341
|
+
where: [
|
|
1342
|
+
{
|
|
1343
|
+
field: 'isActive',
|
|
1344
|
+
value: true
|
|
1345
|
+
},
|
|
1346
|
+
{
|
|
1347
|
+
field: 'type',
|
|
1348
|
+
value: type
|
|
1349
|
+
}
|
|
1350
|
+
],
|
|
1351
|
+
sortBy: {
|
|
1352
|
+
field: 'effectiveDate',
|
|
1353
|
+
direction: 'desc'
|
|
1339
1354
|
}
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1355
|
+
});
|
|
1356
|
+
const latestPolicy = rawLatestPolicy ? validateEntityOutput('consentPolicy', rawLatestPolicy, ctx.options) : null;
|
|
1357
|
+
if (latestPolicy) return latestPolicy;
|
|
1358
|
+
const { content: defaultContent, contentHash } = await generatePolicyPlaceholder(type, now);
|
|
1359
|
+
return txRegistry.createConsentPolicy({
|
|
1360
|
+
version: '1.0.0',
|
|
1361
|
+
type,
|
|
1362
|
+
name: type,
|
|
1363
|
+
effectiveDate: now,
|
|
1364
|
+
content: defaultContent,
|
|
1365
|
+
contentHash,
|
|
1366
|
+
isActive: true,
|
|
1367
|
+
updatedAt: now,
|
|
1368
|
+
expirationDate: null
|
|
1369
|
+
});
|
|
1370
|
+
} catch (error) {
|
|
1371
|
+
ctx.logger.error('Error in findOrCreatePolicy transaction:', error);
|
|
1372
|
+
throw new error_class_DoubleTieError('Failed to find or create policy', {
|
|
1373
|
+
code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
1374
|
+
status: 500,
|
|
1375
|
+
cause: error instanceof Error ? error : new Error(String(error))
|
|
1376
|
+
});
|
|
1377
|
+
}
|
|
1360
1378
|
}
|
|
1361
1379
|
})
|
|
1362
1380
|
};
|
|
@@ -1198,10 +1198,19 @@ function consentRegistry({ adapter, ...ctx }) {
|
|
|
1198
1198
|
}
|
|
1199
1199
|
async function generatePolicyPlaceholder(name, date) {
|
|
1200
1200
|
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()}`;
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1201
|
+
let contentHash;
|
|
1202
|
+
try {
|
|
1203
|
+
const encoder = new TextEncoder();
|
|
1204
|
+
const data = encoder.encode(content);
|
|
1205
|
+
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
|
|
1206
|
+
contentHash = Array.from(new Uint8Array(hashBuffer)).map((b)=>b.toString(16).padStart(2, '0')).join('');
|
|
1207
|
+
} catch (error) {
|
|
1208
|
+
throw new error_class_DoubleTieError('Failed to generate policy content hash', {
|
|
1209
|
+
code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
1210
|
+
status: 500,
|
|
1211
|
+
cause: error instanceof Error ? error : new Error(String(error))
|
|
1212
|
+
});
|
|
1213
|
+
}
|
|
1205
1214
|
return {
|
|
1206
1215
|
content,
|
|
1207
1216
|
contentHash
|
|
@@ -1263,42 +1272,51 @@ function policyRegistry({ adapter, ...ctx }) {
|
|
|
1263
1272
|
},
|
|
1264
1273
|
findOrCreatePolicy: async (type)=>await adapter.transaction({
|
|
1265
1274
|
callback: async (txAdapter)=>{
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1275
|
+
try {
|
|
1276
|
+
const now = new Date();
|
|
1277
|
+
const txRegistry = policyRegistry({
|
|
1278
|
+
adapter: txAdapter,
|
|
1279
|
+
...ctx
|
|
1280
|
+
});
|
|
1281
|
+
const rawLatestPolicy = await txAdapter.findOne({
|
|
1282
|
+
model: 'consentPolicy',
|
|
1283
|
+
where: [
|
|
1284
|
+
{
|
|
1285
|
+
field: 'isActive',
|
|
1286
|
+
value: true
|
|
1287
|
+
},
|
|
1288
|
+
{
|
|
1289
|
+
field: 'type',
|
|
1290
|
+
value: type
|
|
1291
|
+
}
|
|
1292
|
+
],
|
|
1293
|
+
sortBy: {
|
|
1294
|
+
field: 'effectiveDate',
|
|
1295
|
+
direction: 'desc'
|
|
1281
1296
|
}
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1297
|
+
});
|
|
1298
|
+
const latestPolicy = rawLatestPolicy ? validateEntityOutput('consentPolicy', rawLatestPolicy, ctx.options) : null;
|
|
1299
|
+
if (latestPolicy) return latestPolicy;
|
|
1300
|
+
const { content: defaultContent, contentHash } = await generatePolicyPlaceholder(type, now);
|
|
1301
|
+
return txRegistry.createConsentPolicy({
|
|
1302
|
+
version: '1.0.0',
|
|
1303
|
+
type,
|
|
1304
|
+
name: type,
|
|
1305
|
+
effectiveDate: now,
|
|
1306
|
+
content: defaultContent,
|
|
1307
|
+
contentHash,
|
|
1308
|
+
isActive: true,
|
|
1309
|
+
updatedAt: now,
|
|
1310
|
+
expirationDate: null
|
|
1311
|
+
});
|
|
1312
|
+
} catch (error) {
|
|
1313
|
+
ctx.logger.error('Error in findOrCreatePolicy transaction:', error);
|
|
1314
|
+
throw new error_class_DoubleTieError('Failed to find or create policy', {
|
|
1315
|
+
code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
1316
|
+
status: 500,
|
|
1317
|
+
cause: error instanceof Error ? error : new Error(String(error))
|
|
1318
|
+
});
|
|
1319
|
+
}
|
|
1302
1320
|
}
|
|
1303
1321
|
})
|
|
1304
1322
|
};
|
package/dist/router.cjs
CHANGED
|
@@ -1167,7 +1167,9 @@ const consentHandlers = {
|
|
|
1167
1167
|
showBanner: show_banner_handler_showConsentBanner,
|
|
1168
1168
|
verify: verifyConsent
|
|
1169
1169
|
};
|
|
1170
|
-
var package_namespaceObject =
|
|
1170
|
+
var package_namespaceObject = {
|
|
1171
|
+
i8: "1.2.0"
|
|
1172
|
+
};
|
|
1171
1173
|
const statusHandler = os.meta.status.handler(({ context })=>{
|
|
1172
1174
|
const typedContext = context;
|
|
1173
1175
|
const headers = typedContext.headers;
|
package/dist/router.js
CHANGED
|
@@ -1129,7 +1129,9 @@ const consentHandlers = {
|
|
|
1129
1129
|
showBanner: show_banner_handler_showConsentBanner,
|
|
1130
1130
|
verify: verifyConsent
|
|
1131
1131
|
};
|
|
1132
|
-
var package_namespaceObject =
|
|
1132
|
+
var package_namespaceObject = {
|
|
1133
|
+
i8: "1.2.0"
|
|
1134
|
+
};
|
|
1133
1135
|
const statusHandler = os.meta.status.handler(({ context })=>{
|
|
1134
1136
|
const typedContext = context;
|
|
1135
1137
|
const headers = typedContext.headers;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/schema/consent-policy/registry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/schema/consent-policy/registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE5E,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAgD1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,cAAc,CAAC,EAAE,OAAO,EAAE,GAAG,GAAG,EAAE,EAAE,eAAe;IAGjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;kCAEM,IAAI,CAAC,aAAa,EAAE,IAAI,GAAG,WAAW,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,YAC9D,sBAAsB;;;;;;;;;;;;;IAwBjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;4BAEM;QACP,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,eAAe,CAAC,EAAE,OAAO,CAAC;KAC1B;;;;;;;;;;;;;IAuCF;;;;;;;;;;;;;;;;;;;;;;OAsBG;sCACqC,MAAM;;;;;;;;;;;;;IAe9C;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;+BAC8B,UAAU;;;;;;;;;;;;;EAuE5C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-registry.d.ts","sourceRoot":"","sources":["../../src/schema/create-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAWpD,eAAO,MAAM,cAAc,GAAI,KAAK,eAAe;;;;;;;;;;;iBAUmtE,CAAC;yBAA8B,CAAC;iBAAsB,CAAC;eAAoB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"create-registry.d.ts","sourceRoot":"","sources":["../../src/schema/create-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAWpD,eAAO,MAAM,cAAc,GAAI,KAAK,eAAe;;;;;;;;;;;iBAUmtE,CAAC;yBAA8B,CAAC;iBAAsB,CAAC;eAAoB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAA+jI,CAAC;eAAqB,CAAC;uBAA6B,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CADr8M,CAAC"}
|
package/dist/schema/index.cjs
CHANGED
|
@@ -1139,10 +1139,19 @@ function consentRegistry({ adapter, ...ctx }) {
|
|
|
1139
1139
|
}
|
|
1140
1140
|
async function generatePolicyPlaceholder(name, date) {
|
|
1141
1141
|
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()}`;
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1142
|
+
let contentHash;
|
|
1143
|
+
try {
|
|
1144
|
+
const encoder = new TextEncoder();
|
|
1145
|
+
const data = encoder.encode(content);
|
|
1146
|
+
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
|
|
1147
|
+
contentHash = Array.from(new Uint8Array(hashBuffer)).map((b)=>b.toString(16).padStart(2, '0')).join('');
|
|
1148
|
+
} catch (error) {
|
|
1149
|
+
throw new error_class_DoubleTieError('Failed to generate policy content hash', {
|
|
1150
|
+
code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
1151
|
+
status: 500,
|
|
1152
|
+
cause: error instanceof Error ? error : new Error(String(error))
|
|
1153
|
+
});
|
|
1154
|
+
}
|
|
1146
1155
|
return {
|
|
1147
1156
|
content,
|
|
1148
1157
|
contentHash
|
|
@@ -1204,42 +1213,51 @@ function policyRegistry({ adapter, ...ctx }) {
|
|
|
1204
1213
|
},
|
|
1205
1214
|
findOrCreatePolicy: async (type)=>await adapter.transaction({
|
|
1206
1215
|
callback: async (txAdapter)=>{
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1216
|
+
try {
|
|
1217
|
+
const now = new Date();
|
|
1218
|
+
const txRegistry = policyRegistry({
|
|
1219
|
+
adapter: txAdapter,
|
|
1220
|
+
...ctx
|
|
1221
|
+
});
|
|
1222
|
+
const rawLatestPolicy = await txAdapter.findOne({
|
|
1223
|
+
model: 'consentPolicy',
|
|
1224
|
+
where: [
|
|
1225
|
+
{
|
|
1226
|
+
field: 'isActive',
|
|
1227
|
+
value: true
|
|
1228
|
+
},
|
|
1229
|
+
{
|
|
1230
|
+
field: 'type',
|
|
1231
|
+
value: type
|
|
1232
|
+
}
|
|
1233
|
+
],
|
|
1234
|
+
sortBy: {
|
|
1235
|
+
field: 'effectiveDate',
|
|
1236
|
+
direction: 'desc'
|
|
1222
1237
|
}
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1238
|
+
});
|
|
1239
|
+
const latestPolicy = rawLatestPolicy ? validateEntityOutput('consentPolicy', rawLatestPolicy, ctx.options) : null;
|
|
1240
|
+
if (latestPolicy) return latestPolicy;
|
|
1241
|
+
const { content: defaultContent, contentHash } = await generatePolicyPlaceholder(type, now);
|
|
1242
|
+
return txRegistry.createConsentPolicy({
|
|
1243
|
+
version: '1.0.0',
|
|
1244
|
+
type,
|
|
1245
|
+
name: type,
|
|
1246
|
+
effectiveDate: now,
|
|
1247
|
+
content: defaultContent,
|
|
1248
|
+
contentHash,
|
|
1249
|
+
isActive: true,
|
|
1250
|
+
updatedAt: now,
|
|
1251
|
+
expirationDate: null
|
|
1252
|
+
});
|
|
1253
|
+
} catch (error) {
|
|
1254
|
+
ctx.logger.error('Error in findOrCreatePolicy transaction:', error);
|
|
1255
|
+
throw new error_class_DoubleTieError('Failed to find or create policy', {
|
|
1256
|
+
code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
1257
|
+
status: 500,
|
|
1258
|
+
cause: error instanceof Error ? error : new Error(String(error))
|
|
1259
|
+
});
|
|
1260
|
+
}
|
|
1243
1261
|
}
|
|
1244
1262
|
})
|
|
1245
1263
|
};
|
package/dist/schema/index.js
CHANGED
|
@@ -1079,10 +1079,19 @@ function consentRegistry({ adapter, ...ctx }) {
|
|
|
1079
1079
|
}
|
|
1080
1080
|
async function generatePolicyPlaceholder(name, date) {
|
|
1081
1081
|
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()}`;
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1082
|
+
let contentHash;
|
|
1083
|
+
try {
|
|
1084
|
+
const encoder = new TextEncoder();
|
|
1085
|
+
const data = encoder.encode(content);
|
|
1086
|
+
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
|
|
1087
|
+
contentHash = Array.from(new Uint8Array(hashBuffer)).map((b)=>b.toString(16).padStart(2, '0')).join('');
|
|
1088
|
+
} catch (error) {
|
|
1089
|
+
throw new error_class_DoubleTieError('Failed to generate policy content hash', {
|
|
1090
|
+
code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
1091
|
+
status: 500,
|
|
1092
|
+
cause: error instanceof Error ? error : new Error(String(error))
|
|
1093
|
+
});
|
|
1094
|
+
}
|
|
1086
1095
|
return {
|
|
1087
1096
|
content,
|
|
1088
1097
|
contentHash
|
|
@@ -1144,42 +1153,51 @@ function policyRegistry({ adapter, ...ctx }) {
|
|
|
1144
1153
|
},
|
|
1145
1154
|
findOrCreatePolicy: async (type)=>await adapter.transaction({
|
|
1146
1155
|
callback: async (txAdapter)=>{
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1156
|
+
try {
|
|
1157
|
+
const now = new Date();
|
|
1158
|
+
const txRegistry = policyRegistry({
|
|
1159
|
+
adapter: txAdapter,
|
|
1160
|
+
...ctx
|
|
1161
|
+
});
|
|
1162
|
+
const rawLatestPolicy = await txAdapter.findOne({
|
|
1163
|
+
model: 'consentPolicy',
|
|
1164
|
+
where: [
|
|
1165
|
+
{
|
|
1166
|
+
field: 'isActive',
|
|
1167
|
+
value: true
|
|
1168
|
+
},
|
|
1169
|
+
{
|
|
1170
|
+
field: 'type',
|
|
1171
|
+
value: type
|
|
1172
|
+
}
|
|
1173
|
+
],
|
|
1174
|
+
sortBy: {
|
|
1175
|
+
field: 'effectiveDate',
|
|
1176
|
+
direction: 'desc'
|
|
1162
1177
|
}
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1178
|
+
});
|
|
1179
|
+
const latestPolicy = rawLatestPolicy ? validateEntityOutput('consentPolicy', rawLatestPolicy, ctx.options) : null;
|
|
1180
|
+
if (latestPolicy) return latestPolicy;
|
|
1181
|
+
const { content: defaultContent, contentHash } = await generatePolicyPlaceholder(type, now);
|
|
1182
|
+
return txRegistry.createConsentPolicy({
|
|
1183
|
+
version: '1.0.0',
|
|
1184
|
+
type,
|
|
1185
|
+
name: type,
|
|
1186
|
+
effectiveDate: now,
|
|
1187
|
+
content: defaultContent,
|
|
1188
|
+
contentHash,
|
|
1189
|
+
isActive: true,
|
|
1190
|
+
updatedAt: now,
|
|
1191
|
+
expirationDate: null
|
|
1192
|
+
});
|
|
1193
|
+
} catch (error) {
|
|
1194
|
+
ctx.logger.error('Error in findOrCreatePolicy transaction:', error);
|
|
1195
|
+
throw new error_class_DoubleTieError('Failed to find or create policy', {
|
|
1196
|
+
code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
1197
|
+
status: 500,
|
|
1198
|
+
cause: error instanceof Error ? error : new Error(String(error))
|
|
1199
|
+
});
|
|
1200
|
+
}
|
|
1183
1201
|
}
|
|
1184
1202
|
})
|
|
1185
1203
|
};
|
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",
|
|
@@ -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
|
+
});
|