@blamejs/blamejs-shop 0.5.12 → 0.5.13
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.
- package/CHANGELOG.md +2 -0
- package/lib/asset-manifest.json +1 -1
- package/lib/vendor/MANIFEST.json +632 -416
- package/lib/vendor/blamejs/.clusterfuzzlite/Dockerfile +21 -10
- package/lib/vendor/blamejs/.clusterfuzzlite/build.sh +30 -9
- package/lib/vendor/blamejs/.github/dependabot.yml +8 -0
- package/lib/vendor/blamejs/.github/workflows/actions-lint.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/cflite_batch.yml +7 -2
- package/lib/vendor/blamejs/.github/workflows/cflite_pr.yml +7 -2
- package/lib/vendor/blamejs/.github/workflows/ci.yml +21 -21
- package/lib/vendor/blamejs/.github/workflows/codeql.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +4 -4
- package/lib/vendor/blamejs/.github/workflows/release-container.yml +7 -7
- package/lib/vendor/blamejs/.github/workflows/scorecard.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/sha-to-tag-verify.yml +1 -1
- package/lib/vendor/blamejs/.gitignore +2 -0
- package/lib/vendor/blamejs/CHANGELOG.md +122 -0
- package/lib/vendor/blamejs/NOTICE +26 -1
- package/lib/vendor/blamejs/SECURITY.md +1 -1
- package/lib/vendor/blamejs/api-snapshot.json +207 -5
- package/lib/vendor/blamejs/docker/keycloak/realm-blamejs-test.json +29 -0
- package/lib/vendor/blamejs/examples/wiki/DEPLOY.md +1 -0
- package/lib/vendor/blamejs/examples/wiki/lib/build-app.js +31 -0
- package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +109 -0
- package/lib/vendor/blamejs/examples/wiki/nginx.conf +106 -0
- package/lib/vendor/blamejs/examples/wiki/package-lock.json +1 -1
- package/lib/vendor/blamejs/examples/wiki/test/e2e.js +92 -0
- package/lib/vendor/blamejs/fuzz/asn1-der.fuzz.js +28 -0
- package/lib/vendor/blamejs/fuzz/cms-codec.fuzz.js +17 -0
- package/lib/vendor/blamejs/fuzz/link-header.fuzz.js +18 -0
- package/lib/vendor/blamejs/index.js +6 -0
- package/lib/vendor/blamejs/lib/a2a.js +4 -4
- package/lib/vendor/blamejs/lib/agent-idempotency.js +18 -2
- package/lib/vendor/blamejs/lib/agent-saga.js +36 -8
- package/lib/vendor/blamejs/lib/agent-snapshot.js +63 -6
- package/lib/vendor/blamejs/lib/app-shutdown.js +23 -20
- package/lib/vendor/blamejs/lib/archive-read.js +8 -0
- package/lib/vendor/blamejs/lib/archive-tar.js +12 -2
- package/lib/vendor/blamejs/lib/arg-parser.js +49 -5
- package/lib/vendor/blamejs/lib/asn1-der.js +12 -0
- package/lib/vendor/blamejs/lib/audit-sign.js +47 -1
- package/lib/vendor/blamejs/lib/audit.js +71 -8
- package/lib/vendor/blamejs/lib/auth/ciba.js +14 -2
- package/lib/vendor/blamejs/lib/auth/fido-mds3.js +58 -47
- package/lib/vendor/blamejs/lib/auth/jwt.js +34 -0
- package/lib/vendor/blamejs/lib/auth/oauth.js +90 -13
- package/lib/vendor/blamejs/lib/auth/oid4vci.js +20 -17
- package/lib/vendor/blamejs/lib/auth/openid-federation.js +214 -23
- package/lib/vendor/blamejs/lib/auth/saml.js +38 -20
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +10 -4
- package/lib/vendor/blamejs/lib/backup/bundle.js +13 -3
- package/lib/vendor/blamejs/lib/backup/index.js +16 -5
- package/lib/vendor/blamejs/lib/backup/manifest.js +18 -5
- package/lib/vendor/blamejs/lib/base32.js +21 -0
- package/lib/vendor/blamejs/lib/break-glass.js +19 -10
- package/lib/vendor/blamejs/lib/bundler.js +5 -1
- package/lib/vendor/blamejs/lib/cache-status.js +3 -7
- package/lib/vendor/blamejs/lib/calendar.js +21 -1
- package/lib/vendor/blamejs/lib/cbor.js +12 -1
- package/lib/vendor/blamejs/lib/cert.js +29 -11
- package/lib/vendor/blamejs/lib/cli.js +94 -24
- package/lib/vendor/blamejs/lib/cloud-events.js +2 -2
- package/lib/vendor/blamejs/lib/cluster-provider-db.js +13 -3
- package/lib/vendor/blamejs/lib/codepoint-class.js +85 -0
- package/lib/vendor/blamejs/lib/compliance-ai-act-prohibited.js +8 -4
- package/lib/vendor/blamejs/lib/compliance-ai-act-transparency.js +19 -4
- package/lib/vendor/blamejs/lib/compliance-ai-act.js +6 -8
- package/lib/vendor/blamejs/lib/content-credentials.js +1 -1
- package/lib/vendor/blamejs/lib/content-digest.js +2 -1
- package/lib/vendor/blamejs/lib/cookies.js +13 -3
- package/lib/vendor/blamejs/lib/cose.js +31 -16
- package/lib/vendor/blamejs/lib/crypto-field.js +32 -0
- package/lib/vendor/blamejs/lib/crypto-oprf.js +11 -2
- package/lib/vendor/blamejs/lib/crypto-xwing.js +22 -4
- package/lib/vendor/blamejs/lib/crypto.js +314 -19
- package/lib/vendor/blamejs/lib/csp.js +11 -3
- package/lib/vendor/blamejs/lib/daemon.js +270 -24
- package/lib/vendor/blamejs/lib/dark-patterns.js +5 -2
- package/lib/vendor/blamejs/lib/db-declare-view.js +2 -2
- package/lib/vendor/blamejs/lib/db-query.js +34 -7
- package/lib/vendor/blamejs/lib/db.js +18 -6
- package/lib/vendor/blamejs/lib/dbsc.js +17 -0
- package/lib/vendor/blamejs/lib/dev.js +21 -2
- package/lib/vendor/blamejs/lib/dsr.js +157 -102
- package/lib/vendor/blamejs/lib/external-db.js +41 -2
- package/lib/vendor/blamejs/lib/file-upload.js +25 -7
- package/lib/vendor/blamejs/lib/flag-providers.js +27 -15
- package/lib/vendor/blamejs/lib/forms.js +113 -27
- package/lib/vendor/blamejs/lib/gate-contract.js +23 -10
- package/lib/vendor/blamejs/lib/gdpr-ropa.js +8 -1
- package/lib/vendor/blamejs/lib/guard-agent-registry.js +1 -1
- package/lib/vendor/blamejs/lib/guard-archive.js +2 -2
- package/lib/vendor/blamejs/lib/guard-cidr.js +27 -1
- package/lib/vendor/blamejs/lib/guard-graphql.js +30 -11
- package/lib/vendor/blamejs/lib/guard-html.js +26 -53
- package/lib/vendor/blamejs/lib/guard-image.js +24 -5
- package/lib/vendor/blamejs/lib/guard-imap-command.js +10 -2
- package/lib/vendor/blamejs/lib/guard-jmap.js +19 -3
- package/lib/vendor/blamejs/lib/guard-jwt.js +18 -2
- package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +2 -2
- package/lib/vendor/blamejs/lib/guard-managesieve-command.js +10 -2
- package/lib/vendor/blamejs/lib/guard-markdown.js +11 -24
- package/lib/vendor/blamejs/lib/guard-pdf.js +18 -2
- package/lib/vendor/blamejs/lib/guard-pop3-command.js +10 -2
- package/lib/vendor/blamejs/lib/guard-regex.js +8 -5
- package/lib/vendor/blamejs/lib/guard-svg.js +31 -32
- package/lib/vendor/blamejs/lib/guard-time.js +1 -1
- package/lib/vendor/blamejs/lib/guard-uuid.js +2 -2
- package/lib/vendor/blamejs/lib/html-balance.js +3 -3
- package/lib/vendor/blamejs/lib/http-client-cache.js +82 -4
- package/lib/vendor/blamejs/lib/http-client-cookie-jar.js +16 -1
- package/lib/vendor/blamejs/lib/http-client.js +39 -7
- package/lib/vendor/blamejs/lib/http-message-signature.js +35 -1
- package/lib/vendor/blamejs/lib/i18n-messageformat.js +31 -6
- package/lib/vendor/blamejs/lib/i18n.js +35 -21
- package/lib/vendor/blamejs/lib/incident-report.js +8 -1
- package/lib/vendor/blamejs/lib/ip-utils.js +11 -1
- package/lib/vendor/blamejs/lib/json-path.js +23 -1
- package/lib/vendor/blamejs/lib/jwk.js +20 -3
- package/lib/vendor/blamejs/lib/link-header.js +2 -1
- package/lib/vendor/blamejs/lib/log-stream-otlp-grpc.js +5 -1
- package/lib/vendor/blamejs/lib/log-stream-otlp.js +5 -1
- package/lib/vendor/blamejs/lib/log-stream.js +8 -3
- package/lib/vendor/blamejs/lib/mail-auth.js +123 -22
- package/lib/vendor/blamejs/lib/mail-bimi.js +1 -1
- package/lib/vendor/blamejs/lib/mail-bounce.js +8 -0
- package/lib/vendor/blamejs/lib/mail-crypto-pgp.js +46 -10
- package/lib/vendor/blamejs/lib/mail-dav.js +22 -3
- package/lib/vendor/blamejs/lib/mail-dkim.js +96 -30
- package/lib/vendor/blamejs/lib/mail-helo.js +6 -1
- package/lib/vendor/blamejs/lib/mail-scan.js +23 -16
- package/lib/vendor/blamejs/lib/mail-send-deliver.js +34 -8
- package/lib/vendor/blamejs/lib/mail-server-imap.js +3 -4
- package/lib/vendor/blamejs/lib/mail-server-managesieve.js +7 -11
- package/lib/vendor/blamejs/lib/mail-server-mx.js +93 -7
- package/lib/vendor/blamejs/lib/mail-server-registry.js +8 -2
- package/lib/vendor/blamejs/lib/mail.js +15 -5
- package/lib/vendor/blamejs/lib/metrics.js +268 -63
- package/lib/vendor/blamejs/lib/middleware/age-gate.js +7 -1
- package/lib/vendor/blamejs/lib/middleware/asyncapi-serve.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/body-parser.js +19 -4
- package/lib/vendor/blamejs/lib/middleware/bot-guard.js +5 -9
- package/lib/vendor/blamejs/lib/middleware/csp-report.js +40 -8
- package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +24 -10
- package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -5
- package/lib/vendor/blamejs/lib/middleware/index.js +6 -1
- package/lib/vendor/blamejs/lib/middleware/nel.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/openapi-serve.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/rate-limit.js +12 -1
- package/lib/vendor/blamejs/lib/middleware/require-bound-key.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/scim-server.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/tus-upload.js +6 -2
- package/lib/vendor/blamejs/lib/mtls-ca.js +18 -2
- package/lib/vendor/blamejs/lib/network-dns-resolver.js +11 -1
- package/lib/vendor/blamejs/lib/network-dns.js +21 -2
- package/lib/vendor/blamejs/lib/network-tls.js +69 -7
- package/lib/vendor/blamejs/lib/nonce-store.js +9 -1
- package/lib/vendor/blamejs/lib/object-store/gcs.js +7 -0
- package/lib/vendor/blamejs/lib/object-store/sigv4.js +31 -0
- package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +1 -1
- package/lib/vendor/blamejs/lib/outbox.js +1 -1
- package/lib/vendor/blamejs/lib/parsers/safe-ini.js +9 -1
- package/lib/vendor/blamejs/lib/parsers/safe-toml.js +10 -1
- package/lib/vendor/blamejs/lib/permissions.js +6 -3
- package/lib/vendor/blamejs/lib/pid-probe.js +55 -0
- package/lib/vendor/blamejs/lib/pqc-agent.js +8 -1
- package/lib/vendor/blamejs/lib/pqc-software.js +3 -3
- package/lib/vendor/blamejs/lib/pubsub.js +20 -9
- package/lib/vendor/blamejs/lib/queue-local.js +8 -1
- package/lib/vendor/blamejs/lib/queue-redis.js +5 -0
- package/lib/vendor/blamejs/lib/redact.js +54 -0
- package/lib/vendor/blamejs/lib/restore-bundle.js +10 -2
- package/lib/vendor/blamejs/lib/restore.js +19 -0
- package/lib/vendor/blamejs/lib/retention.js +12 -4
- package/lib/vendor/blamejs/lib/router.js +60 -6
- package/lib/vendor/blamejs/lib/safe-buffer.js +69 -0
- package/lib/vendor/blamejs/lib/safe-decompress.js +8 -2
- package/lib/vendor/blamejs/lib/safe-dns.js +25 -20
- package/lib/vendor/blamejs/lib/safe-ical.js +7 -3
- package/lib/vendor/blamejs/lib/safe-mime.js +12 -1
- package/lib/vendor/blamejs/lib/safe-object.js +80 -0
- package/lib/vendor/blamejs/lib/safe-path.js +52 -4
- package/lib/vendor/blamejs/lib/safe-redirect.js +10 -2
- package/lib/vendor/blamejs/lib/safe-schema.js +4 -1
- package/lib/vendor/blamejs/lib/safe-sieve.js +33 -1
- package/lib/vendor/blamejs/lib/safe-sql.js +88 -0
- package/lib/vendor/blamejs/lib/safe-vcard.js +7 -3
- package/lib/vendor/blamejs/lib/scheduler.js +8 -1
- package/lib/vendor/blamejs/lib/security-assert.js +6 -6
- package/lib/vendor/blamejs/lib/self-update-standalone-verifier.js +74 -27
- package/lib/vendor/blamejs/lib/self-update.js +517 -87
- package/lib/vendor/blamejs/lib/server-timing.js +2 -4
- package/lib/vendor/blamejs/lib/session.js +34 -12
- package/lib/vendor/blamejs/lib/sql.js +15 -1
- package/lib/vendor/blamejs/lib/ssrf-guard.js +52 -0
- package/lib/vendor/blamejs/lib/static.js +55 -13
- package/lib/vendor/blamejs/lib/storage.js +8 -2
- package/lib/vendor/blamejs/lib/subject.js +6 -1
- package/lib/vendor/blamejs/lib/tenant-quota.js +52 -13
- package/lib/vendor/blamejs/lib/tls-exporter.js +3 -3
- package/lib/vendor/blamejs/lib/tsa.js +34 -13
- package/lib/vendor/blamejs/lib/uri-template.js +8 -1
- package/lib/vendor/blamejs/lib/vault/index.js +13 -0
- package/lib/vendor/blamejs/lib/vc.js +44 -5
- package/lib/vendor/blamejs/lib/vendor/MANIFEST.json +26 -26
- package/lib/vendor/blamejs/lib/vendor/noble-ciphers.cjs +792 -1
- package/lib/vendor/blamejs/lib/vendor/noble-curves.cjs +3443 -1
- package/lib/vendor/blamejs/lib/vendor/noble-post-quantum.cjs +2737 -1
- package/lib/vendor/blamejs/lib/vendor/pki.cjs +39550 -13
- package/lib/vendor/blamejs/lib/vendor/public-suffix-list.dat +55 -53
- package/lib/vendor/blamejs/lib/vendor/public-suffix-list.data.js +5551 -5554
- package/lib/vendor/blamejs/lib/vendor/simplewebauthn-server.cjs +22459 -32
- package/lib/vendor/blamejs/lib/watcher.js +89 -17
- package/lib/vendor/blamejs/lib/webhook-dispatcher.js +25 -3
- package/lib/vendor/blamejs/lib/webhook.js +12 -2
- package/lib/vendor/blamejs/lib/ws-client.js +32 -1
- package/lib/vendor/blamejs/lib/xml-c14n.js +29 -1
- package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/Dockerfile +1 -1
- package/lib/vendor/blamejs/package-lock.json +2 -2
- package/lib/vendor/blamejs/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.16.x.json +1462 -0
- package/lib/vendor/blamejs/release-notes/v0.17.0.json +31 -0
- package/lib/vendor/blamejs/release-notes/v0.17.1.json +31 -0
- package/lib/vendor/blamejs/release-notes/v0.17.10.json +30 -0
- package/lib/vendor/blamejs/release-notes/v0.17.11.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.17.12.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.13.json +77 -0
- package/lib/vendor/blamejs/release-notes/v0.17.14.json +40 -0
- package/lib/vendor/blamejs/release-notes/v0.17.15.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.16.json +27 -0
- package/lib/vendor/blamejs/release-notes/v0.17.17.json +31 -0
- package/lib/vendor/blamejs/release-notes/v0.17.18.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.19.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.2.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.20.json +43 -0
- package/lib/vendor/blamejs/release-notes/v0.17.21.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.22.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.3.json +43 -0
- package/lib/vendor/blamejs/release-notes/v0.17.4.json +35 -0
- package/lib/vendor/blamejs/release-notes/v0.17.5.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.6.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.7.json +35 -0
- package/lib/vendor/blamejs/release-notes/v0.17.8.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.17.9.json +26 -0
- package/lib/vendor/blamejs/scripts/validate-source-comment-blocks.js +4 -0
- package/lib/vendor/blamejs/scripts/vendor-update.sh +293 -9
- package/lib/vendor/blamejs/socket.yml +94 -0
- package/lib/vendor/blamejs/test/00-primitives.js +605 -0
- package/lib/vendor/blamejs/test/helpers/drivers.js +12 -9
- package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +90 -1
- package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +122 -1
- package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +30 -0
- package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +29 -0
- package/lib/vendor/blamejs/test/integration/dsr-cluster-mysql.test.js +479 -0
- package/lib/vendor/blamejs/test/integration/dsr-cluster-pg.test.js +487 -0
- package/lib/vendor/blamejs/test/integration/federation-auth.test.js +313 -5
- package/lib/vendor/blamejs/test/integration/mail-dkim.test.js +80 -0
- package/lib/vendor/blamejs/test/integration/openid-federation-chain.test.js +275 -0
- package/lib/vendor/blamejs/test/integration/webhook-dispatcher-pg.test.js +96 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/a2a-tasks.test.js +401 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/acme.test.js +1649 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/age-gate.test.js +33 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-idempotency.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-saga.test.js +60 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-snapshot.test.js +524 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/api-encrypt.test.js +891 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/app-shutdown.test.js +128 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-adapters.test.js +271 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-read.test.js +628 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-tar-read.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-wrap.test.js +227 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/arg-parser.test.js +15 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/asn1-der.test.js +73 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file.test.js +114 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-sign-anchor.test.js +141 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-tools.test.js +624 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit.test.js +769 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-jwt-defenses.test.js +436 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-oauth.test.js +1697 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-oid4vp.test.js +495 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-password.test.js +500 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-saml.test.js +1809 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-status-list.test.js +243 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-index.test.js +2226 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-manifest-signature.test.js +183 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/base32.test.js +105 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +693 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cache.test.js +603 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/calendar.test.js +557 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/case-insensitive-security-token-guard.test.js +214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cbor.test.js +25 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cert.test.js +843 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/ciba-authreqid-binding.test.js +77 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/ciba.test.js +866 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/clear-site-data.test.js +18 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-erase.test.js +19 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli.test.js +2790 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cluster-lease-renewal-ttl.test.js +114 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cluster.test.js +1032 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cms-codec.test.js +575 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +739 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/codepoint-class.test.js +8 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-ai-act.test.js +194 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-lifecycle-proto-key.test.js +104 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-sanctions.test.js +254 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials.test.js +613 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/cookies.test.js +140 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cose.test.js +407 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-adversarial.test.js +352 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field.test.js +575 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-files-parallel.test.js +10 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-stream.test.js +24 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-oprf.test.js +17 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-spki-pin.test.js +183 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-xwing.test.js +48 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto.test.js +345 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csp-report.test.js +58 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csv.test.js +48 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/daemon.test.js +459 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/dark-patterns.test.js +19 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-query.test.js +1019 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +77 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db.test.js +1621 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ddl-change-control.test.js +462 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/dnssec.test.js +323 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-verify.test.js +562 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +901 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/dual-control.test.js +249 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +561 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db.test.js +1214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fal.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fedcm-dbsc.test.js +46 -20
- package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +147 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/fido-mds3.test.js +907 -38
- package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +29 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/file-upload.test.js +1135 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/flag.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/forms.test.js +747 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/gate-contract.test.js +1855 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/gdpr-ropa.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-archive.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-auth.test.js +117 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-cidr.test.js +151 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-domain.test.js +422 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-filename.test.js +424 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{guard-gate-disposition-coverage.test.js → guard-gate-disposition.test.js} +1 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-graphql.test.js +340 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-html.test.js +29 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-idempotency-key.test.js +28 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-image.test.js +519 -45
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-imap-command.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-jmap.test.js +51 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-jsonpath.test.js +66 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-jwt.test.js +436 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-managesieve-command.test.js +25 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-markdown.test.js +16 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-mime.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-oauth.test.js +140 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-pdf.test.js +80 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-pop3-command.test.js +27 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-regex.test.js +99 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-shell.test.js +76 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{guard-sql-coverage.test.js → guard-sql.test.js} +3 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-svg.test.js +524 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-template.test.js +71 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-time.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-uuid.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/html-balance.test.js +38 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache-authorization.test.js +347 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache.test.js +908 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client.test.js +2874 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-message-signature.test.js +643 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/i18n-messageformat.test.js +38 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/i18n.test.js +1153 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +494 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ip-utils.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jsdoc-example-execution.test.js +177 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/json-path.test.js +103 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/json-schema.test.js +214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jwk.test.js +41 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jwt-external.test.js +276 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/keychain.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/log-stream.test.js +241 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/log.test.js +106 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-agent.test.js +441 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +2136 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-bimi.test.js +759 -12
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-bounce.test.js +811 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp-experimental.test.js +401 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp.test.js +751 -8
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-smime.test.js +864 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto.test.js +110 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-dav.test.js +830 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-deploy.test.js +635 -86
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-dkim.test.js +818 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-helo.test.js +27 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-scan.test.js +199 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-send-deliver.test.js +686 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-imap.test.js +778 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +1438 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-managesieve.test.js +449 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +773 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-pop3.test.js +623 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-rate-limit.test.js +55 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-registry.test.js +13 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-submission.test.js +877 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-sieve.test.js +326 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store-fts.test.js +55 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +242 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail.test.js +1596 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mcp.test.js +440 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics-snapshot.test.js +89 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics.test.js +1230 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-assetlinks.test.js +113 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-body-parser.test.js +1169 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-bot-disclose.test.js +123 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-cookies.test.js +108 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-gpc.test.js +121 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-headers.test.js +163 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-host-allowlist.test.js +154 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-require-content-type.test.js +127 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{middleware-tus-upload-coverage.test.js → middleware-tus-upload.test.js} +45 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-web-app-manifest.test.js +132 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mtls-ca-crl-fingerprint-only.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-dns-resolver.test.js +65 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-dns.test.js +1727 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/network-nts.test.js +699 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-smtp-policy.test.js +1181 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-tls.test.js +1876 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/network.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/nonce-store-enforce-replay-nonboolean.test.js +81 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ntp-check.test.js +122 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/observability-tracing.test.js +378 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/observability.test.js +77 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/oid4vci.test.js +1016 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/openid-federation.test.js +946 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/outbox.test.js +818 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/own-property-membership-guards.test.js +109 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-safe-toml.test.js +543 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{parsers-safe-yaml-coverage.test.js → parsers-safe-yaml.test.js} +2 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +73 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/passkey.test.js +649 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/permissions.test.js +524 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +22 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pubsub.test.js +295 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue-flow-repeat.test.js +36 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue.test.js +83 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-xff-spoofing.test.js +34 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/redact.test.js +1031 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/request-helpers.test.js +94 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/require-bound-key.test.js +401 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/restore-empty-manifest-wipe.test.js +154 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/retention.test.js +600 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-host-path-injection.test.js +231 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-tls0rtt.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router.test.js +1277 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-async.test.js +133 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer-linear-scans.test.js +14 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer.test.js +80 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-decompress.test.js +28 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-dns.test.js +245 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-ical.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-ini.test.js +376 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-json.test.js +175 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-mime.test.js +518 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-object.test.js +62 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-path.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-schema.test.js +104 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-sql.test.js +142 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-url.test.js +112 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-vcard.test.js +26 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/scheduler.test.js +157 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/scim-server.test.js +396 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +930 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/security-assert.test.js +755 -82
- package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +1053 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/session-device-binding.test.js +200 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/session-strict-binding-missing-failclosed.test.js +110 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +636 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sql-offset-without-limit.test.js +94 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +1190 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +850 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/storage-presigned-url.test.js +146 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/storage.test.js +621 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/subject.test.js +47 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/template.test.js +582 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tenant-quota.test.js +587 -25
- package/lib/vendor/blamejs/test/layer-0-primitives/time.test.js +11 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tsa.test.js +524 -63
- package/lib/vendor/blamejs/test/layer-0-primitives/uri-template.test.js +27 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vault-rotate.test.js +866 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vault.test.js +74 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vc.test.js +215 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/watcher.test.js +550 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/webhook-dispatcher.test.js +388 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +262 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/websocket.test.js +1294 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ws-client.test.js +629 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/xml-c14n-attr-normalization.test.js +164 -0
- package/lib/vendor/blamejs/test/smoke.js +2 -0
- package/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.16.0.json +0 -44
- package/lib/vendor/blamejs/release-notes/v0.16.1.json +0 -36
- package/lib/vendor/blamejs/release-notes/v0.16.2.json +0 -71
- package/lib/vendor/blamejs/release-notes/v0.16.3.json +0 -71
- package/lib/vendor/blamejs/test/layer-0-primitives/acme-coverage.test.js +0 -441
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-oauth-coverage.test.js +0 -482
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-saml-coverage.test.js +0 -671
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-index-coverage.test.js +0 -690
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-coverage.test.js +0 -238
- package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials-coverage.test.js +0 -319
- package/lib/vendor/blamejs/test/layer-0-primitives/keychain-coverage.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth-coverage.test.js +0 -437
- package/lib/vendor/blamejs/test/layer-0-primitives/mcp-coverage.test.js +0 -443
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics-coverage.test.js +0 -395
- package/lib/vendor/blamejs/test/layer-0-primitives/network-smtp-policy-coverage.test.js +0 -565
- package/lib/vendor/blamejs/test/layer-0-primitives/router-coverage.test.js +0 -592
- package/lib/vendor/blamejs/test/layer-0-primitives/sql-coverage.test.js +0 -422
- package/lib/vendor/blamejs/test/layer-0-primitives/test-coverage.test.js +0 -573
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (c) blamejs contributors
|
|
3
|
+
"use strict";
|
|
4
|
+
/**
|
|
5
|
+
* b.auth.password — Argon2id hashing + verify + needsRehash + the
|
|
6
|
+
* b.auth.password.policy() presentation-time gate (length / common /
|
|
7
|
+
* dictionary / context / complexity / HIBP breach check).
|
|
8
|
+
*
|
|
9
|
+
* This file exercises the ERROR, ADVERSARIAL, DEFENSIVE and
|
|
10
|
+
* OPTION-DEFAULT branches: config-time throws (bad params / bad
|
|
11
|
+
* policy), fail-closed request-shape readers (verify tolerates garbage
|
|
12
|
+
* by returning false), the concurrency semaphore's queue path, and the
|
|
13
|
+
* HIBP breach-check response handling — network error, non-200,
|
|
14
|
+
* poisoned-mirror, match and no-match — driven through an injected
|
|
15
|
+
* http-client stub (NEVER real network). Sibling
|
|
16
|
+
* auth-password-audit.test.js covers b.auth.password.params().
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
var helpers = require("../helpers");
|
|
20
|
+
var b = helpers.b;
|
|
21
|
+
var check = helpers.check;
|
|
22
|
+
|
|
23
|
+
// The password policy's HIBP breach check calls httpClient.request.
|
|
24
|
+
// password.js captures `require("../http-client")` (the shared module
|
|
25
|
+
// object) once at load; requiring the same resolved path here hands
|
|
26
|
+
// back that identical object, so replacing `.request` injects a stub
|
|
27
|
+
// into the live consumer path with no real network. Each test restores
|
|
28
|
+
// the original in a finally. Layer-0 files fork into their own process
|
|
29
|
+
// (smoke isolation), so this patch never bleeds into a sibling file.
|
|
30
|
+
var httpClient = require("../../lib/http-client");
|
|
31
|
+
// The framework's own SHA-1 (the only in-process SHA-1, HIBP-only) —
|
|
32
|
+
// used here to build a REALISTIC k-anonymity response body whose suffix
|
|
33
|
+
// matches the plaintext under test, not to mock anything.
|
|
34
|
+
var hibpSha1 = require("../../lib/framework-sha1-hibp");
|
|
35
|
+
|
|
36
|
+
// Fast Argon2 params for round-trip tests — the framework default of
|
|
37
|
+
// 64 MiB / t=3 / p=4 is ~250-500ms per call; 1 MiB / t=1 / p=1 keeps
|
|
38
|
+
// the suite quick while still driving the real vendor hash + verify.
|
|
39
|
+
var FAST = { memoryCost: b.constants.BYTES.kib(1), timeCost: 1, parallelism: 1 };
|
|
40
|
+
|
|
41
|
+
// ---- hash / verify happy path + defensive readers ------------------
|
|
42
|
+
|
|
43
|
+
async function testHashVerifyRoundtrip() {
|
|
44
|
+
var h = await b.auth.password.hash("hunter2", FAST);
|
|
45
|
+
check("hash produces argon2id PHC string", h.indexOf("$argon2id$") === 0);
|
|
46
|
+
check("verify matches the original plaintext",
|
|
47
|
+
(await b.auth.password.verify(h, "hunter2")) === true);
|
|
48
|
+
check("verify rejects a wrong plaintext (returns false, not throw)",
|
|
49
|
+
(await b.auth.password.verify(h, "wrong")) === false);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function testHashRejectsBadPlain() {
|
|
53
|
+
var threwEmpty, threwType, threwBig;
|
|
54
|
+
try { await b.auth.password.hash(""); } catch (e) { threwEmpty = e; }
|
|
55
|
+
check("hash: empty plaintext throws invalid-plain",
|
|
56
|
+
threwEmpty && threwEmpty.code === "auth-password/invalid-plain");
|
|
57
|
+
try { await b.auth.password.hash(12345); } catch (e) { threwType = e; }
|
|
58
|
+
check("hash: non-string plaintext throws invalid-plain",
|
|
59
|
+
threwType && threwType.code === "auth-password/invalid-plain");
|
|
60
|
+
// 4 KiB is the plaintext cap; one byte over must be refused.
|
|
61
|
+
var oversize = "a".repeat(b.constants.BYTES.kib(4) + 1);
|
|
62
|
+
try { await b.auth.password.hash(oversize, FAST); } catch (e) { threwBig = e; }
|
|
63
|
+
check("hash: oversize plaintext throws plain-too-large",
|
|
64
|
+
threwBig && threwBig.code === "auth-password/plain-too-large");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function testHashRejectsBadParams() {
|
|
68
|
+
var threwMem, threwTime, threwPar;
|
|
69
|
+
try {
|
|
70
|
+
await b.auth.password.hash("pw", { memoryCost: b.constants.BYTES.kib(1) - 1, timeCost: 1, parallelism: 1 });
|
|
71
|
+
} catch (e) { threwMem = e; }
|
|
72
|
+
check("hash: memoryCost below 1 MiB floor throws bad-params",
|
|
73
|
+
threwMem && threwMem.code === "auth-password/bad-params");
|
|
74
|
+
try {
|
|
75
|
+
await b.auth.password.hash("pw", { memoryCost: b.constants.BYTES.kib(1), timeCost: 0, parallelism: 1 });
|
|
76
|
+
} catch (e) { threwTime = e; }
|
|
77
|
+
check("hash: timeCost below 1 throws bad-params",
|
|
78
|
+
threwTime && threwTime.code === "auth-password/bad-params");
|
|
79
|
+
try {
|
|
80
|
+
await b.auth.password.hash("pw", { memoryCost: b.constants.BYTES.kib(1), timeCost: 1, parallelism: 0 });
|
|
81
|
+
} catch (e) { threwPar = e; }
|
|
82
|
+
check("hash: parallelism below 1 throws bad-params",
|
|
83
|
+
threwPar && threwPar.code === "auth-password/bad-params");
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function testVerifyDefensiveReturnsFalse() {
|
|
87
|
+
// verify() never throws on garbage — login flows treat false as
|
|
88
|
+
// "credentials didn't match" and shouldn't wrap each call in try/catch.
|
|
89
|
+
check("verify: non-string stored → false",
|
|
90
|
+
(await b.auth.password.verify(null, "pw")) === false);
|
|
91
|
+
check("verify: empty stored → false",
|
|
92
|
+
(await b.auth.password.verify("", "pw")) === false);
|
|
93
|
+
check("verify: non-string plain → false",
|
|
94
|
+
(await b.auth.password.verify("$argon2id$v=19$m=1024,t=1,p=1$x$y", 42)) === false);
|
|
95
|
+
check("verify: empty plain → false",
|
|
96
|
+
(await b.auth.password.verify("$argon2id$v=19$m=1024,t=1,p=1$x$y", "")) === false);
|
|
97
|
+
// Other Argon2 variants are out of spec — verify() refuses without
|
|
98
|
+
// even attempting to validate them.
|
|
99
|
+
check("verify: argon2i variant (wrong prefix) → false",
|
|
100
|
+
(await b.auth.password.verify("$argon2i$v=19$m=1024,t=1,p=1$x$y", "pw")) === false);
|
|
101
|
+
// Oversize plaintext is rejected before touching the vendor.
|
|
102
|
+
var oversize = "a".repeat(b.constants.BYTES.kib(4) + 1);
|
|
103
|
+
check("verify: oversize plain → false",
|
|
104
|
+
(await b.auth.password.verify("$argon2id$v=19$m=1024,t=1,p=1$x$y", oversize)) === false);
|
|
105
|
+
// A corrupted PHC string surfaces as a vendor throw; verify() must
|
|
106
|
+
// swallow it and return false rather than break the login flow.
|
|
107
|
+
check("verify: corrupted argon2id PHC (vendor throws) → false",
|
|
108
|
+
(await b.auth.password.verify("$argon2id$this-is-not-a-valid-phc-body", "pw")) === false);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async function testNeedsRehash() {
|
|
112
|
+
var strong = await b.auth.password.hash("pw", { memoryCost: b.constants.BYTES.kib(64), timeCost: 3, parallelism: 4 });
|
|
113
|
+
check("needsRehash: hash at current defaults → false",
|
|
114
|
+
b.auth.password.needsRehash(strong) === false);
|
|
115
|
+
// A hash weaker than the requested target must be flagged for rehash.
|
|
116
|
+
var weak = await b.auth.password.hash("pw", FAST);
|
|
117
|
+
check("needsRehash: weaker-than-target hash → true",
|
|
118
|
+
b.auth.password.needsRehash(weak, { memoryCost: b.constants.BYTES.kib(64), timeCost: 3, parallelism: 4 }) === true);
|
|
119
|
+
// Non-argon2id / malformed stored value forces a rehash on next login.
|
|
120
|
+
check("needsRehash: non-argon2id variant → true",
|
|
121
|
+
b.auth.password.needsRehash("$argon2i$v=19$m=1024,t=1,p=1$x$y") === true);
|
|
122
|
+
check("needsRehash: non-string stored → true",
|
|
123
|
+
b.auth.password.needsRehash(null) === true);
|
|
124
|
+
// Unparseable argon2id body → vendor throws → forced rehash.
|
|
125
|
+
check("needsRehash: unparseable argon2id PHC → true",
|
|
126
|
+
b.auth.password.needsRehash("$argon2id$broken") === true);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async function testGate() {
|
|
130
|
+
var threw;
|
|
131
|
+
try { b.auth.password.gate(1.5); } catch (e) { threw = e; }
|
|
132
|
+
check("gate: non-integer rejected with bad-gate",
|
|
133
|
+
threw && threw.code === "auth-password/bad-gate");
|
|
134
|
+
var threwNeg;
|
|
135
|
+
try { b.auth.password.gate(0); } catch (e) { threwNeg = e; }
|
|
136
|
+
check("gate: zero rejected with bad-gate",
|
|
137
|
+
threwNeg && threwNeg.code === "auth-password/bad-gate");
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async function testConcurrencySemaphoreQueue() {
|
|
141
|
+
// gate(1) shrinks the semaphore to a single slot; two concurrent
|
|
142
|
+
// hashes force the second to queue on _waiters, then be released when
|
|
143
|
+
// the first finishes — exercising the queue push + release-to-waiter
|
|
144
|
+
// path that a single-call test never reaches.
|
|
145
|
+
b.auth.password.gate(1);
|
|
146
|
+
try {
|
|
147
|
+
var order = [];
|
|
148
|
+
var p1 = b.auth.password.hash("first", FAST).then(function () { order.push("first"); });
|
|
149
|
+
var p2 = b.auth.password.hash("second", FAST).then(function () { order.push("second"); });
|
|
150
|
+
await Promise.all([p1, p2]);
|
|
151
|
+
check("concurrency gate: both queued hashes complete", order.length === 2);
|
|
152
|
+
} finally {
|
|
153
|
+
// Restore a sane default so no later work runs single-slot.
|
|
154
|
+
b.auth.password.gate(8);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// ---- policy() config-time throws -----------------------------------
|
|
159
|
+
|
|
160
|
+
function _expectPolicyThrow(label, opts) {
|
|
161
|
+
var threw;
|
|
162
|
+
try { b.auth.password.policy(opts); } catch (e) { threw = e; }
|
|
163
|
+
check(label, threw && threw.code === "auth-password/bad-policy");
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function testPolicyConstructionRejects() {
|
|
167
|
+
_expectPolicyThrow("policy: unknown profile rejected", { profile: "totally-made-up" });
|
|
168
|
+
_expectPolicyThrow("policy: minLength below 1 rejected", { minLength: 0 });
|
|
169
|
+
_expectPolicyThrow("policy: minLength above cap rejected", { minLength: b.constants.BYTES.kib(4) + 1 });
|
|
170
|
+
_expectPolicyThrow("policy: maxLength below minLength rejected", { minLength: 10, maxLength: 5 });
|
|
171
|
+
_expectPolicyThrow("policy: unsupported breachCheck rejected", { breachCheck: "some-other-service" });
|
|
172
|
+
_expectPolicyThrow("policy: non-positive mustRotateAfterMs rejected", { mustRotateAfterMs: -1 });
|
|
173
|
+
_expectPolicyThrow("policy: non-finite mustRotateAfterMs rejected", { mustRotateAfterMs: Infinity });
|
|
174
|
+
_expectPolicyThrow("policy: fractional historyMinDistance rejected", { historyMinDistance: 2.5 });
|
|
175
|
+
_expectPolicyThrow("policy: negative historyMinDistance rejected", { historyMinDistance: -1 });
|
|
176
|
+
_expectPolicyThrow("policy: non-object complexity rejected", { complexity: "yes" });
|
|
177
|
+
_expectPolicyThrow("policy: complexity.minCategories out of range rejected",
|
|
178
|
+
{ complexity: { minCategories: 9, categories: ["lower", "upper"] } });
|
|
179
|
+
_expectPolicyThrow("policy: complexity.categories bad token rejected",
|
|
180
|
+
{ complexity: { minCategories: 1, categories: ["lower", "emoji"] } });
|
|
181
|
+
// hibpEndpoint must be a valid https URL (safeUrl ALLOW_HTTP_TLS).
|
|
182
|
+
var threwUrl;
|
|
183
|
+
try { b.auth.password.policy({ hibpEndpoint: "ftp://evil.example/range" }); } catch (e) { threwUrl = e; }
|
|
184
|
+
check("policy: non-https hibpEndpoint rejected", threwUrl !== undefined);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function testPolicyProfilesApply() {
|
|
188
|
+
var nist = b.auth.password.policy({ profile: "nist-aal2" });
|
|
189
|
+
var d1 = nist.describe();
|
|
190
|
+
check("policy profile nist-aal2: 8-byte floor + breach check",
|
|
191
|
+
d1.minLength === b.constants.BYTES.bytes(8) && d1.breachCheck === "haveibeenpwned");
|
|
192
|
+
var pci = b.auth.password.policy({ profile: "pci-4.0" });
|
|
193
|
+
var d2 = pci.describe();
|
|
194
|
+
check("policy profile pci-4.0: 12 min, rotation + history",
|
|
195
|
+
d2.minLength === 12 && d2.mustRotateAfterMs === b.constants.TIME.days(90) && d2.historyMinDistance === 4);
|
|
196
|
+
var hipaa = b.auth.password.policy({ profile: "hipaa-aal2" });
|
|
197
|
+
var d3 = hipaa.describe();
|
|
198
|
+
check("policy profile hipaa-aal2: complexity enabled",
|
|
199
|
+
d3.complexity && d3.complexity.minCategories === 3);
|
|
200
|
+
// Operator field override wins over the named profile.
|
|
201
|
+
var overridden = b.auth.password.policy({ profile: "pci-4.0", minLength: 20 });
|
|
202
|
+
check("policy: operator opt overrides profile default",
|
|
203
|
+
overridden.describe().minLength === 20);
|
|
204
|
+
// POLICY_PROFILES constant surface (verbatim dotted form for the gate).
|
|
205
|
+
check("b.auth.password.POLICY_PROFILES exposes the three profiles",
|
|
206
|
+
b.auth.password.POLICY_PROFILES["nist-aal2"] &&
|
|
207
|
+
b.auth.password.POLICY_PROFILES["pci-4.0"] &&
|
|
208
|
+
b.auth.password.POLICY_PROFILES["hipaa-aal2"]);
|
|
209
|
+
check("b.auth.password.DEFAULT_POLICY minLength is the NIST 8 floor",
|
|
210
|
+
b.auth.password.DEFAULT_POLICY.minLength === 8);
|
|
211
|
+
check("b.auth.password.DEFAULT_PARAMS memoryCost is 64 MiB in KiB",
|
|
212
|
+
b.auth.password.DEFAULT_PARAMS.memoryCost === b.constants.BYTES.kib(64));
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// ---- policy.check() gates (no breach check) ------------------------
|
|
216
|
+
|
|
217
|
+
async function testCheckLengthAndTypeGates() {
|
|
218
|
+
var pol = b.auth.password.policy({ minLength: 8, maxLength: 20, useBundledCommon: false });
|
|
219
|
+
var r1 = await pol.check(1234);
|
|
220
|
+
check("check: non-string plaintext → bad-input", r1.ok === false && r1.code === "policy/bad-input");
|
|
221
|
+
var r2 = await pol.check("short");
|
|
222
|
+
check("check: below minLength → too-short", r2.ok === false && r2.code === "policy/too-short");
|
|
223
|
+
var r3 = await pol.check("x".repeat(21));
|
|
224
|
+
check("check: above maxLength → too-long", r3.ok === false && r3.code === "policy/too-long");
|
|
225
|
+
var r4 = await pol.check("a-perfectly-fine-pw");
|
|
226
|
+
check("check: in-range unique pw passes (no breach check) → ok", r4.ok === true);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
async function testCheckCommonAndDictionary() {
|
|
230
|
+
// Bundled top-10000 set is on by default — "password" is in it.
|
|
231
|
+
var pol = b.auth.password.policy({ minLength: 4 });
|
|
232
|
+
var r1 = await pol.check("password");
|
|
233
|
+
check("check: bundled common password → forbidden-common",
|
|
234
|
+
r1.ok === false && r1.code === "policy/forbidden-common");
|
|
235
|
+
// Operator-supplied forbidCommon (bundled off to isolate the branch).
|
|
236
|
+
var pol2 = b.auth.password.policy({ minLength: 4, useBundledCommon: false, forbidCommon: ["s3cr3t-corp-pw"] });
|
|
237
|
+
var r2 = await pol2.check("s3cr3t-corp-pw");
|
|
238
|
+
check("check: operator forbidCommon match → forbidden-common",
|
|
239
|
+
r2.ok === false && r2.code === "policy/forbidden-common");
|
|
240
|
+
// Dictionary substring (brand names) — case-insensitive substring.
|
|
241
|
+
var pol3 = b.auth.password.policy({ minLength: 4, useBundledCommon: false, dictionary: ["acmecorp"] });
|
|
242
|
+
var r3 = await pol3.check("myAcmeCorpLogin");
|
|
243
|
+
check("check: dictionary substring → forbidden-dictionary",
|
|
244
|
+
r3.ok === false && r3.code === "policy/forbidden-dictionary");
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
async function testCheckContextSubstrings() {
|
|
248
|
+
var pol = b.auth.password.policy({ minLength: 4, useBundledCommon: false });
|
|
249
|
+
var r1 = await pol.check("alice-and-friends", { email: "alice@example.com" });
|
|
250
|
+
check("check: password containing email local-part → contains-context",
|
|
251
|
+
r1.ok === false && r1.code === "policy/contains-context");
|
|
252
|
+
var r2 = await pol.check("mybobbypassword", { username: "bob" });
|
|
253
|
+
check("check: password containing username → contains-context",
|
|
254
|
+
r2.ok === false && r2.code === "policy/contains-context");
|
|
255
|
+
var r3 = await pol.check("secret-widgets-99", { deny: ["widgets"] });
|
|
256
|
+
check("check: password containing operator deny string → contains-context",
|
|
257
|
+
r3.ok === false && r3.code === "policy/contains-context");
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
async function testCheckComplexity() {
|
|
261
|
+
var pol = b.auth.password.policy({
|
|
262
|
+
minLength: 4, useBundledCommon: false,
|
|
263
|
+
complexity: { minCategories: 3, minRunRepeat: 3, minSequenceLength: 3 },
|
|
264
|
+
});
|
|
265
|
+
var r1 = await pol.check("alllowercaseonly");
|
|
266
|
+
check("check: too few character categories → complexity-categories",
|
|
267
|
+
r1.ok === false && r1.code === "policy/complexity-categories");
|
|
268
|
+
var r2 = await pol.check("Aaaa1!wxqz");
|
|
269
|
+
check("check: N-identical-run → complexity-run",
|
|
270
|
+
r2.ok === false && r2.code === "policy/complexity-run");
|
|
271
|
+
var r3 = await pol.check("Xabcdef1!q");
|
|
272
|
+
check("check: ascending sequence → complexity-sequence",
|
|
273
|
+
r3.ok === false && r3.code === "policy/complexity-sequence");
|
|
274
|
+
// A password that clears every complexity gate (4 categories, no
|
|
275
|
+
// 3-run, no 3-char sequence) drives the run/sequence scanners through
|
|
276
|
+
// their "not found" return arms and yields ok.
|
|
277
|
+
var r4 = await pol.check("Xk9!mQ2w");
|
|
278
|
+
check("check: complexity all-clear → ok", r4.ok === true);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function testParamsAudit() {
|
|
282
|
+
var p = b.auth.password.params();
|
|
283
|
+
check("params: algorithm is argon2id + meets OWASP floor",
|
|
284
|
+
p.algorithm === "argon2id" && p.meetsFloor === true);
|
|
285
|
+
check("params: active memoryCost matches the 64 MiB default (in KiB)",
|
|
286
|
+
p.active.memoryCostKib === b.constants.BYTES.kib(64));
|
|
287
|
+
check("b.auth.password.OWASP_FLOOR_2026 is the 19 MiB / t2 / p1 floor",
|
|
288
|
+
b.auth.password.OWASP_FLOOR_2026.memoryCostKib === b.constants.BYTES.kib(19) &&
|
|
289
|
+
b.auth.password.OWASP_FLOOR_2026.timeCost === 2 &&
|
|
290
|
+
b.auth.password.OWASP_FLOOR_2026.parallelism === 1);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// ---- HIBP breach check via injected stub ---------------------------
|
|
294
|
+
|
|
295
|
+
// Build a k-anonymity response body: for the target plaintext, place
|
|
296
|
+
// its real SHA-1 suffix into the returned list with `count` sightings,
|
|
297
|
+
// plus a couple of decoy lines. This is exactly the shape HIBP returns.
|
|
298
|
+
function _hibpBodyFor(plaintext, count, extraLines) {
|
|
299
|
+
var full = hibpSha1.sha1Hex(plaintext).toUpperCase();
|
|
300
|
+
var suffix = full.slice(5);
|
|
301
|
+
var lines = ["00000000000000000000000000000000000:3",
|
|
302
|
+
suffix + ":" + count,
|
|
303
|
+
"11111111111111111111111111111111111:9"];
|
|
304
|
+
if (extraLines) lines = lines.concat(extraLines);
|
|
305
|
+
return lines.join("\r\n");
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Run `fn` with httpClient.request replaced by `stub`; always restore.
|
|
309
|
+
async function _withStub(stub, fn) {
|
|
310
|
+
var orig = httpClient.request;
|
|
311
|
+
httpClient.request = stub;
|
|
312
|
+
try { return await fn(); }
|
|
313
|
+
finally { httpClient.request = orig; }
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
async function testBreachCheckMatch() {
|
|
317
|
+
var pol = b.auth.password.policy({ minLength: 4, useBundledCommon: false, breachCheck: "haveibeenpwned" });
|
|
318
|
+
await _withStub(async function () {
|
|
319
|
+
return { statusCode: 200, body: _hibpBodyFor("breached-pw-xyz", 42) };
|
|
320
|
+
}, async function () {
|
|
321
|
+
var r = await pol.check("breached-pw-xyz");
|
|
322
|
+
check("check: plaintext found in HIBP → breached",
|
|
323
|
+
r.ok === false && r.code === "policy/breached");
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
async function testBreachCheckNoMatchAndThreshold() {
|
|
328
|
+
// No matching suffix in the body → ok, breachCheckCount 0.
|
|
329
|
+
var pol = b.auth.password.policy({ minLength: 4, useBundledCommon: false, breachCheck: "haveibeenpwned" });
|
|
330
|
+
await _withStub(async function () {
|
|
331
|
+
return { statusCode: 200, body: "00000000000000000000000000000000000:3\r\n11111111111111111111111111111111111:9" };
|
|
332
|
+
}, async function () {
|
|
333
|
+
var r = await pol.check("unbreached-unique-pw");
|
|
334
|
+
check("check: no HIBP match → ok with breachCheckCount 0",
|
|
335
|
+
r.ok === true && r.breachCheckCount === 0);
|
|
336
|
+
});
|
|
337
|
+
// Suffix present but below breachThreshold → not flagged.
|
|
338
|
+
var polHi = b.auth.password.policy({ minLength: 4, useBundledCommon: false, breachCheck: "haveibeenpwned", breachThreshold: 100 });
|
|
339
|
+
await _withStub(async function () {
|
|
340
|
+
return { statusCode: 200, body: _hibpBodyFor("rare-pw", 5) };
|
|
341
|
+
}, async function () {
|
|
342
|
+
var r = await polHi.check("rare-pw");
|
|
343
|
+
check("check: HIBP count below threshold → ok (not breached)", r.ok === true);
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
async function testBreachCheckNetworkError() {
|
|
348
|
+
// Default (fail-open): a request throw → skip the check, allow.
|
|
349
|
+
var polOpen = b.auth.password.policy({ minLength: 4, useBundledCommon: false, breachCheck: "haveibeenpwned" });
|
|
350
|
+
await _withStub(async function () { throw new Error("ECONNREFUSED simulated"); }, async function () {
|
|
351
|
+
var r = await polOpen.check("some-pw");
|
|
352
|
+
check("check: HIBP request error, fail-open → breachCheckSkipped",
|
|
353
|
+
r.ok === true && r.breachCheckSkipped === true);
|
|
354
|
+
});
|
|
355
|
+
// fail-closed: a request throw → reject.
|
|
356
|
+
var polClosed = b.auth.password.policy({ minLength: 4, useBundledCommon: false, breachCheck: "haveibeenpwned", failClosed: true });
|
|
357
|
+
await _withStub(async function () { throw new Error("ECONNREFUSED simulated"); }, async function () {
|
|
358
|
+
var r = await polClosed.check("some-pw");
|
|
359
|
+
check("check: HIBP request error, fail-closed → breach-check-failed",
|
|
360
|
+
r.ok === false && r.code === "policy/breach-check-failed");
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
async function testBreachCheckBadStatus() {
|
|
365
|
+
// Non-200 (rate limited): fail-open skips, fail-closed rejects.
|
|
366
|
+
var polOpen = b.auth.password.policy({ minLength: 4, useBundledCommon: false, breachCheck: "haveibeenpwned" });
|
|
367
|
+
await _withStub(async function () { return { statusCode: 429, body: "" }; }, async function () {
|
|
368
|
+
var r = await polOpen.check("some-pw");
|
|
369
|
+
check("check: HIBP non-200, fail-open → breachCheckSkipped",
|
|
370
|
+
r.ok === true && r.breachCheckSkipped === true);
|
|
371
|
+
});
|
|
372
|
+
var polClosed = b.auth.password.policy({ minLength: 4, useBundledCommon: false, breachCheck: "haveibeenpwned", failClosed: true });
|
|
373
|
+
await _withStub(async function () { return { statusCode: 503, body: null }; }, async function () {
|
|
374
|
+
var r = await polClosed.check("some-pw");
|
|
375
|
+
check("check: HIBP non-200, fail-closed → breach-check-failed",
|
|
376
|
+
r.ok === false && r.code === "policy/breach-check-failed");
|
|
377
|
+
});
|
|
378
|
+
// 200 with an empty body isolates the `!resp.body` arm (status is
|
|
379
|
+
// fine but there's nothing to scan) — fail-open skips.
|
|
380
|
+
await _withStub(async function () { return { statusCode: 200, body: null }; }, async function () {
|
|
381
|
+
var r = await polOpen.check("some-pw");
|
|
382
|
+
check("check: HIBP 200 with empty body → breachCheckSkipped",
|
|
383
|
+
r.ok === true && r.breachCheckSkipped === true);
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
async function testBreachCheckPoisonedMirror() {
|
|
388
|
+
// A body shaped like HIBP but mostly-unparseable (missing colons /
|
|
389
|
+
// non-numeric counts) must not read as "looks fine". fail-open skips
|
|
390
|
+
// with a reason; fail-closed rejects.
|
|
391
|
+
var poisoned = ["no-colon-line-one", "another-bad-line", "third-bad-line",
|
|
392
|
+
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA:notanumber",
|
|
393
|
+
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:7"].join("\r\n");
|
|
394
|
+
var polOpen = b.auth.password.policy({ minLength: 4, useBundledCommon: false, breachCheck: "haveibeenpwned" });
|
|
395
|
+
await _withStub(async function () { return { statusCode: 200, body: poisoned }; }, async function () {
|
|
396
|
+
var r = await polOpen.check("some-pw");
|
|
397
|
+
check("check: poisoned HIBP mirror, fail-open → skipped w/ reason",
|
|
398
|
+
r.ok === true && r.breachCheckSkipped === true &&
|
|
399
|
+
r.breachCheckSkipReason === "hibp-response-mostly-unparseable");
|
|
400
|
+
});
|
|
401
|
+
var polClosed = b.auth.password.policy({ minLength: 4, useBundledCommon: false, breachCheck: "haveibeenpwned", failClosed: true });
|
|
402
|
+
await _withStub(async function () { return { statusCode: 200, body: poisoned }; }, async function () {
|
|
403
|
+
var r = await polClosed.check("some-pw");
|
|
404
|
+
check("check: poisoned HIBP mirror, fail-closed → breach-check-failed",
|
|
405
|
+
r.ok === false && r.code === "policy/breach-check-failed");
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
async function testBreachCheckEndpointTrailingSlash() {
|
|
410
|
+
// A custom endpoint with trailing slashes must be normalized (the
|
|
411
|
+
// linear backward slash-strip) before "/range/<prefix>" is appended.
|
|
412
|
+
var seenUrl = null;
|
|
413
|
+
var pol = b.auth.password.policy({
|
|
414
|
+
minLength: 4, useBundledCommon: false, breachCheck: "haveibeenpwned",
|
|
415
|
+
hibpEndpoint: "https://api.pwnedpasswords.com///",
|
|
416
|
+
});
|
|
417
|
+
await _withStub(async function (reqOpts) {
|
|
418
|
+
seenUrl = reqOpts.url;
|
|
419
|
+
return { statusCode: 200, body: "00000000000000000000000000000000000:3" };
|
|
420
|
+
}, async function () {
|
|
421
|
+
await pol.check("some-pw");
|
|
422
|
+
check("check: trailing slashes stripped before /range/ appended",
|
|
423
|
+
seenUrl === "https://api.pwnedpasswords.com/range/" + hibpSha1.sha1Hex("some-pw").toUpperCase().slice(0, 5));
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// ---- shouldRotate + reuseProhibited --------------------------------
|
|
428
|
+
|
|
429
|
+
function testShouldRotate() {
|
|
430
|
+
var noRotate = b.auth.password.policy({ minLength: 4, useBundledCommon: false });
|
|
431
|
+
check("shouldRotate: no rotation policy → false",
|
|
432
|
+
noRotate.shouldRotate(Date.now()) === false);
|
|
433
|
+
var pol = b.auth.password.policy({ minLength: 4, useBundledCommon: false, mustRotateAfterMs: b.constants.TIME.days(90) });
|
|
434
|
+
var longAgo = Date.now() - b.constants.TIME.days(200);
|
|
435
|
+
check("shouldRotate: password older than window → true",
|
|
436
|
+
pol.shouldRotate(longAgo) === true);
|
|
437
|
+
check("shouldRotate: fresh password → false",
|
|
438
|
+
pol.shouldRotate(Date.now()) === false);
|
|
439
|
+
// Explicit `now` argument path.
|
|
440
|
+
check("shouldRotate: explicit now arg respected",
|
|
441
|
+
pol.shouldRotate(0, b.constants.TIME.days(91)) === true);
|
|
442
|
+
var threw;
|
|
443
|
+
try { pol.shouldRotate("not-a-timestamp"); } catch (e) { threw = e; }
|
|
444
|
+
check("shouldRotate: non-numeric passwordSetAt throws bad-input",
|
|
445
|
+
threw && threw.code === "auth-password/bad-input");
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
async function testReuseProhibited() {
|
|
449
|
+
var pol = b.auth.password.policy({ minLength: 4, useBundledCommon: false, historyMinDistance: 4 });
|
|
450
|
+
var stored = await b.auth.password.hash("old-password-1", FAST);
|
|
451
|
+
check("reuseProhibited: candidate matches a stored history hash → true",
|
|
452
|
+
(await pol.reuseProhibited("old-password-1", [stored])) === true);
|
|
453
|
+
check("reuseProhibited: candidate absent from history → false",
|
|
454
|
+
(await pol.reuseProhibited("brand-new-pw", [stored])) === false);
|
|
455
|
+
// Non-argon2id history entry is skipped safely (returns false there).
|
|
456
|
+
check("reuseProhibited: non-argon2id history entry ignored → false",
|
|
457
|
+
(await pol.reuseProhibited("whatever", ["$argon2i$garbage"])) === false);
|
|
458
|
+
// Empty plaintext short-circuits false.
|
|
459
|
+
check("reuseProhibited: empty candidate → false",
|
|
460
|
+
(await pol.reuseProhibited("", [stored])) === false);
|
|
461
|
+
// Empty / non-array history short-circuits false.
|
|
462
|
+
check("reuseProhibited: empty history → false",
|
|
463
|
+
(await pol.reuseProhibited("old-password-1", [])) === false);
|
|
464
|
+
// history-distance disabled short-circuits false regardless of match.
|
|
465
|
+
var polOff = b.auth.password.policy({ minLength: 4, useBundledCommon: false });
|
|
466
|
+
check("reuseProhibited: history disabled → false",
|
|
467
|
+
(await polOff.reuseProhibited("old-password-1", [stored])) === false);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
async function run() {
|
|
471
|
+
await testHashVerifyRoundtrip();
|
|
472
|
+
await testHashRejectsBadPlain();
|
|
473
|
+
await testHashRejectsBadParams();
|
|
474
|
+
await testVerifyDefensiveReturnsFalse();
|
|
475
|
+
await testNeedsRehash();
|
|
476
|
+
await testGate();
|
|
477
|
+
await testConcurrencySemaphoreQueue();
|
|
478
|
+
testPolicyConstructionRejects();
|
|
479
|
+
testPolicyProfilesApply();
|
|
480
|
+
await testCheckLengthAndTypeGates();
|
|
481
|
+
await testCheckCommonAndDictionary();
|
|
482
|
+
await testCheckContextSubstrings();
|
|
483
|
+
await testCheckComplexity();
|
|
484
|
+
testParamsAudit();
|
|
485
|
+
await testBreachCheckMatch();
|
|
486
|
+
await testBreachCheckNoMatchAndThreshold();
|
|
487
|
+
await testBreachCheckNetworkError();
|
|
488
|
+
await testBreachCheckBadStatus();
|
|
489
|
+
await testBreachCheckPoisonedMirror();
|
|
490
|
+
await testBreachCheckEndpointTrailingSlash();
|
|
491
|
+
testShouldRotate();
|
|
492
|
+
await testReuseProhibited();
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
module.exports = { run: run };
|
|
496
|
+
|
|
497
|
+
if (require.main === module) {
|
|
498
|
+
run().then(function () { console.log("OK"); })
|
|
499
|
+
.catch(function (e) { console.error(e.stack || e); process.exit(1); });
|
|
500
|
+
}
|