@blamejs/blamejs-shop 0.4.56 → 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 (397) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/lib/asset-manifest.json +1 -1
  3. package/lib/vendor/MANIFEST.json +426 -366
  4. package/lib/vendor/blamejs/.github/codeql/codeql-config.yml +25 -0
  5. package/lib/vendor/blamejs/.github/workflows/actions-lint.yml +3 -3
  6. package/lib/vendor/blamejs/.github/workflows/cflite_batch.yml +1 -1
  7. package/lib/vendor/blamejs/.github/workflows/cflite_pr.yml +1 -1
  8. package/lib/vendor/blamejs/.github/workflows/ci.yml +13 -13
  9. package/lib/vendor/blamejs/.github/workflows/codeql.yml +8 -7
  10. package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +2 -2
  11. package/lib/vendor/blamejs/.github/workflows/release-container.yml +4 -4
  12. package/lib/vendor/blamejs/.github/workflows/scorecard.yml +1 -1
  13. package/lib/vendor/blamejs/.github/workflows/sha-to-tag-verify.yml +1 -1
  14. package/lib/vendor/blamejs/CHANGELOG.md +2 -0
  15. package/lib/vendor/blamejs/api-snapshot.json +1381 -4
  16. package/lib/vendor/blamejs/eslint.config.mjs +1 -0
  17. package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +4 -1
  18. package/lib/vendor/blamejs/examples/wiki/lib/symbol-index.js +5 -2
  19. package/lib/vendor/blamejs/examples/wiki/routes/pages.js +4 -1
  20. package/lib/vendor/blamejs/fuzz/guard-text.fuzz.js +20 -0
  21. package/lib/vendor/blamejs/index.js +2 -0
  22. package/lib/vendor/blamejs/lib/a2a-tasks.js +7 -23
  23. package/lib/vendor/blamejs/lib/acme.js +6 -5
  24. package/lib/vendor/blamejs/lib/agent-event-bus.js +5 -4
  25. package/lib/vendor/blamejs/lib/agent-idempotency.js +2 -5
  26. package/lib/vendor/blamejs/lib/agent-orchestrator.js +2 -5
  27. package/lib/vendor/blamejs/lib/agent-saga.js +3 -5
  28. package/lib/vendor/blamejs/lib/agent-tenant.js +2 -5
  29. package/lib/vendor/blamejs/lib/ai-adverse-decision.js +2 -15
  30. package/lib/vendor/blamejs/lib/ai-capability.js +1 -6
  31. package/lib/vendor/blamejs/lib/ai-dp.js +1 -5
  32. package/lib/vendor/blamejs/lib/ai-input.js +2 -2
  33. package/lib/vendor/blamejs/lib/ai-pref.js +3 -8
  34. package/lib/vendor/blamejs/lib/ai-quota.js +3 -14
  35. package/lib/vendor/blamejs/lib/api-key.js +37 -28
  36. package/lib/vendor/blamejs/lib/archive-adapters.js +2 -4
  37. package/lib/vendor/blamejs/lib/archive-entry-policy.js +32 -0
  38. package/lib/vendor/blamejs/lib/archive-read.js +5 -17
  39. package/lib/vendor/blamejs/lib/archive-tar-read.js +5 -16
  40. package/lib/vendor/blamejs/lib/archive.js +2 -10
  41. package/lib/vendor/blamejs/lib/arg-parser.js +7 -6
  42. package/lib/vendor/blamejs/lib/asyncapi-traits.js +2 -6
  43. package/lib/vendor/blamejs/lib/atomic-file.js +108 -31
  44. package/lib/vendor/blamejs/lib/audit-chain.js +133 -53
  45. package/lib/vendor/blamejs/lib/audit-daily-review.js +24 -14
  46. package/lib/vendor/blamejs/lib/audit-emit.js +82 -0
  47. package/lib/vendor/blamejs/lib/audit-sign.js +257 -0
  48. package/lib/vendor/blamejs/lib/audit.js +84 -0
  49. package/lib/vendor/blamejs/lib/auth/access-lock.js +5 -27
  50. package/lib/vendor/blamejs/lib/auth/dpop.js +23 -35
  51. package/lib/vendor/blamejs/lib/auth/fido-mds3.js +9 -15
  52. package/lib/vendor/blamejs/lib/auth/jwt-external.js +26 -8
  53. package/lib/vendor/blamejs/lib/auth/jwt.js +13 -15
  54. package/lib/vendor/blamejs/lib/auth/lockout.js +6 -25
  55. package/lib/vendor/blamejs/lib/auth/oauth.js +67 -45
  56. package/lib/vendor/blamejs/lib/auth/oid4vci.js +55 -32
  57. package/lib/vendor/blamejs/lib/auth/oid4vp.js +3 -2
  58. package/lib/vendor/blamejs/lib/auth/openid-federation.js +6 -6
  59. package/lib/vendor/blamejs/lib/auth/passkey.js +3 -3
  60. package/lib/vendor/blamejs/lib/auth/password.js +7 -1
  61. package/lib/vendor/blamejs/lib/auth/saml.js +37 -27
  62. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-holder.js +2 -14
  63. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-issuer.js +2 -14
  64. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +1 -1
  65. package/lib/vendor/blamejs/lib/auth/status-list.js +7 -7
  66. package/lib/vendor/blamejs/lib/auth/step-up.js +6 -12
  67. package/lib/vendor/blamejs/lib/auth-bot-challenge.js +6 -37
  68. package/lib/vendor/blamejs/lib/backup/bundle.js +11 -18
  69. package/lib/vendor/blamejs/lib/backup/index.js +14 -47
  70. package/lib/vendor/blamejs/lib/bounded-map.js +112 -1
  71. package/lib/vendor/blamejs/lib/breach-deadline.js +1 -11
  72. package/lib/vendor/blamejs/lib/cache.js +7 -18
  73. package/lib/vendor/blamejs/lib/cbor.js +2 -1
  74. package/lib/vendor/blamejs/lib/cdn-cache-control.js +8 -9
  75. package/lib/vendor/blamejs/lib/cert.js +3 -10
  76. package/lib/vendor/blamejs/lib/chain-writer.js +162 -47
  77. package/lib/vendor/blamejs/lib/cli.js +5 -1
  78. package/lib/vendor/blamejs/lib/client-hints.js +7 -9
  79. package/lib/vendor/blamejs/lib/cloud-events.js +40 -31
  80. package/lib/vendor/blamejs/lib/cluster-storage.js +2 -38
  81. package/lib/vendor/blamejs/lib/cms-codec.js +2 -1
  82. package/lib/vendor/blamejs/lib/codepoint-class.js +67 -1
  83. package/lib/vendor/blamejs/lib/compliance-ai-act-logging.js +1 -6
  84. package/lib/vendor/blamejs/lib/compliance-ai-act-transparency.js +2 -4
  85. package/lib/vendor/blamejs/lib/compliance-eaa.js +1 -11
  86. package/lib/vendor/blamejs/lib/compliance-sanctions-fetcher.js +21 -28
  87. package/lib/vendor/blamejs/lib/compliance-sanctions.js +2 -14
  88. package/lib/vendor/blamejs/lib/compliance.js +2 -9
  89. package/lib/vendor/blamejs/lib/config-drift.js +2 -12
  90. package/lib/vendor/blamejs/lib/content-digest.js +10 -8
  91. package/lib/vendor/blamejs/lib/cookies.js +5 -11
  92. package/lib/vendor/blamejs/lib/cose.js +19 -11
  93. package/lib/vendor/blamejs/lib/cra-report.js +1 -11
  94. package/lib/vendor/blamejs/lib/crypto-field.js +5 -10
  95. package/lib/vendor/blamejs/lib/crypto.js +120 -3
  96. package/lib/vendor/blamejs/lib/csp.js +235 -3
  97. package/lib/vendor/blamejs/lib/daemon.js +42 -41
  98. package/lib/vendor/blamejs/lib/data-act.js +19 -9
  99. package/lib/vendor/blamejs/lib/db-query.js +6 -40
  100. package/lib/vendor/blamejs/lib/db.js +34 -12
  101. package/lib/vendor/blamejs/lib/dbsc.js +5 -6
  102. package/lib/vendor/blamejs/lib/ddl-change-control.js +18 -14
  103. package/lib/vendor/blamejs/lib/deprecate.js +4 -5
  104. package/lib/vendor/blamejs/lib/did.js +6 -2
  105. package/lib/vendor/blamejs/lib/dsr.js +8 -12
  106. package/lib/vendor/blamejs/lib/external-db-migrate.js +21 -22
  107. package/lib/vendor/blamejs/lib/external-db.js +14 -26
  108. package/lib/vendor/blamejs/lib/fda-21cfr11.js +12 -8
  109. package/lib/vendor/blamejs/lib/fdx.js +22 -18
  110. package/lib/vendor/blamejs/lib/file-upload.js +80 -66
  111. package/lib/vendor/blamejs/lib/flag-evaluation-context.js +5 -8
  112. package/lib/vendor/blamejs/lib/framework-error.js +12 -0
  113. package/lib/vendor/blamejs/lib/framework-schema.js +19 -0
  114. package/lib/vendor/blamejs/lib/fsm.js +7 -12
  115. package/lib/vendor/blamejs/lib/gate-contract.js +869 -38
  116. package/lib/vendor/blamejs/lib/gdpr-ropa.js +4 -13
  117. package/lib/vendor/blamejs/lib/graphql-federation.js +1 -1
  118. package/lib/vendor/blamejs/lib/guard-agent-registry.js +2 -1
  119. package/lib/vendor/blamejs/lib/guard-all.js +1 -0
  120. package/lib/vendor/blamejs/lib/guard-archive.js +9 -30
  121. package/lib/vendor/blamejs/lib/guard-auth.js +23 -80
  122. package/lib/vendor/blamejs/lib/guard-cidr.js +20 -96
  123. package/lib/vendor/blamejs/lib/guard-csv.js +135 -196
  124. package/lib/vendor/blamejs/lib/guard-domain.js +23 -106
  125. package/lib/vendor/blamejs/lib/guard-dsn.js +16 -13
  126. package/lib/vendor/blamejs/lib/guard-email.js +46 -53
  127. package/lib/vendor/blamejs/lib/guard-envelope.js +1 -1
  128. package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +2 -1
  129. package/lib/vendor/blamejs/lib/guard-filename.js +12 -60
  130. package/lib/vendor/blamejs/lib/guard-graphql.js +28 -75
  131. package/lib/vendor/blamejs/lib/guard-html-wcag.js +15 -2
  132. package/lib/vendor/blamejs/lib/guard-html.js +65 -117
  133. package/lib/vendor/blamejs/lib/guard-idempotency-key.js +2 -1
  134. package/lib/vendor/blamejs/lib/guard-image.js +280 -77
  135. package/lib/vendor/blamejs/lib/guard-imap-command.js +8 -9
  136. package/lib/vendor/blamejs/lib/guard-json.js +87 -103
  137. package/lib/vendor/blamejs/lib/guard-jsonpath.js +20 -88
  138. package/lib/vendor/blamejs/lib/guard-jwt.js +32 -114
  139. package/lib/vendor/blamejs/lib/guard-list-id.js +2 -7
  140. package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +2 -7
  141. package/lib/vendor/blamejs/lib/guard-mail-compose.js +5 -6
  142. package/lib/vendor/blamejs/lib/guard-mail-move.js +2 -1
  143. package/lib/vendor/blamejs/lib/guard-mail-query.js +5 -3
  144. package/lib/vendor/blamejs/lib/guard-mail-sieve.js +6 -7
  145. package/lib/vendor/blamejs/lib/guard-managesieve-command.js +5 -4
  146. package/lib/vendor/blamejs/lib/guard-markdown.js +76 -110
  147. package/lib/vendor/blamejs/lib/guard-message-id.js +5 -6
  148. package/lib/vendor/blamejs/lib/guard-mime.js +20 -99
  149. package/lib/vendor/blamejs/lib/guard-oauth.js +19 -73
  150. package/lib/vendor/blamejs/lib/guard-pdf.js +65 -72
  151. package/lib/vendor/blamejs/lib/guard-pop3-command.js +12 -13
  152. package/lib/vendor/blamejs/lib/guard-posture-chain.js +2 -1
  153. package/lib/vendor/blamejs/lib/guard-regex.js +24 -99
  154. package/lib/vendor/blamejs/lib/guard-saga-config.js +2 -1
  155. package/lib/vendor/blamejs/lib/guard-shell.js +22 -87
  156. package/lib/vendor/blamejs/lib/guard-smtp-command.js +8 -11
  157. package/lib/vendor/blamejs/lib/guard-sql.js +15 -13
  158. package/lib/vendor/blamejs/lib/guard-stream-args.js +2 -1
  159. package/lib/vendor/blamejs/lib/guard-svg.js +95 -140
  160. package/lib/vendor/blamejs/lib/guard-template.js +23 -80
  161. package/lib/vendor/blamejs/lib/guard-tenant-id.js +2 -1
  162. package/lib/vendor/blamejs/lib/guard-text.js +592 -0
  163. package/lib/vendor/blamejs/lib/guard-time.js +27 -95
  164. package/lib/vendor/blamejs/lib/guard-uuid.js +21 -93
  165. package/lib/vendor/blamejs/lib/guard-xml.js +76 -106
  166. package/lib/vendor/blamejs/lib/guard-yaml.js +24 -60
  167. package/lib/vendor/blamejs/lib/http-client-cache.js +5 -12
  168. package/lib/vendor/blamejs/lib/http-client-cookie-jar.js +2 -4
  169. package/lib/vendor/blamejs/lib/http-client.js +8 -21
  170. package/lib/vendor/blamejs/lib/http-message-signature.js +3 -2
  171. package/lib/vendor/blamejs/lib/i18n-messageformat.js +5 -7
  172. package/lib/vendor/blamejs/lib/i18n.js +83 -26
  173. package/lib/vendor/blamejs/lib/inbox.js +8 -8
  174. package/lib/vendor/blamejs/lib/incident-report.js +3 -21
  175. package/lib/vendor/blamejs/lib/ip-utils.js +49 -6
  176. package/lib/vendor/blamejs/lib/jobs.js +3 -2
  177. package/lib/vendor/blamejs/lib/keychain.js +6 -18
  178. package/lib/vendor/blamejs/lib/legal-hold.js +6 -15
  179. package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +44 -112
  180. package/lib/vendor/blamejs/lib/log-stream-otlp-grpc.js +17 -14
  181. package/lib/vendor/blamejs/lib/log-stream-otlp.js +16 -80
  182. package/lib/vendor/blamejs/lib/log-stream-webhook.js +20 -92
  183. package/lib/vendor/blamejs/lib/mail-arc-sign.js +8 -3
  184. package/lib/vendor/blamejs/lib/mail-arf.js +3 -2
  185. package/lib/vendor/blamejs/lib/mail-auth.js +40 -66
  186. package/lib/vendor/blamejs/lib/mail-bimi.js +19 -39
  187. package/lib/vendor/blamejs/lib/mail-crypto-pgp.js +3 -2
  188. package/lib/vendor/blamejs/lib/mail-dav.js +8 -35
  189. package/lib/vendor/blamejs/lib/mail-deploy.js +6 -9
  190. package/lib/vendor/blamejs/lib/mail-dkim.js +19 -38
  191. package/lib/vendor/blamejs/lib/mail-greylist.js +15 -26
  192. package/lib/vendor/blamejs/lib/mail-helo.js +2 -3
  193. package/lib/vendor/blamejs/lib/mail-journal.js +2 -1
  194. package/lib/vendor/blamejs/lib/mail-mdn.js +4 -3
  195. package/lib/vendor/blamejs/lib/mail-rbl.js +5 -8
  196. package/lib/vendor/blamejs/lib/mail-scan.js +2 -2
  197. package/lib/vendor/blamejs/lib/mail-send-deliver.js +33 -20
  198. package/lib/vendor/blamejs/lib/mail-server-imap.js +32 -87
  199. package/lib/vendor/blamejs/lib/mail-server-jmap.js +35 -51
  200. package/lib/vendor/blamejs/lib/mail-server-managesieve.js +29 -83
  201. package/lib/vendor/blamejs/lib/mail-server-mx.js +33 -74
  202. package/lib/vendor/blamejs/lib/mail-server-net.js +177 -0
  203. package/lib/vendor/blamejs/lib/mail-server-pop3.js +30 -83
  204. package/lib/vendor/blamejs/lib/mail-server-rate-limit.js +30 -6
  205. package/lib/vendor/blamejs/lib/mail-server-submission.js +34 -73
  206. package/lib/vendor/blamejs/lib/mail-server-tls.js +89 -0
  207. package/lib/vendor/blamejs/lib/mail-spam-score.js +7 -8
  208. package/lib/vendor/blamejs/lib/mail-store.js +3 -2
  209. package/lib/vendor/blamejs/lib/mail.js +6 -11
  210. package/lib/vendor/blamejs/lib/markup-escape.js +31 -0
  211. package/lib/vendor/blamejs/lib/markup-tokenizer.js +54 -0
  212. package/lib/vendor/blamejs/lib/mcp-tool-registry.js +26 -23
  213. package/lib/vendor/blamejs/lib/mcp.js +1 -1
  214. package/lib/vendor/blamejs/lib/mdoc.js +11 -12
  215. package/lib/vendor/blamejs/lib/metrics.js +32 -30
  216. package/lib/vendor/blamejs/lib/middleware/age-gate.js +3 -23
  217. package/lib/vendor/blamejs/lib/middleware/api-encrypt.js +11 -22
  218. package/lib/vendor/blamejs/lib/middleware/assetlinks.js +2 -7
  219. package/lib/vendor/blamejs/lib/middleware/bearer-auth.js +2 -1
  220. package/lib/vendor/blamejs/lib/middleware/body-parser.js +31 -48
  221. package/lib/vendor/blamejs/lib/middleware/bot-disclose.js +7 -10
  222. package/lib/vendor/blamejs/lib/middleware/bot-guard.js +2 -10
  223. package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +13 -2
  224. package/lib/vendor/blamejs/lib/middleware/daily-byte-quota.js +6 -26
  225. package/lib/vendor/blamejs/lib/middleware/deny-response.js +19 -1
  226. package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +7 -0
  227. package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +4 -20
  228. package/lib/vendor/blamejs/lib/middleware/rate-limit.js +20 -28
  229. package/lib/vendor/blamejs/lib/middleware/scim-server.js +3 -2
  230. package/lib/vendor/blamejs/lib/middleware/security-headers.js +9 -1
  231. package/lib/vendor/blamejs/lib/middleware/security-txt.js +2 -6
  232. package/lib/vendor/blamejs/lib/middleware/tus-upload.js +12 -27
  233. package/lib/vendor/blamejs/lib/middleware/web-app-manifest.js +2 -7
  234. package/lib/vendor/blamejs/lib/migrations.js +4 -13
  235. package/lib/vendor/blamejs/lib/mime-parse.js +34 -17
  236. package/lib/vendor/blamejs/lib/module-loader.js +44 -0
  237. package/lib/vendor/blamejs/lib/money.js +105 -0
  238. package/lib/vendor/blamejs/lib/mtls-ca.js +116 -36
  239. package/lib/vendor/blamejs/lib/network-byte-quota.js +4 -18
  240. package/lib/vendor/blamejs/lib/network-dane.js +8 -6
  241. package/lib/vendor/blamejs/lib/network-dns-resolver.js +97 -6
  242. package/lib/vendor/blamejs/lib/network-dnssec.js +16 -16
  243. package/lib/vendor/blamejs/lib/network-heartbeat.js +3 -2
  244. package/lib/vendor/blamejs/lib/network-smtp-policy.js +29 -41
  245. package/lib/vendor/blamejs/lib/network-tls.js +40 -42
  246. package/lib/vendor/blamejs/lib/nis2-report.js +1 -11
  247. package/lib/vendor/blamejs/lib/nonce-store.js +81 -3
  248. package/lib/vendor/blamejs/lib/numeric-bounds.js +22 -8
  249. package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +2 -6
  250. package/lib/vendor/blamejs/lib/object-store/azure-blob.js +5 -45
  251. package/lib/vendor/blamejs/lib/object-store/gcs.js +8 -71
  252. package/lib/vendor/blamejs/lib/object-store/http-put.js +1 -5
  253. package/lib/vendor/blamejs/lib/object-store/http-request.js +128 -0
  254. package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +2 -1
  255. package/lib/vendor/blamejs/lib/object-store/sigv4.js +9 -77
  256. package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +9 -25
  257. package/lib/vendor/blamejs/lib/observability.js +95 -0
  258. package/lib/vendor/blamejs/lib/openapi-paths-builder.js +7 -3
  259. package/lib/vendor/blamejs/lib/otel-export.js +7 -10
  260. package/lib/vendor/blamejs/lib/outbox.js +43 -37
  261. package/lib/vendor/blamejs/lib/pagination.js +11 -15
  262. package/lib/vendor/blamejs/lib/parsers/safe-env.js +5 -4
  263. package/lib/vendor/blamejs/lib/parsers/safe-ini.js +10 -4
  264. package/lib/vendor/blamejs/lib/parsers/safe-toml.js +11 -9
  265. package/lib/vendor/blamejs/lib/parsers/safe-xml.js +2 -2
  266. package/lib/vendor/blamejs/lib/parsers/safe-yaml.js +7 -6
  267. package/lib/vendor/blamejs/lib/pick.js +63 -5
  268. package/lib/vendor/blamejs/lib/pipl-cn.js +69 -59
  269. package/lib/vendor/blamejs/lib/privacy-pass.js +8 -6
  270. package/lib/vendor/blamejs/lib/problem-details.js +2 -5
  271. package/lib/vendor/blamejs/lib/pubsub.js +4 -8
  272. package/lib/vendor/blamejs/lib/redact.js +2 -1
  273. package/lib/vendor/blamejs/lib/render.js +4 -2
  274. package/lib/vendor/blamejs/lib/request-helpers.js +133 -6
  275. package/lib/vendor/blamejs/lib/restore.js +5 -22
  276. package/lib/vendor/blamejs/lib/retention.js +3 -5
  277. package/lib/vendor/blamejs/lib/safe-async.js +457 -0
  278. package/lib/vendor/blamejs/lib/safe-buffer.js +137 -6
  279. package/lib/vendor/blamejs/lib/safe-decompress.js +2 -1
  280. package/lib/vendor/blamejs/lib/safe-dns.js +2 -1
  281. package/lib/vendor/blamejs/lib/safe-ical.js +12 -26
  282. package/lib/vendor/blamejs/lib/safe-json.js +7 -8
  283. package/lib/vendor/blamejs/lib/safe-jsonpath.js +6 -5
  284. package/lib/vendor/blamejs/lib/safe-mime.js +25 -29
  285. package/lib/vendor/blamejs/lib/safe-redirect.js +2 -5
  286. package/lib/vendor/blamejs/lib/safe-schema.js +7 -6
  287. package/lib/vendor/blamejs/lib/safe-sql.js +126 -0
  288. package/lib/vendor/blamejs/lib/safe-vcard.js +12 -26
  289. package/lib/vendor/blamejs/lib/sandbox-worker.js +9 -2
  290. package/lib/vendor/blamejs/lib/sandbox.js +3 -2
  291. package/lib/vendor/blamejs/lib/scheduler.js +5 -12
  292. package/lib/vendor/blamejs/lib/sec-cyber.js +82 -37
  293. package/lib/vendor/blamejs/lib/seeders.js +4 -11
  294. package/lib/vendor/blamejs/lib/self-update.js +92 -69
  295. package/lib/vendor/blamejs/lib/session-device-binding.js +112 -66
  296. package/lib/vendor/blamejs/lib/session.js +194 -6
  297. package/lib/vendor/blamejs/lib/sql.js +225 -78
  298. package/lib/vendor/blamejs/lib/sse.js +6 -10
  299. package/lib/vendor/blamejs/lib/static.js +136 -98
  300. package/lib/vendor/blamejs/lib/storage.js +4 -2
  301. package/lib/vendor/blamejs/lib/structured-fields.js +275 -16
  302. package/lib/vendor/blamejs/lib/tenant-quota.js +2 -20
  303. package/lib/vendor/blamejs/lib/tsa.js +11 -15
  304. package/lib/vendor/blamejs/lib/validate-opts.js +154 -8
  305. package/lib/vendor/blamejs/lib/vault/seal-pem-file.js +30 -48
  306. package/lib/vendor/blamejs/lib/vault-aad.js +3 -2
  307. package/lib/vendor/blamejs/lib/vc.js +2 -7
  308. package/lib/vendor/blamejs/lib/vex.js +35 -13
  309. package/lib/vendor/blamejs/lib/web-push-vapid.js +23 -20
  310. package/lib/vendor/blamejs/lib/webhook-dispatcher.js +706 -0
  311. package/lib/vendor/blamejs/lib/webhook.js +43 -18
  312. package/lib/vendor/blamejs/lib/websocket-channels.js +9 -7
  313. package/lib/vendor/blamejs/lib/websocket.js +7 -3
  314. package/lib/vendor/blamejs/lib/worm.js +2 -3
  315. package/lib/vendor/blamejs/lib/ws-client.js +8 -10
  316. package/lib/vendor/blamejs/package.json +1 -1
  317. package/lib/vendor/blamejs/release-notes/v0.15.13.json +81 -0
  318. package/lib/vendor/blamejs/scripts/check-changelog-extract.js +1 -1
  319. package/lib/vendor/blamejs/test/00-primitives.js +136 -7
  320. package/lib/vendor/blamejs/test/10-state.js +9 -3
  321. package/lib/vendor/blamejs/test/30-chain.js +40 -0
  322. package/lib/vendor/blamejs/test/helpers/check.js +18 -0
  323. package/lib/vendor/blamejs/test/helpers/db.js +4 -0
  324. package/lib/vendor/blamejs/test/helpers/index.js +1 -0
  325. package/lib/vendor/blamejs/test/integration/audit-chain-external-db.test.js +2 -1
  326. package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +2 -1
  327. package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +8 -1
  328. package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +1 -1
  329. package/lib/vendor/blamejs/test/integration/framework-schema-mysql.test.js +2 -1
  330. package/lib/vendor/blamejs/test/integration/webhook-dispatcher-pg.test.js +269 -0
  331. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-fd-read.test.js +149 -0
  332. package/lib/vendor/blamejs/test/layer-0-primitives/audit-framework-namespaces.test.js +51 -0
  333. package/lib/vendor/blamejs/test/layer-0-primitives/audit-sign-anchor.test.js +88 -0
  334. package/lib/vendor/blamejs/test/layer-0-primitives/audit-use-store.test.js +55 -1
  335. package/lib/vendor/blamejs/test/layer-0-primitives/backup-object-store-adapter.test.js +2 -2
  336. package/lib/vendor/blamejs/test/layer-0-primitives/bot-guard.test.js +1 -1
  337. package/lib/vendor/blamejs/test/layer-0-primitives/bounded-map.test.js +129 -0
  338. package/lib/vendor/blamejs/test/layer-0-primitives/chain-writer-multichain.test.js +107 -0
  339. package/lib/vendor/blamejs/test/layer-0-primitives/cli-api-key.test.js +12 -0
  340. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +2788 -3214
  341. package/lib/vendor/blamejs/test/layer-0-primitives/codepoint-class.test.js +78 -0
  342. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-base64url.test.js +63 -0
  343. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-stream.test.js +2 -1
  344. package/lib/vendor/blamejs/test/layer-0-primitives/csp-builder.test.js +50 -0
  345. package/lib/vendor/blamejs/test/layer-0-primitives/csp-nonce.test.js +1 -1
  346. package/lib/vendor/blamejs/test/layer-0-primitives/daemon.test.js +2 -1
  347. package/lib/vendor/blamejs/test/layer-0-primitives/defineguard-resolve-opts.test.js +76 -0
  348. package/lib/vendor/blamejs/test/layer-0-primitives/flag.test.js +9 -0
  349. package/lib/vendor/blamejs/test/layer-0-primitives/gate-contract-content-gate.test.js +290 -0
  350. package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +84 -0
  351. package/lib/vendor/blamejs/test/layer-0-primitives/guard-email.test.js +78 -0
  352. package/lib/vendor/blamejs/test/layer-0-primitives/guard-filename.test.js +23 -0
  353. package/lib/vendor/blamejs/test/layer-0-primitives/guard-gate-disposition-coverage.test.js +93 -0
  354. package/lib/vendor/blamejs/test/layer-0-primitives/guard-html.test.js +60 -0
  355. package/lib/vendor/blamejs/test/layer-0-primitives/guard-image.test.js +184 -0
  356. package/lib/vendor/blamejs/test/layer-0-primitives/guard-imap-command.test.js +0 -0
  357. package/lib/vendor/blamejs/test/layer-0-primitives/guard-json.test.js +54 -0
  358. package/lib/vendor/blamejs/test/layer-0-primitives/guard-managesieve-command.test.js +10 -0
  359. package/lib/vendor/blamejs/test/layer-0-primitives/guard-markdown.test.js +45 -0
  360. package/lib/vendor/blamejs/test/layer-0-primitives/guard-pdf.test.js +101 -0
  361. package/lib/vendor/blamejs/test/layer-0-primitives/guard-pop3-command.test.js +18 -0
  362. package/lib/vendor/blamejs/test/layer-0-primitives/guard-svg.test.js +76 -0
  363. package/lib/vendor/blamejs/test/layer-0-primitives/guard-text.test.js +365 -0
  364. package/lib/vendor/blamejs/test/layer-0-primitives/guard-xml.test.js +35 -0
  365. package/lib/vendor/blamejs/test/layer-0-primitives/guard-yaml.test.js +36 -0
  366. package/lib/vendor/blamejs/test/layer-0-primitives/i18n.test.js +20 -0
  367. package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +15 -0
  368. package/lib/vendor/blamejs/test/layer-0-primitives/ip-utils.test.js +83 -0
  369. package/lib/vendor/blamejs/test/layer-0-primitives/mail-arf.test.js +10 -0
  370. package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +39 -0
  371. package/lib/vendor/blamejs/test/layer-0-primitives/mail-dkim.test.js +36 -0
  372. package/lib/vendor/blamejs/test/layer-0-primitives/mail-greylist.test.js +17 -0
  373. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-tls.test.js +39 -0
  374. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +17 -0
  375. package/lib/vendor/blamejs/test/layer-0-primitives/mime-parse.test.js +106 -0
  376. package/lib/vendor/blamejs/test/layer-0-primitives/money.test.js +17 -0
  377. package/lib/vendor/blamejs/test/layer-0-primitives/mtls-ca-revocation.test.js +98 -0
  378. package/lib/vendor/blamejs/test/layer-0-primitives/nonce-store-release.test.js +77 -0
  379. package/lib/vendor/blamejs/test/layer-0-primitives/observability.test.js +48 -0
  380. package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-memory-getorinsert.test.js +100 -0
  381. package/lib/vendor/blamejs/test/layer-0-primitives/request-helpers.test.js +88 -0
  382. package/lib/vendor/blamejs/test/layer-0-primitives/safe-async-loops.test.js +278 -0
  383. package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer-linear-scans.test.js +37 -0
  384. package/lib/vendor/blamejs/test/layer-0-primitives/safe-jsonpath.test.js +14 -0
  385. package/lib/vendor/blamejs/test/layer-0-primitives/sandbox.test.js +19 -0
  386. package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +1 -1
  387. package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +2 -1
  388. package/lib/vendor/blamejs/test/layer-0-primitives/session-device-binding.test.js +18 -0
  389. package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +1 -1
  390. package/lib/vendor/blamejs/test/layer-0-primitives/session-valid-from.test.js +73 -0
  391. package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +100 -0
  392. package/lib/vendor/blamejs/test/layer-0-primitives/structured-fields.test.js +80 -0
  393. package/lib/vendor/blamejs/test/layer-0-primitives/validate-opts-shape.test.js +235 -0
  394. package/lib/vendor/blamejs/test/layer-0-primitives/webhook-dispatcher.test.js +374 -0
  395. package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +75 -8
  396. package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +3 -3
  397. package/package.json +1 -1
