@c15t/backend 2.0.0-rc.6 → 2.0.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.
Files changed (54) hide show
  1. package/README.md +3 -3
  2. package/dist/302.js +2 -3
  3. package/dist/{364.js → 915.js} +656 -25
  4. package/dist/core.cjs +497 -15
  5. package/dist/core.js +8 -156
  6. package/dist/db/schema.cjs +4 -0
  7. package/dist/db/schema.js +3 -2
  8. package/dist/edge.cjs +8 -8
  9. package/dist/edge.js +3 -3
  10. package/dist/router.cjs +253 -42
  11. package/dist/router.js +1 -1
  12. package/dist-types/cache/gvl-resolver.d.ts +1 -1
  13. package/dist-types/db/registry/consent-policy.d.ts +57 -1
  14. package/dist-types/db/registry/index.d.ts +43 -1
  15. package/dist-types/db/registry/types.d.ts +2 -1
  16. package/dist-types/db/schema/1.0.0/consent.d.ts +1 -1
  17. package/dist-types/db/schema/2.0.0/audit-log.d.ts +1 -1
  18. package/dist-types/db/schema/2.0.0/consent-policy.d.ts +3 -2
  19. package/dist-types/db/schema/2.0.0/consent-purpose.d.ts +1 -1
  20. package/dist-types/db/schema/2.0.0/consent.d.ts +1 -1
  21. package/dist-types/db/schema/2.0.0/domain.d.ts +1 -1
  22. package/dist-types/db/schema/2.0.0/index.d.ts +7 -0
  23. package/dist-types/db/schema/2.0.0/runtime-policy-decision.d.ts +1 -1
  24. package/dist-types/db/schema/2.0.0/subject.d.ts +1 -1
  25. package/dist-types/db/schema/index.d.ts +14 -0
  26. package/dist-types/edge/index.d.ts +2 -2
  27. package/dist-types/edge/init-handler.d.ts +5 -3
  28. package/dist-types/edge/resolve-consent.d.ts +6 -6
  29. package/dist-types/edge/types.d.ts +1 -1
  30. package/dist-types/handlers/init/index.d.ts +4 -4
  31. package/dist-types/handlers/init/policy.d.ts +1 -1
  32. package/dist-types/handlers/init/resolve-init.d.ts +2 -2
  33. package/dist-types/handlers/init/translations.d.ts +1 -1
  34. package/dist-types/handlers/legal-document/current.handler.d.ts +11 -0
  35. package/dist-types/handlers/legal-document/snapshot.d.ts +39 -0
  36. package/dist-types/handlers/subject/get.handler.d.ts +3 -0
  37. package/dist-types/handlers/subject/list.handler.d.ts +3 -0
  38. package/dist-types/handlers/utils/consent-enrichment.d.ts +3 -0
  39. package/dist-types/middleware/cors/is-origin-trusted.d.ts +1 -1
  40. package/dist-types/policies/builder.d.ts +7 -7
  41. package/dist-types/policies/defaults.d.ts +2 -2
  42. package/dist-types/policies/matchers.d.ts +2 -2
  43. package/dist-types/routes/index.d.ts +1 -0
  44. package/dist-types/routes/legal-document.d.ts +7 -0
  45. package/dist-types/types/index.d.ts +39 -18
  46. package/dist-types/utils/instrumentation.d.ts +2 -2
  47. package/dist-types/utils/logger.d.ts +1 -1
  48. package/dist-types/version.d.ts +1 -1
  49. package/docs/api/configuration.md +24 -13
  50. package/docs/guides/database-setup.md +4 -4
  51. package/docs/guides/edge-deployment.md +18 -15
  52. package/docs/guides/iab-tcf.md +4 -4
  53. package/docs/quickstart.md +9 -9
  54. package/package.json +8 -8
package/dist/core.js CHANGED
@@ -5,13 +5,12 @@ import { Hono } from "hono";
5
5
  import { cors } from "hono/cors";
6
6
  import { HTTPException } from "hono/http-exception";
7
7
  import { openAPIRouteHandler } from "hono-openapi";
8
- import base_x from "base-x";
9
8
  import { compactDefined, dedupeTrimmedStrings, policyPackPresets } from "@c15t/schema";
