@c15t/backend 2.0.0-rc.3 → 2.0.0-rc.5

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 (314) hide show
  1. package/dist/cache.cjs +4 -4
  2. package/dist/cache.js +4 -4
  3. package/dist/core.cjs +845 -87
  4. package/dist/core.js +821 -87
  5. package/dist/db/schema.cjs +37 -0
  6. package/dist/db/schema.js +33 -2
  7. package/dist/edge.cjs +1106 -0
  8. package/dist/edge.js +1069 -0
  9. package/dist/router.cjs +621 -71
  10. package/dist/router.js +621 -71
  11. package/{dist → dist-types}/cache/adapters/cloudflare-kv.d.ts +0 -1
  12. package/{dist → dist-types}/cache/adapters/index.d.ts +0 -1
  13. package/{dist → dist-types}/cache/adapters/memory.d.ts +0 -1
  14. package/{dist → dist-types}/cache/adapters/upstash-redis.d.ts +0 -1
  15. package/{dist → dist-types}/cache/gvl-resolver.d.ts +1 -2
  16. package/{dist → dist-types}/cache/index.d.ts +0 -1
  17. package/{dist → dist-types}/cache/keys.d.ts +0 -1
  18. package/{dist → dist-types}/cache/types.d.ts +0 -1
  19. package/{dist → dist-types}/core.d.ts +8 -1
  20. package/{dist → dist-types}/db/migrator/index.d.ts +0 -1
  21. package/{dist → dist-types}/db/registry/consent-policy.d.ts +0 -1
  22. package/{dist → dist-types}/db/registry/consent-purpose.d.ts +0 -1
  23. package/{dist → dist-types}/db/registry/domain.d.ts +0 -1
  24. package/{dist → dist-types}/db/registry/index.d.ts +22 -2
  25. package/dist-types/db/registry/runtime-policy-decision.d.ts +60 -0
  26. package/{dist → dist-types}/db/registry/subject.d.ts +0 -1
  27. package/{dist → dist-types}/db/registry/types.d.ts +1 -2
  28. package/{dist → dist-types}/db/registry/utils/generate-id.d.ts +0 -1
  29. package/{dist → dist-types}/db/registry/utils.d.ts +0 -1
  30. package/{dist → dist-types}/db/schema/1.0.0/audit-log.d.ts +0 -1
  31. package/{dist → dist-types}/db/schema/1.0.0/consent-policy.d.ts +0 -1
  32. package/{dist → dist-types}/db/schema/1.0.0/consent-purpose.d.ts +0 -1
  33. package/{dist → dist-types}/db/schema/1.0.0/consent-record.d.ts +0 -1
  34. package/{dist → dist-types}/db/schema/1.0.0/consent.d.ts +1 -2
  35. package/{dist → dist-types}/db/schema/1.0.0/domain.d.ts +0 -1
  36. package/{dist → dist-types}/db/schema/1.0.0/index.d.ts +0 -1
  37. package/{dist → dist-types}/db/schema/1.0.0/subject.d.ts +0 -1
  38. package/{dist → dist-types}/db/schema/2.0.0/audit-log.d.ts +1 -2
  39. package/{dist → dist-types}/db/schema/2.0.0/consent-policy.d.ts +1 -2
  40. package/{dist → dist-types}/db/schema/2.0.0/consent-purpose.d.ts +1 -2
  41. package/{dist → dist-types}/db/schema/2.0.0/consent.d.ts +5 -2
  42. package/{dist → dist-types}/db/schema/2.0.0/domain.d.ts +1 -2
  43. package/{dist → dist-types}/db/schema/2.0.0/index.d.ts +432 -17
  44. package/dist-types/db/schema/2.0.0/runtime-policy-decision.d.ts +23 -0
  45. package/{dist → dist-types}/db/schema/2.0.0/subject.d.ts +1 -2
  46. package/{dist → dist-types}/db/schema/index.d.ts +862 -33
  47. package/{dist → dist-types}/db/tenant-scope.d.ts +0 -1
  48. package/dist-types/define-config.d.ts +17 -0
  49. package/dist-types/edge/index.d.ts +5 -0
  50. package/dist-types/edge/init-handler.d.ts +38 -0
  51. package/dist-types/edge/resolve-consent.d.ts +80 -0
  52. package/dist-types/edge/types.d.ts +13 -0
  53. package/{dist → dist-types}/handlers/consent/check.handler.d.ts +0 -1
  54. package/{src/handlers/consent/index.ts → dist-types/handlers/consent/index.d.ts} +0 -1
  55. package/{dist → dist-types}/handlers/init/geo.d.ts +2 -3
  56. package/{dist → dist-types}/handlers/init/index.d.ts +4 -5
  57. package/dist-types/handlers/init/policy.d.ts +26 -0
  58. package/dist-types/handlers/init/resolve-init.d.ts +44 -0
  59. package/dist-types/handlers/init/translations.d.ts +48 -0
  60. package/dist-types/handlers/policy/snapshot.d.ts +99 -0
  61. package/{src/handlers/status/index.ts → dist-types/handlers/status/index.d.ts} +0 -1
  62. package/{dist → dist-types}/handlers/status/status.handler.d.ts +0 -1
  63. package/{dist → dist-types}/handlers/subject/get.handler.d.ts +0 -1
  64. package/{src/handlers/subject/index.ts → dist-types/handlers/subject/index.d.ts} +0 -1
  65. package/{dist → dist-types}/handlers/subject/list.handler.d.ts +0 -1
  66. package/{dist → dist-types}/handlers/subject/patch.handler.d.ts +0 -1
  67. package/{dist → dist-types}/handlers/subject/post.handler.d.ts +12 -1
  68. package/{dist → dist-types}/handlers/utils/consent-enrichment.d.ts +0 -1
  69. package/{dist → dist-types}/init.d.ts +4 -7
  70. package/{dist → dist-types}/middleware/auth/index.d.ts +0 -1
  71. package/{dist → dist-types}/middleware/auth/validate-api-key.d.ts +0 -1
  72. package/{dist → dist-types}/middleware/cors/cors.d.ts +0 -1
  73. package/{src/middleware/cors/index.ts → dist-types/middleware/cors/index.d.ts} +0 -1
  74. package/{dist → dist-types}/middleware/cors/is-origin-trusted.d.ts +1 -2
  75. package/{dist → dist-types}/middleware/cors/process-cors.d.ts +0 -1
  76. package/{dist → dist-types}/middleware/openapi/config.d.ts +0 -1
  77. package/{dist → dist-types}/middleware/openapi/handlers.d.ts +0 -1
  78. package/{src/middleware/openapi/index.ts → dist-types/middleware/openapi/index.d.ts} +0 -1
  79. package/{dist → dist-types}/middleware/process-ip/index.d.ts +0 -1
  80. package/dist-types/policies/builder.d.ts +127 -0
  81. package/dist-types/policies/defaults.d.ts +2 -0
  82. package/dist-types/policies/matchers.d.ts +3 -0
  83. package/{dist → dist-types}/router.d.ts +0 -1
  84. package/{dist → dist-types}/routes/consent.d.ts +0 -1
  85. package/{src/routes/index.ts → dist-types/routes/index.d.ts} +0 -1
  86. package/{dist → dist-types}/routes/init.d.ts +0 -1
  87. package/{dist → dist-types}/routes/status.d.ts +0 -1
  88. package/{dist → dist-types}/routes/subject.d.ts +0 -1
  89. package/{dist → dist-types}/types/api.d.ts +0 -1
  90. package/dist-types/types/index.d.ts +443 -0
  91. package/dist-types/utils/background.d.ts +6 -0
  92. package/{dist → dist-types}/utils/create-telemetry-options.d.ts +1 -2
  93. package/{dist → dist-types}/utils/env.d.ts +0 -1
  94. package/{dist → dist-types}/utils/extract-error-message.d.ts +0 -1
  95. package/{dist → dist-types}/utils/instrumentation.d.ts +0 -1
  96. package/{dist → dist-types}/utils/logger.d.ts +1 -2
  97. package/{dist → dist-types}/utils/metrics.d.ts +0 -1
  98. package/dist-types/version.d.ts +1 -0
  99. package/docs/README.md +49 -0
  100. package/docs/api/configuration.md +197 -0
  101. package/docs/api/endpoints.md +211 -0
  102. package/docs/guides/caching.md +85 -0
  103. package/docs/guides/database-setup.md +128 -0
  104. package/docs/guides/edge-deployment.md +248 -0
  105. package/docs/guides/framework-integration.md +142 -0
  106. package/docs/guides/iab-tcf.md +89 -0
  107. package/docs/guides/observability.md +96 -0
  108. package/docs/guides/policy-packs.md +396 -0
  109. package/docs/quickstart.md +129 -0
  110. package/package.json +37 -23
  111. package/.turbo/turbo-build.log +0 -49
  112. package/CHANGELOG.md +0 -115
  113. package/dist/cache/adapters/cloudflare-kv.d.ts.map +0 -1
  114. package/dist/cache/adapters/index.d.ts.map +0 -1
  115. package/dist/cache/adapters/memory.d.ts.map +0 -1
  116. package/dist/cache/adapters/upstash-redis.d.ts.map +0 -1
  117. package/dist/cache/gvl-resolver.d.ts.map +0 -1
  118. package/dist/cache/index.d.ts.map +0 -1
  119. package/dist/cache/keys.d.ts.map +0 -1
  120. package/dist/cache/types.d.ts.map +0 -1
  121. package/dist/core.d.ts.map +0 -1
  122. package/dist/db/adapters/drizzle.d.ts +0 -2
  123. package/dist/db/adapters/drizzle.d.ts.map +0 -1
  124. package/dist/db/adapters/index.d.ts +0 -2
  125. package/dist/db/adapters/index.d.ts.map +0 -1
  126. package/dist/db/adapters/kysely.d.ts +0 -2
  127. package/dist/db/adapters/kysely.d.ts.map +0 -1
  128. package/dist/db/adapters/mongo.d.ts +0 -2
  129. package/dist/db/adapters/mongo.d.ts.map +0 -1
  130. package/dist/db/adapters/prisma.d.ts +0 -2
  131. package/dist/db/adapters/prisma.d.ts.map +0 -1
  132. package/dist/db/adapters/typeorm.d.ts +0 -2
  133. package/dist/db/adapters/typeorm.d.ts.map +0 -1
  134. package/dist/db/migrator/index.d.ts.map +0 -1
  135. package/dist/db/registry/consent-policy.d.ts.map +0 -1
  136. package/dist/db/registry/consent-purpose.d.ts.map +0 -1
  137. package/dist/db/registry/domain.d.ts.map +0 -1
  138. package/dist/db/registry/index.d.ts.map +0 -1
  139. package/dist/db/registry/subject.d.ts.map +0 -1
  140. package/dist/db/registry/types.d.ts.map +0 -1
  141. package/dist/db/registry/utils/generate-id.d.ts.map +0 -1
  142. package/dist/db/registry/utils.d.ts.map +0 -1
  143. package/dist/db/schema/1.0.0/audit-log.d.ts.map +0 -1
  144. package/dist/db/schema/1.0.0/consent-policy.d.ts.map +0 -1
  145. package/dist/db/schema/1.0.0/consent-purpose.d.ts.map +0 -1
  146. package/dist/db/schema/1.0.0/consent-record.d.ts.map +0 -1
  147. package/dist/db/schema/1.0.0/consent.d.ts.map +0 -1
  148. package/dist/db/schema/1.0.0/domain.d.ts.map +0 -1
  149. package/dist/db/schema/1.0.0/index.d.ts.map +0 -1
  150. package/dist/db/schema/1.0.0/subject.d.ts.map +0 -1
  151. package/dist/db/schema/2.0.0/audit-log.d.ts.map +0 -1
  152. package/dist/db/schema/2.0.0/consent-policy.d.ts.map +0 -1
  153. package/dist/db/schema/2.0.0/consent-purpose.d.ts.map +0 -1
  154. package/dist/db/schema/2.0.0/consent.d.ts.map +0 -1
  155. package/dist/db/schema/2.0.0/domain.d.ts.map +0 -1
  156. package/dist/db/schema/2.0.0/index.d.ts.map +0 -1
  157. package/dist/db/schema/2.0.0/subject.d.ts.map +0 -1
  158. package/dist/db/schema/index.d.ts.map +0 -1
  159. package/dist/db/tenant-scope.d.ts.map +0 -1
  160. package/dist/define-config.d.ts +0 -5
  161. package/dist/define-config.d.ts.map +0 -1
  162. package/dist/handlers/consent/check.handler.d.ts.map +0 -1
  163. package/dist/handlers/consent/index.d.ts +0 -12
  164. package/dist/handlers/consent/index.d.ts.map +0 -1
  165. package/dist/handlers/init/geo.d.ts.map +0 -1
  166. package/dist/handlers/init/index.d.ts.map +0 -1
  167. package/dist/handlers/init/translations.d.ts +0 -28
  168. package/dist/handlers/init/translations.d.ts.map +0 -1
  169. package/dist/handlers/status/index.d.ts +0 -7
  170. package/dist/handlers/status/index.d.ts.map +0 -1
  171. package/dist/handlers/status/status.handler.d.ts.map +0 -1
  172. package/dist/handlers/subject/get.handler.d.ts.map +0 -1
  173. package/dist/handlers/subject/index.d.ts +0 -10
  174. package/dist/handlers/subject/index.d.ts.map +0 -1
  175. package/dist/handlers/subject/list.handler.d.ts.map +0 -1
  176. package/dist/handlers/subject/patch.handler.d.ts.map +0 -1
  177. package/dist/handlers/subject/post.handler.d.ts.map +0 -1
  178. package/dist/handlers/utils/consent-enrichment.d.ts.map +0 -1
  179. package/dist/init.d.ts.map +0 -1
  180. package/dist/middleware/auth/index.d.ts.map +0 -1
  181. package/dist/middleware/auth/validate-api-key.d.ts.map +0 -1
  182. package/dist/middleware/cors/cors.d.ts.map +0 -1
  183. package/dist/middleware/cors/index.d.ts +0 -30
  184. package/dist/middleware/cors/index.d.ts.map +0 -1
  185. package/dist/middleware/cors/is-origin-trusted.d.ts.map +0 -1
  186. package/dist/middleware/cors/process-cors.d.ts.map +0 -1
  187. package/dist/middleware/openapi/config.d.ts.map +0 -1
  188. package/dist/middleware/openapi/handlers.d.ts.map +0 -1
  189. package/dist/middleware/openapi/index.d.ts +0 -12
  190. package/dist/middleware/openapi/index.d.ts.map +0 -1
  191. package/dist/middleware/process-ip/index.d.ts.map +0 -1
  192. package/dist/router.d.ts.map +0 -1
  193. package/dist/routes/consent.d.ts.map +0 -1
  194. package/dist/routes/index.d.ts +0 -10
  195. package/dist/routes/index.d.ts.map +0 -1
  196. package/dist/routes/init.d.ts.map +0 -1
  197. package/dist/routes/status.d.ts.map +0 -1
  198. package/dist/routes/subject.d.ts.map +0 -1
  199. package/dist/types/api.d.ts.map +0 -1
  200. package/dist/types/index.d.ts +0 -263
  201. package/dist/types/index.d.ts.map +0 -1
  202. package/dist/utils/create-telemetry-options.d.ts.map +0 -1
  203. package/dist/utils/env.d.ts.map +0 -1
  204. package/dist/utils/extract-error-message.d.ts.map +0 -1
  205. package/dist/utils/index.d.ts +0 -4
  206. package/dist/utils/index.d.ts.map +0 -1
  207. package/dist/utils/instrumentation.d.ts.map +0 -1
  208. package/dist/utils/logger.d.ts.map +0 -1
  209. package/dist/utils/metrics.d.ts.map +0 -1
  210. package/dist/version.d.ts +0 -2
  211. package/dist/version.d.ts.map +0 -1
  212. package/knip.json +0 -31
  213. package/rslib.config.ts +0 -93
  214. package/src/cache/adapters/cloudflare-kv.ts +0 -71
  215. package/src/cache/adapters/index.ts +0 -22
  216. package/src/cache/adapters/memory.ts +0 -111
  217. package/src/cache/adapters/upstash-redis.ts +0 -113
  218. package/src/cache/gvl-resolver.ts +0 -289
  219. package/src/cache/index.ts +0 -34
  220. package/src/cache/keys.ts +0 -68
  221. package/src/cache/types.ts +0 -66
  222. package/src/core.ts +0 -369
  223. package/src/db/migrator/index.ts +0 -80
  224. package/src/db/registry/consent-policy.test.ts +0 -451
  225. package/src/db/registry/consent-policy.ts +0 -82
  226. package/src/db/registry/consent-purpose.test.ts +0 -428
  227. package/src/db/registry/consent-purpose.ts +0 -61
  228. package/src/db/registry/domain.test.ts +0 -445
  229. package/src/db/registry/domain.ts +0 -91
  230. package/src/db/registry/index.ts +0 -14
  231. package/src/db/registry/subject.test.ts +0 -371
  232. package/src/db/registry/subject.ts +0 -126
  233. package/src/db/registry/types.ts +0 -10
  234. package/src/db/registry/utils/generate-id.test.ts +0 -216
  235. package/src/db/registry/utils/generate-id.ts +0 -133
  236. package/src/db/registry/utils.ts +0 -133
  237. package/src/db/schema/1.0.0/audit-log.ts +0 -15
  238. package/src/db/schema/1.0.0/consent-policy.ts +0 -14
  239. package/src/db/schema/1.0.0/consent-purpose.ts +0 -14
  240. package/src/db/schema/1.0.0/consent-record.ts +0 -10
  241. package/src/db/schema/1.0.0/consent.ts +0 -20
  242. package/src/db/schema/1.0.0/domain.ts +0 -12
  243. package/src/db/schema/1.0.0/index.ts +0 -48
  244. package/src/db/schema/1.0.0/subject.ts +0 -11
  245. package/src/db/schema/2.0.0/audit-log.ts +0 -18
  246. package/src/db/schema/2.0.0/consent-policy.ts +0 -28
  247. package/src/db/schema/2.0.0/consent-purpose.ts +0 -12
  248. package/src/db/schema/2.0.0/consent.ts +0 -28
  249. package/src/db/schema/2.0.0/domain.ts +0 -12
  250. package/src/db/schema/2.0.0/index.ts +0 -47
  251. package/src/db/schema/2.0.0/subject.ts +0 -13
  252. package/src/db/schema/index.ts +0 -15
  253. package/src/db/tenant-scope.test.ts +0 -747
  254. package/src/db/tenant-scope.ts +0 -103
  255. package/src/define-config.ts +0 -5
  256. package/src/handlers/consent/check.handler.ts +0 -126
  257. package/src/handlers/init/geo.test.ts +0 -317
  258. package/src/handlers/init/geo.ts +0 -195
  259. package/src/handlers/init/index.test.ts +0 -205
  260. package/src/handlers/init/index.ts +0 -114
  261. package/src/handlers/init/translations.test.ts +0 -121
  262. package/src/handlers/init/translations.ts +0 -72
  263. package/src/handlers/status/status.handler.test.ts +0 -155
  264. package/src/handlers/status/status.handler.ts +0 -51
  265. package/src/handlers/subject/get.handler.ts +0 -92
  266. package/src/handlers/subject/list.handler.ts +0 -92
  267. package/src/handlers/subject/patch.handler.ts +0 -119
  268. package/src/handlers/subject/post.handler.test.ts +0 -294
  269. package/src/handlers/subject/post.handler.ts +0 -268
  270. package/src/handlers/utils/consent-enrichment.test.ts +0 -380
  271. package/src/handlers/utils/consent-enrichment.ts +0 -218
  272. package/src/init.test.ts +0 -126
  273. package/src/init.ts +0 -87
  274. package/src/middleware/auth/index.ts +0 -11
  275. package/src/middleware/auth/validate-api-key.test.ts +0 -86
  276. package/src/middleware/auth/validate-api-key.ts +0 -107
  277. package/src/middleware/cors/cors.test.ts +0 -135
  278. package/src/middleware/cors/cors.ts +0 -186
  279. package/src/middleware/cors/is-origin-trusted.test.ts +0 -164
  280. package/src/middleware/cors/is-origin-trusted.ts +0 -130
  281. package/src/middleware/cors/process-cors.ts +0 -91
  282. package/src/middleware/openapi/config.ts +0 -29
  283. package/src/middleware/openapi/handlers.ts +0 -34
  284. package/src/middleware/process-ip/index.test.ts +0 -195
  285. package/src/middleware/process-ip/index.ts +0 -199
  286. package/src/router.ts +0 -15
  287. package/src/routes/consent.ts +0 -52
  288. package/src/routes/init.ts +0 -105
  289. package/src/routes/status.ts +0 -46
  290. package/src/routes/subject.ts +0 -152
  291. package/src/types/api.ts +0 -48
  292. package/src/types/index.ts +0 -297
  293. package/src/utils/create-telemetry-options.test.ts +0 -302
  294. package/src/utils/create-telemetry-options.ts +0 -229
  295. package/src/utils/env.ts +0 -84
  296. package/src/utils/extract-error-message.ts +0 -21
  297. package/src/utils/instrumentation.test.ts +0 -185
  298. package/src/utils/instrumentation.ts +0 -196
  299. package/src/utils/logger.ts +0 -41
  300. package/src/utils/metrics.test.ts +0 -323
  301. package/src/utils/metrics.ts +0 -402
  302. package/src/utils/telemetry-pii.test.ts +0 -325
  303. package/src/version.ts +0 -2
  304. package/tsconfig.json +0 -11
  305. package/vitest.config.ts +0 -28
  306. /package/dist/{types.cjs → types/index.cjs} +0 -0
  307. /package/dist/{types.js → types/index.js} +0 -0
  308. /package/{src/db/adapters/drizzle.ts → dist-types/db/adapters/drizzle.d.ts} +0 -0
  309. /package/{src/db/adapters/index.ts → dist-types/db/adapters/index.d.ts} +0 -0
  310. /package/{src/db/adapters/kysely.ts → dist-types/db/adapters/kysely.d.ts} +0 -0
  311. /package/{src/db/adapters/mongo.ts → dist-types/db/adapters/mongo.d.ts} +0 -0
  312. /package/{src/db/adapters/prisma.ts → dist-types/db/adapters/prisma.d.ts} +0 -0
  313. /package/{src/db/adapters/typeorm.ts → dist-types/db/adapters/typeorm.d.ts} +0 -0
  314. /package/{src/utils/index.ts → dist-types/utils/index.d.ts} +0 -0