@@ -0,0 +1,365 @@
1
+ "use strict";
2
+ /**
3
+ * guard-text — general-purpose UTF-8 free-text content-safety primitive
4
+ * (b.guardText).
5
+ *
6
+ * Covers: required guard-family surface (NAME / KIND / MIME_TYPES /
7
+ * EXTENSIONS / PROFILES / COMPLIANCE_POSTURES / validate / sanitize / gate /
8
+ * buildProfile / compliancePosture / loadRulePack / INTEGRATION_FIXTURES +
9
+ * GuardTextError); the codepoint threat catalog (bidi override / C0 control /
10
+ * null byte / zero-width / Unicode Tags / mixed-script confusable);
11
+ * byte-accurate maxBytes on multibyte input; multibyte legitimate-script
12
+ * preservation; sanitize strip + amplification cap; non-repairable confusable;
13
+ * the gate serve→audit-only→sanitize→refuse decision chain; operator rules;
14
+ * profile + posture composition; registration in b.guardAll.allGuards().
15
+ *
16
+ * Hostile codepoints are constructed via String.fromCharCode so this test
17
+ * source stays pure ASCII (the guard-family source-purity invariant).
18
+ *
19
+ * Run standalone: node test/layer-0-primitives/guard-text.test.js
20
+ * Or via smoke: node test/smoke.js
21
+ */
22
+
23
+ var helpers = require("../helpers");
24
+ var b = helpers.b;
25
+ var check = helpers.check;
26
+
27
+ // Hostile codepoints, built numerically.
28
+ var RLO = String.fromCharCode(0x202E); // RIGHT-TO-LEFT OVERRIDE (bidi)
29
+ var LRO = String.fromCharCode(0x202D); // LEFT-TO-RIGHT OVERRIDE (bidi)
30
+ var NUL = String.fromCharCode(0x00); // null byte
31
+ var BELL = String.fromCharCode(0x07); // C0 control
32
+ var ZWSP = String.fromCharCode(0x200B); // ZERO WIDTH SPACE
33
+ var ZWNJ = String.fromCharCode(0x200C); // ZERO WIDTH NON-JOINER
34
+ var TAGA = String.fromCodePoint(0xE0041); // Unicode Tags block "A" (ASCII smuggling; astral — needs fromCodePoint)
35
+ var CYR_A = String.fromCharCode(0x0430); // Cyrillic small a (confusable with Latin a)
36
+
37
+ // ---- surface ----
38
+
39
+ function testSurface() {
40
+ check("guardText is an object", typeof b.guardText === "object");
41
+ check("guardText.NAME === text", b.guardText.NAME === "text");
42
+ check("guardText.KIND === content", b.guardText.KIND === "content");
43
+ check("guardText.MIME_TYPES includes text/plain",
44
+ b.guardText.MIME_TYPES.indexOf("text/plain") !== -1);
45
+ check("guardText.EXTENSIONS includes .txt",
46
+ b.guardText.EXTENSIONS.indexOf(".txt") !== -1);
47
+ check("guardText.validate is a function", typeof b.guardText.validate === "function");
48
+ check("guardText.sanitize is a function", typeof b.guardText.sanitize === "function");
49
+ check("guardText.gate is a function", typeof b.guardText.gate === "function");
50
+ check("guardText.buildProfile is a function", typeof b.guardText.buildProfile === "function");
51
+ check("guardText.compliancePosture is a function",
52
+ typeof b.guardText.compliancePosture === "function");
53
+ check("guardText.loadRulePack is a function", typeof b.guardText.loadRulePack === "function");
54
+ check("guardText.INTEGRATION_FIXTURES is an object",
55
+ typeof b.guardText.INTEGRATION_FIXTURES === "object");
56
+ check("guardText.GuardTextError is a function",
57
+ typeof b.guardText.GuardTextError === "function");
58
+ }
59
+
60
+ function testProfilesAndPostures() {
61
+ var p = Object.keys(b.guardText.PROFILES);
62
+ check("PROFILES has strict/balanced/permissive",
63
+ p.indexOf("strict") !== -1 && p.indexOf("balanced") !== -1 && p.indexOf("permissive") !== -1);
64
+ var c = Object.keys(b.guardText.COMPLIANCE_POSTURES);
65
+ check("POSTURES has hipaa/pci-dss/gdpr/soc2",
66
+ c.indexOf("hipaa") !== -1 && c.indexOf("pci-dss") !== -1 &&
67
+ c.indexOf("gdpr") !== -1 && c.indexOf("soc2") !== -1);
68
+ // buildProfile composes overlays without mutating the frozen preset.
69
+ var prof = b.guardText.buildProfile({ baseProfile: "strict", overrides: { maxBytes: 1024 } });
70
+ check("buildProfile overlays maxBytes", prof.maxBytes === 1024);
71
+ check("buildProfile keeps strict bidi reject", prof.bidiPolicy === "reject");
72
+ // compliancePosture resolves a known posture.
73
+ var hipaa = b.guardText.compliancePosture("hipaa");
74
+ check("compliancePosture hipaa bidi reject", hipaa.bidiPolicy === "reject");
75
+ }
76
+
77
+ function testRegisteredInGuardAll() {
78
+ var names = b.guardAll.allGuards().map(function (g) { return g.NAME; });
79
+ check("text registered in b.guardAll.allGuards()", names.indexOf("text") !== -1);
80
+ }
81
+
82
+ function testGdprPostureMatchesBalancedTier() {
83
+ // text is a content guard: gdpr maps to the balanced tier, whose maxBytes
84
+ // is 4 MiB. A hand-rolled partial posture omitting maxBytes silently
85
+ // backfills the strict 1 MiB cap from DEFAULTS — an incoherent hybrid. The
86
+ // routed posture inherits the full balanced tier, so maxBytes is 4194304.
87
+ var gdpr = b.guardText.COMPLIANCE_POSTURES.gdpr;
88
+ check("gdpr posture maxBytes is balanced-tier 4 MiB", gdpr.maxBytes === 4194304);
89
+ // Consumer-path proof: a 2 MiB input (between the strict 1 MiB and balanced
90
+ // 4 MiB caps) validates OK under the gdpr posture. Under the strict-backfill
91
+ // hybrid it was rejected as too-large.
92
+ var twoMiB = "a".repeat(2 * 1024 * 1024);
93
+ var rv = b.guardText.validate(twoMiB, { compliancePosture: "gdpr" });
94
+ check("2 MiB text validates OK under gdpr posture", rv.ok === true);
95
+ }
96
+
97
+ // ---- validate: each threat class ----
98
+
99
+ function testValidateBenign() {
100
+ var rv = b.guardText.validate("a perfectly ordinary review", { profile: "strict" });
101
+ check("benign text ok", rv.ok === true);
102
+ check("benign text has no issues", rv.issues.length === 0);
103
+ }
104
+
105
+ function testValidateBidi() {
106
+ var rv = b.guardText.validate("review " + RLO + "txt.exe", { profile: "strict" });
107
+ check("bidi override not ok", rv.ok === false);
108
+ check("bidi override kind",
109
+ rv.issues.some(function (i) { return i.kind === "bidi-override"; }));
110
+ // LRO is also a bidi override.
111
+ var rv2 = b.guardText.validate("a" + LRO + "b", { profile: "strict" });
112
+ check("LRO bidi override not ok", rv2.ok === false);
113
+ }
114
+
115
+ function testValidateControl() {
116
+ var rv = b.guardText.validate("log line" + BELL + "injection", { profile: "strict" });
117
+ check("control char not ok", rv.ok === false);
118
+ check("control char kind",
119
+ rv.issues.some(function (i) { return i.kind === "control-char"; }));
120
+ }
121
+
122
+ function testValidateNullByte() {
123
+ var rv = b.guardText.validate("name" + NUL + "truncate", { profile: "strict" });
124
+ check("null byte not ok", rv.ok === false);
125
+ check("null byte kind",
126
+ rv.issues.some(function (i) { return i.kind === "null-byte"; }));
127
+ }
128
+
129
+ function testValidateZeroWidth() {
130
+ var rv = b.guardText.validate("hid" + ZWSP + "den", { profile: "strict" });
131
+ check("zero-width not ok", rv.ok === false);
132
+ check("zero-width kind",
133
+ rv.issues.some(function (i) { return i.kind === "zero-width"; }));
134
+ }
135
+
136
+ function testValidateUnicodeTags() {
137
+ // ASCII-smuggling: an invisible Tags-block instruction (prompt injection).
138
+ var rv = b.guardText.validate("hello" + TAGA + "world", { profile: "strict" });
139
+ check("unicode-tags not ok", rv.ok === false);
140
+ check("unicode-tags kind critical",
141
+ rv.issues.some(function (i) {
142
+ return i.kind === "unicode-tags" && i.severity === "critical";
143
+ }));
144
+ }
145
+
146
+ function testValidateConfusableStrictRefuses() {
147
+ // A Latin word with one Cyrillic letter swapped in (UTS #39 confusable).
148
+ var rv = b.guardText.validate("p" + CYR_A + "ypal", { profile: "strict" });
149
+ check("mixed-script confusable not ok under strict", rv.ok === false);
150
+ check("confusable kind",
151
+ rv.issues.some(function (i) { return i.kind === "mixed-script-confusable"; }));
152
+ }
153
+
154
+ function testValidateConfusableAuditOnlyUnderPermissive() {
155
+ // permissive: confusablePolicy "allow" -> not even reported.
156
+ var rv = b.guardText.validate("p" + CYR_A + "ypal", { profile: "permissive" });
157
+ check("confusable suppressed under permissive (allow)", rv.ok === true);
158
+ }
159
+
160
+ function testValidateMaxBytesByteAccurate() {
161
+ // "€" is 3 UTF-8 bytes; 2 of them = 6 bytes > 5. text.length would be 2.
162
+ var rv = b.guardText.validate("€€", { profile: "strict", maxBytes: 5 });
163
+ check("maxBytes measured in bytes not chars", rv.ok === false);
164
+ check("too-large kind",
165
+ rv.issues.some(function (i) { return i.kind === "too-large"; }));
166
+ // 1 euro = 3 bytes <= 5 passes.
167
+ var rv2 = b.guardText.validate("€", { profile: "strict", maxBytes: 5 });
168
+ check("single euro within byte budget ok", rv2.ok === true);
169
+ }
170
+
171
+ function testValidateMaxBytesInfinityThrows() {
172
+ var threw = false;
173
+ try { b.guardText.validate("x", { profile: "strict", maxBytes: Infinity }); }
174
+ catch (e) { threw = e && e.code === "text.bad-opt"; }
175
+ check("maxBytes Infinity throws config-time", threw === true);
176
+ }
177
+
178
+ function testValidateMultibyteScriptsPreservedAsBenign() {
179
+ // Legitimate single-script multilingual text is NOT an issue — the guard
180
+ // imposes no grammar. Each is its own script (no mixing).
181
+ check("Han text benign", b.guardText.validate("你好世界", { profile: "strict" }).ok === true);
182
+ check("Arabic text benign", b.guardText.validate("مرحبا", { profile: "strict" }).ok === true);
183
+ check("emoji benign", b.guardText.validate("great product 👍", { profile: "strict" }).ok === true);
184
+ }
185
+
186
+ function testValidateBufferInput() {
187
+ var rv = b.guardText.validate(Buffer.from("plain bytes", "utf8"), { profile: "strict" });
188
+ check("Buffer input validates", rv.ok === true);
189
+ }
190
+
191
+ // ---- encoding validity (byte → codepoint layer) ----
192
+
193
+ function testValidateInvalidEncoding() {
194
+ // Overlong encoding of "/" (0x2F) as C0 AF — the classic UTF-8 filter bypass;
195
+ // a lossy toString would launder it into U+FFFD.
196
+ var overlong = Buffer.from([0x2F, 0xC0, 0xAF, 0x2F]);
197
+ var rv = b.guardText.validate(overlong, { profile: "strict" });
198
+ check("overlong UTF-8 flagged invalid-encoding", rv.ok === false &&
199
+ rv.issues.some(function (i) { return i.kind === "invalid-encoding"; }));
200
+ // Truncated multibyte (lead byte, no continuation).
201
+ var trunc = b.guardText.validate(Buffer.from([0x41, 0xE2, 0x82]), { profile: "strict" });
202
+ check("truncated UTF-8 flagged", trunc.ok === false);
203
+ // Well-formed multibyte passes the encoding check.
204
+ check("valid UTF-8 (euro) passes encoding",
205
+ b.guardText.validate(Buffer.from("€10", "utf8"), { profile: "strict" }).ok === true);
206
+ // permissive audits (does not reject) malformed encoding.
207
+ var perm = b.guardText.validate(Buffer.from([0xC0, 0xAF]), { profile: "permissive" });
208
+ check("permissive encoding policy is audit (warn, ok stays by that axis)",
209
+ perm.issues.some(function (i) { return i.kind === "invalid-encoding" && i.severity === "warn"; }));
210
+ }
211
+
212
+ // ---- keyspace bounds ----
213
+
214
+ function testValidateAsciiOnly() {
215
+ var rv = b.guardText.validate("café", { profile: "strict", asciiOnly: true });
216
+ check("asciiOnly flags non-ASCII", rv.ok === false &&
217
+ rv.issues.some(function (i) { return i.kind === "non-ascii"; }));
218
+ check("asciiOnly allows pure ASCII",
219
+ b.guardText.validate("plain ascii", { profile: "strict", asciiOnly: true }).ok === true);
220
+ }
221
+
222
+ function testValidateMaxCodepoint() {
223
+ var astral = "hi " + String.fromCodePoint(0x1F600);
224
+ var rv = b.guardText.validate(astral, { profile: "strict", maxCodepoint: 0xFFFF });
225
+ check("maxCodepoint flags astral codepoint", rv.ok === false &&
226
+ rv.issues.some(function (i) { return i.kind === "codepoint-out-of-range"; }));
227
+ check("maxCodepoint allows within ceiling",
228
+ b.guardText.validate("你好", { profile: "strict", maxCodepoint: 0xFFFF }).ok === true);
229
+ }
230
+
231
+ async function testGateRefuseInvalidEncoding() {
232
+ var overlong = Buffer.from([0x2F, 0xC0, 0xAF]);
233
+ var v = await b.guardText.gate({ profile: "strict" }).check({ bytes: overlong });
234
+ check("gate refuses malformed UTF-8", v.action === "refuse");
235
+ }
236
+
237
+ // ---- sanitize ----
238
+
239
+ function testSanitizeStripsInvisibles() {
240
+ var clean = b.guardText.sanitize("nice" + ZWSP + "re" + ZWNJ + "view", { profile: "balanced" });
241
+ check("sanitize strips zero-width", clean.indexOf(ZWSP) === -1 && clean.indexOf(ZWNJ) === -1);
242
+ check("sanitize result text intact", clean === "nicereview");
243
+ }
244
+
245
+ function testSanitizeStripsBidiControlNullTags() {
246
+ var dirty = "a" + RLO + "b" + BELL + "c" + NUL + "d" + TAGA + "e";
247
+ var clean = b.guardText.sanitize(dirty, { profile: "balanced" });
248
+ check("sanitize strips bidi", clean.indexOf(RLO) === -1);
249
+ check("sanitize strips control", clean.indexOf(BELL) === -1);
250
+ check("sanitize strips null", clean.indexOf(NUL) === -1);
251
+ check("sanitize strips tags", clean.indexOf(TAGA) === -1);
252
+ check("sanitize preserves letters", clean === "abcde");
253
+ }
254
+
255
+ function testSanitizePreservesMultibyte() {
256
+ var clean = b.guardText.sanitize("你好" + ZWSP + "世界", { profile: "balanced" });
257
+ check("sanitize preserves Han, strips zwsp", clean === "你好世界");
258
+ }
259
+
260
+ function testSanitizeAmplificationContract() {
261
+ // Sanitize is shrinking by contract: stripping can only remove, never grow.
262
+ var clean = b.guardText.sanitize("hello world", { profile: "balanced" });
263
+ check("sanitize never grows output", clean.length <= "hello world".length);
264
+ }
265
+
266
+ // ---- gate decision chain ----
267
+
268
+ async function testGateServe() {
269
+ var v = await b.guardText.gate({ profile: "strict" })
270
+ .check({ bytes: Buffer.from("ordinary text", "utf8") });
271
+ check("gate serve on benign", v.action === "serve");
272
+ }
273
+
274
+ async function testGateRefuseBidiStrict() {
275
+ var v = await b.guardText.gate({ profile: "strict" })
276
+ .check({ bytes: Buffer.from("ok " + RLO + "danger", "utf8") });
277
+ check("gate refuse on bidi under strict", v.action === "refuse" && v.ok === false);
278
+ }
279
+
280
+ async function testGateSanitizeBalanced() {
281
+ // balanced strips invisibles -> sanitize action with cleaned bytes.
282
+ var v = await b.guardText.gate({ profile: "balanced" })
283
+ .check({ bytes: Buffer.from("nice" + ZWSP + "review", "utf8") });
284
+ check("gate sanitize under balanced", v.action === "sanitize");
285
+ check("gate sanitize returns cleaned bytes",
286
+ Buffer.isBuffer(v.sanitized) && v.sanitized.toString("utf8") === "nicereview");
287
+ }
288
+
289
+ async function testGateAuditOnlyConfusable() {
290
+ // balanced confusablePolicy "audit" -> warn-only -> audit-only, not refuse.
291
+ var v = await b.guardText.gate({ profile: "balanced" })
292
+ .check({ bytes: Buffer.from("p" + CYR_A + "ypal", "utf8") });
293
+ check("gate audit-only on balanced confusable", v.action === "audit-only");
294
+ }
295
+
296
+ async function testGateRefuseConfusableStrict() {
297
+ // strict confusablePolicy "reject" -> high severity, non-repairable -> refuse.
298
+ var v = await b.guardText.gate({ profile: "strict" })
299
+ .check({ bytes: Buffer.from("p" + CYR_A + "ypal", "utf8") });
300
+ check("gate refuse on strict confusable", v.action === "refuse");
301
+ }
302
+
303
+ async function testGateOperatorRule() {
304
+ var gate = b.guardText.gate({
305
+ profile: "permissive",
306
+ operatorRules: [{
307
+ id: "no-profanity", severity: "high",
308
+ detect: function (c) { return /badword/.test(c.bytes); },
309
+ reason: "operator profanity filter",
310
+ }],
311
+ });
312
+ var v = await gate.check({ bytes: Buffer.from("this has badword in it", "utf8") });
313
+ check("operator rule fires -> refuse", v.action === "refuse");
314
+ check("operator rule issue surfaced",
315
+ v.issues.some(function (i) { return i.kind === "no-profanity"; }));
316
+ // A throwing operator rule is skipped, never crashes the gate.
317
+ var gate2 = b.guardText.gate({
318
+ profile: "permissive",
319
+ operatorRules: [{ id: "boom", detect: function () { throw new Error("rule bug"); } }],
320
+ });
321
+ var v2 = await gate2.check({ bytes: Buffer.from("clean text", "utf8") });
322
+ check("throwing operator rule does not crash gate", v2.action === "serve");
323
+ }
324
+
325
+ async function run() {
326
+ testSurface();
327
+ testProfilesAndPostures();
328
+ testRegisteredInGuardAll();
329
+ testGdprPostureMatchesBalancedTier();
330
+ testValidateBenign();
331
+ testValidateBidi();
332
+ testValidateControl();
333
+ testValidateNullByte();
334
+ testValidateZeroWidth();
335
+ testValidateUnicodeTags();
336
+ testValidateConfusableStrictRefuses();
337
+ testValidateConfusableAuditOnlyUnderPermissive();
338
+ testValidateMaxBytesByteAccurate();
339
+ testValidateMaxBytesInfinityThrows();
340
+ testValidateMultibyteScriptsPreservedAsBenign();
341
+ testValidateBufferInput();
342
+ testValidateInvalidEncoding();
343
+ testValidateAsciiOnly();
344
+ testValidateMaxCodepoint();
345
+ await testGateRefuseInvalidEncoding();
346
+ testSanitizeStripsInvisibles();
347
+ testSanitizeStripsBidiControlNullTags();
348
+ testSanitizePreservesMultibyte();
349
+ testSanitizeAmplificationContract();
350
+ await testGateServe();
351
+ await testGateRefuseBidiStrict();
352
+ await testGateSanitizeBalanced();
353
+ await testGateAuditOnlyConfusable();
354
+ await testGateRefuseConfusableStrict();
355
+ await testGateOperatorRule();
356
+ }
357
+
358
+ module.exports = { run: run };
359
+
360
+ if (require.main === module) {
361
+ run().then(
362
+ function () { console.log("[guard-text] OK — " + helpers.getChecks() + " checks passed"); process.exit(0); },
363
+ function (e) { console.error("FAIL:", e && e.stack || e); process.exit(1); }
364
+ );
365
+ }
@@ -134,6 +134,39 @@ function testGuardXmlElementCap() {
134
134
  rv.issues.some(function (i) { return i.kind === "element-cap"; }));
