@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
@@ -40,11 +40,12 @@
40
40
  */
41
41
 
42
42
  var lazyRequire = require("./lazy-require");
43
- var audit = lazyRequire(function () { return require("./audit"); });
43
+ var auditEmit = require("./audit-emit");
44
44
  var log = lazyRequire(function () { return require("./log").boot("scheduler"); });
45
45
  var clusterStorage = require("./cluster-storage");
46
46
  var sql = require("./sql");
47
47
  var validateOpts = require("./validate-opts");
48
+ var boundedMap = require("./bounded-map");
48
49
  var C = require("./constants");
49
50
  var { SchedulerError } = require("./framework-error");
50
51
 
@@ -417,15 +418,7 @@ function create(opts) {
417
418
 
418
419
  var _err = SchedulerError.factory;
419
420
 
420
- function _emit(action, info, outcome) {
421
- if (!auditOn) return;
422
- audit().safeEmit({
423
- action: action,
424
- outcome: outcome,
425
- metadata: info || {},
426
- reason: info && info.reason ? info.reason : null,
427
- });
428
- }
421
+ var _emit = auditEmit.gatedReasonEmitter({ audit: auditOn });
429
422
 
430
423
  function _isLeaderHere() {
431
424
  if (!clusterInstance) return true;
@@ -447,10 +440,10 @@ function create(opts) {
447
440
  if (typeof spec.name !== "string" || spec.name.length === 0) {
448
441
  throw _err("INVALID_NAME", "scheduler.schedule: spec.name is required", true);
449
442
  }
450
- if (tasks.has(spec.name)) {
443
+ boundedMap.requireAbsent(tasks, spec.name, function () {
451
444
  throw _err("DUPLICATE_NAME",
452
445
  "scheduler.schedule: '" + spec.name + "' is already scheduled", true);
453
- }
446
+ });
454
447
 
455
448
  var hasCron = typeof spec.cron === "string";
456
449
  var hasEvery = typeof spec.every === "number";
@@ -94,45 +94,90 @@ function eightKArtifact(opts) {
94
94
  throw SecCyberError.factory("sec-cyber/bad-opts",
95
95
  "secCyber.eightKArtifact: opts required");
96
96
  }
97
- validateOpts.requireNonEmptyString(opts.incidentId,
98
- "secCyber.eightKArtifact: incidentId", SecCyberError, "BAD_INCIDENT_ID");
99
- if (!opts.registrant || typeof opts.registrant !== "object") {
100
- throw SecCyberError.factory("sec-cyber/bad-registrant",
101
- "secCyber.eightKArtifact: registrant object required");
102
- }
103
- validateOpts.requireNonEmptyString(opts.registrant.name,
104
- "secCyber.eightKArtifact: registrant.name", SecCyberError, "BAD_REGISTRANT_NAME");
105
- validateOpts.requireNonEmptyString(opts.registrant.cik,
106
- "secCyber.eightKArtifact: registrant.cik", SecCyberError, "BAD_CIK");
107
- numericBounds.requirePositiveFiniteIntIfPresent(opts.detectedAt,
108
- "secCyber.eightKArtifact: detectedAt", SecCyberError, "BAD_DETECTED_AT");
109
- numericBounds.requirePositiveFiniteIntIfPresent(opts.materialityDeterminedAt,
110
- "secCyber.eightKArtifact: materialityDeterminedAt", SecCyberError, "BAD_MAT_AT");
111
-
112
- if (FINDINGS.indexOf(opts.materialityFinding) === -1) {
113
- throw SecCyberError.factory("sec-cyber/bad-finding",
114
- "secCyber.eightKArtifact: materialityFinding must be one of " + FINDINGS.join(", "));
115
- }
116
- validateOpts.requireNonEmptyString(opts.materialityReasoning,
117
- "secCyber.eightKArtifact: materialityReasoning", SecCyberError, "BAD_REASONING");
118
-
119
- if (opts.materialityFinding === "material") {
120
- validateOpts.requireNonEmptyString(opts.nature,
121
- "secCyber.eightKArtifact: nature", SecCyberError, "BAD_NATURE");
122
- validateOpts.requireNonEmptyString(opts.scope,
123
- "secCyber.eightKArtifact: scope", SecCyberError, "BAD_SCOPE");
124
- validateOpts.requireNonEmptyString(opts.timing,
125
- "secCyber.eightKArtifact: timing", SecCyberError, "BAD_TIMING");
126
- validateOpts.requireNonEmptyString(opts.impact,
127
- "secCyber.eightKArtifact: impact", SecCyberError, "BAD_IMPACT");
128
- }
97
+ validateOpts.shape(opts, {
98
+ incidentId: "required-string",
99
+ registrant: function (registrant) {
100
+ if (!registrant || typeof registrant !== "object") {
101
+ throw SecCyberError.factory("sec-cyber/bad-registrant",
102
+ "secCyber.eightKArtifact: registrant object required");
103
+ }
104
+ validateOpts.requireNonEmptyString(registrant.name,
105
+ "secCyber.eightKArtifact: registrant.name", SecCyberError, "BAD_REGISTRANT_NAME");
106
+ validateOpts.requireNonEmptyString(registrant.cik,
107
+ "secCyber.eightKArtifact: registrant.cik", SecCyberError, "BAD_CIK");
108
+ },
109
+ detectedAt: function (detectedAt) {
110
+ numericBounds.requirePositiveFiniteIntIfPresent(detectedAt,
111
+ "secCyber.eightKArtifact: detectedAt", SecCyberError, "BAD_DETECTED_AT");
112
+ },
113
+ materialityDeterminedAt: function (materialityDeterminedAt) {
114
+ numericBounds.requirePositiveFiniteIntIfPresent(materialityDeterminedAt,
115
+ "secCyber.eightKArtifact: materialityDeterminedAt", SecCyberError, "BAD_MAT_AT");
116
+ },
117
+ // materialityFinding / materialityReasoning and the material-only fields
118
+ // (nature/scope/timing/impact) and the AG-delay fields each carry their own
119
+ // per-field code (BAD_FINDING / BAD_REASONING / BAD_NATURE / ... /
120
+ // BAD_AG_JUSTIFICATION). Cross-field requiredness (the material-only and
121
+ // AG-delay fields) lives in the function rule via the 5th `opts` arg, so the
122
+ // whole contract is enforced inside this one exhaustive shape.
123
+ materialityFinding: function (v) {
124
+ if (FINDINGS.indexOf(v) === -1) {
125
+ throw SecCyberError.factory("sec-cyber/bad-finding",
126
+ "secCyber.eightKArtifact: materialityFinding must be one of " + FINDINGS.join(", "));
127
+ }
128
+ },
129
+ materialityReasoning: function (v) {
130
+ validateOpts.requireNonEmptyString(v,
131
+ "secCyber.eightKArtifact: materialityReasoning", SecCyberError, "BAD_REASONING");
132
+ },
133
+ nature: function (v, label, e, c, o) {
134
+ if (o.materialityFinding === "material") {
135
+ validateOpts.requireNonEmptyString(v,
136
+ "secCyber.eightKArtifact: nature", SecCyberError, "BAD_NATURE");
137
+ } else {
138
+ validateOpts.optionalNonEmptyString(v, label, e, c);
139
+ }
140
+ },
141
+ scope: function (v, label, e, c, o) {
142
+ if (o.materialityFinding === "material") {
143
+ validateOpts.requireNonEmptyString(v,
144
+ "secCyber.eightKArtifact: scope", SecCyberError, "BAD_SCOPE");
145
+ } else {
146
+ validateOpts.optionalNonEmptyString(v, label, e, c);
147
+ }
148
+ },
149
+ timing: function (v, label, e, c, o) {
150
+ if (o.materialityFinding === "material") {
151
+ validateOpts.requireNonEmptyString(v,
152
+ "secCyber.eightKArtifact: timing", SecCyberError, "BAD_TIMING");
153
+ } else {
154
+ validateOpts.optionalNonEmptyString(v, label, e, c);
155
+ }
156
+ },
157
+ impact: function (v, label, e, c, o) {
158
+ if (o.materialityFinding === "material") {
159
+ validateOpts.requireNonEmptyString(v,
160
+ "secCyber.eightKArtifact: impact", SecCyberError, "BAD_IMPACT");
161
+ } else {
162
+ validateOpts.optionalNonEmptyString(v, label, e, c);
163
+ }
164
+ },
165
+ agDelayRequested: "optional-boolean",
166
+ agDelayJustification: function (v, label, e, c, o) {
167
+ if (o.agDelayRequested === true) {
168
+ validateOpts.requireNonEmptyString(v,
169
+ "secCyber.eightKArtifact: agDelayJustification (required when agDelayRequested=true)",
170
+ SecCyberError, "BAD_AG_JUSTIFICATION");
171
+ } else {
172
+ validateOpts.optionalNonEmptyString(v, label, e, c);
173
+ }
174
+ },
175
+ // audit is a boolean toggle (`opts.audit !== false` suppresses emission);
176
+ // the emit uses the module-level b.audit sink, not this value.
177
+ audit: "optional-boolean",
178
+ }, "secCyber.eightKArtifact", SecCyberError, "BAD_INCIDENT_ID");
129
179
 
130
180
  var agDelayRequested = opts.agDelayRequested === true;
131
- if (agDelayRequested) {
132
- validateOpts.requireNonEmptyString(opts.agDelayJustification,
133
- "secCyber.eightKArtifact: agDelayJustification (required when agDelayRequested=true)",
134
- SecCyberError, "BAD_AG_JUSTIFICATION");
135
- }
136
181
 
137
182
  var matAt = opts.materialityDeterminedAt || Date.now();
138
183
  var deadline = agDelayRequested ? null : _addBusinessDays(matAt, 4);
@@ -55,6 +55,7 @@
55
55
  */
56
56
 
57
57
  var nodePath = require("node:path");
58
+ var moduleLoader = require("./module-loader");
58
59
  var atomicFile = require("./atomic-file");
59
60
  var C = require("./constants");
60
61
  var dbSchema = require("./db-schema");
@@ -190,18 +191,10 @@ function _listSeedFiles(rootDir, env) {
190
191
  }
191
192
 
192
193
  function _loadSeed(rootDir, env, file) {
193
- var fullPath = nodePath.join(_envDir(rootDir, env), file);
194
- // Drop require cache for this path so a test rewriting a fixture
195
- // between calls picks it up. Production restarts the process anyway.
196
- try { delete require.cache[require.resolve(fullPath)]; } catch (_e) { /* not yet cached */ }
197
- var mod;
198
- // Operator-supplied seed — dynamic by design, can't be bundle-traced.
199
- // Host-CLI scope; deploying via SEA / pkg drops this surface.
200
- try { mod = require(fullPath); } // allow:dynamic-require — operator-supplied seed
201
- catch (e) {
202
- throw _err("LOAD_FAILED",
194
+ var mod = moduleLoader.requireFresh(nodePath.join(_envDir(rootDir, env), file), function (e) {
195
+ return _err("LOAD_FAILED",
203
196
  "seed '" + env + "/" + file + "' failed to load: " + ((e && e.message) || String(e)));
204
- }
197
+ });
205
198
  if (!mod || typeof mod.run !== "function") {
206
199
  throw _err("BAD_SEED",
207
200
  "seed '" + env + "/" + file + "' must export an async `run(db, ctx)` function");
@@ -57,13 +57,12 @@ var bCrypto = require("./crypto");
57
57
  var httpClient = require("./http-client");
58
58
  var safeJson = require("./safe-json");
59
59
  var { URL: NodeUrl } = require("node:url");
60
- var lazyRequire = require("./lazy-require");
61
60
  var C = require("./constants");
62
61
  var standaloneVerifier = require("./self-update-standalone-verifier");
63
62
  var { boot } = require("./log");
64
63
  var { defineClass } = require("./framework-error");
65
64
 
66
- var audit = lazyRequire(function () { return require("./audit"); });
65
+ var auditEmit = require("./audit-emit");
67
66
 
68
67
  var SelfUpdateError = defineClass("SelfUpdateError", { alwaysPermanent: true });
69
68
  var log = boot("self-update");
@@ -76,13 +75,7 @@ var DEFAULT_HASH_ALG = "sha3-512";
76
75
  var DEFAULT_RELEASES_BYTES = C.BYTES.mib(8); // GitHub releases JSON ~hundreds of KB; 8 MiB caps a malicious response
77
76
 
78
77
  function _safeAuditEmit(action, outcome, metadata) {
79
- try {
80
- audit().safeEmit({
81
- action: action,
82
- outcome: outcome || "success",
83
- metadata: metadata || {},
84
- });
85
- } catch (_e) { /* drop-silent — by design */ }
78
+ auditEmit.emit(action, metadata, outcome);
86
79
  }
87
80
 
88
81
  // ---- semver-shaped comparison (tag_name like "v0.7.30" or "0.7.30") ----
@@ -218,44 +211,66 @@ function _compareTags(a, b) {
218
211
  // ---- poll ----
219
212
 
220
213
  function _validatePollOpts(opts) {
221
- validateOpts.requireObject(opts, "selfUpdate.poll", SelfUpdateError, "selfupdate/bad-opts");
222
- validateOpts.requireNonEmptyString(opts.releasesUrl,
223
- "selfUpdate.poll: opts.releasesUrl", SelfUpdateError, "selfupdate/bad-releases-url");
224
- // Scheme enforcement at config-time so the bug surfaces here, not
225
- // inside the request loop. Default policy: https only. Operators
226
- // wiring against an internal mirror can pass allowedProtocols
227
- // explicitly to opt in to http (e.g. a TLS-terminating proxy
228
- // upstream of the framework process). The full SSRF / hostname /
229
- // length policy still runs inside httpClient.request.
230
- var parsedProto;
231
- try { parsedProto = new NodeUrl(opts.releasesUrl).protocol; }
232
- catch (_e) {
233
- throw new SelfUpdateError("selfupdate/bad-releases-url",
234
- "selfUpdate.poll: opts.releasesUrl is not parseable as a URL");
235
- }
236
- var allowedProtocols = Array.isArray(opts.allowedProtocols) && opts.allowedProtocols.length > 0
237
- ? opts.allowedProtocols.slice() : ["https:"];
238
- if (allowedProtocols.indexOf(parsedProto) === -1) {
239
- throw new SelfUpdateError("selfupdate/bad-releases-url",
240
- "selfUpdate.poll: opts.releasesUrl protocol '" + parsedProto +
241
- "' not in allowedProtocols [" + allowedProtocols.join(", ") + "]");
242
- }
243
- validateOpts.requireNonEmptyString(opts.currentVersion,
244
- "selfUpdate.poll: opts.currentVersion", SelfUpdateError, "selfupdate/bad-current-version");
245
- if (opts.assetPattern !== undefined && !(opts.assetPattern instanceof RegExp) &&
246
- typeof opts.assetPattern !== "string") {
247
- throw new SelfUpdateError("selfupdate/bad-asset-pattern",
248
- "selfUpdate.poll: opts.assetPattern must be a RegExp or string when present");
249
- }
250
- if (opts.signaturePattern !== undefined && !(opts.signaturePattern instanceof RegExp) &&
251
- typeof opts.signaturePattern !== "string") {
252
- throw new SelfUpdateError("selfupdate/bad-sig-pattern",
253
- "selfUpdate.poll: opts.signaturePattern must be a RegExp or string when present");
254
- }
255
- numericBounds.requirePositiveFiniteIntIfPresent(opts.maxBytes,
256
- "selfUpdate.poll: opts.maxBytes", SelfUpdateError, "selfupdate/bad-max-bytes");
257
- numericBounds.requirePositiveFiniteIntIfPresent(opts.timeoutMs,
258
- "selfUpdate.poll: opts.timeoutMs", SelfUpdateError, "selfupdate/bad-timeout");
214
+ validateOpts.shape(opts, {
215
+ releasesUrl: function (value) {
216
+ validateOpts.requireNonEmptyString(value,
217
+ "selfUpdate.poll: opts.releasesUrl", SelfUpdateError, "selfupdate/bad-releases-url");
218
+ // Scheme enforcement at config-time so the bug surfaces here, not
219
+ // inside the request loop. Default policy: https only. Operators
220
+ // wiring against an internal mirror can pass allowedProtocols
221
+ // explicitly to opt in to http (e.g. a TLS-terminating proxy
222
+ // upstream of the framework process). The full SSRF / hostname /
223
+ // length policy still runs inside httpClient.request.
224
+ var parsedProto;
225
+ try { parsedProto = new NodeUrl(value).protocol; }
226
+ catch (_e) {
227
+ throw new SelfUpdateError("selfupdate/bad-releases-url",
228
+ "selfUpdate.poll: opts.releasesUrl is not parseable as a URL");
229
+ }
230
+ var allowedProtocols = Array.isArray(opts.allowedProtocols) && opts.allowedProtocols.length > 0
231
+ ? opts.allowedProtocols.slice() : ["https:"];
232
+ if (allowedProtocols.indexOf(parsedProto) === -1) {
233
+ throw new SelfUpdateError("selfupdate/bad-releases-url",
234
+ "selfUpdate.poll: opts.releasesUrl protocol '" + parsedProto +
235
+ "' not in allowedProtocols [" + allowedProtocols.join(", ") + "]");
236
+ }
237
+ },
238
+ currentVersion: { rule: "required-string", code: "selfupdate/bad-current-version",
239
+ label: "selfUpdate.poll: opts.currentVersion" },
240
+ assetPattern: function (value) {
241
+ if (value !== undefined && !(value instanceof RegExp) && typeof value !== "string") {
242
+ throw new SelfUpdateError("selfupdate/bad-asset-pattern",
243
+ "selfUpdate.poll: opts.assetPattern must be a RegExp or string when present");
244
+ }
245
+ },
246
+ signaturePattern: function (value) {
247
+ if (value !== undefined && !(value instanceof RegExp) && typeof value !== "string") {
248
+ throw new SelfUpdateError("selfupdate/bad-sig-pattern",
249
+ "selfUpdate.poll: opts.signaturePattern must be a RegExp or string when present");
250
+ }
251
+ },
252
+ maxBytes: function (value) {
253
+ numericBounds.requirePositiveFiniteIntIfPresent(value,
254
+ "selfUpdate.poll: opts.maxBytes", SelfUpdateError, "selfupdate/bad-max-bytes");
255
+ },
256
+ timeoutMs: function (value) {
257
+ numericBounds.requirePositiveFiniteIntIfPresent(value,
258
+ "selfUpdate.poll: opts.timeoutMs", SelfUpdateError, "selfupdate/bad-timeout");
259
+ },
260
+ // allowedProtocols is consumed locally (the releasesUrl scheme gate
261
+ // above reads it) and also forwarded to httpClient.request.
262
+ allowedProtocols: { rule: "optional-string-array", code: "selfupdate/bad-allowed-protocols",
263
+ label: "selfUpdate.poll: opts.allowedProtocols" },
264
+ // headers is merged onto the outbound request headers locally.
265
+ headers: { rule: "optional-plain-object", code: "selfupdate/bad-headers",
266
+ label: "selfUpdate.poll: opts.headers" },
267
+ // etag is used locally for the If-None-Match request header.
268
+ etag: { rule: "optional-string", code: "selfupdate/bad-etag",
269
+ label: "selfUpdate.poll: opts.etag" },
270
+ // allowedHosts / allowInternal are forwarded verbatim to
271
+ // httpClient.request, which owns their SSRF-gate validation.
272
+ }, "selfUpdate.poll", SelfUpdateError, "selfupdate/bad-opts",
273
+ { allow: ["allowedHosts", "allowInternal"] });
259
274
  }
260
275
 
261
276
  function _matchAsset(name, pattern, fallback) {
@@ -461,21 +476,25 @@ async function poll(opts) {
461
476
  // ---- verify ----
462
477
 
463
478
  function _validateVerifyOpts(opts) {
464
- validateOpts.requireObject(opts, "selfUpdate.verify", SelfUpdateError, "selfupdate/bad-opts");
465
- validateOpts.requireNonEmptyString(opts.assetPath,
466
- "selfUpdate.verify: opts.assetPath", SelfUpdateError, "selfupdate/bad-asset-path");
467
- validateOpts.requireNonEmptyString(opts.signaturePath,
468
- "selfUpdate.verify: opts.signaturePath", SelfUpdateError, "selfupdate/bad-signature-path");
469
- validateOpts.requireNonEmptyString(opts.pubkeyPem,
470
- "selfUpdate.verify: opts.pubkeyPem (PEM-encoded public key)",
471
- SelfUpdateError, "selfupdate/bad-pubkey");
472
- if (opts.hashAlgo !== undefined &&
473
- (typeof opts.hashAlgo !== "string" || ALLOWED_HASH_ALGS.indexOf(opts.hashAlgo) === -1)) {
474
- throw new SelfUpdateError("selfupdate/bad-hash-algo",
475
- "selfUpdate.verify: opts.hashAlgo must be one of " + ALLOWED_HASH_ALGS.join(", "));
476
- }
477
- numericBounds.requirePositiveFiniteIntIfPresent(opts.maxBytes,
478
- "selfUpdate.verify: opts.maxBytes", SelfUpdateError, "selfupdate/bad-max-bytes");
479
+ validateOpts.shape(opts, {
480
+ assetPath: { rule: "required-string", code: "selfupdate/bad-asset-path",
481
+ label: "selfUpdate.verify: opts.assetPath" },
482
+ signaturePath: { rule: "required-string", code: "selfupdate/bad-signature-path",
483
+ label: "selfUpdate.verify: opts.signaturePath" },
484
+ pubkeyPem: { rule: "required-string", code: "selfupdate/bad-pubkey",
485
+ label: "selfUpdate.verify: opts.pubkeyPem (PEM-encoded public key)" },
486
+ hashAlgo: function (value) {
487
+ if (value !== undefined &&
488
+ (typeof value !== "string" || ALLOWED_HASH_ALGS.indexOf(value) === -1)) {
489
+ throw new SelfUpdateError("selfupdate/bad-hash-algo",
490
+ "selfUpdate.verify: opts.hashAlgo must be one of " + ALLOWED_HASH_ALGS.join(", "));
491
+ }
492
+ },
493
+ maxBytes: function (value) {
494
+ numericBounds.requirePositiveFiniteIntIfPresent(value,
495
+ "selfUpdate.verify: opts.maxBytes", SelfUpdateError, "selfupdate/bad-max-bytes");
496
+ },
497
+ }, "selfUpdate.verify", SelfUpdateError, "selfupdate/bad-opts");
479
498
  }
480
499
 
481
500
  /**
@@ -565,15 +584,19 @@ async function verify(opts) {
565
584
  // ---- swap ----
566
585
 
567
586
  function _validateSwapOpts(opts, label) {
568
- validateOpts.requireObject(opts, "selfUpdate." + label, SelfUpdateError, "selfupdate/bad-opts");
587
+ // requireObject runs first (shape does it) so an opts-shape error keeps
588
+ // the selfupdate/bad-opts code. `from` is validated only for swap, and
589
+ // first to preserve the original field-evaluation order.
590
+ var schema = {};
569
591
  if (label === "swap") {
570
- validateOpts.requireNonEmptyString(opts.from,
571
- "selfUpdate.swap: opts.from", SelfUpdateError, "selfupdate/bad-from");
592
+ schema.from = { rule: "required-string", code: "selfupdate/bad-from",
593
+ label: "selfUpdate.swap: opts.from" };
572
594
  }
573
- validateOpts.requireNonEmptyString(opts.to,
574
- "selfUpdate." + label + ": opts.to", SelfUpdateError, "selfupdate/bad-to");
575
- validateOpts.requireNonEmptyString(opts.backupTo,
576
- "selfUpdate." + label + ": opts.backupTo", SelfUpdateError, "selfupdate/bad-backup");
595
+ schema.to = { rule: "required-string", code: "selfupdate/bad-to",
596
+ label: "selfUpdate." + label + ": opts.to" };
597
+ schema.backupTo = { rule: "required-string", code: "selfupdate/bad-backup",
598
+ label: "selfUpdate." + label + ": opts.backupTo" };
599
+ validateOpts.shape(opts, schema, "selfUpdate." + label, SelfUpdateError, "selfupdate/bad-opts");
577
600
  }
578
601
 
579
602
  // _safeRollback — best-effort restore of `to` from `backupTo` during
@@ -97,13 +97,8 @@ function _requireFunction(name, val) {
97
97
  }
98
98
 
99
99
  function _requireBindingStore(s) {
100
- if (!s || typeof s !== "object" ||
101
- typeof s.get !== "function" ||
102
- typeof s.set !== "function" ||
103
- typeof s.del !== "function") {
104
- throw new SessionDeviceBindingError("session-device-binding/bad-opt",
105
- "bindingStore must be a b.cache-shaped object (get/set/del)");
106
- }
100
+ validateOpts.requireMethods(s, ["get", "set", "del"],
101
+ "bindingStore (b.cache-shaped)", SessionDeviceBindingError, "session-device-binding/bad-opt");
107
102
  }
108
103
 
109
104
  function _requireToken(token) {
@@ -164,6 +159,105 @@ function _ipPrefix(ip, bits) {
164
159
  return "v4:" + maskedOctets.join(".") + "/" + v4Bits;
165
160
  }
166
161
 
162
+ // Resolve operator-supplied fingerprintExtras(req) to a stable string. A
163
+ // throwing or non-serializable extractor drops to "" — extras only sharpen the
164
+ // digest, they must never crash fingerprinting.
165
+ function _resolveExtrasFn(fn, req) {
166
+ if (!fn) return "";
167
+ var v;
168
+ try { v = fn(req); } catch (_e) { return ""; }
169
+ if (v === null || v === undefined) return "";
170
+ if (typeof v === "string") return v;
171
+ try { return JSON.stringify(v); } catch (_e) { return ""; }
172
+ }
173
+
174
+ // Clamp an { v4, v6 } prefix-bits opt to valid IPv4/IPv6 ranges, defaulting
175
+ // each independently.
176
+ function _resolveIpBits(ipBits) {
177
+ ipBits = ipBits || {};
178
+ return {
179
+ v4: (typeof ipBits.v4 === "number" && isFinite(ipBits.v4) && ipBits.v4 >= 0 && ipBits.v4 <= 32) // IPv4 max prefix length in bits
180
+ ? ipBits.v4 : DEFAULT_IP_V4_PREFIX,
181
+ v6: (typeof ipBits.v6 === "number" && isFinite(ipBits.v6) && ipBits.v6 >= 0 && ipBits.v6 <= 128) // IPv6 max prefix length in bits
182
+ ? ipBits.v6 : DEFAULT_IP_V6_PREFIX,
183
+ };
184
+ }
185
+
186
+ // Pure request-shape device fingerprint — the side-effect-free core shared by
187
+ // the instance lookup and the static fingerprint() entry point. cfg: { v4Bits,
188
+ // v6Bits, extras (string), boundKey (Buffer|null) }. No store, no audit, no
189
+ // session — just headers + masked client IP (+ optional bound key) -> SHAKE256.
190
+ function _computeDeviceFingerprint(req, cfg) {
191
+ _requireReq(req);
192
+ var headers = req.headers || {};
193
+ var ua = typeof headers["user-agent"] === "string" ? headers["user-agent"] : "";
194
+ var al = _normalizeAcceptLanguage(headers["accept-language"]);
195
+ var ae = _normalizeAcceptEncoding(headers["accept-encoding"]);
196
+ var ip = "";
197
+ try { ip = requestHelpers.clientIp(req); } catch (_e) { ip = ""; }
198
+ var family = ip.indexOf(":") !== -1 ? "v6" : "v4";
199
+ var ipPart = _ipPrefix(ip, family === "v6" ? cfg.v6Bits : cfg.v4Bits);
200
+ var keyPart = "";
201
+ if (Buffer.isBuffer(cfg.boundKey)) {
202
+ keyPart = "k:" + nodeCrypto.createHash("sha3-256").update(cfg.boundKey).digest("hex");
203
+ }
204
+ var canonical = [
205
+ "ua=" + ua,
206
+ "al=" + al,
207
+ "ae=" + ae,
208
+ "ip=" + ipPart,
209
+ "ex=" + (cfg.extras || ""),
210
+ keyPart,
211
+ ].join("\n");
212
+ var hash = nodeCrypto.createHash("shake256", { outputLength: FINGERPRINT_BYTES })
213
+ .update(canonical)
214
+ .digest();
215
+ return { fingerprint: hash, components: {
216
+ ua: ua, al: al, ae: ae, ip: ipPart, hasBoundKey: !!keyPart,
217
+ } };
218
+ }
219
+
220
+ /**
221
+ * @primitive b.sessionDeviceBinding.fingerprint
222
+ * @signature b.sessionDeviceBinding.fingerprint(req, opts?)
223
+ * @since 0.15.13
224
+ * @status stable
225
+ * @related b.session.rotate, b.session.create
226
+ *
227
+ * Compute the stateless SHAKE256 device-shape digest for a request with no
228
+ * store, no session, and no side effects — the soft device-binding building
229
+ * block for self-validating tokens (a sealed cookie, a JWT) that carry the
230
+ * fingerprint inside the token and compare it themselves. `create()` requires a
231
+ * bindingStore for the persisted bind()/verify() lifecycle; this static form
232
+ * skips that gate because it touches no store. Returns a 32-byte Buffer derived
233
+ * from User-Agent + normalized Accept-Language / Accept-Encoding + the masked
234
+ * client-IP prefix (+ optional operator extras). Throws only on a missing or
235
+ * malformed request object.
236
+ *
237
+ * @opts
238
+ * ipPrefixBits: { v4: number, v6: number }, // default { v4: 24, v6: 48 } — mask width that survives a roaming IP
239
+ * fingerprintExtras: function, // (req) => string|object, optional extra signal folded into the digest
240
+ *
241
+ * @example
242
+ * var fp = b.sessionDeviceBinding.fingerprint(req);
243
+ * // seal fp inside the cookie/JWT; on the next request recompute + constant-time compare
244
+ */
245
+ function fingerprint(req, opts) {
246
+ opts = opts || {};
247
+ if (opts.fingerprintExtras !== undefined && opts.fingerprintExtras !== null &&
248
+ typeof opts.fingerprintExtras !== "function") {
249
+ throw new SessionDeviceBindingError("session-device-binding/bad-opt",
250
+ "fingerprint: fingerprintExtras must be a function (req) => string|object");
251
+ }
252
+ var bits = _resolveIpBits(opts.ipPrefixBits);
253
+ return _computeDeviceFingerprint(req, {
254
+ v4Bits: bits.v4,
255
+ v6Bits: bits.v6,
256
+ extras: _resolveExtrasFn(opts.fingerprintExtras, req),
257
+ boundKey: null,
258
+ }).fingerprint;
259
+ }
260
+
167
261
  function create(opts) {
168
262
  opts = opts || {};
169
263
  validateOpts(opts, ALLOWED_OPTS, "sessionDeviceBinding.create");
@@ -215,29 +309,9 @@ function create(opts) {
215
309
  var boundKeyResolver = opts.boundKeyResolver || null;
216
310
  var fingerprintExtras = opts.fingerprintExtras || null;
217
311
 
218
- function _emitObs(name, labels) {
219
- var sink = obsInst || _safeGlobalObs();
220
- if (!sink) return;
221
- try { sink.event(name, 1, labels); } catch (_e) { /* drop-silent */ }
222
- }
223
-
224
- function _safeGlobalObs() {
225
- try { return observability(); } catch (_e) { return null; }
226
- }
312
+ var _emitObs = observability().makeCounterEmitter(obsInst);
227
313
 
228
- function _emitAudit(action, tokenHash, outcome, metadata, req) {
229
- if (!auditInst) return;
230
- try {
231
- var event = {
232
- action: action,
233
- outcome: outcome,
234
- resource: { kind: "session.device", id: tokenHash },
235
- metadata: metadata || {},
236
- };
237
- if (req) event.actor = requestHelpers.extractActorContext(req);
238
- auditInst.safeEmit(event);
239
- } catch (_e) { /* drop-silent */ }
240
- }
314
+ var _emitAudit = requestHelpers.makeResourceAuditEmitter(auditInst, "session.device");
241
315
 
242
316
  function _hashTokenForAudit(token) {
243
317
  // Don't put the raw session id in the audit log. SHAKE256 to a
@@ -259,51 +333,22 @@ function create(opts) {
259
333
  }
260
334
 
261
335
  function _resolveExtras(req) {
262
- if (!fingerprintExtras) return "";
263
- var v;
264
- try { v = fingerprintExtras(req); }
265
- catch (_e) { return ""; }
266
- if (v === null || v === undefined) return "";
267
- if (typeof v === "string") return v;
268
- try { return JSON.stringify(v); } catch (_e) { return ""; }
336
+ return _resolveExtrasFn(fingerprintExtras, req);
269
337
  }
270
338
 
271
339
  function _computeFingerprint(req) {
272
340
  _requireReq(req);
273
- var headers = req.headers || {};
274
- var ua = typeof headers["user-agent"] === "string" ? headers["user-agent"] : "";
275
- var al = _normalizeAcceptLanguage(headers["accept-language"]);
276
- var ae = _normalizeAcceptEncoding(headers["accept-encoding"]);
277
- var ip = "";
278
- try { ip = requestHelpers.clientIp(req); } catch (_e) { ip = ""; }
279
- var family = ip.indexOf(":") !== -1 ? "v6" : "v4";
280
- var ipPart = _ipPrefix(ip, family === "v6" ? v6Bits : v4Bits);
281
- var extras = _resolveExtras(req);
282
-
283
341
  var boundKeyMaybe = _resolveBoundKey(req);
284
342
  if (requireBoundKey && (boundKeyMaybe === null || boundKeyMaybe === undefined)) {
285
343
  return { ok: false, reason: "missing-bound-key" };
286
344
  }
287
- var keyPart = "";
288
- if (Buffer.isBuffer(boundKeyMaybe)) {
289
- keyPart = "k:" + nodeCrypto.createHash("sha3-256").update(boundKeyMaybe).digest("hex");
290
- }
291
-
292
- var canonical = [
293
- "ua=" + ua,
294
- "al=" + al,
295
- "ae=" + ae,
296
- "ip=" + ipPart,
297
- "ex=" + extras,
298
- keyPart,
299
- ].join("\n");
300
-
301
- var hash = nodeCrypto.createHash("shake256", { outputLength: FINGERPRINT_BYTES })
302
- .update(canonical)
303
- .digest();
304
- return { ok: true, fingerprint: hash, components: {
305
- ua: ua, al: al, ae: ae, ip: ipPart, hasBoundKey: !!keyPart,
306
- } };
345
+ var r = _computeDeviceFingerprint(req, {
346
+ v4Bits: v4Bits,
347
+ v6Bits: v6Bits,
348
+ extras: _resolveExtras(req),
349
+ boundKey: Buffer.isBuffer(boundKeyMaybe) ? boundKeyMaybe : null,
350
+ });
351
+ return { ok: true, fingerprint: r.fingerprint, components: r.components };
307
352
  }
308
353
 
309
354
  async function bind(token, req) {
@@ -421,6 +466,7 @@ function create(opts) {
421
466
 
422
467
  module.exports = {
423
468
  create: create,
469
+ fingerprint: fingerprint,
424
470
  SessionDeviceBindingError: SessionDeviceBindingError,
425
471
  DEFAULTS: Object.freeze({
426
472
  ttlMs: DEFAULT_TTL_MS,