@blamejs/blamejs-shop 0.4.55 → 0.4.57

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 (399) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/lib/admin.js +385 -2
  3. package/lib/asset-manifest.json +1 -1
  4. package/lib/vendor/MANIFEST.json +426 -366
  5. package/lib/vendor/blamejs/.github/codeql/codeql-config.yml +25 -0
  6. package/lib/vendor/blamejs/.github/workflows/actions-lint.yml +3 -3
  7. package/lib/vendor/blamejs/.github/workflows/cflite_batch.yml +1 -1
  8. package/lib/vendor/blamejs/.github/workflows/cflite_pr.yml +1 -1
  9. package/lib/vendor/blamejs/.github/workflows/ci.yml +13 -13
  10. package/lib/vendor/blamejs/.github/workflows/codeql.yml +8 -7
  11. package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +2 -2
  12. package/lib/vendor/blamejs/.github/workflows/release-container.yml +4 -4
  13. package/lib/vendor/blamejs/.github/workflows/scorecard.yml +1 -1
  14. package/lib/vendor/blamejs/.github/workflows/sha-to-tag-verify.yml +1 -1
  15. package/lib/vendor/blamejs/CHANGELOG.md +2 -0
  16. package/lib/vendor/blamejs/api-snapshot.json +1381 -4
  17. package/lib/vendor/blamejs/eslint.config.mjs +1 -0
  18. package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +4 -1
  19. package/lib/vendor/blamejs/examples/wiki/lib/symbol-index.js +5 -2
  20. package/lib/vendor/blamejs/examples/wiki/routes/pages.js +4 -1
  21. package/lib/vendor/blamejs/fuzz/guard-text.fuzz.js +20 -0
  22. package/lib/vendor/blamejs/index.js +2 -0
  23. package/lib/vendor/blamejs/lib/a2a-tasks.js +7 -23
  24. package/lib/vendor/blamejs/lib/acme.js +6 -5
  25. package/lib/vendor/blamejs/lib/agent-event-bus.js +5 -4
  26. package/lib/vendor/blamejs/lib/agent-idempotency.js +2 -5
  27. package/lib/vendor/blamejs/lib/agent-orchestrator.js +2 -5
  28. package/lib/vendor/blamejs/lib/agent-saga.js +3 -5
  29. package/lib/vendor/blamejs/lib/agent-tenant.js +2 -5
  30. package/lib/vendor/blamejs/lib/ai-adverse-decision.js +2 -15
  31. package/lib/vendor/blamejs/lib/ai-capability.js +1 -6
  32. package/lib/vendor/blamejs/lib/ai-dp.js +1 -5
  33. package/lib/vendor/blamejs/lib/ai-input.js +2 -2
  34. package/lib/vendor/blamejs/lib/ai-pref.js +3 -8
  35. package/lib/vendor/blamejs/lib/ai-quota.js +3 -14
  36. package/lib/vendor/blamejs/lib/api-key.js +37 -28
  37. package/lib/vendor/blamejs/lib/archive-adapters.js +2 -4
  38. package/lib/vendor/blamejs/lib/archive-entry-policy.js +32 -0
  39. package/lib/vendor/blamejs/lib/archive-read.js +5 -17
  40. package/lib/vendor/blamejs/lib/archive-tar-read.js +5 -16
  41. package/lib/vendor/blamejs/lib/archive.js +2 -10
  42. package/lib/vendor/blamejs/lib/arg-parser.js +7 -6
  43. package/lib/vendor/blamejs/lib/asyncapi-traits.js +2 -6
  44. package/lib/vendor/blamejs/lib/atomic-file.js +108 -31
  45. package/lib/vendor/blamejs/lib/audit-chain.js +133 -53
  46. package/lib/vendor/blamejs/lib/audit-daily-review.js +24 -14
  47. package/lib/vendor/blamejs/lib/audit-emit.js +82 -0
  48. package/lib/vendor/blamejs/lib/audit-sign.js +257 -0
  49. package/lib/vendor/blamejs/lib/audit.js +84 -0
  50. package/lib/vendor/blamejs/lib/auth/access-lock.js +5 -27
  51. package/lib/vendor/blamejs/lib/auth/dpop.js +23 -35
  52. package/lib/vendor/blamejs/lib/auth/fido-mds3.js +9 -15
  53. package/lib/vendor/blamejs/lib/auth/jwt-external.js +26 -8
  54. package/lib/vendor/blamejs/lib/auth/jwt.js +13 -15
  55. package/lib/vendor/blamejs/lib/auth/lockout.js +6 -25
  56. package/lib/vendor/blamejs/lib/auth/oauth.js +67 -45
  57. package/lib/vendor/blamejs/lib/auth/oid4vci.js +55 -32
  58. package/lib/vendor/blamejs/lib/auth/oid4vp.js +3 -2
  59. package/lib/vendor/blamejs/lib/auth/openid-federation.js +6 -6
  60. package/lib/vendor/blamejs/lib/auth/passkey.js +3 -3
  61. package/lib/vendor/blamejs/lib/auth/password.js +7 -1
  62. package/lib/vendor/blamejs/lib/auth/saml.js +37 -27
  63. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-holder.js +2 -14
  64. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-issuer.js +2 -14
  65. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +1 -1
  66. package/lib/vendor/blamejs/lib/auth/status-list.js +7 -7
  67. package/lib/vendor/blamejs/lib/auth/step-up.js +6 -12
  68. package/lib/vendor/blamejs/lib/auth-bot-challenge.js +6 -37
  69. package/lib/vendor/blamejs/lib/backup/bundle.js +11 -18
  70. package/lib/vendor/blamejs/lib/backup/index.js +14 -47
  71. package/lib/vendor/blamejs/lib/bounded-map.js +112 -1
  72. package/lib/vendor/blamejs/lib/breach-deadline.js +1 -11
  73. package/lib/vendor/blamejs/lib/cache.js +7 -18
  74. package/lib/vendor/blamejs/lib/cbor.js +2 -1
  75. package/lib/vendor/blamejs/lib/cdn-cache-control.js +8 -9
  76. package/lib/vendor/blamejs/lib/cert.js +3 -10
  77. package/lib/vendor/blamejs/lib/chain-writer.js +162 -47
  78. package/lib/vendor/blamejs/lib/cli.js +5 -1
  79. package/lib/vendor/blamejs/lib/client-hints.js +7 -9
  80. package/lib/vendor/blamejs/lib/cloud-events.js +40 -31
  81. package/lib/vendor/blamejs/lib/cluster-storage.js +2 -38
  82. package/lib/vendor/blamejs/lib/cms-codec.js +2 -1
  83. package/lib/vendor/blamejs/lib/codepoint-class.js +67 -1
  84. package/lib/vendor/blamejs/lib/compliance-ai-act-logging.js +1 -6
  85. package/lib/vendor/blamejs/lib/compliance-ai-act-transparency.js +2 -4
  86. package/lib/vendor/blamejs/lib/compliance-eaa.js +1 -11
  87. package/lib/vendor/blamejs/lib/compliance-sanctions-fetcher.js +21 -28
  88. package/lib/vendor/blamejs/lib/compliance-sanctions.js +2 -14
  89. package/lib/vendor/blamejs/lib/compliance.js +2 -9
  90. package/lib/vendor/blamejs/lib/config-drift.js +2 -12
  91. package/lib/vendor/blamejs/lib/content-digest.js +10 -8
  92. package/lib/vendor/blamejs/lib/cookies.js +5 -11
  93. package/lib/vendor/blamejs/lib/cose.js +19 -11
  94. package/lib/vendor/blamejs/lib/cra-report.js +1 -11
  95. package/lib/vendor/blamejs/lib/crypto-field.js +5 -10
  96. package/lib/vendor/blamejs/lib/crypto.js +120 -3
  97. package/lib/vendor/blamejs/lib/csp.js +235 -3
  98. package/lib/vendor/blamejs/lib/daemon.js +42 -41
  99. package/lib/vendor/blamejs/lib/data-act.js +19 -9
  100. package/lib/vendor/blamejs/lib/db-query.js +6 -40
  101. package/lib/vendor/blamejs/lib/db.js +34 -12
  102. package/lib/vendor/blamejs/lib/dbsc.js +5 -6
  103. package/lib/vendor/blamejs/lib/ddl-change-control.js +18 -14
  104. package/lib/vendor/blamejs/lib/deprecate.js +4 -5
  105. package/lib/vendor/blamejs/lib/did.js +6 -2
  106. package/lib/vendor/blamejs/lib/dsr.js +8 -12
  107. package/lib/vendor/blamejs/lib/external-db-migrate.js +21 -22
  108. package/lib/vendor/blamejs/lib/external-db.js +14 -26
  109. package/lib/vendor/blamejs/lib/fda-21cfr11.js +12 -8
  110. package/lib/vendor/blamejs/lib/fdx.js +22 -18
  111. package/lib/vendor/blamejs/lib/file-upload.js +80 -66
  112. package/lib/vendor/blamejs/lib/flag-evaluation-context.js +5 -8
  113. package/lib/vendor/blamejs/lib/framework-error.js +12 -0
  114. package/lib/vendor/blamejs/lib/framework-schema.js +19 -0
  115. package/lib/vendor/blamejs/lib/fsm.js +7 -12
  116. package/lib/vendor/blamejs/lib/gate-contract.js +869 -38
  117. package/lib/vendor/blamejs/lib/gdpr-ropa.js +4 -13
  118. package/lib/vendor/blamejs/lib/graphql-federation.js +1 -1
  119. package/lib/vendor/blamejs/lib/guard-agent-registry.js +2 -1
  120. package/lib/vendor/blamejs/lib/guard-all.js +1 -0
  121. package/lib/vendor/blamejs/lib/guard-archive.js +9 -30
  122. package/lib/vendor/blamejs/lib/guard-auth.js +23 -80
  123. package/lib/vendor/blamejs/lib/guard-cidr.js +20 -96
  124. package/lib/vendor/blamejs/lib/guard-csv.js +135 -196
  125. package/lib/vendor/blamejs/lib/guard-domain.js +23 -106
  126. package/lib/vendor/blamejs/lib/guard-dsn.js +16 -13
  127. package/lib/vendor/blamejs/lib/guard-email.js +46 -53
  128. package/lib/vendor/blamejs/lib/guard-envelope.js +1 -1
  129. package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +2 -1
  130. package/lib/vendor/blamejs/lib/guard-filename.js +12 -60
  131. package/lib/vendor/blamejs/lib/guard-graphql.js +28 -75
  132. package/lib/vendor/blamejs/lib/guard-html-wcag.js +15 -2
  133. package/lib/vendor/blamejs/lib/guard-html.js +65 -117
  134. package/lib/vendor/blamejs/lib/guard-idempotency-key.js +2 -1
  135. package/lib/vendor/blamejs/lib/guard-image.js +280 -77
  136. package/lib/vendor/blamejs/lib/guard-imap-command.js +8 -9
  137. package/lib/vendor/blamejs/lib/guard-json.js +87 -103
  138. package/lib/vendor/blamejs/lib/guard-jsonpath.js +20 -88
  139. package/lib/vendor/blamejs/lib/guard-jwt.js +32 -114
  140. package/lib/vendor/blamejs/lib/guard-list-id.js +2 -7
  141. package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +2 -7
  142. package/lib/vendor/blamejs/lib/guard-mail-compose.js +5 -6
  143. package/lib/vendor/blamejs/lib/guard-mail-move.js +2 -1
  144. package/lib/vendor/blamejs/lib/guard-mail-query.js +5 -3
  145. package/lib/vendor/blamejs/lib/guard-mail-sieve.js +6 -7
  146. package/lib/vendor/blamejs/lib/guard-managesieve-command.js +5 -4
  147. package/lib/vendor/blamejs/lib/guard-markdown.js +76 -110
  148. package/lib/vendor/blamejs/lib/guard-message-id.js +5 -6
  149. package/lib/vendor/blamejs/lib/guard-mime.js +20 -99
  150. package/lib/vendor/blamejs/lib/guard-oauth.js +19 -73
  151. package/lib/vendor/blamejs/lib/guard-pdf.js +65 -72
  152. package/lib/vendor/blamejs/lib/guard-pop3-command.js +12 -13
  153. package/lib/vendor/blamejs/lib/guard-posture-chain.js +2 -1
  154. package/lib/vendor/blamejs/lib/guard-regex.js +24 -99
  155. package/lib/vendor/blamejs/lib/guard-saga-config.js +2 -1
  156. package/lib/vendor/blamejs/lib/guard-shell.js +22 -87
  157. package/lib/vendor/blamejs/lib/guard-smtp-command.js +8 -11
  158. package/lib/vendor/blamejs/lib/guard-sql.js +15 -13
  159. package/lib/vendor/blamejs/lib/guard-stream-args.js +2 -1
  160. package/lib/vendor/blamejs/lib/guard-svg.js +95 -140
  161. package/lib/vendor/blamejs/lib/guard-template.js +23 -80
  162. package/lib/vendor/blamejs/lib/guard-tenant-id.js +2 -1
  163. package/lib/vendor/blamejs/lib/guard-text.js +592 -0
  164. package/lib/vendor/blamejs/lib/guard-time.js +27 -95
  165. package/lib/vendor/blamejs/lib/guard-uuid.js +21 -93
  166. package/lib/vendor/blamejs/lib/guard-xml.js +76 -106
  167. package/lib/vendor/blamejs/lib/guard-yaml.js +24 -60
  168. package/lib/vendor/blamejs/lib/http-client-cache.js +5 -12
  169. package/lib/vendor/blamejs/lib/http-client-cookie-jar.js +2 -4
  170. package/lib/vendor/blamejs/lib/http-client.js +8 -21
  171. package/lib/vendor/blamejs/lib/http-message-signature.js +3 -2
  172. package/lib/vendor/blamejs/lib/i18n-messageformat.js +5 -7
  173. package/lib/vendor/blamejs/lib/i18n.js +83 -26
  174. package/lib/vendor/blamejs/lib/inbox.js +8 -8
  175. package/lib/vendor/blamejs/lib/incident-report.js +3 -21
  176. package/lib/vendor/blamejs/lib/ip-utils.js +49 -6
  177. package/lib/vendor/blamejs/lib/jobs.js +3 -2
  178. package/lib/vendor/blamejs/lib/keychain.js +6 -18
  179. package/lib/vendor/blamejs/lib/legal-hold.js +6 -15
  180. package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +44 -112
  181. package/lib/vendor/blamejs/lib/log-stream-otlp-grpc.js +17 -14
  182. package/lib/vendor/blamejs/lib/log-stream-otlp.js +16 -80
  183. package/lib/vendor/blamejs/lib/log-stream-webhook.js +20 -92
  184. package/lib/vendor/blamejs/lib/mail-arc-sign.js +8 -3
  185. package/lib/vendor/blamejs/lib/mail-arf.js +3 -2
  186. package/lib/vendor/blamejs/lib/mail-auth.js +40 -66
  187. package/lib/vendor/blamejs/lib/mail-bimi.js +19 -39
  188. package/lib/vendor/blamejs/lib/mail-crypto-pgp.js +3 -2
  189. package/lib/vendor/blamejs/lib/mail-dav.js +8 -35
  190. package/lib/vendor/blamejs/lib/mail-deploy.js +6 -9
  191. package/lib/vendor/blamejs/lib/mail-dkim.js +19 -38
  192. package/lib/vendor/blamejs/lib/mail-greylist.js +15 -26
  193. package/lib/vendor/blamejs/lib/mail-helo.js +2 -3
  194. package/lib/vendor/blamejs/lib/mail-journal.js +2 -1
  195. package/lib/vendor/blamejs/lib/mail-mdn.js +4 -3
  196. package/lib/vendor/blamejs/lib/mail-rbl.js +5 -8
  197. package/lib/vendor/blamejs/lib/mail-scan.js +2 -2
  198. package/lib/vendor/blamejs/lib/mail-send-deliver.js +33 -20
  199. package/lib/vendor/blamejs/lib/mail-server-imap.js +32 -87
  200. package/lib/vendor/blamejs/lib/mail-server-jmap.js +35 -51
  201. package/lib/vendor/blamejs/lib/mail-server-managesieve.js +29 -83
  202. package/lib/vendor/blamejs/lib/mail-server-mx.js +33 -74
  203. package/lib/vendor/blamejs/lib/mail-server-net.js +177 -0
  204. package/lib/vendor/blamejs/lib/mail-server-pop3.js +30 -83
  205. package/lib/vendor/blamejs/lib/mail-server-rate-limit.js +30 -6
  206. package/lib/vendor/blamejs/lib/mail-server-submission.js +34 -73
  207. package/lib/vendor/blamejs/lib/mail-server-tls.js +89 -0
  208. package/lib/vendor/blamejs/lib/mail-spam-score.js +7 -8
  209. package/lib/vendor/blamejs/lib/mail-store.js +3 -2
  210. package/lib/vendor/blamejs/lib/mail.js +6 -11
  211. package/lib/vendor/blamejs/lib/markup-escape.js +31 -0
  212. package/lib/vendor/blamejs/lib/markup-tokenizer.js +54 -0
  213. package/lib/vendor/blamejs/lib/mcp-tool-registry.js +26 -23
  214. package/lib/vendor/blamejs/lib/mcp.js +1 -1
  215. package/lib/vendor/blamejs/lib/mdoc.js +11 -12
  216. package/lib/vendor/blamejs/lib/metrics.js +32 -30
  217. package/lib/vendor/blamejs/lib/middleware/age-gate.js +3 -23
  218. package/lib/vendor/blamejs/lib/middleware/api-encrypt.js +11 -22
  219. package/lib/vendor/blamejs/lib/middleware/assetlinks.js +2 -7
  220. package/lib/vendor/blamejs/lib/middleware/bearer-auth.js +2 -1
  221. package/lib/vendor/blamejs/lib/middleware/body-parser.js +31 -48
  222. package/lib/vendor/blamejs/lib/middleware/bot-disclose.js +7 -10
  223. package/lib/vendor/blamejs/lib/middleware/bot-guard.js +2 -10
  224. package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +13 -2
  225. package/lib/vendor/blamejs/lib/middleware/daily-byte-quota.js +6 -26
  226. package/lib/vendor/blamejs/lib/middleware/deny-response.js +19 -1
  227. package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +7 -0
  228. package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +4 -20
  229. package/lib/vendor/blamejs/lib/middleware/rate-limit.js +20 -28
  230. package/lib/vendor/blamejs/lib/middleware/scim-server.js +3 -2
  231. package/lib/vendor/blamejs/lib/middleware/security-headers.js +9 -1
  232. package/lib/vendor/blamejs/lib/middleware/security-txt.js +2 -6
  233. package/lib/vendor/blamejs/lib/middleware/tus-upload.js +12 -27
  234. package/lib/vendor/blamejs/lib/middleware/web-app-manifest.js +2 -7
  235. package/lib/vendor/blamejs/lib/migrations.js +4 -13
  236. package/lib/vendor/blamejs/lib/mime-parse.js +34 -17
  237. package/lib/vendor/blamejs/lib/module-loader.js +44 -0
  238. package/lib/vendor/blamejs/lib/money.js +105 -0
  239. package/lib/vendor/blamejs/lib/mtls-ca.js +116 -36
  240. package/lib/vendor/blamejs/lib/network-byte-quota.js +4 -18
  241. package/lib/vendor/blamejs/lib/network-dane.js +8 -6
  242. package/lib/vendor/blamejs/lib/network-dns-resolver.js +97 -6
  243. package/lib/vendor/blamejs/lib/network-dnssec.js +16 -16
  244. package/lib/vendor/blamejs/lib/network-heartbeat.js +3 -2
  245. package/lib/vendor/blamejs/lib/network-smtp-policy.js +29 -41
  246. package/lib/vendor/blamejs/lib/network-tls.js +40 -42
  247. package/lib/vendor/blamejs/lib/nis2-report.js +1 -11
  248. package/lib/vendor/blamejs/lib/nonce-store.js +81 -3
  249. package/lib/vendor/blamejs/lib/numeric-bounds.js +22 -8
  250. package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +2 -6
  251. package/lib/vendor/blamejs/lib/object-store/azure-blob.js +5 -45
  252. package/lib/vendor/blamejs/lib/object-store/gcs.js +8 -71
  253. package/lib/vendor/blamejs/lib/object-store/http-put.js +1 -5
  254. package/lib/vendor/blamejs/lib/object-store/http-request.js +128 -0
  255. package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +2 -1
  256. package/lib/vendor/blamejs/lib/object-store/sigv4.js +9 -77
  257. package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +9 -25
  258. package/lib/vendor/blamejs/lib/observability.js +95 -0
  259. package/lib/vendor/blamejs/lib/openapi-paths-builder.js +7 -3
  260. package/lib/vendor/blamejs/lib/otel-export.js +7 -10
  261. package/lib/vendor/blamejs/lib/outbox.js +43 -37
  262. package/lib/vendor/blamejs/lib/pagination.js +11 -15
  263. package/lib/vendor/blamejs/lib/parsers/safe-env.js +5 -4
  264. package/lib/vendor/blamejs/lib/parsers/safe-ini.js +10 -4
  265. package/lib/vendor/blamejs/lib/parsers/safe-toml.js +11 -9
  266. package/lib/vendor/blamejs/lib/parsers/safe-xml.js +2 -2
  267. package/lib/vendor/blamejs/lib/parsers/safe-yaml.js +7 -6
  268. package/lib/vendor/blamejs/lib/pick.js +63 -5
  269. package/lib/vendor/blamejs/lib/pipl-cn.js +69 -59
  270. package/lib/vendor/blamejs/lib/privacy-pass.js +8 -6
  271. package/lib/vendor/blamejs/lib/problem-details.js +2 -5
  272. package/lib/vendor/blamejs/lib/pubsub.js +4 -8
  273. package/lib/vendor/blamejs/lib/redact.js +2 -1
  274. package/lib/vendor/blamejs/lib/render.js +4 -2
  275. package/lib/vendor/blamejs/lib/request-helpers.js +133 -6
  276. package/lib/vendor/blamejs/lib/restore.js +5 -22
  277. package/lib/vendor/blamejs/lib/retention.js +3 -5
  278. package/lib/vendor/blamejs/lib/safe-async.js +457 -0
  279. package/lib/vendor/blamejs/lib/safe-buffer.js +137 -6
  280. package/lib/vendor/blamejs/lib/safe-decompress.js +2 -1
  281. package/lib/vendor/blamejs/lib/safe-dns.js +2 -1
  282. package/lib/vendor/blamejs/lib/safe-ical.js +12 -26
  283. package/lib/vendor/blamejs/lib/safe-json.js +7 -8
  284. package/lib/vendor/blamejs/lib/safe-jsonpath.js +6 -5
  285. package/lib/vendor/blamejs/lib/safe-mime.js +25 -29
  286. package/lib/vendor/blamejs/lib/safe-redirect.js +2 -5
  287. package/lib/vendor/blamejs/lib/safe-schema.js +7 -6
  288. package/lib/vendor/blamejs/lib/safe-sql.js +126 -0
  289. package/lib/vendor/blamejs/lib/safe-vcard.js +12 -26
  290. package/lib/vendor/blamejs/lib/sandbox-worker.js +9 -2
  291. package/lib/vendor/blamejs/lib/sandbox.js +3 -2
  292. package/lib/vendor/blamejs/lib/scheduler.js +5 -12
  293. package/lib/vendor/blamejs/lib/sec-cyber.js +82 -37
  294. package/lib/vendor/blamejs/lib/seeders.js +4 -11
  295. package/lib/vendor/blamejs/lib/self-update.js +92 -69
  296. package/lib/vendor/blamejs/lib/session-device-binding.js +112 -66
  297. package/lib/vendor/blamejs/lib/session.js +194 -6
  298. package/lib/vendor/blamejs/lib/sql.js +225 -78
  299. package/lib/vendor/blamejs/lib/sse.js +6 -10
  300. package/lib/vendor/blamejs/lib/static.js +136 -98
  301. package/lib/vendor/blamejs/lib/storage.js +4 -2
  302. package/lib/vendor/blamejs/lib/structured-fields.js +275 -16
  303. package/lib/vendor/blamejs/lib/tenant-quota.js +2 -20
  304. package/lib/vendor/blamejs/lib/tsa.js +11 -15
  305. package/lib/vendor/blamejs/lib/validate-opts.js +154 -8
  306. package/lib/vendor/blamejs/lib/vault/seal-pem-file.js +30 -48
  307. package/lib/vendor/blamejs/lib/vault-aad.js +3 -2
  308. package/lib/vendor/blamejs/lib/vc.js +2 -7
  309. package/lib/vendor/blamejs/lib/vex.js +35 -13
  310. package/lib/vendor/blamejs/lib/web-push-vapid.js +23 -20
  311. package/lib/vendor/blamejs/lib/webhook-dispatcher.js +706 -0
  312. package/lib/vendor/blamejs/lib/webhook.js +43 -18
  313. package/lib/vendor/blamejs/lib/websocket-channels.js +9 -7
  314. package/lib/vendor/blamejs/lib/websocket.js +7 -3
  315. package/lib/vendor/blamejs/lib/worm.js +2 -3
  316. package/lib/vendor/blamejs/lib/ws-client.js +8 -10
  317. package/lib/vendor/blamejs/package.json +1 -1
  318. package/lib/vendor/blamejs/release-notes/v0.15.13.json +81 -0
  319. package/lib/vendor/blamejs/scripts/check-changelog-extract.js +1 -1
  320. package/lib/vendor/blamejs/test/00-primitives.js +136 -7
  321. package/lib/vendor/blamejs/test/10-state.js +9 -3
  322. package/lib/vendor/blamejs/test/30-chain.js +40 -0
  323. package/lib/vendor/blamejs/test/helpers/check.js +18 -0
  324. package/lib/vendor/blamejs/test/helpers/db.js +4 -0
  325. package/lib/vendor/blamejs/test/helpers/index.js +1 -0
  326. package/lib/vendor/blamejs/test/integration/audit-chain-external-db.test.js +2 -1
  327. package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +2 -1
  328. package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +8 -1
  329. package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +1 -1
  330. package/lib/vendor/blamejs/test/integration/framework-schema-mysql.test.js +2 -1
  331. package/lib/vendor/blamejs/test/integration/webhook-dispatcher-pg.test.js +269 -0
  332. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-fd-read.test.js +149 -0
  333. package/lib/vendor/blamejs/test/layer-0-primitives/audit-framework-namespaces.test.js +51 -0
  334. package/lib/vendor/blamejs/test/layer-0-primitives/audit-sign-anchor.test.js +88 -0
  335. package/lib/vendor/blamejs/test/layer-0-primitives/audit-use-store.test.js +55 -1
  336. package/lib/vendor/blamejs/test/layer-0-primitives/backup-object-store-adapter.test.js +2 -2
  337. package/lib/vendor/blamejs/test/layer-0-primitives/bot-guard.test.js +1 -1
  338. package/lib/vendor/blamejs/test/layer-0-primitives/bounded-map.test.js +129 -0
  339. package/lib/vendor/blamejs/test/layer-0-primitives/chain-writer-multichain.test.js +107 -0
  340. package/lib/vendor/blamejs/test/layer-0-primitives/cli-api-key.test.js +12 -0
  341. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +2788 -3214
  342. package/lib/vendor/blamejs/test/layer-0-primitives/codepoint-class.test.js +78 -0
  343. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-base64url.test.js +63 -0
  344. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-stream.test.js +2 -1
  345. package/lib/vendor/blamejs/test/layer-0-primitives/csp-builder.test.js +50 -0
  346. package/lib/vendor/blamejs/test/layer-0-primitives/csp-nonce.test.js +1 -1
  347. package/lib/vendor/blamejs/test/layer-0-primitives/daemon.test.js +2 -1
  348. package/lib/vendor/blamejs/test/layer-0-primitives/defineguard-resolve-opts.test.js +76 -0
  349. package/lib/vendor/blamejs/test/layer-0-primitives/flag.test.js +9 -0
  350. package/lib/vendor/blamejs/test/layer-0-primitives/gate-contract-content-gate.test.js +290 -0
  351. package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +84 -0
  352. package/lib/vendor/blamejs/test/layer-0-primitives/guard-email.test.js +78 -0
  353. package/lib/vendor/blamejs/test/layer-0-primitives/guard-filename.test.js +23 -0
  354. package/lib/vendor/blamejs/test/layer-0-primitives/guard-gate-disposition-coverage.test.js +93 -0
  355. package/lib/vendor/blamejs/test/layer-0-primitives/guard-html.test.js +60 -0
  356. package/lib/vendor/blamejs/test/layer-0-primitives/guard-image.test.js +184 -0
  357. package/lib/vendor/blamejs/test/layer-0-primitives/guard-imap-command.test.js +0 -0
  358. package/lib/vendor/blamejs/test/layer-0-primitives/guard-json.test.js +54 -0
  359. package/lib/vendor/blamejs/test/layer-0-primitives/guard-managesieve-command.test.js +10 -0
  360. package/lib/vendor/blamejs/test/layer-0-primitives/guard-markdown.test.js +45 -0
  361. package/lib/vendor/blamejs/test/layer-0-primitives/guard-pdf.test.js +101 -0
  362. package/lib/vendor/blamejs/test/layer-0-primitives/guard-pop3-command.test.js +18 -0
  363. package/lib/vendor/blamejs/test/layer-0-primitives/guard-svg.test.js +76 -0
  364. package/lib/vendor/blamejs/test/layer-0-primitives/guard-text.test.js +365 -0
  365. package/lib/vendor/blamejs/test/layer-0-primitives/guard-xml.test.js +35 -0
  366. package/lib/vendor/blamejs/test/layer-0-primitives/guard-yaml.test.js +36 -0
  367. package/lib/vendor/blamejs/test/layer-0-primitives/i18n.test.js +20 -0
  368. package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +15 -0
  369. package/lib/vendor/blamejs/test/layer-0-primitives/ip-utils.test.js +83 -0
  370. package/lib/vendor/blamejs/test/layer-0-primitives/mail-arf.test.js +10 -0
  371. package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +39 -0
  372. package/lib/vendor/blamejs/test/layer-0-primitives/mail-dkim.test.js +36 -0
  373. package/lib/vendor/blamejs/test/layer-0-primitives/mail-greylist.test.js +17 -0
  374. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-tls.test.js +39 -0
  375. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +17 -0
  376. package/lib/vendor/blamejs/test/layer-0-primitives/mime-parse.test.js +106 -0
  377. package/lib/vendor/blamejs/test/layer-0-primitives/money.test.js +17 -0
  378. package/lib/vendor/blamejs/test/layer-0-primitives/mtls-ca-revocation.test.js +98 -0
  379. package/lib/vendor/blamejs/test/layer-0-primitives/nonce-store-release.test.js +77 -0
  380. package/lib/vendor/blamejs/test/layer-0-primitives/observability.test.js +48 -0
  381. package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-memory-getorinsert.test.js +100 -0
  382. package/lib/vendor/blamejs/test/layer-0-primitives/request-helpers.test.js +88 -0
  383. package/lib/vendor/blamejs/test/layer-0-primitives/safe-async-loops.test.js +278 -0
  384. package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer-linear-scans.test.js +37 -0
  385. package/lib/vendor/blamejs/test/layer-0-primitives/safe-jsonpath.test.js +14 -0
  386. package/lib/vendor/blamejs/test/layer-0-primitives/sandbox.test.js +19 -0
  387. package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +1 -1
  388. package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +2 -1
  389. package/lib/vendor/blamejs/test/layer-0-primitives/session-device-binding.test.js +18 -0
  390. package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +1 -1
  391. package/lib/vendor/blamejs/test/layer-0-primitives/session-valid-from.test.js +73 -0
  392. package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +100 -0
  393. package/lib/vendor/blamejs/test/layer-0-primitives/structured-fields.test.js +80 -0
  394. package/lib/vendor/blamejs/test/layer-0-primitives/validate-opts-shape.test.js +235 -0
  395. package/lib/vendor/blamejs/test/layer-0-primitives/webhook-dispatcher.test.js +374 -0
  396. package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +75 -8
  397. package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +3 -3
  398. package/lib/winback-campaigns.js +202 -42
  399. package/package.json +1 -1