@@ -1,325 +0,0 @@
1
- /**
2
- * E2E test: every span attribute key must be in the allowlist,
3
- * and no attribute value may match PII patterns.
4
- *
5
- * Uses a real BasicTracerProvider + InMemorySpanExporter (no mocks).
6
- */
7
-
8
- import {
9
- BasicTracerProvider,
10
- InMemorySpanExporter,
11
- SimpleSpanProcessor,
12
- } from '@opentelemetry/sdk-trace-base';
13
- import { afterEach, beforeAll, describe, expect, it } from 'vitest';
14
- import type { C15TOptions } from '../types';
15
- import {
16
- createRequestSpan,
17
- createTelemetryOptions,
18
- resetTelemetryConfig,
19
- withRequestSpan,
20
- } from './create-telemetry-options';
21
- import {
22
- withCacheSpan,
23
- withDatabaseSpan,
24
- withExternalSpan,
25
- } from './instrumentation';
26
-
27
- // ── Allowlist ───────────────────────────────────────────────────────────
28
- const ALLOWED_KEYS = new Set([
29
- 'http.method',
30
- 'http.route',
31
- 'http.host',
32
- 'http.path',
33
- 'http.url',
34
- 'error.type',
35
- 'db.system',
36
- 'db.operation',
37
- 'db.entity',
38
- 'cache.operation',
39
- 'cache.layer',
40
- 'service.name',
41
- 'service.version',
42
- 'tenant.id',
43
- ]);
44
-
45
- const BLOCKED_KEYS = new Set(['error.stack', 'error.message']);
46
-
47
- const PII_PATTERNS = [
48
- /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/, // IPv4
49
- /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/, // email
50
- /at .+\(.+:\d+:\d+\)/, // stack trace line
51
- /\?[^=]+=/, // query string
52
- ];
53
-
54
- // ── Provider setup ──────────────────────────────────────────────────────
55
- const exporter = new InMemorySpanExporter();
56
- const provider = new BasicTracerProvider();
57
- provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
58
- provider.register();
59
-
60
- const tracer = provider.getTracer('pii-test');
61
-
62
- function telemetryOptions(): C15TOptions {
63
- return {
64
- trustedOrigins: [],
65
- adapter: {} as C15TOptions['adapter'],
66
- advanced: {
67
- telemetry: {
68
- enabled: true,
69
- tracer,
70
- },
71
- },
72
- };
73
- }
74
-
75
- // ── Helpers ─────────────────────────────────────────────────────────────
76
- function drainSpans() {
77
- const spans = exporter.getFinishedSpans();
78
- const copy = [...spans];
79
- exporter.reset();
80
- return copy;
81
- }
82
-
83
- function assertAllowlist(spans: ReturnType<typeof drainSpans>) {
84
- for (const span of spans) {
85
- const attrs = span.attributes;
86
- for (const key of Object.keys(attrs)) {
87
- expect(ALLOWED_KEYS.has(key)).toBe(true);
88
- }
89
- }
90
- }
91
-
92
- function assertNoBlockedKeys(spans: ReturnType<typeof drainSpans>) {
93
- for (const span of spans) {
94
- const attrs = span.attributes;
95
- for (const key of Object.keys(attrs)) {
96
- expect(BLOCKED_KEYS.has(key)).toBe(false);
97
- }
98
- }
99
- }
100
-
101
- function assertNoPiiValues(spans: ReturnType<typeof drainSpans>) {
102
- for (const span of spans) {
103
- const attrs = span.attributes;
104
- for (const [key, value] of Object.entries(attrs)) {
105
- if (typeof value === 'string') {
106
- for (const pattern of PII_PATTERNS) {
107
- expect(
108
- pattern.test(value),
109
- `Attribute "${key}" value "${value}" matches PII pattern ${pattern}`
110
- ).toBe(false);
111
- }
112
- }
113
- }
114
- }
115
- }
116
-
117
- // ── Tests ───────────────────────────────────────────────────────────────
118
- beforeAll(() => {
119
- createTelemetryOptions('pii-test', { enabled: true, tracer });
120
- });
121
-
122
- afterEach(() => {
123
- exporter.reset();
124
- });
125
-
126
- describe('telemetry PII safeguards', () => {
127
- // 1. withDatabaseSpan success
128
- it('withDatabaseSpan attributes pass allowlist', async () => {
129
- await withDatabaseSpan(
130
- { operation: 'find', entity: 'subject' },
131
- async () => 'ok',
132
- telemetryOptions()
133
- );
134
-
135
- const spans = drainSpans();
136
- expect(spans.length).toBe(1);
137
- assertAllowlist(spans);
138
- assertNoPiiValues(spans);
139
- });
140
-
141
- // 2. withExternalSpan success — span name = hostname only
142
- it('withExternalSpan span name is HTTP METHOD hostname only', async () => {
143
- await withExternalSpan(
144
- { url: 'https://api.example.com/v1/charges', method: 'GET' },
145
- async () => 'ok',
146
- telemetryOptions()
147
- );
148
-
149
- const spans = drainSpans();
150
- expect(spans.length).toBe(1);
151
- expect(spans[0].name).toBe('HTTP GET api.example.com');
152
- assertAllowlist(spans);
153
- assertNoPiiValues(spans);
154
- });
155
-
156
- // 3. withExternalSpan strips query params from http.url
157
- it('withExternalSpan strips query params from http.url', async () => {
158
- await withExternalSpan(
159
- {
160
- url: 'https://api.example.com/v1/data?key=secret&email=user@ex.com',
161
- method: 'POST',
162
- },
163
- async () => 'ok',
164
- telemetryOptions()
165
- );
166
-
167
- const spans = drainSpans();
168
- expect(spans.length).toBe(1);
169
- const url = spans[0].attributes['http.url'] as string;
170
- expect(url).toBe('https://api.example.com/v1/data');
171
- expect(url).not.toContain('?');
172
- assertAllowlist(spans);
173
- assertNoPiiValues(spans);
174
- });
175
-
176
- // 4. withCacheSpan success
177
- it('withCacheSpan has no unexpected attributes', async () => {
178
- await withCacheSpan('get', 'memory', async () => 'ok', telemetryOptions());
179
-
180
- const spans = drainSpans();
181
- expect(spans.length).toBe(1);
182
- assertAllowlist(spans);
183
- assertNoPiiValues(spans);
184
- });
185
-
186
- // 5. withRequestSpan success — no http.path
187
- it('withRequestSpan has no http.path attribute', async () => {
188
- await withRequestSpan(
189
- 'GET',
190
- '/subjects/abc123',
191
- async () => 'ok',
192
- telemetryOptions()
193
- );
194
-
195
- const spans = drainSpans();
196
- expect(spans.length).toBe(1);
197
- expect(spans[0].attributes['http.path']).toBeUndefined();
198
- assertAllowlist(spans);
199
- });
200
-
201
- // 6. createRequestSpan direct — no http.path
202
- it('createRequestSpan has no http.path attribute', () => {
203
- const span = createRequestSpan(
204
- 'POST',
205
- '/subjects/xyz789',
206
- telemetryOptions()
207
- );
208
-
209
- expect(span).toBeDefined();
210
- span!.end();
211
-
212
- const spans = drainSpans();
213
- expect(spans.length).toBe(1);
214
- expect(spans[0].attributes['http.path']).toBeUndefined();
215
- assertAllowlist(spans);
216
- });
217
-
218
- // 7. withDatabaseSpan error — PII in message
219
- it('withDatabaseSpan error does not leak error.message or error.stack', async () => {
220
- await expect(
221
- withDatabaseSpan(
222
- { operation: 'find', entity: 'subject' },
223
- async () => {
224
- throw new Error('User user@example.com not found at 192.168.1.1');
225
- },
226
- telemetryOptions()
227
- )
228
- ).rejects.toThrow();
229
-
230
- const spans = drainSpans();
231
- expect(spans.length).toBe(1);
232
- assertNoBlockedKeys(spans);
233
- assertNoPiiValues(spans);
234
- });
235
-
236
- // 8. withExternalSpan error — IP in message
237
- it('withExternalSpan error does not leak error.message or error.stack', async () => {
238
- await expect(
239
- withExternalSpan(
240
- { url: 'https://api.example.com/v1/data', method: 'GET' },
241
- async () => {
242
- throw new Error('Connection refused at 10.0.0.1:5432');
243
- },
244
- telemetryOptions()
245
- )
246
- ).rejects.toThrow();
247
-
248
- const spans = drainSpans();
249
- expect(spans.length).toBe(1);
250
- assertNoBlockedKeys(spans);
251
- assertNoPiiValues(spans);
252
- });
253
-
254
- // 9. withCacheSpan error
255
- it('withCacheSpan error does not leak error.message or error.stack', async () => {
256
- await expect(
257
- withCacheSpan(
258
- 'get',
259
- 'external',
260
- async () => {
261
- throw new Error('Redis timeout at 172.16.0.1');
262
- },
263
- telemetryOptions()
264
- )
265
- ).rejects.toThrow();
266
-
267
- const spans = drainSpans();
268
- expect(spans.length).toBe(1);
269
- assertNoBlockedKeys(spans);
270
- assertNoPiiValues(spans);
271
- });
272
-
273
- // 10. withRequestSpan error
274
- it('withRequestSpan error does not leak error.message or error.stack', async () => {
275
- await expect(
276
- withRequestSpan(
277
- 'GET',
278
- '/subjects/abc123',
279
- async () => {
280
- throw new Error('Subject user@corp.io failed auth');
281
- },
282
- telemetryOptions()
283
- )
284
- ).rejects.toThrow();
285
-
286
- const spans = drainSpans();
287
- expect(spans.length).toBe(1);
288
- assertNoBlockedKeys(spans);
289
- assertNoPiiValues(spans);
290
- });
291
-
292
- // 11. All 4 span types combined — every key in allowlist
293
- it('all span types combined: every attribute key is in allowlist', async () => {
294
- // database
295
- await withDatabaseSpan(
296
- { operation: 'create', entity: 'consent' },
297
- async () => 'ok',
298
- telemetryOptions()
299
- );
300
-
301
- // external
302
- await withExternalSpan(
303
- { url: 'https://vendor.example.com/api', method: 'POST' },
304
- async () => 'ok',
305
- telemetryOptions()
306
- );
307
-
308
- // cache
309
- await withCacheSpan('set', 'bundled', async () => 'ok', telemetryOptions());
310
-
311
- // request
312
- await withRequestSpan(
313
- 'DELETE',
314
- '/consents/123',
315
- async () => 'ok',
316
- telemetryOptions()
317
- );
318
-
319
- const spans = drainSpans();
320
- expect(spans.length).toBe(4);
321
- assertAllowlist(spans);
322
- assertNoBlockedKeys(spans);
323
- assertNoPiiValues(spans);
324
- });
325
- });
package/src/version.ts DELETED
@@ -1,2 +0,0 @@
1
- // Generated by genversion.
2
- export const version = '2.0.0-rc.3';
package/tsconfig.json DELETED
@@ -1,11 +0,0 @@
1
- {
2
- "extends": "@c15t/typescript-config/node.json",
3
- "compilerOptions": {
4
- "baseUrl": ".",
5
- "paths": {
6
- "~/*": ["./src/*"]
7
- }
8
- },
9
- "include": ["src"],
10
- "exclude": ["node_modules", "**/*.test.ts", "**/__tests__/**"]
11
- }
package/vitest.config.ts DELETED
@@ -1,28 +0,0 @@
1
- import path from 'node:path';
2
- import { fileURLToPath } from 'node:url';
3
- import { baseConfig } from '@c15t/vitest-config/base';
4
- import { defineConfig, mergeConfig } from 'vitest/config';
5
-
6
- const __filename = fileURLToPath(import.meta.url);
7
- const __dirname = path.dirname(__filename);
8
-
9
- export default mergeConfig(
10
- baseConfig,
11
- defineConfig({
12
- resolve: {
13
- alias: {
14
- '~': path.resolve(__dirname, './src'),
15
- // Workaround: fumadb imports without extension, but Node ESM needs .js
16
- 'semver/functions/compare': 'semver/functions/compare.js',
17
- },
18
- },
19
- test: {
20
- environment: 'node',
21
- server: {
22
- deps: {
23
- inline: ['fumadb'],
24
- },
25
- },
26
- },
27
- })
28
- );
File without changes
File without changes