10
9
  import { EEA_COUNTRY_CODES, EU_COUNTRY_CODES, POLICY_MATCH_DATASET_VERSION, UK_COUNTRY_CODES, policyMatchers } from "@c15t/schema/types";
11
- import { version as version_version, extractErrorMessage, withDatabaseSpan, getTraceContext as create_telemetry_options_getTraceContext, createRequestSpan, handleSpanError, createTelemetryOptions, getMetrics, isTelemetryEnabled, withSpanContext } from "./302.js";
10
+ import { extractErrorMessage, withDatabaseSpan, getTraceContext as create_telemetry_options_getTraceContext, createRequestSpan, handleSpanError, createTelemetryOptions, getMetrics, isTelemetryEnabled, withSpanContext } from "./302.js";
11
+ import { createLegalDocumentRoutes, createSubjectRoutes, generateUniqueId, createStatusRoute, createInitRoute, createConsentRoutes, policyRegistry } from "./915.js";
12
12
  import { validateMessages, inspectPolicies as policy_inspectPolicies } from "./583.js";
13
13
  import { DB } from "./db/schema.js";
14
- import { createStatusRoute, createInitRoute, createConsentRoutes, createSubjectRoutes } from "./364.js";
15
14
  function extractBearerToken(authHeader) {
16
15
  if (!authHeader) return null;
17
16
  const parts = authHeader.split(' ');
@@ -252,155 +251,6 @@ function getIpAddress(req, options) {
252
251
  }
253
252
  return null;
254
253
  }
