@c15t/backend 2.0.0-rc.0 → 2.0.0-rc.10

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 (336) hide show
  1. package/README.md +3 -3
  2. package/dist/302.js +473 -0
  3. package/dist/583.js +540 -0
  4. package/dist/915.js +1771 -0
  5. package/dist/cache.cjs +5 -5
  6. package/dist/cache.js +4 -415
  7. package/dist/core.cjs +1356 -120
  8. package/dist/core.js +163 -1981
  9. package/dist/db/adapters/drizzle.cjs +1 -1
  10. package/dist/db/adapters/drizzle.js +1 -2
  11. package/dist/db/adapters/kysely.cjs +1 -1
  12. package/dist/db/adapters/kysely.js +1 -2
  13. package/dist/db/adapters/mongo.cjs +1 -1
  14. package/dist/db/adapters/mongo.js +1 -2
  15. package/dist/db/adapters/prisma.cjs +1 -1
  16. package/dist/db/adapters/prisma.js +1 -2
  17. package/dist/db/adapters/typeorm.cjs +1 -1
  18. package/dist/db/adapters/typeorm.js +1 -2
  19. package/dist/db/adapters.cjs +1 -1
  20. package/dist/db/migrator.cjs +1 -1
  21. package/dist/db/schema.cjs +43 -3
  22. package/dist/db/schema.js +35 -4
  23. package/dist/define-config.cjs +1 -1
  24. package/dist/edge.cjs +1106 -0
  25. package/dist/edge.js +190 -0
  26. package/dist/router.cjs +885 -123
  27. package/dist/router.js +1 -1507
  28. package/dist/{types.cjs → types/index.cjs} +1 -1
  29. package/{dist → dist-types}/cache/adapters/cloudflare-kv.d.ts +0 -1
  30. package/{dist → dist-types}/cache/adapters/index.d.ts +0 -1
  31. package/{dist → dist-types}/cache/adapters/memory.d.ts +0 -1
  32. package/{dist → dist-types}/cache/adapters/upstash-redis.d.ts +0 -1
  33. package/{dist → dist-types}/cache/gvl-resolver.d.ts +0 -1
  34. package/{dist → dist-types}/cache/index.d.ts +0 -1
  35. package/{dist → dist-types}/cache/keys.d.ts +0 -1
  36. package/{dist → dist-types}/cache/types.d.ts +0 -1
  37. package/{dist → dist-types}/core.d.ts +8 -1
  38. package/{dist → dist-types}/db/migrator/index.d.ts +0 -1
  39. package/dist-types/db/registry/consent-policy.d.ts +78 -0
  40. package/{dist → dist-types}/db/registry/consent-purpose.d.ts +0 -1
  41. package/{dist → dist-types}/db/registry/domain.d.ts +0 -1
  42. package/dist-types/db/registry/index.d.ts +118 -0
  43. package/dist-types/db/registry/runtime-policy-decision.d.ts +60 -0
  44. package/{dist → dist-types}/db/registry/subject.d.ts +0 -2
  45. package/{dist → dist-types}/db/registry/types.d.ts +1 -1
  46. package/{dist → dist-types}/db/registry/utils/generate-id.d.ts +0 -1
  47. package/{dist → dist-types}/db/registry/utils.d.ts +0 -1
  48. package/{dist → dist-types}/db/schema/1.0.0/audit-log.d.ts +0 -1
  49. package/{dist → dist-types}/db/schema/1.0.0/consent-policy.d.ts +0 -1
  50. package/{dist → dist-types}/db/schema/1.0.0/consent-purpose.d.ts +0 -1
  51. package/{dist → dist-types}/db/schema/1.0.0/consent-record.d.ts +0 -1
  52. package/{dist → dist-types}/db/schema/1.0.0/consent.d.ts +1 -2
  53. package/{dist → dist-types}/db/schema/1.0.0/domain.d.ts +0 -1
  54. package/{dist → dist-types}/db/schema/1.0.0/index.d.ts +0 -32
  55. package/{dist → dist-types}/db/schema/1.0.0/subject.d.ts +0 -2
  56. package/{dist → dist-types}/db/schema/2.0.0/audit-log.d.ts +1 -2
  57. package/{dist → dist-types}/db/schema/2.0.0/consent-policy.d.ts +3 -3
  58. package/{dist → dist-types}/db/schema/2.0.0/consent-purpose.d.ts +1 -2
  59. package/{dist → dist-types}/db/schema/2.0.0/consent.d.ts +7 -2
  60. package/{dist → dist-types}/db/schema/2.0.0/domain.d.ts +1 -2
  61. package/{dist → dist-types}/db/schema/2.0.0/index.d.ts +455 -28
  62. package/dist-types/db/schema/2.0.0/runtime-policy-decision.d.ts +23 -0
  63. package/{dist → dist-types}/db/schema/2.0.0/subject.d.ts +1 -3
  64. package/{dist → dist-types}/db/schema/index.d.ts +908 -86
  65. package/{dist → dist-types}/db/tenant-scope.d.ts +0 -1
  66. package/dist-types/define-config.d.ts +17 -0
  67. package/dist-types/edge/index.d.ts +5 -0
  68. package/dist-types/edge/init-handler.d.ts +40 -0
  69. package/dist-types/edge/resolve-consent.d.ts +80 -0
  70. package/dist-types/edge/types.d.ts +13 -0
  71. package/{dist → dist-types}/handlers/consent/check.handler.d.ts +0 -1
  72. package/{src/handlers/consent/index.ts → dist-types/handlers/consent/index.d.ts} +0 -1
  73. package/{dist → dist-types}/handlers/init/geo.d.ts +2 -3
  74. package/{dist → dist-types}/handlers/init/index.d.ts +2 -3
  75. package/dist-types/handlers/init/policy.d.ts +26 -0
  76. package/dist-types/handlers/init/resolve-init.d.ts +44 -0
  77. package/dist-types/handlers/init/translations.d.ts +48 -0
  78. package/dist-types/handlers/legal-document/current.handler.d.ts +11 -0
  79. package/dist-types/handlers/legal-document/snapshot.d.ts +39 -0
  80. package/dist-types/handlers/policy/snapshot.d.ts +99 -0
  81. package/{src/handlers/status/index.ts → dist-types/handlers/status/index.d.ts} +0 -1
  82. package/{dist → dist-types}/handlers/status/status.handler.d.ts +0 -1
  83. package/{dist → dist-types}/handlers/subject/get.handler.d.ts +3 -2
  84. package/{src/handlers/subject/index.ts → dist-types/handlers/subject/index.d.ts} +0 -1
  85. package/{dist → dist-types}/handlers/subject/list.handler.d.ts +3 -2
  86. package/{dist → dist-types}/handlers/subject/patch.handler.d.ts +0 -2
  87. package/{dist → dist-types}/handlers/subject/post.handler.d.ts +12 -1
  88. package/{dist → dist-types}/handlers/utils/consent-enrichment.d.ts +3 -1
  89. package/{dist → dist-types}/init.d.ts +4 -7
  90. package/{dist → dist-types}/middleware/auth/index.d.ts +0 -1
  91. package/{dist → dist-types}/middleware/auth/validate-api-key.d.ts +0 -1
  92. package/{dist → dist-types}/middleware/cors/cors.d.ts +0 -1
  93. package/{src/middleware/cors/index.ts → dist-types/middleware/cors/index.d.ts} +0 -1
  94. package/{dist → dist-types}/middleware/cors/is-origin-trusted.d.ts +0 -1
  95. package/{dist → dist-types}/middleware/cors/process-cors.d.ts +0 -1
  96. package/{dist → dist-types}/middleware/openapi/config.d.ts +0 -1
  97. package/{dist → dist-types}/middleware/openapi/handlers.d.ts +0 -1
  98. package/{src/middleware/openapi/index.ts → dist-types/middleware/openapi/index.d.ts} +0 -1
  99. package/{dist → dist-types}/middleware/process-ip/index.d.ts +0 -1
  100. package/dist-types/policies/builder.d.ts +127 -0
  101. package/dist-types/policies/defaults.d.ts +2 -0
  102. package/dist-types/policies/matchers.d.ts +3 -0
  103. package/{dist → dist-types}/router.d.ts +0 -1
  104. package/{dist → dist-types}/routes/consent.d.ts +0 -1
  105. package/{dist → dist-types}/routes/index.d.ts +1 -1
  106. package/{dist → dist-types}/routes/init.d.ts +0 -1
  107. package/dist-types/routes/legal-document.d.ts +7 -0
  108. package/{dist → dist-types}/routes/status.d.ts +0 -1
  109. package/{dist → dist-types}/routes/subject.d.ts +0 -1
  110. package/{dist → dist-types}/types/api.d.ts +0 -1
  111. package/dist-types/types/index.d.ts +464 -0
  112. package/dist-types/utils/background.d.ts +6 -0
  113. package/{dist → dist-types}/utils/create-telemetry-options.d.ts +1 -2
  114. package/{dist → dist-types}/utils/env.d.ts +0 -1
  115. package/{dist → dist-types}/utils/extract-error-message.d.ts +0 -1
  116. package/{dist → dist-types}/utils/instrumentation.d.ts +2 -3
  117. package/{dist → dist-types}/utils/logger.d.ts +0 -1
  118. package/{dist → dist-types}/utils/metrics.d.ts +0 -1
  119. package/dist-types/version.d.ts +1 -0
  120. package/docs/README.md +49 -0
  121. package/docs/api/configuration.md +208 -0
  122. package/docs/api/endpoints.md +211 -0
  123. package/docs/guides/caching.md +85 -0
  124. package/docs/guides/database-setup.md +128 -0
  125. package/docs/guides/edge-deployment.md +251 -0
  126. package/docs/guides/framework-integration.md +142 -0
  127. package/docs/guides/iab-tcf.md +89 -0
  128. package/docs/guides/observability.md +96 -0
  129. package/docs/guides/policy-packs.md +396 -0
  130. package/docs/quickstart.md +129 -0
  131. package/package.json +53 -39
  132. package/.turbo/turbo-build.log +0 -49
  133. package/CHANGELOG.md +0 -89
  134. package/dist/cache/adapters/cloudflare-kv.d.ts.map +0 -1
  135. package/dist/cache/adapters/index.d.ts.map +0 -1
  136. package/dist/cache/adapters/memory.d.ts.map +0 -1
  137. package/dist/cache/adapters/upstash-redis.d.ts.map +0 -1
  138. package/dist/cache/gvl-resolver.d.ts.map +0 -1
  139. package/dist/cache/index.d.ts.map +0 -1
  140. package/dist/cache/keys.d.ts.map +0 -1
  141. package/dist/cache/types.d.ts.map +0 -1
  142. package/dist/core.d.ts.map +0 -1
  143. package/dist/db/adapters/drizzle.d.ts +0 -2
  144. package/dist/db/adapters/drizzle.d.ts.map +0 -1
  145. package/dist/db/adapters/index.d.ts +0 -2
  146. package/dist/db/adapters/index.d.ts.map +0 -1
  147. package/dist/db/adapters/kysely.d.ts +0 -2
  148. package/dist/db/adapters/kysely.d.ts.map +0 -1
  149. package/dist/db/adapters/mongo.d.ts +0 -2
  150. package/dist/db/adapters/mongo.d.ts.map +0 -1
  151. package/dist/db/adapters/prisma.d.ts +0 -2
  152. package/dist/db/adapters/prisma.d.ts.map +0 -1
  153. package/dist/db/adapters/typeorm.d.ts +0 -2
  154. package/dist/db/adapters/typeorm.d.ts.map +0 -1
  155. package/dist/db/migrator/index.d.ts.map +0 -1
  156. package/dist/db/registry/consent-policy.d.ts +0 -23
  157. package/dist/db/registry/consent-policy.d.ts.map +0 -1
  158. package/dist/db/registry/consent-purpose.d.ts.map +0 -1
  159. package/dist/db/registry/domain.d.ts.map +0 -1
  160. package/dist/db/registry/index.d.ts +0 -57
  161. package/dist/db/registry/index.d.ts.map +0 -1
  162. package/dist/db/registry/subject.d.ts.map +0 -1
  163. package/dist/db/registry/types.d.ts.map +0 -1
  164. package/dist/db/registry/utils/generate-id.d.ts.map +0 -1
  165. package/dist/db/registry/utils.d.ts.map +0 -1
  166. package/dist/db/schema/1.0.0/audit-log.d.ts.map +0 -1
  167. package/dist/db/schema/1.0.0/consent-policy.d.ts.map +0 -1
  168. package/dist/db/schema/1.0.0/consent-purpose.d.ts.map +0 -1
  169. package/dist/db/schema/1.0.0/consent-record.d.ts.map +0 -1
  170. package/dist/db/schema/1.0.0/consent.d.ts.map +0 -1
  171. package/dist/db/schema/1.0.0/domain.d.ts.map +0 -1
  172. package/dist/db/schema/1.0.0/index.d.ts.map +0 -1
  173. package/dist/db/schema/1.0.0/subject.d.ts.map +0 -1
  174. package/dist/db/schema/2.0.0/audit-log.d.ts.map +0 -1
  175. package/dist/db/schema/2.0.0/consent-policy.d.ts.map +0 -1
  176. package/dist/db/schema/2.0.0/consent-purpose.d.ts.map +0 -1
  177. package/dist/db/schema/2.0.0/consent.d.ts.map +0 -1
  178. package/dist/db/schema/2.0.0/domain.d.ts.map +0 -1
  179. package/dist/db/schema/2.0.0/index.d.ts.map +0 -1
  180. package/dist/db/schema/2.0.0/subject.d.ts.map +0 -1
  181. package/dist/db/schema/index.d.ts.map +0 -1
  182. package/dist/db/tenant-scope.d.ts.map +0 -1
  183. package/dist/define-config.d.ts +0 -5
  184. package/dist/define-config.d.ts.map +0 -1
  185. package/dist/handlers/consent/check.handler.d.ts.map +0 -1
  186. package/dist/handlers/consent/index.d.ts +0 -12
  187. package/dist/handlers/consent/index.d.ts.map +0 -1
  188. package/dist/handlers/init/geo.d.ts.map +0 -1
  189. package/dist/handlers/init/index.d.ts.map +0 -1
  190. package/dist/handlers/init/translations.d.ts +0 -28
  191. package/dist/handlers/init/translations.d.ts.map +0 -1
  192. package/dist/handlers/status/index.d.ts +0 -7
  193. package/dist/handlers/status/index.d.ts.map +0 -1
  194. package/dist/handlers/status/status.handler.d.ts.map +0 -1
  195. package/dist/handlers/subject/get.handler.d.ts.map +0 -1
  196. package/dist/handlers/subject/index.d.ts +0 -10
  197. package/dist/handlers/subject/index.d.ts.map +0 -1
  198. package/dist/handlers/subject/list.handler.d.ts.map +0 -1
  199. package/dist/handlers/subject/patch.handler.d.ts.map +0 -1
  200. package/dist/handlers/subject/post.handler.d.ts.map +0 -1
  201. package/dist/handlers/utils/consent-enrichment.d.ts.map +0 -1
  202. package/dist/init.d.ts.map +0 -1
  203. package/dist/middleware/auth/index.d.ts.map +0 -1
  204. package/dist/middleware/auth/validate-api-key.d.ts.map +0 -1
  205. package/dist/middleware/cors/cors.d.ts.map +0 -1
  206. package/dist/middleware/cors/index.d.ts +0 -30
  207. package/dist/middleware/cors/index.d.ts.map +0 -1
  208. package/dist/middleware/cors/is-origin-trusted.d.ts.map +0 -1
  209. package/dist/middleware/cors/process-cors.d.ts.map +0 -1
  210. package/dist/middleware/openapi/config.d.ts.map +0 -1
  211. package/dist/middleware/openapi/handlers.d.ts.map +0 -1
  212. package/dist/middleware/openapi/index.d.ts +0 -12
  213. package/dist/middleware/openapi/index.d.ts.map +0 -1
  214. package/dist/middleware/process-ip/index.d.ts.map +0 -1
  215. package/dist/router.d.ts.map +0 -1
  216. package/dist/routes/consent.d.ts.map +0 -1
  217. package/dist/routes/index.d.ts.map +0 -1
  218. package/dist/routes/init.d.ts.map +0 -1
  219. package/dist/routes/status.d.ts.map +0 -1
  220. package/dist/routes/subject.d.ts.map +0 -1
  221. package/dist/types/api.d.ts.map +0 -1
  222. package/dist/types/index.d.ts +0 -255
  223. package/dist/types/index.d.ts.map +0 -1
  224. package/dist/utils/create-telemetry-options.d.ts.map +0 -1
  225. package/dist/utils/env.d.ts.map +0 -1
  226. package/dist/utils/extract-error-message.d.ts.map +0 -1
  227. package/dist/utils/index.d.ts +0 -4
  228. package/dist/utils/index.d.ts.map +0 -1
  229. package/dist/utils/instrumentation.d.ts.map +0 -1
  230. package/dist/utils/logger.d.ts.map +0 -1
  231. package/dist/utils/metrics.d.ts.map +0 -1
  232. package/dist/version.d.ts +0 -2
  233. package/dist/version.d.ts.map +0 -1
  234. package/knip.json +0 -31
  235. package/rslib.config.ts +0 -93
  236. package/src/cache/adapters/cloudflare-kv.ts +0 -71
  237. package/src/cache/adapters/index.ts +0 -22
  238. package/src/cache/adapters/memory.ts +0 -111
  239. package/src/cache/adapters/upstash-redis.ts +0 -113
  240. package/src/cache/gvl-resolver.ts +0 -289
  241. package/src/cache/index.ts +0 -34
  242. package/src/cache/keys.ts +0 -68
  243. package/src/cache/types.ts +0 -66
  244. package/src/core.ts +0 -368
  245. package/src/db/migrator/index.ts +0 -80
  246. package/src/db/registry/consent-policy.test.ts +0 -451
  247. package/src/db/registry/consent-policy.ts +0 -82
  248. package/src/db/registry/consent-purpose.test.ts +0 -428
  249. package/src/db/registry/consent-purpose.ts +0 -61
  250. package/src/db/registry/domain.test.ts +0 -445
  251. package/src/db/registry/domain.ts +0 -91
  252. package/src/db/registry/index.ts +0 -14
  253. package/src/db/registry/subject.test.ts +0 -388
  254. package/src/db/registry/subject.ts +0 -129
  255. package/src/db/registry/types.ts +0 -10
  256. package/src/db/registry/utils/generate-id.test.ts +0 -216
  257. package/src/db/registry/utils/generate-id.ts +0 -133
  258. package/src/db/registry/utils.ts +0 -133
  259. package/src/db/schema/1.0.0/audit-log.ts +0 -15
  260. package/src/db/schema/1.0.0/consent-policy.ts +0 -14
  261. package/src/db/schema/1.0.0/consent-purpose.ts +0 -14
  262. package/src/db/schema/1.0.0/consent-record.ts +0 -10
  263. package/src/db/schema/1.0.0/consent.ts +0 -20
  264. package/src/db/schema/1.0.0/domain.ts +0 -12
  265. package/src/db/schema/1.0.0/index.ts +0 -48
  266. package/src/db/schema/1.0.0/subject.ts +0 -12
  267. package/src/db/schema/2.0.0/audit-log.ts +0 -18
  268. package/src/db/schema/2.0.0/consent-policy.ts +0 -28
  269. package/src/db/schema/2.0.0/consent-purpose.ts +0 -12
  270. package/src/db/schema/2.0.0/consent.ts +0 -26
  271. package/src/db/schema/2.0.0/domain.ts +0 -12
  272. package/src/db/schema/2.0.0/index.ts +0 -47
  273. package/src/db/schema/2.0.0/subject.ts +0 -14
  274. package/src/db/schema/index.ts +0 -15
  275. package/src/db/tenant-scope.test.ts +0 -750
  276. package/src/db/tenant-scope.ts +0 -103
  277. package/src/define-config.ts +0 -5
  278. package/src/handlers/consent/check.handler.ts +0 -126
  279. package/src/handlers/init/geo.test.ts +0 -317
  280. package/src/handlers/init/geo.ts +0 -195
  281. package/src/handlers/init/index.test.ts +0 -205
  282. package/src/handlers/init/index.ts +0 -114
  283. package/src/handlers/init/translations.test.ts +0 -121
  284. package/src/handlers/init/translations.ts +0 -72
  285. package/src/handlers/status/status.handler.test.ts +0 -155
  286. package/src/handlers/status/status.handler.ts +0 -51
  287. package/src/handlers/subject/get.handler.ts +0 -93
  288. package/src/handlers/subject/list.handler.ts +0 -93
  289. package/src/handlers/subject/patch.handler.ts +0 -122
  290. package/src/handlers/subject/post.handler.test.ts +0 -294
  291. package/src/handlers/subject/post.handler.ts +0 -254
  292. package/src/handlers/utils/consent-enrichment.test.ts +0 -380
  293. package/src/handlers/utils/consent-enrichment.ts +0 -218
  294. package/src/init.test.ts +0 -126
  295. package/src/init.ts +0 -87
  296. package/src/middleware/auth/index.ts +0 -11
  297. package/src/middleware/auth/validate-api-key.test.ts +0 -86
  298. package/src/middleware/auth/validate-api-key.ts +0 -107
  299. package/src/middleware/cors/cors.test.ts +0 -135
  300. package/src/middleware/cors/cors.ts +0 -186
  301. package/src/middleware/cors/is-origin-trusted.test.ts +0 -164
  302. package/src/middleware/cors/is-origin-trusted.ts +0 -130
  303. package/src/middleware/cors/process-cors.ts +0 -91
  304. package/src/middleware/openapi/config.ts +0 -29
  305. package/src/middleware/openapi/handlers.ts +0 -34
  306. package/src/middleware/process-ip/index.test.ts +0 -195
  307. package/src/middleware/process-ip/index.ts +0 -199
  308. package/src/router.ts +0 -15
  309. package/src/routes/consent.ts +0 -52
  310. package/src/routes/index.ts +0 -10
  311. package/src/routes/init.ts +0 -102
  312. package/src/routes/status.ts +0 -46
  313. package/src/routes/subject.ts +0 -152
  314. package/src/types/api.ts +0 -48
  315. package/src/types/index.ts +0 -288
  316. package/src/utils/create-telemetry-options.test.ts +0 -302
  317. package/src/utils/create-telemetry-options.ts +0 -229
  318. package/src/utils/env.ts +0 -84
  319. package/src/utils/extract-error-message.ts +0 -21
  320. package/src/utils/instrumentation.test.ts +0 -185
  321. package/src/utils/instrumentation.ts +0 -196
  322. package/src/utils/logger.ts +0 -41
  323. package/src/utils/metrics.test.ts +0 -323
  324. package/src/utils/metrics.ts +0 -402
  325. package/src/utils/telemetry-pii.test.ts +0 -325
  326. package/src/version.ts +0 -2
  327. package/tsconfig.json +0 -11
  328. package/vitest.config.ts +0 -28
  329. /package/dist/{types.js → types/index.js} +0 -0
  330. /package/{src/db/adapters/drizzle.ts → dist-types/db/adapters/drizzle.d.ts} +0 -0
  331. /package/{src/db/adapters/index.ts → dist-types/db/adapters/index.d.ts} +0 -0
  332. /package/{src/db/adapters/kysely.ts → dist-types/db/adapters/kysely.d.ts} +0 -0
  333. /package/{src/db/adapters/mongo.ts → dist-types/db/adapters/mongo.d.ts} +0 -0
  334. /package/{src/db/adapters/prisma.ts → dist-types/db/adapters/prisma.d.ts} +0 -0
  335. /package/{src/db/adapters/typeorm.ts → dist-types/db/adapters/typeorm.d.ts} +0 -0
  336. /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.0';
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