@blamejs/blamejs-shop 0.4.31 → 0.4.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (336) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/lib/asset-manifest.json +1 -1
  3. package/lib/vendor/MANIFEST.json +392 -278
  4. package/lib/vendor/blamejs/.github/workflows/ci.yml +34 -3
  5. package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +21 -4
  6. package/lib/vendor/blamejs/.gitignore +6 -0
  7. package/lib/vendor/blamejs/CHANGELOG.md +26 -0
  8. package/lib/vendor/blamejs/MIGRATING.md +43 -0
  9. package/lib/vendor/blamejs/README.md +8 -6
  10. package/lib/vendor/blamejs/SECURITY.md +19 -3
  11. package/lib/vendor/blamejs/api-snapshot.json +2190 -664
  12. package/lib/vendor/blamejs/docker/caddy/localstack.Caddyfile +19 -0
  13. package/lib/vendor/blamejs/docker/init/generate-certs.sh +1 -1
  14. package/lib/vendor/blamejs/docker/otel/config.yaml +42 -0
  15. package/lib/vendor/blamejs/docker/otel/export/.gitkeep +0 -0
  16. package/lib/vendor/blamejs/docker/postgres/initdb/10-replication.sh +15 -0
  17. package/lib/vendor/blamejs/docker/postgres/replica-entrypoint.sh +38 -0
  18. package/lib/vendor/blamejs/docker/toxiproxy/toxiproxy.json +14 -0
  19. package/lib/vendor/blamejs/docker-compose.test.yml +209 -0
  20. package/lib/vendor/blamejs/examples/wiki/lib/page-generator.js +132 -0
  21. package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +221 -61
  22. package/lib/vendor/blamejs/examples/wiki/lib/source-doc-parser.js +144 -9
  23. package/lib/vendor/blamejs/examples/wiki/test/e2e.js +99 -0
  24. package/lib/vendor/blamejs/fuzz/guard-sql.fuzz.js +36 -0
  25. package/lib/vendor/blamejs/index.js +4 -0
  26. package/lib/vendor/blamejs/lib/agent-envelope-mac.js +104 -0
  27. package/lib/vendor/blamejs/lib/agent-event-bus.js +105 -4
  28. package/lib/vendor/blamejs/lib/agent-posture-chain.js +8 -42
  29. package/lib/vendor/blamejs/lib/ai-content-detect.js +9 -10
  30. package/lib/vendor/blamejs/lib/api-key.js +158 -77
  31. package/lib/vendor/blamejs/lib/atomic-file.js +62 -4
  32. package/lib/vendor/blamejs/lib/audit-chain.js +47 -11
  33. package/lib/vendor/blamejs/lib/audit-sign.js +77 -2
  34. package/lib/vendor/blamejs/lib/audit-tools.js +79 -51
  35. package/lib/vendor/blamejs/lib/audit.js +259 -123
  36. package/lib/vendor/blamejs/lib/auth/oauth.js +53 -9
  37. package/lib/vendor/blamejs/lib/auth/openid-federation.js +108 -47
  38. package/lib/vendor/blamejs/lib/auth/saml.js +6 -8
  39. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +31 -5
  40. package/lib/vendor/blamejs/lib/backup/index.js +45 -10
  41. package/lib/vendor/blamejs/lib/break-glass.js +355 -147
  42. package/lib/vendor/blamejs/lib/cache.js +174 -105
  43. package/lib/vendor/blamejs/lib/chain-writer.js +38 -16
  44. package/lib/vendor/blamejs/lib/cli.js +19 -14
  45. package/lib/vendor/blamejs/lib/cluster-provider-db.js +130 -104
  46. package/lib/vendor/blamejs/lib/cluster-storage.js +119 -22
  47. package/lib/vendor/blamejs/lib/cluster.js +119 -71
  48. package/lib/vendor/blamejs/lib/codepoint-class.js +23 -0
  49. package/lib/vendor/blamejs/lib/compliance.js +206 -4
  50. package/lib/vendor/blamejs/lib/consent.js +82 -29
  51. package/lib/vendor/blamejs/lib/constants.js +27 -11
  52. package/lib/vendor/blamejs/lib/crypto-field.js +916 -156
  53. package/lib/vendor/blamejs/lib/db-declare-row-policy.js +35 -22
  54. package/lib/vendor/blamejs/lib/db-file-lifecycle.js +3 -2
  55. package/lib/vendor/blamejs/lib/db-query.js +882 -260
  56. package/lib/vendor/blamejs/lib/db-schema.js +228 -44
  57. package/lib/vendor/blamejs/lib/db.js +249 -99
  58. package/lib/vendor/blamejs/lib/dsr.js +385 -55
  59. package/lib/vendor/blamejs/lib/error-page.js +14 -1
  60. package/lib/vendor/blamejs/lib/external-db-migrate.js +239 -137
  61. package/lib/vendor/blamejs/lib/external-db.js +549 -34
  62. package/lib/vendor/blamejs/lib/file-upload.js +52 -7
  63. package/lib/vendor/blamejs/lib/framework-error.js +20 -1
  64. package/lib/vendor/blamejs/lib/framework-files.js +73 -0
  65. package/lib/vendor/blamejs/lib/framework-schema.js +695 -394
  66. package/lib/vendor/blamejs/lib/gate-contract.js +659 -1
  67. package/lib/vendor/blamejs/lib/guard-agent-registry.js +26 -44
  68. package/lib/vendor/blamejs/lib/guard-all.js +1 -0
  69. package/lib/vendor/blamejs/lib/guard-auth.js +42 -112
  70. package/lib/vendor/blamejs/lib/guard-cidr.js +33 -154
  71. package/lib/vendor/blamejs/lib/guard-csv.js +46 -113
  72. package/lib/vendor/blamejs/lib/guard-domain.js +34 -157
  73. package/lib/vendor/blamejs/lib/guard-dsn.js +27 -43
  74. package/lib/vendor/blamejs/lib/guard-email.js +47 -69
  75. package/lib/vendor/blamejs/lib/guard-envelope.js +19 -32
  76. package/lib/vendor/blamejs/lib/guard-event-bus-payload.js +24 -42
  77. package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +25 -43
  78. package/lib/vendor/blamejs/lib/guard-filename.js +42 -106
  79. package/lib/vendor/blamejs/lib/guard-graphql.js +42 -123
  80. package/lib/vendor/blamejs/lib/guard-html.js +53 -108
  81. package/lib/vendor/blamejs/lib/guard-idempotency-key.js +24 -42
  82. package/lib/vendor/blamejs/lib/guard-image.js +46 -103
  83. package/lib/vendor/blamejs/lib/guard-imap-command.js +18 -32
  84. package/lib/vendor/blamejs/lib/guard-jmap.js +16 -30
  85. package/lib/vendor/blamejs/lib/guard-json.js +38 -108
  86. package/lib/vendor/blamejs/lib/guard-jsonpath.js +38 -171
  87. package/lib/vendor/blamejs/lib/guard-jwt.js +49 -179
  88. package/lib/vendor/blamejs/lib/guard-list-id.js +25 -41
  89. package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +27 -43
  90. package/lib/vendor/blamejs/lib/guard-mail-compose.js +24 -42
  91. package/lib/vendor/blamejs/lib/guard-mail-move.js +26 -44
  92. package/lib/vendor/blamejs/lib/guard-mail-query.js +28 -46
  93. package/lib/vendor/blamejs/lib/guard-mail-reply.js +24 -42
  94. package/lib/vendor/blamejs/lib/guard-mail-sieve.js +24 -42
  95. package/lib/vendor/blamejs/lib/guard-managesieve-command.js +17 -31
  96. package/lib/vendor/blamejs/lib/guard-markdown.js +37 -104
  97. package/lib/vendor/blamejs/lib/guard-message-id.js +26 -45
  98. package/lib/vendor/blamejs/lib/guard-mime.js +39 -151
  99. package/lib/vendor/blamejs/lib/guard-oauth.js +54 -135
  100. package/lib/vendor/blamejs/lib/guard-pdf.js +45 -101
  101. package/lib/vendor/blamejs/lib/guard-pop3-command.js +21 -31
  102. package/lib/vendor/blamejs/lib/guard-posture-chain.js +24 -42
  103. package/lib/vendor/blamejs/lib/guard-regex.js +33 -107
  104. package/lib/vendor/blamejs/lib/guard-saga-config.js +24 -42
  105. package/lib/vendor/blamejs/lib/guard-shell.js +42 -172
  106. package/lib/vendor/blamejs/lib/guard-smtp-command.js +48 -54
  107. package/lib/vendor/blamejs/lib/guard-snapshot-envelope.js +24 -42
  108. package/lib/vendor/blamejs/lib/guard-sql.js +1491 -0
  109. package/lib/vendor/blamejs/lib/guard-stream-args.js +24 -43
  110. package/lib/vendor/blamejs/lib/guard-svg.js +47 -65
  111. package/lib/vendor/blamejs/lib/guard-template.js +35 -172
  112. package/lib/vendor/blamejs/lib/guard-tenant-id.js +26 -45
  113. package/lib/vendor/blamejs/lib/guard-time.js +32 -154
  114. package/lib/vendor/blamejs/lib/guard-trace-context.js +25 -44
  115. package/lib/vendor/blamejs/lib/guard-uuid.js +32 -153
  116. package/lib/vendor/blamejs/lib/guard-xml.js +38 -113
  117. package/lib/vendor/blamejs/lib/guard-yaml.js +51 -163
  118. package/lib/vendor/blamejs/lib/http-client.js +37 -9
  119. package/lib/vendor/blamejs/lib/inbox.js +120 -107
  120. package/lib/vendor/blamejs/lib/legal-hold.js +121 -50
  121. package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +47 -31
  122. package/lib/vendor/blamejs/lib/log-stream-otlp.js +32 -18
  123. package/lib/vendor/blamejs/lib/mail-auth.js +236 -0
  124. package/lib/vendor/blamejs/lib/mail-crypto-smime.js +2 -6
  125. package/lib/vendor/blamejs/lib/mail-dkim.js +1 -0
  126. package/lib/vendor/blamejs/lib/mail-greylist.js +2 -6
  127. package/lib/vendor/blamejs/lib/mail-helo.js +2 -6
  128. package/lib/vendor/blamejs/lib/mail-journal.js +85 -64
  129. package/lib/vendor/blamejs/lib/mail-rbl.js +2 -6
  130. package/lib/vendor/blamejs/lib/mail-scan.js +2 -6
  131. package/lib/vendor/blamejs/lib/mail-server-jmap.js +117 -12
  132. package/lib/vendor/blamejs/lib/mail-server-mx.js +276 -7
  133. package/lib/vendor/blamejs/lib/mail-spam-score.js +2 -6
  134. package/lib/vendor/blamejs/lib/mail-store.js +293 -154
  135. package/lib/vendor/blamejs/lib/mail.js +8 -4
  136. package/lib/vendor/blamejs/lib/middleware/body-parser.js +71 -25
  137. package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +19 -8
  138. package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -1
  139. package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +17 -7
  140. package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +75 -51
  141. package/lib/vendor/blamejs/lib/middleware/rate-limit.js +102 -32
  142. package/lib/vendor/blamejs/lib/middleware/security-headers.js +21 -5
  143. package/lib/vendor/blamejs/lib/migrations.js +108 -66
  144. package/lib/vendor/blamejs/lib/network-heartbeat.js +7 -0
  145. package/lib/vendor/blamejs/lib/network-proxy.js +24 -1
  146. package/lib/vendor/blamejs/lib/nonce-store.js +31 -9
  147. package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +9 -4
  148. package/lib/vendor/blamejs/lib/object-store/azure-blob.js +57 -3
  149. package/lib/vendor/blamejs/lib/object-store/gcs.js +4 -1
  150. package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +5 -2
  151. package/lib/vendor/blamejs/lib/object-store/sigv4.js +38 -6
  152. package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +9 -1
  153. package/lib/vendor/blamejs/lib/observability.js +124 -0
  154. package/lib/vendor/blamejs/lib/otel-export.js +12 -3
  155. package/lib/vendor/blamejs/lib/outbox.js +184 -83
  156. package/lib/vendor/blamejs/lib/parsers/safe-xml.js +47 -7
  157. package/lib/vendor/blamejs/lib/pqc-agent.js +44 -0
  158. package/lib/vendor/blamejs/lib/pubsub-cluster.js +42 -20
  159. package/lib/vendor/blamejs/lib/queue-local.js +225 -140
  160. package/lib/vendor/blamejs/lib/queue-redis.js +9 -1
  161. package/lib/vendor/blamejs/lib/queue-sqs.js +6 -0
  162. package/lib/vendor/blamejs/lib/queue.js +7 -0
  163. package/lib/vendor/blamejs/lib/redact.js +68 -11
  164. package/lib/vendor/blamejs/lib/redis-client.js +160 -31
  165. package/lib/vendor/blamejs/lib/request-helpers.js +7 -0
  166. package/lib/vendor/blamejs/lib/retention.js +101 -40
  167. package/lib/vendor/blamejs/lib/router.js +212 -5
  168. package/lib/vendor/blamejs/lib/safe-dns.js +29 -45
  169. package/lib/vendor/blamejs/lib/safe-ical.js +18 -33
  170. package/lib/vendor/blamejs/lib/safe-icap.js +27 -43
  171. package/lib/vendor/blamejs/lib/safe-sieve.js +21 -40
  172. package/lib/vendor/blamejs/lib/safe-sql.js +212 -3
  173. package/lib/vendor/blamejs/lib/safe-url.js +170 -3
  174. package/lib/vendor/blamejs/lib/safe-vcard.js +18 -33
  175. package/lib/vendor/blamejs/lib/scheduler.js +35 -12
  176. package/lib/vendor/blamejs/lib/seeders.js +122 -74
  177. package/lib/vendor/blamejs/lib/session-stores.js +42 -14
  178. package/lib/vendor/blamejs/lib/session.js +175 -77
  179. package/lib/vendor/blamejs/lib/sql.js +3842 -0
  180. package/lib/vendor/blamejs/lib/sse.js +26 -0
  181. package/lib/vendor/blamejs/lib/ssrf-guard.js +151 -4
  182. package/lib/vendor/blamejs/lib/static.js +177 -34
  183. package/lib/vendor/blamejs/lib/subject.js +96 -49
  184. package/lib/vendor/blamejs/lib/vault/index.js +3 -2
  185. package/lib/vendor/blamejs/lib/vault/passphrase-ops.js +3 -2
  186. package/lib/vendor/blamejs/lib/vault/rotate.js +168 -108
  187. package/lib/vendor/blamejs/lib/vault-aad.js +6 -0
  188. package/lib/vendor/blamejs/lib/vendor-data.js +2 -0
  189. package/lib/vendor/blamejs/lib/websocket.js +35 -5
  190. package/lib/vendor/blamejs/lib/worker-pool.js +11 -0
  191. package/lib/vendor/blamejs/package.json +2 -2
  192. package/lib/vendor/blamejs/release-notes/v0.14.x.json +1503 -0
  193. package/lib/vendor/blamejs/release-notes/v0.15.0.json +77 -0
  194. package/lib/vendor/blamejs/release-notes/v0.15.1.json +22 -0
  195. package/lib/vendor/blamejs/release-notes/v0.15.2.json +22 -0
  196. package/lib/vendor/blamejs/release-notes/v0.15.3.json +39 -0
  197. package/lib/vendor/blamejs/release-notes/v0.15.4.json +39 -0
  198. package/lib/vendor/blamejs/release-notes/v0.15.5.json +22 -0
  199. package/lib/vendor/blamejs/release-notes/v0.15.6.json +59 -0
  200. package/lib/vendor/blamejs/scripts/check-services.js +21 -0
  201. package/lib/vendor/blamejs/scripts/gen-migrating.js +51 -0
  202. package/lib/vendor/blamejs/scripts/release.js +398 -38
  203. package/lib/vendor/blamejs/test/00-primitives.js +117 -0
  204. package/lib/vendor/blamejs/test/10-state.js +140 -14
  205. package/lib/vendor/blamejs/test/20-db.js +65 -2
  206. package/lib/vendor/blamejs/test/helpers/db.js +9 -0
  207. package/lib/vendor/blamejs/test/helpers/drivers.js +27 -15
  208. package/lib/vendor/blamejs/test/helpers/services.js +21 -0
  209. package/lib/vendor/blamejs/test/integration/audit-actor-binding-pg.test.js +246 -0
  210. package/lib/vendor/blamejs/test/integration/audit-chain-external-db.test.js +517 -0
  211. package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +639 -0
  212. package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +832 -0
  213. package/lib/vendor/blamejs/test/integration/backup-restore-objectstore.test.js +453 -0
  214. package/lib/vendor/blamejs/test/integration/data-layer-cluster-mysql.test.js +649 -0
  215. package/lib/vendor/blamejs/test/integration/data-layer-cluster-pg.test.js +770 -0
  216. package/lib/vendor/blamejs/test/integration/data-layer-mysql-privacy.test.js +630 -0
  217. package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +610 -0
  218. package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +577 -0
  219. package/lib/vendor/blamejs/test/integration/data-layer-postgres.test.js +771 -0
  220. package/lib/vendor/blamejs/test/integration/db-layer-mysql.test.js +549 -0
  221. package/lib/vendor/blamejs/test/integration/db-layer-postgres.test.js +598 -0
  222. package/lib/vendor/blamejs/test/integration/distributed-scheduler-fencing-pg.test.js +602 -0
  223. package/lib/vendor/blamejs/test/integration/external-db-postgres.test.js +576 -0
  224. package/lib/vendor/blamejs/test/integration/framework-schema-mysql.test.js +353 -0
  225. package/lib/vendor/blamejs/test/integration/log-stream-cloudwatch.test.js +224 -0
  226. package/lib/vendor/blamejs/test/integration/mail-crypto-smime.test.js +142 -17
  227. package/lib/vendor/blamejs/test/integration/network-heartbeat.test.js +25 -10
  228. package/lib/vendor/blamejs/test/integration/object-store-azure.test.js +101 -0
  229. package/lib/vendor/blamejs/test/integration/object-store-gcs.test.js +239 -0
  230. package/lib/vendor/blamejs/test/integration/object-store-sigv4.test.js +35 -16
  231. package/lib/vendor/blamejs/test/integration/object-store-worm-lock.test.js +291 -0
  232. package/lib/vendor/blamejs/test/integration/pubsub.test.js +14 -0
  233. package/lib/vendor/blamejs/test/integration/queue-sqs.test.js +322 -0
  234. package/lib/vendor/blamejs/test/integration/redis-reconnect-toxiproxy.test.js +300 -0
  235. package/lib/vendor/blamejs/test/integration/sql-fts5-catalog-sqlite.test.js +154 -0
  236. package/lib/vendor/blamejs/test/integration/tls-classical-downgrade-audit.test.js +71 -0
  237. package/lib/vendor/blamejs/test/layer-0-primitives/agent-event-bus.test.js +175 -12
  238. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-exclusive-temp.test.js +216 -0
  239. package/lib/vendor/blamejs/test/layer-0-primitives/audit-checkpoint-false-rollback.test.js +203 -0
  240. package/lib/vendor/blamejs/test/layer-0-primitives/audit-query-self-log.test.js +126 -0
  241. package/lib/vendor/blamejs/test/layer-0-primitives/audit-safeemit-redacts-secrets.test.js +196 -0
  242. package/lib/vendor/blamejs/test/layer-0-primitives/audit-signing-key-rotation.test.js +197 -0
  243. package/lib/vendor/blamejs/test/layer-0-primitives/audit-verifybundle-tamper.test.js +209 -0
  244. package/lib/vendor/blamejs/test/layer-0-primitives/azure-blob-key-encoding.test.js +121 -0
  245. package/lib/vendor/blamejs/test/layer-0-primitives/backup-residency-posture.test.js +168 -0
  246. package/lib/vendor/blamejs/test/layer-0-primitives/backup-scheduletest-drill.test.js +318 -0
  247. package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +233 -7
  248. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +1120 -14
  249. package/lib/vendor/blamejs/test/layer-0-primitives/compliance.test.js +229 -0
  250. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +24 -7
  251. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-dual-read-migrate.test.js +165 -0
  252. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-per-row-key.test.js +350 -0
  253. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-unseal-rate-cap.test.js +27 -9
  254. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-upgrade-dialect.test.js +76 -0
  255. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-interop-oracles.test.js +392 -0
  256. package/lib/vendor/blamejs/test/layer-0-primitives/csrf-protect.test.js +159 -0
  257. package/lib/vendor/blamejs/test/layer-0-primitives/db-column-gate.test.js +180 -1
  258. package/lib/vendor/blamejs/test/layer-0-primitives/db-query-cross-schema.test.js +5 -2
  259. package/lib/vendor/blamejs/test/layer-0-primitives/db-query-sealed-field-in.test.js +101 -0
  260. package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +128 -0
  261. package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-drift.test.js +38 -5
  262. package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-reconcile-emittable.test.js +127 -0
  263. package/lib/vendor/blamejs/test/layer-0-primitives/db-stream-and-payload-shape.test.js +267 -0
  264. package/lib/vendor/blamejs/test/layer-0-primitives/db-worm.test.js +150 -0
  265. package/lib/vendor/blamejs/test/layer-0-primitives/defineguard-default-gate-posture-caps.test.js +30 -0
  266. package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-replaystore-required.test.js +46 -0
  267. package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +218 -0
  268. package/lib/vendor/blamejs/test/layer-0-primitives/erase-posture-vacuum.test.js +210 -0
  269. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-hardening.test.js +4 -1
  270. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +48 -2
  271. package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +237 -5
  272. package/lib/vendor/blamejs/test/layer-0-primitives/fetch-metadata.test.js +20 -9
  273. package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +193 -0
  274. package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +90 -0
  275. package/lib/vendor/blamejs/test/layer-0-primitives/http-client-stream.test.js +85 -0
  276. package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +10 -6
  277. package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +15 -4
  278. package/lib/vendor/blamejs/test/layer-0-primitives/legal-hold.test.js +146 -0
  279. package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +189 -0
  280. package/lib/vendor/blamejs/test/layer-0-primitives/mail-journal.test.js +3 -1
  281. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +123 -4
  282. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +207 -2
  283. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +74 -0
  284. package/lib/vendor/blamejs/test/layer-0-primitives/oauth-callback.test.js +43 -0
  285. package/lib/vendor/blamejs/test/layer-0-primitives/otel-export.test.js +133 -0
  286. package/lib/vendor/blamejs/test/layer-0-primitives/otlp-attr-redaction.test.js +101 -0
  287. package/lib/vendor/blamejs/test/layer-0-primitives/outbox-inflight-reaper.test.js +136 -0
  288. package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +83 -0
  289. package/lib/vendor/blamejs/test/layer-0-primitives/passkey-real-vectors.test.js +429 -0
  290. package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +21 -11
  291. package/lib/vendor/blamejs/test/layer-0-primitives/queue-byo-db.test.js +40 -0
  292. package/lib/vendor/blamejs/test/layer-0-primitives/redact-dlp.test.js +83 -0
  293. package/lib/vendor/blamejs/test/layer-0-primitives/redis-client.test.js +113 -0
  294. package/lib/vendor/blamejs/test/layer-0-primitives/retention-dryrun-no-vacuum.test.js +99 -0
  295. package/lib/vendor/blamejs/test/layer-0-primitives/router-use-path-scope.test.js +255 -0
  296. package/lib/vendor/blamejs/test/layer-0-primitives/safe-url-canonicalize.test.js +309 -0
  297. package/lib/vendor/blamejs/test/layer-0-primitives/safe-xml.test.js +143 -0
  298. package/lib/vendor/blamejs/test/layer-0-primitives/saml-subjectconfirmation-notonorafter.test.js +287 -0
  299. package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc-ecdsa-p1363.test.js +79 -0
  300. package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +50 -0
  301. package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +31 -4
  302. package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +45 -0
  303. package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +49 -0
  304. package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +595 -0
  305. package/lib/vendor/blamejs/test/layer-0-primitives/sse-backpressure.test.js +91 -0
  306. package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +69 -0
  307. package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +194 -2
  308. package/lib/vendor/blamejs/test/layer-0-primitives/websocket-extension-header.test.js +88 -0
  309. package/lib/vendor/blamejs/test/layer-0-primitives/worker-pool-recycle-race.test.js +66 -0
  310. package/lib/vendor/blamejs/test/layer-1-state/api-key.test.js +84 -0
  311. package/lib/vendor/blamejs/test/layer-5-integration/external-db-residency.test.js +638 -0
  312. package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +21 -0
  313. package/lib/vendor/blamejs/test/smoke.js +79 -21
  314. package/package.json +1 -1
  315. package/lib/vendor/blamejs/release-notes/v0.14.0.json +0 -43
  316. package/lib/vendor/blamejs/release-notes/v0.14.1.json +0 -60
  317. package/lib/vendor/blamejs/release-notes/v0.14.10.json +0 -54
  318. package/lib/vendor/blamejs/release-notes/v0.14.11.json +0 -72
  319. package/lib/vendor/blamejs/release-notes/v0.14.12.json +0 -95
  320. package/lib/vendor/blamejs/release-notes/v0.14.13.json +0 -52
  321. package/lib/vendor/blamejs/release-notes/v0.14.14.json +0 -31
  322. package/lib/vendor/blamejs/release-notes/v0.14.16.json +0 -45
  323. package/lib/vendor/blamejs/release-notes/v0.14.17.json +0 -57
  324. package/lib/vendor/blamejs/release-notes/v0.14.18.json +0 -127
  325. package/lib/vendor/blamejs/release-notes/v0.14.19.json +0 -61
  326. package/lib/vendor/blamejs/release-notes/v0.14.2.json +0 -18
  327. package/lib/vendor/blamejs/release-notes/v0.14.20.json +0 -73
  328. package/lib/vendor/blamejs/release-notes/v0.14.21.json +0 -98
  329. package/lib/vendor/blamejs/release-notes/v0.14.22.json +0 -91
  330. package/lib/vendor/blamejs/release-notes/v0.14.3.json +0 -18
  331. package/lib/vendor/blamejs/release-notes/v0.14.4.json +0 -18
  332. package/lib/vendor/blamejs/release-notes/v0.14.5.json +0 -18
  333. package/lib/vendor/blamejs/release-notes/v0.14.6.json +0 -60
  334. package/lib/vendor/blamejs/release-notes/v0.14.7.json +0 -77
  335. package/lib/vendor/blamejs/release-notes/v0.14.8.json +0 -27
  336. package/lib/vendor/blamejs/release-notes/v0.14.9.json +0 -40