255
- const prefixes = {
256
- auditLog: 'log',
257
- consent: 'cns',
258
- consentPolicy: 'pol',
259
- consentPurpose: 'pur',
260
- domain: 'dom',
261
- runtimePolicyDecision: 'rpd',
262
- subject: 'sub'
263
- };
264
- const b58 = base_x('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
265
- function generateId(model) {
266
- const buf = crypto.getRandomValues(new Uint8Array(20));
267
- const prefix = prefixes[model];
268
- const EPOCH_TIMESTAMP = 1700000000000;
269
- const t = Date.now() - EPOCH_TIMESTAMP;
270
- const high = Math.floor(t / 0x100000000);
271
- const low = t >>> 0;
272
- buf[0] = high >>> 24 & 255;
273
- buf[1] = high >>> 16 & 255;
274
- buf[2] = high >>> 8 & 255;
275
- buf[3] = 255 & high;
276
- buf[4] = low >>> 24 & 255;
277
- buf[5] = low >>> 16 & 255;
278
- buf[6] = low >>> 8 & 255;
279
- buf[7] = 255 & low;
280
- return `${prefix}_${b58.encode(buf)}`;
281
- }
282
- async function generateUniqueId(db, model, ctx, options = {}) {
283
- const { maxRetries = 10, attempt = 0, baseDelay = 5 } = options;
284
- if (attempt >= maxRetries) {
285
- const error = new Error(`Failed to generate unique ID for ${model} after ${maxRetries} attempts`);
286
- ctx?.logger?.error?.('ID generation failed', {
287
- model,
288
- maxRetries
289
- });
290
- throw error;
291
- }
292
- const id = generateId(model);
293
- try {
294
- const existing = await db.findFirst(model, {
295
- where: (b)=>b('id', '=', id)
296
- });
297
- if (existing) {
298
- ctx?.logger?.debug?.('ID conflict detected', {
299
- id,
300
- model,
301
- attempt: attempt + 1,
302
- maxRetries
303
- });
304
- const delay = Math.min(baseDelay * 2 ** attempt, 1000);
305
- await new Promise((resolve)=>setTimeout(resolve, delay));
306
- return generateUniqueId(db, model, ctx, {
307
- maxRetries,
308
- attempt: attempt + 1,
309
- baseDelay
310
- });
311
- }
312
- return id;
313
- } catch (error) {
314
- ctx?.logger?.error?.('Error checking ID uniqueness', {
315
- error: error.message,
316
- model,
317
- attempt
318
- });
319
- if (attempt < maxRetries - 1) {
320
- const delay = Math.min(baseDelay * 2 ** attempt, 2000);
321
- await new Promise((resolve)=>setTimeout(resolve, delay));
322
- return generateUniqueId(db, model, ctx, {
323
- maxRetries,
324
- attempt: attempt + 1,
325
- baseDelay
326
- });
327
- }
328
- throw error;
329
- }
330
- }
331
- function policyRegistry({ db, ctx }) {
332
- const { logger } = ctx;
333
- return {
334
- findConsentPolicyById: async (policyId)=>{
335
- const start = Date.now();
336
- try {
337
- const result = await withDatabaseSpan({
338
- operation: 'find',
339
- entity: 'consentPolicy'
340
- }, async ()=>{
341
- const policy = await db.findFirst('consentPolicy', {
342
- where: (b)=>b('id', '=', policyId)
343
- });
344
- return policy;
345
- });
346
- getMetrics()?.recordDbQuery({
347
- operation: 'find',
348
- entity: 'consentPolicy'
349
- }, Date.now() - start);
350
- return result;
351
- } catch (error) {
352
- getMetrics()?.recordDbError({
353
- operation: 'find',
354
- entity: 'consentPolicy'
355
- });
356
- throw error;
357
- }
358
- },
359
- findOrCreatePolicy: async (type)=>{
360
- const start = Date.now();
361
- try {
362
- const result = await withDatabaseSpan({
363
- operation: 'findOrCreate',
364
- entity: 'consentPolicy'
365
- }, async ()=>{
366
- const existingPolicy = await db.findFirst('consentPolicy', {
367
- where: (b)=>b.and(b('isActive', '=', true), b('type', '=', type)),
368
- orderBy: [
369
- 'effectiveDate',
370
- 'desc'
371
- ]
372
- });
373
- if (existingPolicy) {
374
- logger.debug('Found existing policy', {
375
- type,
376
- policyId: existingPolicy.id
377
- });
378
- return existingPolicy;
379
- }
380
- const policy = await db.create('consentPolicy', {
381
- id: await generateUniqueId(db, 'consentPolicy', ctx),
382
- version: '1.0.0',
383
- type,
384
- effectiveDate: new Date(),
385
- isActive: true
386
- });
387
- return policy;
388
- });
389
- getMetrics()?.recordDbQuery({
390
- operation: 'findOrCreate',
391
- entity: 'consentPolicy'
392
- }, Date.now() - start);
393
- return result;
394
- } catch (error) {
395
- getMetrics()?.recordDbError({
396
- operation: 'findOrCreate',
397
- entity: 'consentPolicy'
398
- });
399
- throw error;
400
- }
401
- }
402
- };
403
- }
404
254
  function consentPurposeRegistry({ db, ctx }) {
405
255
  const { logger } = ctx;
406
256
  return {
@@ -767,7 +617,8 @@ const init = (options)=>{
767
617
  registry: createRegistry({
768
618
  db: orm,
769
619
  ctx: {
770
- logger
620
+ logger,
621
+ tenantId: options.tenantId
771
622
  }
772
623
  })
773
624
  };
@@ -914,7 +765,7 @@ const c15tInstance = (options)=>{
914
765
  openapi: '3.1.0',
915
766
  info: {
916
767
  title: options.appName || 'c15t API',
917
- version: version_version,
768
+ version: "2.0.0",
918
769
  description: 'API for consent management'
919
770
  },
920
771
  servers: [
@@ -939,6 +790,7 @@ const c15tInstance = (options)=>{
939
790
  }));
940
791
  }
941
792
  app.route('/init', createInitRoute(options));
793
+ app.route('/legal-documents', createLegalDocumentRoutes());
942
794
  app.route('/subjects', createSubjectRoutes());
943
795
  app.route('/consents', createConsentRoutes());
944
796
  app.route('/status', createStatusRoute());
@@ -1027,7 +879,7 @@ const c15tInstance = (options)=>{
1027
879
  getDocsUI
1028
880
  };
1029
881
  };
882
+ var core_version = "2.0.0";
1030
883
  export { defineConfig } from "./define-config.js";
1031
884
  export { inspectPolicies } from "./583.js";
1032
- export { version } from "./302.js";
1033
- export { EEA_COUNTRY_CODES, EU_COUNTRY_CODES, POLICY_MATCH_DATASET_VERSION, UK_COUNTRY_CODES, c15tInstance, policyBuilder, policyMatchers, policyPackPresets };
885
+ export { EEA_COUNTRY_CODES, EU_COUNTRY_CODES, POLICY_MATCH_DATASET_VERSION, UK_COUNTRY_CODES, c15tInstance, core_version as version, policyBuilder, policyMatchers, policyPackPresets };
@@ -46,6 +46,7 @@ var __webpack_exports__ = {};
46
46
  domainTable: ()=>domain_domainTable,
47
47
  DB: ()=>DB,
48
48
  PolicyTypeSchema: ()=>PolicyTypeSchema,
49
+ legalDocumentPolicyTypeSchema: ()=>schema_.legalDocumentPolicyTypeSchema,
49
50
  auditLogSchema: ()=>schema_.auditLogSchema,
50
51
  consentPolicySchema: ()=>schema_.consentPolicySchema,
51
52
  consentTable: ()=>consent_consentTable,
@@ -235,6 +236,7 @@ var __webpack_exports__ = {};
235
236
  id: (0, schema_namespaceObject.idColumn)('id', 'varchar(255)'),
236
237
  version: (0, schema_namespaceObject.column)('version', 'string'),
237
238
  type: (0, schema_namespaceObject.column)('type', 'string'),
239
+ hash: (0, schema_namespaceObject.column)('hash', 'string').nullable(),
238
240
  effectiveDate: (0, schema_namespaceObject.column)('effectiveDate', 'timestamp'),
239
241
  isActive: (0, schema_namespaceObject.column)('isActive', 'bool').defaultTo$(()=>true),
240
242
  createdAt: (0, schema_namespaceObject.column)('createdAt', 'timestamp').defaultTo$('now'),
@@ -363,6 +365,7 @@ exports.consentSchema = __webpack_exports__.consentSchema;
363
365
  exports.consentTable = __webpack_exports__.consentTable;
364
366
  exports.domainSchema = __webpack_exports__.domainSchema;
365
367
  exports.domainTable = __webpack_exports__.domainTable;
368
+ exports.legalDocumentPolicyTypeSchema = __webpack_exports__.legalDocumentPolicyTypeSchema;
366
369
  exports.policyTypeSchema = __webpack_exports__.policyTypeSchema;
367
370
  exports.runtimePolicyDecisionSchema = __webpack_exports__.runtimePolicyDecisionSchema;
368
371
  exports.runtimePolicyDecisionTable = __webpack_exports__.runtimePolicyDecisionTable;
@@ -383,6 +386,7 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
383
386
  "consentTable",
384
387
  "domainSchema",
385
388
  "domainTable",
389
+ "legalDocumentPolicyTypeSchema",
386
390
  "policyTypeSchema",
387
391
  "runtimePolicyDecisionSchema",
388
392
  "runtimePolicyDecisionTable",
package/dist/db/schema.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { fumadb } from "fumadb";
2
2
  import { column, idColumn, schema, table } from "fumadb/schema";
3
- import { auditLogSchema, consentPolicySchema, consentPurposeSchema, consentSchema, domainSchema, policyTypeSchema, runtimePolicyDecisionSchema, subjectSchema } from "@c15t/schema";
3
+ import { auditLogSchema, consentPolicySchema, consentPurposeSchema, consentSchema, domainSchema, legalDocumentPolicyTypeSchema, policyTypeSchema, runtimePolicyDecisionSchema, subjectSchema } from "@c15t/schema";
4
4
  const auditLogTable = table('auditLog', {
5
5
  id: idColumn('id', 'varchar(255)'),
6
6
  entityType: column('entityType', 'string'),
@@ -174,6 +174,7 @@ const consent_policy_consentPolicyTable = table('consentPolicy', {
174
174
  id: idColumn('id', 'varchar(255)'),
175
175
  version: column('version', 'string'),
176
176
  type: column('type', 'string'),
177
+ hash: column('hash', 'string').nullable(),
177
178
  effectiveDate: column('effectiveDate', 'timestamp'),
178
179
  isActive: column('isActive', 'bool').defaultTo$(()=>true),
179
180
  createdAt: column('createdAt', 'timestamp').defaultTo$('now'),
@@ -288,4 +289,4 @@ const LatestDB = fumadb({
288
289
  v2
289
290
  ]
290
291
  });
291
- export { DB, LatestDB, PolicyTypeSchema, auditLogSchema, audit_log_auditLogTable as auditLogTable, consentPolicySchema, consentPurposeSchema, consentSchema, consent_consentTable as consentTable, consent_policy_consentPolicyTable as consentPolicyTable, consent_purpose_consentPurposeTable as consentPurposeTable, domainSchema, domain_domainTable as domainTable, policyTypeSchema, runtimePolicyDecisionSchema, runtimePolicyDecisionTable, subjectSchema, subject_subjectTable as subjectTable, v2 };
292
+ export { DB, LatestDB, PolicyTypeSchema, auditLogSchema, audit_log_auditLogTable as auditLogTable, consentPolicySchema, consentPurposeSchema, consentSchema, consent_consentTable as consentTable, consent_policy_consentPolicyTable as consentPolicyTable, consent_purpose_consentPurposeTable as consentPurposeTable, domainSchema, domain_domainTable as domainTable, legalDocumentPolicyTypeSchema, policyTypeSchema, runtimePolicyDecisionSchema, runtimePolicyDecisionTable, subjectSchema, subject_subjectTable as subjectTable, v2 };
package/dist/edge.cjs CHANGED
@@ -24,8 +24,8 @@ var __webpack_require__ = {};
24
24
  var __webpack_exports__ = {};
25
25
  __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
- resolveConsent: ()=>resolveConsent,
28
- c15tEdgeInit: ()=>c15tEdgeInit
27
+ unstable_resolveConsent: ()=>unstable_resolveConsent,
28
+ unstable_c15tEdgeInit: ()=>unstable_c15tEdgeInit
29
29
  });
30
30
  const logger_namespaceObject = require("@c15t/logger");
31
31
  const types_namespaceObject = require("@c15t/schema/types");
@@ -943,7 +943,7 @@ function isOriginTrusted(origin, trustedDomains, logger) {
943
943
  return false;
944
944
  }
945
945
  }
946
- function c15tEdgeInit(options) {
946
+ function unstable_c15tEdgeInit(options) {
947
947
  const logger = (0, logger_namespaceObject.createLogger)(options.logger);
948
948
  const validation = validateMessages({
949
949
  customTranslations: options.customTranslations,
@@ -1062,7 +1062,7 @@ function resolveDefaultConsent(policy, gpc) {
1062
1062
  };
1063
1063
  return defaults;
1064
1064
  }
1065
- function resolveConsent(request, options, logger) {
1065
+ function unstable_resolveConsent(request, options, logger) {
1066
1066
  const location = options.disableGeoLocation ? {
1067
1067
  countryCode: null,
1068
1068
  regionCode: null
@@ -1095,11 +1095,11 @@ function resolveConsent(request, options, logger) {
1095
1095
  gpc
1096
1096
  };
1097
1097
  }
1098
- exports.c15tEdgeInit = __webpack_exports__.c15tEdgeInit;
1099
- exports.resolveConsent = __webpack_exports__.resolveConsent;
1098
+ exports.unstable_c15tEdgeInit = __webpack_exports__.unstable_c15tEdgeInit;
1099
+ exports.unstable_resolveConsent = __webpack_exports__.unstable_resolveConsent;
1100
1100
  for(var __rspack_i in __webpack_exports__)if (-1 === [
1101
- "c15tEdgeInit",
1102
- "resolveConsent"
1101
+ "unstable_c15tEdgeInit",
1102
+ "unstable_resolveConsent"
1103
1103
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
1104
1104
  Object.defineProperty(exports, '__esModule', {
1105
1105
  value: true
package/dist/edge.js CHANGED
@@ -35,7 +35,7 @@ function isOriginTrusted(origin, trustedDomains, logger) {
35
35
  return false;
36
36
  }
37
37
  }
38
- function c15tEdgeInit(options) {
38
+ function unstable_c15tEdgeInit(options) {
39
39
  const logger = createLogger(options.logger);
40
40
  const validation = validateMessages({
41
41
  customTranslations: options.customTranslations,
@@ -154,7 +154,7 @@ function resolveDefaultConsent(policy, gpc) {
154
154
  };
155
155
  return defaults;
156
156
  }
157
- function resolveConsent(request, options, logger) {
157
+ function unstable_resolveConsent(request, options, logger) {
158
158
  const location = options.disableGeoLocation ? {
159
159
  countryCode: null,
160
160
  regionCode: null
@@ -187,4 +187,4 @@ function resolveConsent(request, options, logger) {
187
187
  gpc
188
188
  };
189
189
  }
190
- export { c15tEdgeInit, resolveConsent };
190
+ export { unstable_c15tEdgeInit, unstable_resolveConsent };