@@ -57,7 +57,9 @@ var nodeCrypto = require("node:crypto");
57
57
  var zlib = require("node:zlib");
58
58
  var asn1 = require("./asn1-der");
59
59
  var lazyRequire = require("./lazy-require");
60
+ var networkDnsResolver = lazyRequire(function () { return require("./network-dns-resolver"); });
60
61
  var validateOpts = require("./validate-opts");
62
+ var structuredFields = require("./structured-fields");
61
63
  var bCrypto = require("./crypto");
62
64
  var safeUrl = require("./safe-url");
63
65
  var safeJson = require("./safe-json");
@@ -91,14 +93,12 @@ function _parseStsPolicy(text) {
91
93
  "MTA-STS policy text is empty");
92
94
  }
93
95
  var policy = { version: null, mode: null, mx: [], max_age: null };
94
- var lines = text.split(/\r?\n/);
95
- for (var i = 0; i < lines.length; i += 1) {
96
- var line = lines[i].trim();
97
- if (line.length === 0) continue;
98
- var colonAt = line.indexOf(":");
99
- if (colonAt === -1) continue;
100
- var key = line.slice(0, colonAt).trim().toLowerCase();
101
- var val = line.slice(colonAt + 1).trim();
96
+ // RFC 8461 §3.2 — newline-separated `key: value` lines, no quoted-string;
97
+ // mx may repeat, so iterate pairs (a last-wins map would drop hosts).
98
+ var pairs = structuredFields.parseTagList(text, { sep: /\r?\n/, kvSep: ":" });
99
+ for (var i = 0; i < pairs.length; i += 1) {
100
+ var key = pairs[i][0];
101
+ var val = pairs[i][1];
102
102
  if (key === "version") policy.version = val;
103
103
  else if (key === "mode") policy.mode = val.toLowerCase();
104
104
  else if (key === "mx") policy.mx.push(val.toLowerCase());
@@ -123,17 +123,13 @@ function _parseStsPolicy(text) {
123
123
  // cached policy forever (defeating operator rotation), and would also
124
124
  // fetch policies from domains that don't publish one.
125
125
  async function _fetchStsTxt(domain, dnsLookup) {
126
- var records;
127
- try {
128
- records = dnsLookup
129
- ? await dnsLookup("_mta-sts." + domain, "TXT")
130
- : await dnsPromises.resolveTxt("_mta-sts." + domain);
131
- } catch (e) {
132
- if (e && (e.code === "ENOTFOUND" || e.code === "ENODATA")) return null;
133
- throw new SmtpPolicyError("smtp/mta-sts-txt-lookup-failed",
134
- "_mta-sts." + domain + " TXT lookup failed: " +
135
- ((e && e.message) || String(e)));
136
- }
126
+ // Secure DNS path — a spoofed _mta-sts TXT could downgrade mail TLS, so this
127
+ // must not use plaintext dnsPromises.
128
+ var records = await networkDnsResolver().safeResolveTxt("_mta-sts." + domain, {
129
+ dnsLookup: dnsLookup,
130
+ errorFactory: function (code, msg) { return new SmtpPolicyError(code, msg); },
131
+ code: "smtp/mta-sts-txt-lookup-failed",
132
+ });
137
133
  if (!Array.isArray(records)) return null;
138
134
  for (var i = 0; i < records.length; i += 1) {
139
135
  var rec = Array.isArray(records[i]) ? records[i].join("") : records[i];
@@ -577,19 +573,14 @@ async function tlsRptFetchPolicy(domain, opts) {
577
573
  }
578
574
  opts = opts || {};
579
575
  var qname = "_smtp._tls." + domain;
580
- var records;
581
- try {
582
- if (opts.dnsLookup) {
583
- records = await opts.dnsLookup(qname, "TXT");
584
- } else {
585
- records = await dnsPromises.resolveTxt(qname);
586
- }
587
- } catch (e) {
588
- if (e && (e.code === "ENOTFOUND" || e.code === "ENODATA")) return null;
589
- throw new SmtpPolicyError("smtp/tls-rpt-lookup-failed",
590
- "TLS-RPT TXT lookup for " + qname + " failed: " +
591
- ((e && e.message) || String(e)));
592
- }
576
+ // Secure DNS path — not plaintext dnsPromises (a spoofed TLS-RPT TXT could
577
+ // redirect failure reports).
578
+ var records = await networkDnsResolver().safeResolveTxt(qname, {
579
+ dnsLookup: opts.dnsLookup,
580
+ errorFactory: function (code, msg) { return new SmtpPolicyError(code, msg); },
581
+ code: "smtp/tls-rpt-lookup-failed",
582
+ });
583
+ if (records === null) return null;
593
584
  // Pick the first record that begins with v=TLSRPTv1 per RFC 8460 §3.
594
585
  var joined = "";
595
586
  for (var i = 0; i < (records || []).length; i += 1) {
@@ -598,16 +589,13 @@ async function tlsRptFetchPolicy(domain, opts) {
598
589
  if (/^v=TLSRPTv1\b/i.test(s)) { joined = s; break; }
599
590
  }
600
591
  if (joined.length === 0) return null;
601
- var parts = joined.split(";"); // allow:bare-split-on-quoted-header — allow:raw-time-literal — TLS-RPT record grammar (RFC 8460 §3): `tlsrpt-record = "v=TLSRPTv1;" *(WSP) tlsrpt-rua` with token-only values; no quoted-string
592
+ // TLS-RPT record grammar (RFC 8460 §3): `"v=TLSRPTv1;" *(WSP) tlsrpt-rua`
593
+ // with token-only values, no quoted-string — the naive split is correct.
594
+ var pairs = structuredFields.parseTagList(joined);
602
595
  var rua = [];
603
- for (var p = 0; p < parts.length; p += 1) {
604
- var t = parts[p].trim();
605
- var eq = t.indexOf("=");
606
- if (eq === -1) continue;
607
- var k = t.slice(0, eq).trim().toLowerCase();
608
- var v = t.slice(eq + 1).trim();
609
- if (k === "rua") {
610
- var uris = v.split(","); // allow:bare-split-on-quoted-header — allow:raw-time-literal — TLS-RPT rua grammar (RFC 8460 §3): rua = tlsrpt-uri *("," tlsrpt-uri); URIs percent-encode reserved chars, no quoted-string
596
+ for (var p = 0; p < pairs.length; p += 1) {
597
+ if (pairs[p][0] === "rua") {
598
+ var uris = pairs[p][1].split(","); // allow:bare-split-on-quoted-header — allow:raw-time-literal — TLS-RPT rua grammar (RFC 8460 §3): rua = tlsrpt-uri *("," tlsrpt-uri); URIs percent-encode reserved chars, no quoted-string
611
599
  for (var u = 0; u < uris.length; u += 1) {
612
600
  var uri = uris[u].trim();
613
601
  if (uri.length > 0) rua.push(uri);
@@ -5,6 +5,8 @@ var nodeFs = require("node:fs");
5
5
  var nodePath = require("node:path");
6
6
  var net = require("node:net");
7
7
  var nodeCrypto = require("node:crypto");
8
+ var numericBounds = require("./numeric-bounds");
9
+ var atomicFile = require("./atomic-file");
8
10
 
9
11
  var bCrypto = require("./crypto");
10
12
  var C = require("./constants");
@@ -103,7 +105,7 @@ function _certMetadata(pem) {
103
105
 
104
106
  function _isPathLike(s) {
105
107
  if (s.indexOf("-----BEGIN") !== -1) return false;
106
- if (s.length > C.BYTES.kib(1)) return false;
108
+ if (safeBuffer.byteLengthOf(s) > C.BYTES.kib(1)) return false;
107
109
  if (safeBuffer.hasCrlf(s)) return false;
108
110
  return true;
109
111
  }
@@ -115,20 +117,13 @@ function _isPathLike(s) {
115
117
  // shape, where an attacker who could swap the file in-between could
116
118
  // short-circuit the PEM marker check downstream.
117
119
  function _readPathFile(p) {
118
- var fd = nodeFs.openSync(p, "r");
119
- try {
120
- var fstat = nodeFs.fstatSync(fd);
121
- var buf = Buffer.alloc(fstat.size);
122
- var read = 0;
123
- while (read < fstat.size) {
124
- var n = nodeFs.readSync(fd, buf, read, fstat.size - read, null);
125
- if (n === 0) break;
126
- read += n;
127
- }
128
- return buf.slice(0, read).toString("utf8");
129
- } finally {
130
- try { nodeFs.closeSync(fd); } catch (_c) { /* close best-effort */ }
131
- }
120
+ // TOCTOU-safe read via atomic-file: utf8 string, slice on a short read,
121
+ // raw ENOENT preserved (errorFor returns undefined → rethrow).
122
+ return atomicFile.fdSafeReadSync(p, {
123
+ encoding: "utf8",
124
+ allowShortRead: true,
125
+ errorFor: function () { return undefined; },
126
+ });
132
127
  }
133
128
 
134
129
  function _readPath(p) {
@@ -198,6 +193,21 @@ function getTrustStore() {
198
193
  });
199
194
  }
200
195
 
196
+ // _certAuditMetadata(m) — the shared cert-identity fields stamped on every
197
+ // network.tls.ca.* audit event (the add / remove emitters overlay their
198
+ // own label / reason on top via Object.assign). Distinct from
199
+ // _certMetadata(pem), which PARSES a PEM into the meta object `m`.
200
+ function _certAuditMetadata(m) {
201
+ return {
202
+ subject: m.subject,
203
+ issuer: m.issuer,
204
+ fingerprint256: m.fingerprint256,
205
+ validFrom: m.validFrom,
206
+ validTo: m.validTo,
207
+ isSelfSigned: m.isSelfSigned,
208
+ };
209
+ }
210
+
201
211
  function _emitAuditRemove(metaList, reason) {
202
212
  var sink;
203
213
  try { sink = audit(); } catch (_e) { sink = null; }
@@ -208,16 +218,10 @@ function _emitAuditRemove(metaList, reason) {
208
218
  sink.safeEmit({
209
219
  action: "network.tls.ca.removed",
210
220
  outcome: "success",
211
- metadata: {
212
- subject: m.subject,
213
- issuer: m.issuer,
214
- fingerprint256: m.fingerprint256,
215
- validFrom: m.validFrom,
216
- validTo: m.validTo,
217
- isSelfSigned: m.isSelfSigned,
218
- label: m.label,
219
- reason: reason || "operator",
220
- },
221
+ metadata: Object.assign(_certAuditMetadata(m), {
222
+ label: m.label,
223
+ reason: reason || "operator",
224
+ }),
221
225
  });
222
226
  } catch (_e) { /* audit best-effort — never break the caller */ }
223
227
  }
@@ -515,7 +519,7 @@ var DEFAULT_PQC_KEY_SHARES = Object.freeze([
515
519
  ]);
516
520
 
517
521
  function _validateKeyShare(name) {
518
- if (typeof name !== "string" || name.length === 0 || name.length > C.BYTES.bytes(64)) { // bound
522
+ if (typeof name !== "string" || name.length === 0 || safeBuffer.byteLengthOf(name) > C.BYTES.bytes(64)) { // bound
519
523
  throw new TlsTrustError("tls/bad-key-share",
520
524
  "tls.pqc.setKeyShares: each entry must be a non-empty string up to 64 chars");
521
525
  }
@@ -714,15 +718,7 @@ function _emitAuditAdd(metaList, opts) {
714
718
  sink.safeEmit({
715
719
  action: "network.tls.ca.added",
716
720
  outcome: "success",
717
- metadata: {
718
- subject: m.subject,
719
- issuer: m.issuer,
720
- fingerprint256: m.fingerprint256,
721
- validFrom: m.validFrom,
722
- validTo: m.validTo,
723
- isSelfSigned: m.isSelfSigned,
724
- label: opts.label || null,
725
- },
721
+ metadata: Object.assign(_certAuditMetadata(m), { label: opts.label || null }),
726
722
  });
727
723
  } catch (_e) { /* audit best-effort — never break the caller */ }
728
724
  }
@@ -2701,11 +2697,8 @@ function connectWithEch(opts) {
2701
2697
  validateOpts.requireNonEmptyString(opts.host, "connectWithEch: host",
2702
2698
  NetworkTlsError, "tls/ech-bad-opts");
2703
2699
  var port = opts.port === undefined ? 443 : opts.port; // HTTPS default port
2704
- if (typeof port !== "number" || !isFinite(port) ||
2705
- port <= 0 || port > 65535 || Math.floor(port) !== port) { // TCP port range
2706
- throw new NetworkTlsError("tls/ech-bad-opts",
2707
- "connectWithEch: port must be an integer in 1..65535");
2708
- }
2700
+ numericBounds.requirePositiveFiniteInt(port,
2701
+ "connectWithEch: port", NetworkTlsError, "tls/ech-bad-opts", { max: 65535 });
2709
2702
  if (opts.alpn !== undefined && !Array.isArray(opts.alpn)) {
2710
2703
  throw new NetworkTlsError("tls/ech-bad-opts",
2711
2704
  "connectWithEch: alpn must be an array of strings");
@@ -2742,8 +2735,13 @@ function connectWithEch(opts) {
2742
2735
  if (typeof opts.checkServerIdentity === "function") {
2743
2736
  connectOpts.checkServerIdentity = opts.checkServerIdentity;
2744
2737
  }
2745
- if (opts.rejectUnauthorized === false) {
2746
- connectOpts.rejectUnauthorized = false;
2738
+ // rejectUnauthorized defaults to true (full validation). An operator may
2739
+ // explicitly opt out — audited, never a framework default. Derived from
2740
+ // the operator's own value (operator-governed shape, mirroring mail.js /
2741
+ // log-stream-syslog.js), not a hardcoded literal.
2742
+ var rejectUnauthorized = opts.rejectUnauthorized !== false;
2743
+ connectOpts.rejectUnauthorized = rejectUnauthorized;
2744
+ if (!rejectUnauthorized) {
2747
2745
  auditInsecureTls({ host: opts.host, port: port, source: "network.tls.connectWithEch" });
2748
2746
  }
2749
2747
  var echAttached = false;
@@ -66,7 +66,6 @@ function create(opts) {
66
66
  var sectorAnnex = opts.sectorAnnex;
67
67
  var csirtEndpoint = opts.csirtEndpoint || null;
68
68
  var httpClient = opts.httpClient || null;
69
- var auditOn = opts.audit !== false;
70
69
 
71
70
  var ir = incidentReport().create({
72
71
  audit: opts.audit,
@@ -79,16 +78,7 @@ function create(opts) {
79
78
  },
80
79
  });
81
80
 
82
- function _emitAudit(action, outcome, metadata) {
83
- if (!auditOn) return;
84
- try {
85
- audit().safeEmit({
86
- action: "nis2.report." + action,
87
- outcome: outcome,
88
- metadata: metadata || {},
89
- });
90
- } catch (_e) { /* drop-silent */ }
91
- }
81
+ var _emitAudit = audit().namespaced("nis2.report", opts.audit);
92
82
 
93
83
  async function _submitToCsirt(payload) {
94
84
  if (!csirtEndpoint || !httpClient) {
@@ -13,6 +13,16 @@
13
13
  * inserting second would race on concurrent requests carrying
14
14
  * the same nonce.
15
15
  *
16
+ * await store.release(nonce) → boolean
17
+ * Un-claims a single nonce so a later checkAndInsert of the same value
18
+ * succeeds again — the rollback half of reserve -> commit -> rollback.
19
+ * A handler that claims an event id the moment a signature verifies (to
20
+ * win the race against a concurrent duplicate) MUST release it when
21
+ * downstream processing fails, otherwise the provider's at-least-once
22
+ * redelivery is reported as a replay and the event is dropped. Returns
23
+ * whether a live claim existed. Pair with checkAndInsert; without it an
24
+ * eager claim inverts the at-least-once contract on any failure.
25
+ *
16
26
  * await store.purgeExpired() → number
17
27
  * Removes entries past their expireAt. Called periodically by the
18
28
  * middleware that uses the store. Returns the count purged.
@@ -32,8 +42,11 @@
32
42
  * table _blamejs_api_encrypt_nonces. The PRIMARY KEY race is what
33
43
  * makes the check + insert atomic across nodes.
34
44
  *
35
- * { checkAndInsert, purgeExpired, close } — operator-supplied
36
- * custom backend (Redis SETNX, Memcached add, etc.). Use this
45
+ * { checkAndInsert, release?, purgeExpired?, close? } — operator-supplied
46
+ * custom backend (Redis SETNX, Memcached add, etc.). release() is
47
+ * optional but required to use reserve -> rollback; a backend omitting
48
+ * it throws NONCE_BACKEND_NO_RELEASE the first time release() is called
49
+ * (a loud gap, never a silent dropped rollback). Use this
37
50
  * for cross-process accuracy without a per-request SQL hop.
38
51
  *
39
52
  * Sweep cadence: memory backend sweeps every opts.sweepIntervalMs
@@ -132,6 +145,21 @@ function _memoryBackend(opts) {
132
145
  return Promise.resolve(true);
133
146
  }
134
147
 
148
+ // Un-claim a nonce so a future checkAndInsert of the same value succeeds
149
+ // again — the rollback half of reserve -> commit -> rollback. A handler
150
+ // that claims an event id the moment a signature verifies (to win the race
151
+ // against a concurrent duplicate) MUST release it when downstream processing
152
+ // fails, otherwise the provider's at-least-once redelivery is reported as a
153
+ // replay and the event is dropped. Returns whether a live claim existed.
154
+ function release(nonce) {
155
+ if (typeof nonce !== "string" || nonce.length === 0) {
156
+ return Promise.reject(_err("INVALID_NONCE", "nonce must be a non-empty string"));
157
+ }
158
+ var existed = seen.get(nonce) !== undefined;
159
+ if (existed) seen.delete(nonce);
160
+ return Promise.resolve(existed);
161
+ }
162
+
135
163
  function purgeExpired() {
136
164
  return Promise.resolve(_purgeExpiredSync());
137
165
  }
@@ -144,6 +172,7 @@ function _memoryBackend(opts) {
144
172
  return {
145
173
  name: "memory",
146
174
  checkAndInsert: checkAndInsert,
175
+ release: release,
147
176
  purgeExpired: purgeExpired,
148
177
  close: close,
149
178
  // Test hooks — underlying entry count + count of capacity fail-closed
@@ -178,6 +207,19 @@ function _clusterBackend(_opts) {
178
207
  return (result && result.rowCount > 0);
179
208
  }
180
209
 
210
+ async function release(nonce) {
211
+ if (typeof nonce !== "string" || nonce.length === 0) {
212
+ throw _err("INVALID_NONCE", "nonce must be a non-empty string");
213
+ }
214
+ // Un-claim a single nonce (the reserve -> rollback half). The middleware
215
+ // hashes the raw nonce before it reaches here, so we delete by hash.
216
+ var built = sql.delete(frameworkSchema.tableName(NONCE_TABLE), _nonceSqlOpts())
217
+ .where("nonceHash", "=", nonce)
218
+ .toSql();
219
+ var result = await clusterStorage.execute(built.sql, built.params);
220
+ return (result && result.rowCount > 0);
221
+ }
222
+
181
223
  async function purgeExpired() {
182
224
  var built = sql.delete(frameworkSchema.tableName(NONCE_TABLE), _nonceSqlOpts())
183
225
  .where("expireAt", "<=", Date.now())
@@ -191,6 +233,7 @@ function _clusterBackend(_opts) {
191
233
  return {
192
234
  name: "cluster",
193
235
  checkAndInsert: checkAndInsert,
236
+ release: release,
194
237
  purgeExpired: purgeExpired,
195
238
  close: close,
196
239
  };
@@ -208,6 +251,15 @@ function create(opts) {
208
251
  return Object.assign({
209
252
  name: "custom",
210
253
  purgeExpired: function () { return Promise.resolve(0); },
254
+ // A custom backend that omits release() cannot participate in
255
+ // reserve -> rollback. Fail LOUDLY (not a silent no-op) so the gap
256
+ // surfaces the first time a handler tries to un-claim, rather than
257
+ // silently dropping the rollback and inverting the at-least-once contract.
258
+ release: function () {
259
+ return Promise.reject(_err("BACKEND_NO_RELEASE",
260
+ "this custom nonce backend does not implement release(nonce); " +
261
+ "the reserve -> commit -> rollback pattern requires it"));
262
+ },
211
263
  close: function () {},
212
264
  }, backend);
213
265
  }
@@ -215,11 +267,37 @@ function create(opts) {
215
267
  if (!backend || backend === "memory") return _memoryBackend(opts);
216
268
  throw _err("UNKNOWN_BACKEND",
217
269
  "nonce-store: unknown backend '" + backend +
218
- "' (must be 'memory', 'cluster', or { checkAndInsert, purgeExpired, close })");
270
+ "' (must be 'memory', 'cluster', or { checkAndInsert, release?, purgeExpired?, close? })");
271
+ }
272
+
273
+ // enforceReplay(store, jti, expireAtMs, opts) — single-use enforcement
274
+ // against a replay store: `await store.checkAndInsert(jti, expireAtMs)`,
275
+ // raising opts.errorClass(opts.storeFailedCode, …) if the store itself
276
+ // fails (a store outage must NOT be mistaken for a clean token) and
277
+ // opts.errorClass(opts.replayCode, "<opts.tokenLabel> jti='<jti>' has
278
+ // been seen before — replay refused") if the jti was already seen. The
279
+ // fail-closed anti-replay control flow every JWT / DPoP verifier repeated
280
+ // identically — centralised here so the contract lives in one place.
281
+ // Verifiers with a divergent message or store contract (e.g. an atomic
282
+ // back-channel-logout-token store) keep their own inline check.
283
+ async function enforceReplay(store, jti, expireAtMs, opts) {
284
+ opts = opts || {};
285
+ var inserted;
286
+ try {
287
+ inserted = await store.checkAndInsert(jti, expireAtMs);
288
+ } catch (e) {
289
+ throw new opts.errorClass(opts.storeFailedCode,
290
+ "replayStore.checkAndInsert threw: " + ((e && e.message) || String(e)));
291
+ }
292
+ if (inserted === false) {
293
+ throw new opts.errorClass(opts.replayCode,
294
+ opts.tokenLabel + " jti='" + jti + "' has been seen before — replay refused");
295
+ }
219
296
  }
220
297
 
221
298
  module.exports = {
222
299
  create: create,
300
+ enforceReplay: enforceReplay,
223
301
  NonceStoreError: NonceStoreError,
224
302
  _memoryBackend: _memoryBackend,
225
303
  _clusterBackend: _clusterBackend,
@@ -42,6 +42,20 @@ function shape(value) {
42
42
  return (typeof value) + " " + String(value);
43
43
  }
44
44
 
45
+ // _throwInt — construct + throw a code-first defineClass error. When no
46
+ // errorOpts is supplied the call is the historical bare `new ErrorClass(
47
+ // code, message)` (byte-identical for every existing caller); pass
48
+ // errorOpts { permanent, statusCode } to forward the framework error's
49
+ // non-retryable flag / HTTP status (a config opt that's wrong on retry
50
+ // stays wrong; a request-shaped opt carries its 4xx). Message-FIRST
51
+ // classes (AtomicFileError / SafeBufferError / SafeUrlError) must NOT use
52
+ // the require* throwers — they use the isPositiveFiniteInt predicate + their
53
+ // own throw (see the module header) so code/message don't swap.
54
+ function _throwInt(errorClass, code, message, errorOpts) {
55
+ if (errorOpts) throw new errorClass(code, message, errorOpts.permanent, errorOpts.statusCode);
56
+ throw new errorClass(code, message);
57
+ }
58
+
45
59
  function isPositiveFiniteInt(value) {
46
60
  return typeof value === "number" && Number.isFinite(value) &&
47
61
  Number.isInteger(value) && value > 0;
@@ -64,11 +78,11 @@ function isNonNegativeFiniteInt(value) {
64
78
  // nb.requirePositiveFiniteIntIfPresent(opts.graceMs,
65
79
  // "app-shutdown.create: opts.graceMs", AppShutdownError,
66
80
  // "app-shutdown/bad-grace-ms");
67
- function requirePositiveFiniteIntIfPresent(value, label, errorClass, code) {
81
+ function requirePositiveFiniteIntIfPresent(value, label, errorClass, code, errorOpts) {
68
82
  if (value === undefined) return value;
69
83
  if (!isPositiveFiniteInt(value)) {
70
- throw new errorClass(code,
71
- (label || "value") + " must be a positive finite integer; got " + shape(value));
84
+ _throwInt(errorClass, code,
85
+ (label || "value") + " must be a positive finite integer; got " + shape(value), errorOpts);
72
86
  }
73
87
  return value;
74
88
  }
@@ -102,13 +116,13 @@ function _rangeSuffix(range) {
102
116
  if (range.min != null) return " >= " + range.min;
103
117
  return "";
104
118
  }
105
- function requirePositiveFiniteInt(value, label, errorClass, code, range) {
119
+ function requirePositiveFiniteInt(value, label, errorClass, code, range, errorOpts) {
106
120
  var inRange = !range ||
107
121
  ((range.min == null || value >= range.min) && (range.max == null || value <= range.max));
108
122
  if (!isPositiveFiniteInt(value) || !inRange) {
109
- throw new errorClass(code,
123
+ _throwInt(errorClass, code,
110
124
  (label || "value") + " must be a positive finite integer" +
111
- _rangeSuffix(range) + "; got " + shape(value));
125
+ _rangeSuffix(range) + "; got " + shape(value), errorOpts);
112
126
  }
113
127
  return value;
114
128
  }
@@ -123,12 +137,12 @@ function requirePositiveFiniteInt(value, label, errorClass, code, range) {
123
137
  // nb.requireAllPositiveFiniteIntIfPresent(opts,
124
138
  // ["maxBytes", "maxAttrValueBytes", "maxTagDepth", "maxAttrsPerTag"],
125
139
  // "guardHtml.validate", GuardHtmlError, "html.bad-opt");
126
- function requireAllPositiveFiniteIntIfPresent(opts, names, labelPrefix, errorClass, code) {
140
+ function requireAllPositiveFiniteIntIfPresent(opts, names, labelPrefix, errorClass, code, errorOpts) {
127
141
  if (!opts || !Array.isArray(names)) return;
128
142
  for (var i = 0; i < names.length; i += 1) {
129
143
  var n = names[i];
130
144
  requirePositiveFiniteIntIfPresent(opts[n],
131
- (labelPrefix || "") + ": " + n, errorClass, code);
145
+ (labelPrefix || "") + ": " + n, errorClass, code, errorOpts);
132
146
  }
133
147
  }
134
148
 
@@ -33,6 +33,7 @@ var C = require("../constants");
33
33
  var httpClient = require("../http-client");
34
34
  var requestHelpers = require("../request-helpers");
35
35
  var safeUrl = require("../safe-url");
36
+ var markupEscape = require("../markup-escape").markupEscape;
36
37
  var { ObjectStoreError } = require("../framework-error");
37
38
 
38
39
  var _err = ObjectStoreError.factory;
@@ -122,12 +123,7 @@ function _validateCorsRule(rule, idx) {
122
123
  }
123
124
 
124
125
  function _xmlEscape(s) {
125
- return String(s)
126
- .replace(/&/g, "&amp;")
127
- .replace(/</g, "&lt;")
128
- .replace(/>/g, "&gt;")
129
- .replace(/"/g, "&quot;")
130
- .replace(/'/g, "&apos;");
126
+ return markupEscape(s, { apos: "&apos;" });
131
127
  }
132
128
 
133
129
  function _buildCorsXml(rules) {
@@ -93,14 +93,6 @@ function _encodeBlobKey(key) {
93
93
 
94
94
  var DEFAULT_API_VERSION = "2024-08-04";
95
95
 
96
- // Service SAS expiry bounds. Azure doesn't enforce a hard max, but
97
- // matching the SigV4 / V4 7-day cap keeps semantics uniform across
98
- // backends and reflects best practice (long-lived SAS tokens are
99
- // effectively credentials).
100
- var SAS_DEFAULT_EXPIRES_SECONDS = C.TIME.minutes(15) / C.TIME.seconds(1);
101
- var SAS_MAX_EXPIRES_SECONDS = C.TIME.days(7) / C.TIME.seconds(1);
102
- var SAS_MIN_EXPIRES_SECONDS = 1;
103
-
104
96
  var _err = ObjectStoreError.factory;
105
97
 
106
98
  var _httpRequest = sharedRequest;
@@ -312,33 +304,13 @@ function create(config) {
312
304
  function getResponse(key, opts) {
313
305
  opts = opts || {};
314
306
  var url = _blobUrl(key);
315
- var extraHeaders = {};
316
- if (opts.range) {
317
- extraHeaders["x-ms-range"] = "bytes=" + opts.range.start + "-" + opts.range.end;
318
- }
319
- if (opts.ifNoneMatch) extraHeaders["If-None-Match"] = opts.ifNoneMatch;
320
- if (opts.ifMatch) extraHeaders["If-Match"] = opts.ifMatch;
321
- if (opts.ifModifiedSince) extraHeaders["If-Modified-Since"] = opts.ifModifiedSince;
322
- if (opts.ifUnmodifiedSince) extraHeaders["If-Unmodified-Since"] = opts.ifUnmodifiedSince;
307
+ var extraHeaders = sharedRequest.applyConditionalGetHeaders({}, opts, "x-ms-range");
323
308
  var headers = _signed("GET", url, extraHeaders);
324
309
  return _httpRequest("GET", url, headers, null, reqOpts).then(function (res) {
325
- return {
326
- statusCode: res.statusCode,
327
- body: res.body,
328
- etag: res.headers && res.headers.etag,
329
- lastModified: res.headers && res.headers["last-modified"]
330
- ? Date.parse(res.headers["last-modified"]) : null,
331
- contentRange: res.headers && res.headers["content-range"] || null,
332
- size: res.headers && res.headers["content-length"]
333
- ? parseInt(res.headers["content-length"], 10) : null,
334
- contentType: res.headers && res.headers["content-type"] || null,
335
- };
310
+ return sharedRequest.mapGetResponse(res);
336
311
  }, function (err) {
337
312
  if (err && err.statusCode === requestHelpers.HTTP_STATUS.NOT_MODIFIED) {
338
- return {
339
- statusCode: requestHelpers.HTTP_STATUS.NOT_MODIFIED,
340
- body: null, etag: null, lastModified: null,
341
- };
313
+ return sharedRequest.notModifiedGetResult();
342
314
  }
343
315
  throw err;
344
316
  });
@@ -348,11 +320,7 @@ function create(config) {
348
320
  var url = _blobUrl(key);
349
321
  var headers = _signed("HEAD", url, {});
350
322
  return _httpRequest("HEAD", url, headers, null, reqOpts).then(function (res) {
351
- return {
352
- size: res.headers["content-length"] ? parseInt(res.headers["content-length"], 10) : null,
353
- etag: res.headers.etag,
354
- lastModified: res.headers["last-modified"] ? Date.parse(res.headers["last-modified"]) : null,
355
- };
323
+ return sharedRequest.mapHeadResponse(res);
356
324
  });
357
325
  }
358
326
 
@@ -415,15 +383,7 @@ function create(config) {
415
383
  // "Create a service SAS". We sign with the account key (HMAC-SHA256
416
384
  // over the canonical string) and emit the token as URL query params.
417
385
  function _buildSasToken(permissions, opts) {
418
- var expiresIn = opts.expiresIn != null ? opts.expiresIn : SAS_DEFAULT_EXPIRES_SECONDS;
419
- if (typeof expiresIn !== "number" ||
420
- expiresIn < SAS_MIN_EXPIRES_SECONDS ||
421
- expiresIn > SAS_MAX_EXPIRES_SECONDS) {
422
- throw _err("INVALID_EXPIRES",
423
- "presigned URL: expiresIn must be a number of seconds between " +
424
- SAS_MIN_EXPIRES_SECONDS + " and " + SAS_MAX_EXPIRES_SECONDS +
425
- " (7 days)", true);
426
- }
386
+ var expiresIn = sharedRequest.resolvePresignExpires(opts, "presigned URL", "");
427
387
  var nowDate = opts.date || new Date();
428
388
  var expiry = new Date(nowDate.getTime() + C.TIME.seconds(expiresIn));
429
389
  // Azure accepts ISO 8601 with second precision; strip ms.