@@ -0,0 +1,309 @@
1
+ "use strict";
2
+ /**
3
+ * b.safeUrl.canonicalize — URL/host canonicalizer for safe comparison and
4
+ * SSRF-allowlist defense.
5
+ *
6
+ * Every obfuscated spelling of one destination must reduce to one string so a
7
+ * host allowlist / dedup key / SSRF pre-check compares equal. The adversarial
8
+ * cases below are the exact shapes an attacker reaches for to slip a naive
9
+ * `===` allowlist: IPv4 in octal / hex / decimal-int / shorthand, IPv4-mapped
10
+ * and zero-compressed IPv6, IDN homographs, trailing-dot and default-port and
11
+ * case variations, and over-encoded path bytes.
12
+ *
13
+ * Source-discipline: NO attack characters are typed as literals. The one
14
+ * mixed-script case is expressed as its already-encoded punycode A-label
15
+ * (`xn--ggle-55da.com`, same fixture the homograph suite uses) so this file
16
+ * stays pure ASCII.
17
+ */
18
+
19
+ var b = require("../..");
20
+ var check = require("../helpers/check").check;
21
+
22
+ // ---- Equivalence classes: obfuscated loopback collapses to one string ----
23
+
24
+ function testIpv4LoopbackEquivalenceClass() {
25
+ // Decimal-dotted, octal, hex-word, decimal-int, and shorthand spellings of
26
+ // 127.0.0.1 — in the OLD world (raw string compare, no canonicalizer) every
27
+ // pair below compared UNEQUAL, so an allowlist of "127.0.0.1" let them all
28
+ // through. canonicalize collapses them to one form.
29
+ var forms = [
30
+ "http://127.0.0.1/",
31
+ "http://0177.0.0.1/", // octal first octet
32
+ "http://0x7f.1/", // hex octet + shorthand
33
+ "http://0x7f000001/", // single hex dword
34
+ "http://2130706433/", // single decimal dword
35
+ "http://127.1/", // a.d shorthand
36
+ ];
37
+ var expected = "http://127.0.0.1/";
38
+ for (var i = 0; i < forms.length; i += 1) {
39
+ var got = b.safeUrl.canonicalize(forms[i]);
40
+ check("ipv4 loopback form '" + forms[i] + "' canonicalizes to " + expected,
41
+ got === expected);
42
+ // The pairwise equality the allowlist actually relies on.
43
+ check("ipv4 loopback '" + forms[i] + "' === canonical '127.0.0.1' form",
44
+ b.safeUrl.canonicalize(forms[i]) === b.safeUrl.canonicalize(forms[0]));
45
+ // Prove the test is meaningful: the RAW strings were NOT equal.
46
+ if (forms[i] !== forms[0]) {
47
+ check("raw '" + forms[i] + "' !== raw canonical (old-world bypass shape)",
48
+ forms[i] !== forms[0]);
49
+ }
50
+ }
51
+ }
52
+
53
+ function testIpv6MappedEquivalenceClass() {
54
+ // IPv4-mapped IPv6 in dotted, hex, and fully-expanded spellings — all the
55
+ // same 16 bytes, all collapse to one bracketed RFC 5952 form.
56
+ var forms = [
57
+ "http://[::ffff:127.0.0.1]/",
58
+ "http://[::ffff:7f00:1]/",
59
+ "http://[0:0:0:0:0:ffff:7f00:1]/",
60
+ "http://[0:0:0:0:0:FFFF:7F00:1]/", // mixed-case hex
61
+ ];
62
+ var first = b.safeUrl.canonicalize(forms[0]);
63
+ check("ipv4-mapped IPv6 canonical is bracketed RFC 5952",
64
+ first === "http://[::ffff:7f00:1]/");
65
+ for (var i = 1; i < forms.length; i += 1) {
66
+ check("ipv4-mapped form '" + forms[i] + "' === first canonical",
67
+ b.safeUrl.canonicalize(forms[i]) === first);
68
+ check("raw '" + forms[i] + "' !== raw '" + forms[0] + "' (old-world unequal)",
69
+ forms[i] !== forms[0]);
70
+ }
71
+ }
72
+
73
+ function testIpv6ZeroCompressionEquivalenceClass() {
74
+ // ::1 in compressed, fully-expanded, and zero-padded spellings.
75
+ var forms = [
76
+ "http://[::1]/",
77
+ "http://[0:0:0:0:0:0:0:1]/",
78
+ "http://[0000:0000:0000:0000:0000:0000:0000:0001]/",
79
+ ];
80
+ var first = b.safeUrl.canonicalize(forms[0]);
81
+ check("IPv6 loopback canonical is [::1]", first === "http://[::1]/");
82
+ for (var i = 1; i < forms.length; i += 1) {
83
+ check("IPv6 loopback form '" + forms[i] + "' === [::1] canonical",
84
+ b.safeUrl.canonicalize(forms[i]) === first);
85
+ check("raw '" + forms[i] + "' !== raw '[::1]' (old-world unequal)",
86
+ forms[i] !== forms[0]);
87
+ }
88
+ // A documentation address with an INTERIOR zero run picks the longest run
89
+ // (RFC 5952 §4.2.3) and stays lower-hex.
90
+ check("interior zero-run compresses correctly",
91
+ b.safeUrl.canonicalize("https://[2001:0DB8:0:0:0:0:0:1]/") ===
92
+ "https://[2001:db8::1]/");
93
+ }
94
+
95
+ // ---- IP-literal cross-check against the SSRF classifier's byte parser ----
96
+
97
+ function testIpCanonicalAgreesWithClassifier() {
98
+ // The canonical host string and the SSRF verdict are derived from the SAME
99
+ // bytes — so the canonical loopback string classifies as loopback and the
100
+ // canonical mapped form re-classifies its embedded v4 as loopback too.
101
+ check("canonical 127.0.0.1 classifies loopback",
102
+ b.ssrfGuard.classify("127.0.0.1") === "loopback");
103
+ // canonicalizeHost is the IP-byte + case layer: it byte-canonicalizes
104
+ // net.isIP-recognized literals (the numeric-base decode of 0x.../octal/dword
105
+ // is the WHATWG-URL-parser layer that safeUrl.canonicalize runs first).
106
+ check("ssrfGuard.canonicalizeHost passes an already-canonical dotted-quad",
107
+ b.ssrfGuard.canonicalizeHost("127.0.0.1") === "127.0.0.1");
108
+ check("ssrfGuard.canonicalizeHost collapses expanded v6 to ::1",
109
+ b.ssrfGuard.canonicalizeHost("[0:0:0:0:0:0:0:1]") === "::1");
110
+ check("ssrfGuard.canonicalizeHost compresses + lower-hexes a mixed-case v6",
111
+ b.ssrfGuard.canonicalizeHost("2001:0DB8:0:0:0:0:0:1") === "2001:db8::1");
112
+ check("ssrfGuard.canonicalizeHost lowercases + strips trailing dot",
113
+ b.ssrfGuard.canonicalizeHost("Example.COM.") === "example.com");
114
+ }
115
+
116
+ // ---- IDN: A-label emission + homograph refusal ----
117
+
118
+ function testIdnEmittedAsPunycode() {
119
+ // A pure-Cyrillic+Latin-tld host parses (single script per label) and is
120
+ // emitted as its xn-- A-label, never the Unicode form.
121
+ var got = b.safeUrl.canonicalize("https://xn--80akhbyknj4f.com/");
122
+ check("IDN host emitted as xn-- A-label",
123
+ got === "https://xn--80akhbyknj4f.com/");
124
+ }
125
+
126
+ function testConfusableHostThrows() {
127
+ // xn--ggle-55da.com decodes to a label mixing Cyrillic + Latin (the
128
+ // gооgle.com homograph). canonicalize must THROW, never silently pass it.
129
+ var threw = false;
130
+ var code = null;
131
+ try { b.safeUrl.canonicalize("https://xn--ggle-55da.com/"); }
132
+ catch (e) { threw = true; code = e.code; }
133
+ check("confusable / mixed-script host throws", threw === true);
134
+ check("confusable host throw carries safe-url/idn-homograph",
135
+ code === "safe-url/idn-homograph");
136
+ }
137
+
138
+ function testMixedScriptOptInCanonicalizes() {
139
+ // Operators with a legitimate non-Latin host opt in; the A-label is then
140
+ // canonicalized rather than refused.
141
+ var got = b.safeUrl.canonicalize("https://xn--ggle-55da.com/", {
142
+ allowMixedScript: true,
143
+ });
144
+ check("allowMixedScript:true canonicalizes the mixed-script host",
145
+ got === "https://xn--ggle-55da.com/");
146
+ }
147
+
148
+ // ---- scheme / host case, default port, trailing dot, path ----
149
+
150
+ function testEndToEndNormalization() {
151
+ // The headline end-to-end case from the spec: case-folded host, stripped
152
+ // default port, resolved `..`, all in one.
153
+ check("https://Example.COM:443/a/../b -> https://example.com/b",
154
+ b.safeUrl.canonicalize("https://Example.COM:443/a/../b") ===
155
+ "https://example.com/b");
156
+ check("http default :80 stripped + host lowercased",
157
+ b.safeUrl.canonicalize("http://Example.COM:80/") ===
158
+ "http://example.com/");
159
+ check("trailing-dot host removed",
160
+ b.safeUrl.canonicalize("https://example.com./path") ===
161
+ "https://example.com/path");
162
+ check("non-default port preserved",
163
+ b.safeUrl.canonicalize("https://example.com:8443/") ===
164
+ "https://example.com:8443/");
165
+ }
166
+
167
+ function testPathPercentNormalization() {
168
+ // RFC 3986 §6.2.2: escapes of unreserved chars are decoded, hex digits
169
+ // uppercased — in the PATH only.
170
+ check("path %7E decodes to ~ and %2D to -",
171
+ b.safeUrl.canonicalize("https://example.com/%7Euser/a%2Db") ===
172
+ "https://example.com/~user/a-b");
173
+ // A reserved char (%2F = '/') is NOT decoded (would change structure); its
174
+ // hex is uppercased.
175
+ check("reserved %2f path escape uppercased, NOT decoded",
176
+ b.safeUrl.canonicalize("https://example.com/a%2fb") ===
177
+ "https://example.com/a%2Fb");
178
+ // Query semantics are conservative: a %2D in the QUERY is left verbatim
179
+ // (lowercase, undecoded) so value semantics are never altered.
180
+ check("query percent-escape left byte-for-byte",
181
+ b.safeUrl.canonicalize("https://example.com/?x=%2d") ===
182
+ "https://example.com/?x=%2d");
183
+ }
184
+
185
+ // ---- throw paths: disallowed scheme + unparseable + scheme allowlist ----
186
+
187
+ function testDisallowedSchemeThrows() {
188
+ var threw = false;
189
+ var code = null;
190
+ try { b.safeUrl.canonicalize("ftp://example.com/file"); }
191
+ catch (e) { threw = true; code = e.code; }
192
+ check("ftp scheme throws", threw === true);
193
+ check("disallowed-scheme code is safe-url/protocol-disallowed",
194
+ code === "safe-url/protocol-disallowed");
195
+ }
196
+
197
+ function testUnparseableThrows() {
198
+ var threw = false;
199
+ var code = null;
200
+ try { b.safeUrl.canonicalize("this is not a url"); }
201
+ catch (e) { threw = true; code = e.code; }
202
+ check("unparseable input throws", threw === true);
203
+ check("unparseable code is safe-url/malformed", code === "safe-url/malformed");
204
+ }
205
+
206
+ function testMissingInputThrows() {
207
+ var threw = false;
208
+ var code = null;
209
+ try { b.safeUrl.canonicalize(""); }
210
+ catch (e) { threw = true; code = e.code; }
211
+ check("empty input throws safe-url/missing", threw === true && code === "safe-url/missing");
212
+ }
213
+
214
+ function testCustomSchemeAllowlist() {
215
+ // Narrow the allowlist: https-only refuses an http URL.
216
+ var threw = false;
217
+ var code = null;
218
+ try {
219
+ b.safeUrl.canonicalize("http://example.com/", {
220
+ allowedSchemes: b.safeUrl.ALLOW_HTTP_TLS,
221
+ });
222
+ } catch (e) { threw = true; code = e.code; }
223
+ check("custom allowedSchemes (https-only) refuses http",
224
+ threw === true && code === "safe-url/protocol-disallowed");
225
+ // ws canonicalizes under the default ALLOW_ANY.
226
+ check("ws scheme canonicalizes under default allowlist",
227
+ b.safeUrl.canonicalize("ws://Example.COM:80/s") === "ws://example.com/s");
228
+ }
229
+
230
+ function testIdempotence() {
231
+ // canonicalize(canonicalize(x)) === canonicalize(x) for the whole adversarial
232
+ // set — a canonical form must be a fixed point.
233
+ var inputs = [
234
+ "http://0177.0.0.1/",
235
+ "http://[0:0:0:0:0:ffff:7f00:1]/",
236
+ "https://Example.COM:443/a/../b",
237
+ "https://example.com/%7Euser",
238
+ "https://xn--80akhbyknj4f.com/",
239
+ ];
240
+ for (var i = 0; i < inputs.length; i += 1) {
241
+ var once = b.safeUrl.canonicalize(inputs[i]);
242
+ var twice = b.safeUrl.canonicalize(once);
243
+ check("canonicalize is idempotent for '" + inputs[i] + "'", once === twice);
244
+ }
245
+ }
246
+
247
+ function testUncanonicalizableCodeIsRegistered() {
248
+ // The post-parse fallback code is reachable as a documented SafeUrlError
249
+ // code — constructing it directly proves the class accepts it.
250
+ var e = new b.safeUrl.SafeUrlError("safe-url/uncanonicalizable", "x");
251
+ check("safe-url/uncanonicalizable is a valid SafeUrlError code",
252
+ e.code === "safe-url/uncanonicalizable" && e.isSafeUrlError === true);
253
+ }
254
+
255
+ // ---- Credentials are never carried into the canonical form ----
256
+
257
+ function testUserinfoDroppedFromCanonicalForm() {
258
+ // The canonical string is built to be compared, used as a dedup / cache key,
259
+ // or logged — it must never carry user:pass credentials, and the creds are
260
+ // not part of the target identity for an allowlist / SSRF decision. parse()
261
+ // refuses userinfo by default; even opted-in, the canonical output omits it.
262
+ var user = "alice";
263
+ var token = "s3cr" + "et-pw-9f3a"; // split so no secret-shaped literal sits in source
264
+ var withCreds = "https://" + user + ":" + token + "@host.example.com/p";
265
+
266
+ var deniedCode = null;
267
+ try { b.safeUrl.canonicalize(withCreds); }
268
+ catch (e) { deniedCode = e && e.code; }
269
+ check("canonicalize refuses userinfo by default",
270
+ deniedCode === "safe-url/userinfo-disallowed");
271
+
272
+ var canon = b.safeUrl.canonicalize(withCreds, { allowUserinfo: true });
273
+ check("canonicalize drops the userinfo delimiter from the canonical form",
274
+ canon.indexOf("@") === -1);
275
+ check("canonicalize does not carry the password into the canonical form",
276
+ canon.indexOf(token) === -1);
277
+ check("canonicalize does not carry the username into the canonical form",
278
+ canon.indexOf("//" + user) === -1);
279
+ check("the credential-stripped canonical form is the bare target",
280
+ canon === "https://host.example.com/p");
281
+ check("URLs differing only in credentials canonicalize equal",
282
+ b.safeUrl.canonicalize("https://x:y@host.example.com/p", { allowUserinfo: true }) === canon);
283
+ }
284
+
285
+ async function run() {
286
+ testUserinfoDroppedFromCanonicalForm();
287
+ testIpv4LoopbackEquivalenceClass();
288
+ testIpv6MappedEquivalenceClass();
289
+ testIpv6ZeroCompressionEquivalenceClass();
290
+ testIpCanonicalAgreesWithClassifier();
291
+ testIdnEmittedAsPunycode();
292
+ testConfusableHostThrows();
293
+ testMixedScriptOptInCanonicalizes();
294
+ testEndToEndNormalization();
295
+ testPathPercentNormalization();
296
+ testDisallowedSchemeThrows();
297
+ testUnparseableThrows();
298
+ testMissingInputThrows();
299
+ testCustomSchemeAllowlist();
300
+ testIdempotence();
301
+ testUncanonicalizableCodeIsRegistered();
302
+ }
303
+
304
+ module.exports = { run: run };
305
+
306
+ if (require.main === module) {
307
+ run().then(function () { console.log("OK"); })
308
+ .catch(function (e) { console.error(e.stack || e); process.exit(1); });
309
+ }
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ /**
3
+ * b.parsers.xml.parse — security-focused XML parser.
4
+ *
5
+ * Covers the structural defaults (XXE / DOCTYPE / billion-laughs / depth
6
+ * + element + attribute caps) and the prototype-pollution posture: the
7
+ * result tree and every nested object it contains carry a null prototype,
8
+ * and element / attribute names equal to __proto__ / constructor /
9
+ * prototype are rejected with xml/forbidden-name (CWE-1321 / OWASP
10
+ * prototype-pollution).
11
+ *
12
+ * Run standalone: `node test/layer-0-primitives/safe-xml.test.js`
13
+ */
14
+
15
+ var helpers = require("../helpers");
16
+ var b = helpers.b;
17
+ var check = helpers.check;
18
+
19
+ var xml = b.parsers.xml;
20
+
21
+ // ---- Baseline parse + shape ----
22
+
23
+ function testParsesAttributedElement() {
24
+ var result = xml.parse('<root id="x"><child>text</child></root>');
25
+ check("xml.parse returns the root key",
26
+ result && result.root && result.root["@attrs"] && result.root["@attrs"].id === "x");
27
+ check("xml.parse groups child element",
28
+ result.root.child === "text");
29
+ }
30
+
31
+ function testRejectsDoctype() {
32
+ var threw = null;
33
+ try { xml.parse('<!DOCTYPE x SYSTEM "file:///etc/passwd"><root/>'); }
34
+ catch (e) { threw = e; }
35
+ check("xml.parse rejects DOCTYPE (XXE defense)",
36
+ threw && threw.code === "xml/doctype");
37
+ }
38
+
39
+ function testRejectsCustomEntity() {
40
+ var threw = null;
41
+ try { xml.parse("<root>&xxe;</root>"); }
42
+ catch (e) { threw = e; }
43
+ check("xml.parse rejects custom entity (XXE defense)",
44
+ threw && threw.code === "xml/external-entity");
45
+ }
46
+
47
+ // ---- Prototype-pollution posture (CWE-1321) ----
48
+
49
+ function testResultTreeHasNullPrototype() {
50
+ // A document that exercises every keyed accumulator: attributes (attrs),
51
+ // grouped child elements (grouped / obj), and the element-name wrapper
52
+ // (out). Each must carry a null prototype so a consumer reading an
53
+ // absent key sees undefined, never an inherited Object member.
54
+ var result = xml.parse(
55
+ '<root attr="v"><a>1</a><a>2</a><b><c>deep</c></b></root>'
56
+ );
57
+
58
+ check("result wrapper has null prototype",
59
+ Object.getPrototypeOf(result) === null);
60
+ check("element object has null prototype",
61
+ Object.getPrototypeOf(result.root) === null);
62
+ check("@attrs object has null prototype",
63
+ Object.getPrototypeOf(result.root["@attrs"]) === null);
64
+ check("nested element object has null prototype",
65
+ Object.getPrototypeOf(result.root.b) === null);
66
+ check("repeated child became an array",
67
+ Array.isArray(result.root.a) && result.root.a.length === 2);
68
+
69
+ // No inherited Object.prototype members leak through any accumulator —
70
+ // a plain {} would surface a function here.
71
+ check("no inherited toString on result",
72
+ result.toString === undefined);
73
+ check("no inherited hasOwnProperty on element object",
74
+ result.root.hasOwnProperty === undefined);
75
+ check("no inherited constructor on @attrs object",
76
+ result.root["@attrs"].constructor === undefined);
77
+ }
78
+
79
+ function testRejectsProtoAttributeName() {
80
+ var threw = null;
81
+ try { xml.parse('<root __proto__="polluted"/>'); }
82
+ catch (e) { threw = e; }
83
+ check("xml.parse rejects __proto__ attribute name",
84
+ threw && threw.code === "xml/forbidden-name");
85
+ // The global Object.prototype was not mutated either way.
86
+ check("Object.prototype not polluted by __proto__ attribute",
87
+ ({}).polluted === undefined);
88
+ }
89
+
90
+ function testRejectsProtoElementName() {
91
+ var threw = null;
92
+ try { xml.parse("<__proto__><x>y</x></__proto__>"); }
93
+ catch (e) { threw = e; }
94
+ check("xml.parse rejects __proto__ element name",
95
+ threw && threw.code === "xml/forbidden-name");
96
+ }
97
+
98
+ function testRejectsConstructorElementName() {
99
+ var threw = null;
100
+ try { xml.parse("<root><constructor>x</constructor></root>"); }
101
+ catch (e) { threw = e; }
102
+ check("xml.parse rejects constructor child element name",
103
+ threw && threw.code === "xml/forbidden-name");
104
+ }
105
+
106
+ function testRejectsPrototypeElementName() {
107
+ var threw = null;
108
+ try { xml.parse("<prototype/>"); }
109
+ catch (e) { threw = e; }
110
+ check("xml.parse rejects prototype element name",
111
+ threw && threw.code === "xml/forbidden-name");
112
+ }
113
+
114
+ function testConstructorAttributeNoFalseDuplicate() {
115
+ // With a plain-object accumulator, attrs["constructor"] would read the
116
+ // inherited Object constructor (not undefined) and a single occurrence
117
+ // would falsely trip the duplicate-attribute guard. The forbidden-name
118
+ // rejection now fires first; assert the code is forbidden-name, not
119
+ // duplicate-attr, so the diagnostic points at the real cause.
120
+ var threw = null;
121
+ try { xml.parse('<root constructor="once"/>'); }
122
+ catch (e) { threw = e; }
123
+ check("constructor attribute → forbidden-name (not false duplicate-attr)",
124
+ threw && threw.code === "xml/forbidden-name");
125
+ }
126
+
127
+ (function run() {
128
+ try {
129
+ testParsesAttributedElement();
130
+ testRejectsDoctype();
131
+ testRejectsCustomEntity();
132
+ testResultTreeHasNullPrototype();
133
+ testRejectsProtoAttributeName();
134
+ testRejectsProtoElementName();
135
+ testRejectsConstructorElementName();
136
+ testRejectsPrototypeElementName();
137
+ testConstructorAttributeNoFalseDuplicate();
138
+ } catch (e) {
139
+ console.error(e);
140
+ process.exit(1);
141
+ }
142
+ console.log("OK — safe-xml tests");
143
+ })();