135
135
  }
136
136
 
137
+ function testGuardXmlByteCap() {
138
+ // The cap is named in BYTES; it must measure UTF-8 bytes, not UTF-16
139
+ // code units. "é" is one .length unit but two UTF-8 bytes, so a string
140
+ // whose .length is under the cap can still exceed it in bytes.
141
+ var multibyte = "é".repeat(40); // .length === 40, Buffer.byteLength === 80
142
+ var rv = b.guardXml.validate(multibyte, { profile: "strict", maxBytes: 50 });
143
+ var cap = rv.issues.filter(function (i) { return i.kind === "too-large"; });
144
+ check("multibyte input over the byte cap is refused",
145
+ rv.ok === false && cap.length === 1 &&
146
+ cap[0].ruleId === "xml.too-large" &&
147
+ /80 bytes exceeds maxBytes 50/.test(cap[0].snippet));
148
+
149
+ // ASCII under the cap must NOT trip too-large.
150
+ var underAscii = "a".repeat(40);
151
+ var rvUnder = b.guardXml.validate(underAscii, { profile: "strict", maxBytes: 50 });
152
+ check("ASCII input under the byte cap is not flagged too-large",
153
+ !rvUnder.issues.some(function (i) { return i.kind === "too-large"; }));
154
+
155
+ // ASCII over the cap still trips too-large.
156
+ var overAscii = "a".repeat(60);
157
+ var rvOver = b.guardXml.validate(overAscii, { profile: "strict", maxBytes: 50 });
158
+ check("ASCII input over the byte cap is refused",
159
+ rvOver.issues.some(function (i) { return i.kind === "too-large"; }));
160
+ }
161
+
162
+ function testGuardXmlBadInputRuleId() {
163
+ var rv = b.guardXml.validate(12345, { profile: "strict" });
164
+ check("non-string input carries xml.bad-input ruleId",
165
+ rv.issues.some(function (i) {
166
+ return i.kind === "bad-input" && i.ruleId === "xml.bad-input";
167
+ }));
168
+ }
169
+
137
170
  function testGuardXmlClean() {
138
171
  var rv = b.guardXml.validate(
139
172
  '<?xml version="1.0"?><root><name>alice</name><age>30</age></root>',
@@ -193,6 +226,8 @@ async function run() {
193
226
  testGuardXmlCdata();
194
227
  testGuardXmlBidiNull();
195
228
  testGuardXmlElementCap();
229
+ testGuardXmlByteCap();
230
+ testGuardXmlBadInputRuleId();
196
231
  testGuardXmlClean();
197
232
  testGuardXmlSanitizeRefusesCritical();
198
233
  testGuardXmlCompliancePosture();
@@ -128,6 +128,41 @@ function testGuardYamlBidiNull() {
128
128
  rvNull.issues.some(function (issue) { return issue.kind === "null-byte"; }));
129
129
  }
130
130
 
131
+ function testGuardYamlByteCap() {
132
+ // "é" (U+00E9) is 1 UTF-16 code unit but 2 UTF-8 bytes. Five of them are
133
+ // 5 code units / 10 bytes; with maxBytes:6 the cap must measure BYTES — a
134
+ // .length compare would see 5 <= 6 and let a 10-byte input past a 6-byte cap.
135
+ var multibyte = "é".repeat(5);
136
+ var rvOver = b.guardYaml.validate(multibyte, { profile: "permissive", maxBytes: 6 });
137
+ var capIssue = rvOver.issues.filter(function (issue) { return issue.kind === "too-large"; })[0];
138
+ check("multibyte over byte cap → too-large fires (byte measure, not char)",
139
+ !!capIssue);
140
+ check("too-large snippet reports the byte length, not the char length",
141
+ !!capIssue && capIssue.snippet === "input 10 bytes exceeds maxBytes 6");
142
+ check("too-large carries ruleId yaml.too-large",
143
+ !!capIssue && capIssue.ruleId === "yaml.too-large");
144
+
145
+ // Same five code units fit under a byte cap that covers their 10 bytes.
146
+ var rvUnder = b.guardYaml.validate(multibyte, { profile: "permissive", maxBytes: 16 });
147
+ check("multibyte under byte cap → too-large does NOT fire",
148
+ !rvUnder.issues.some(function (issue) { return issue.kind === "too-large"; }));
149
+
150
+ // ASCII (1 byte == 1 code unit) is unaffected by the byte measure.
151
+ var rvAscii = b.guardYaml.validate("aaaaaaaa", { profile: "permissive", maxBytes: 4 });
152
+ check("ASCII over cap still fires with byte-count snippet",
153
+ rvAscii.issues.some(function (issue) {
154
+ return issue.kind === "too-large" &&
155
+ issue.snippet === "input 8 bytes exceeds maxBytes 4";
156
+ }));
157
+
158
+ // Non-string input is refused with the yaml.bad-input ruleId.
159
+ var rvBad = b.guardYaml.validate(12345, { profile: "permissive" });
160
+ check("non-string input → bad-input with ruleId yaml.bad-input",
161
+ rvBad.issues.some(function (issue) {
162
+ return issue.kind === "bad-input" && issue.ruleId === "yaml.bad-input";
163
+ }));
164
+ }
165
+
131
166
  function testGuardYamlClean() {
132
167
  var rv = b.guardYaml.validate("name: alice\nage: 30\ntags:\n - one\n - two\n",
133
168
  { profile: "strict" });
@@ -193,6 +228,7 @@ async function run() {
193
228
  testGuardYamlMergeKey();
194
229
  testGuardYamlDuplicateKeys();
195
230
  testGuardYamlBidiNull();
231
+ testGuardYamlByteCap();
196
232
  testGuardYamlClean();
197
233
  testGuardYamlParseStrictThrows();
198
234
  testGuardYamlCompliancePosture();
@@ -801,6 +801,26 @@ async function run() {
801
801
  testLazyLoadValidatesOnLoad();
802
802
  testLazyLoadRejectsInlineTranslations();
803
803
  testEagerLocalesValidation();
804
+ testLocaleChain();
805
+ }
806
+
807
+ function testLocaleChain() {
808
+ function arrEq(a, e) { return JSON.stringify(a) === JSON.stringify(e); }
809
+ check("localeChain: fr-CA → fr → en (fallback en)",
810
+ arrEq(b.i18n.localeChain("fr-CA", { defaultLocale: "en", fallbackLocale: "en" }),
811
+ ["fr-CA", "fr", "en"]));
812
+ check("localeChain: strict (fallback null) does not jump to default",
813
+ arrEq(b.i18n.localeChain("zh-Hant-TW", { defaultLocale: "en", fallbackLocale: null }),
814
+ ["zh-Hant-TW", "zh-Hant", "zh"]));
815
+ check("localeChain: omitted fallback defaults to defaultLocale",
816
+ b.i18n.localeChain("de-DE", { defaultLocale: "en" }).indexOf("en") !== -1);
817
+ check("localeChain: bad locale throws",
818
+ (function () { try { b.i18n.localeChain("", { defaultLocale: "en" }); return false; }
819
+ catch (_e) { return true; } })());
820
+ check("localeChain: configured-set membership enforced",
821
+ (function () { try {
822
+ b.i18n.localeChain("fr", { defaultLocale: "en", locales: ["fr", "de"] }); return false;
823
+ } catch (_e) { return true; } })());
804
824
  }
805
825
 
806
826
  // ---- v0.4.14 ordinal + onMissingKey + lazyLoad ----
@@ -94,7 +94,22 @@ function _makeFakeExternalDb() {
94
94
  };
95
95
  }
96
96
 
97
+ async function testByteCapMultibyte() {
98
+ // maxPayloadBytes is a BYTE cap on the serialized metadata. A multibyte
99
+ // value under the char count but over the byte cap must be refused.
100
+ var fake = _makeFakeExternalDb();
101
+ var inbox = b.inbox.create({ externalDb: fake.db, table: "bytecap_inbox", audit: false, maxPayloadBytes: 30 });
102
+ var mb = String.fromCharCode(0x4e2d).repeat(15); // 15 chars / 45 UTF-8 bytes
103
+ var threw = null;
104
+ try {
105
+ await inbox.recordReceive({ messageId: "mb-1", source: "kafka:test", metadata: { note: mb } }, fake.xdb);
106
+ } catch (e) { threw = e; }
107
+ check("inbox byte-cap: multibyte metadata over byte cap refused",
108
+ threw && threw.code === "inbox/bad-receive");
109
+ }
110
+
97
111
  async function run() {
112
+ await testByteCapMultibyte();
98
113
  check("b.inbox is object", typeof b.inbox === "object");
99
114
  check("b.inbox.create is fn", typeof b.inbox.create === "function");
100
115
 
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ /**
3
+ * lib/ip-utils — internal IP-address textual helpers shared across the
4
+ * mail (greylist / rbl / helo), guard-domain, and safe-schema consumers.
5
+ * Covers the strict dotted-quad IPv4 validator, the RFC 5321 bracketed
6
+ * address-literal form, and the bounded loose-IPv6 pre-filter that were
7
+ * consolidated here from five hand-rolled regex spellings.
8
+ */
9
+
10
+ var helpers = require("../helpers");
11
+ var check = helpers.check;
12
+ var ip = require("../../lib/ip-utils");
13
+
14
+ function run() {
15
+ // ---- isIPv4 / IPV4_RE — strict RFC 791 dotted-quad ----
16
+ ["0.0.0.0", "255.255.255.255", "1.2.3.4", "192.168.0.1", "10.0.0.255",
17
+ "203.0.113.42", "9.9.9.9", "199.199.199.199", "250.250.250.250"]
18
+ .forEach(function (s) {
19
+ check("isIPv4 accepts " + s, ip.isIPv4(s) === true);
20
+ check("IPV4_RE matches isIPv4 for " + s, ip.IPV4_RE.test(s) === ip.isIPv4(s));
21
+ });
22
+
23
+ ["256.0.0.1", "1.2.3", "1.2.3.4.5", "01.2.3.4", "1.2.3.256", "300.1.1.1",
24
+ "", "abc", "1.2.3.4 ", " 1.2.3.4", "1.2.3.x", "999.0.0.0", "1.2.3.04",
25
+ "0xC0.0.0.1"]
26
+ .forEach(function (s) {
27
+ check("isIPv4 rejects " + JSON.stringify(s), ip.isIPv4(s) === false);
28
+ });
29
+
30
+ // Non-string inputs never throw, always false.
31
+ [null, undefined, 1234, {}, [], Buffer.from("1.2.3.4")].forEach(function (v) {
32
+ check("isIPv4 false on non-string " + Object.prototype.toString.call(v),
33
+ ip.isIPv4(v) === false);
34
+ });
35
+
36
+ // ---- IPV4_ADDR_LITERAL_RE — RFC 5321 §4.1.3 bracketed form ----
37
+ var lit = "[203.0.113.42]".match(ip.IPV4_ADDR_LITERAL_RE);
38
+ check("IPV4_ADDR_LITERAL_RE matches bracketed literal", lit !== null);
39
+ check("IPV4_ADDR_LITERAL_RE captures inner dotted-quad", lit && lit[1] === "203.0.113.42");
40
+ check("IPV4_ADDR_LITERAL_RE rejects out-of-range octet",
41
+ ip.IPV4_ADDR_LITERAL_RE.test("[256.0.0.1]") === false);
42
+ check("IPV4_ADDR_LITERAL_RE rejects unbracketed", ip.IPV4_ADDR_LITERAL_RE.test("1.2.3.4") === false);
43
+
44
+ // ---- looksLikeIPv6Hex — bounded hex-colon pre-filter ----
45
+ ["::1", "2001:db8::1", "fe80::1", "0:0:0:0:0:0:0:0",
46
+ "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"] // 39 chars — the upper bound
47
+ .forEach(function (s) {
48
+ check("looksLikeIPv6Hex accepts " + s, ip.looksLikeIPv6Hex(s) === true);
49
+ });
50
+ check("looksLikeIPv6Hex boundary is exactly 39",
51
+ "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff".length === ip.IPV6_TEXT_MAX_LEN);
52
+
53
+ ["::ffff:1.2.3.4", // dotted IPv4-mapped tail — excluded
54
+ "gggg::1", "nothex", "", "1.2.3.4",
55
+ "aaaa:aaaa:aaaa:aaaa:aaaa:aaaa:aaaa:aaaa:aaaa"] // 44 chars — over the bound
56
+ .forEach(function (s) {
57
+ check("looksLikeIPv6Hex rejects " + JSON.stringify(s), ip.looksLikeIPv6Hex(s) === false);
58
+ });
59
+ [null, undefined, 42, {}].forEach(function (v) {
60
+ check("looksLikeIPv6Hex false on non-string", ip.looksLikeIPv6Hex(v) === false);
61
+ });
62
+
63
+ // A valid IPv6 that passes the pre-filter still expands cleanly.
64
+ check("pre-filter then expandIpv6Hex parses ::1",
65
+ ip.looksLikeIPv6Hex("::1") && ip.expandIpv6Hex("::1") === "00000000000000000000000000000001");
66
+
67
+ // ---- regression: existing helpers unchanged ----
68
+ check("isIPv4Shape loose still true for 999.0.0.0", ip.isIPv4Shape("999.0.0.0") === true);
69
+ check("isIPv4Shape false for non-dotted", ip.isIPv4Shape("notip") === false);
70
+ check("expandIpv6Hex(bad) null", ip.expandIpv6Hex("bad") === null);
71
+ check("expandIpv6Groups ::1", JSON.stringify(ip.expandIpv6Groups("::1")) === JSON.stringify([0, 0, 0, 0, 0, 0, 0, 1]));
72
+
73
+ return Promise.resolve();
74
+ }
75
+
76
+ module.exports = { run: run };
77
+
78
+ if (require.main === module) run().then(function () {
79
+ process.stdout.write("OK — ip-utils\n");
80
+ }).catch(function (e) {
81
+ process.stderr.write("FAIL: " + (e && e.stack || e) + "\n");
82
+ process.exit(1);
83
+ });
@@ -187,7 +187,17 @@ function testParseAuthFailureType() {
187
187
  event.authFailure === "dmarc");
188
188
  }
189
189
 
190
+ function testByteCapMultibyte() {
191
+ // maxBytes is a BYTE cap (regression for byte-cap-vs-char-length).
192
+ var report = String.fromCharCode(0x4e2d).repeat(20); // 20 chars / 60 UTF-8 bytes; cap 30
193
+ var threw = null;
194
+ try { b.mailArf.parse(report, { maxBytes: 30 }); } catch (e) { threw = e; }
195
+ check("mailArf byte-cap: multibyte report over byte cap refused",
196
+ threw && threw.message.indexOf("exceeds 30 bytes") !== -1);
197
+ }
198
+
190
199
  async function run() {
200
+ testByteCapMultibyte();
191
201
  testSurface();
192
202
  testParseRfc5965Sample();
193
203
  testParseMissingRequired();