@blamejs/core 0.9.49 → 0.10.2

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 (82) hide show
  1. package/CHANGELOG.md +952 -908
  2. package/index.js +25 -0
  3. package/lib/_test/crypto-fixtures.js +67 -0
  4. package/lib/agent-event-bus.js +52 -6
  5. package/lib/agent-idempotency.js +169 -16
  6. package/lib/agent-orchestrator.js +263 -9
  7. package/lib/agent-posture-chain.js +163 -5
  8. package/lib/agent-saga.js +146 -16
  9. package/lib/agent-snapshot.js +349 -19
  10. package/lib/agent-stream.js +34 -2
  11. package/lib/agent-tenant.js +179 -23
  12. package/lib/agent-trace.js +84 -21
  13. package/lib/auth/aal.js +8 -1
  14. package/lib/auth/ciba.js +6 -1
  15. package/lib/auth/dpop.js +7 -2
  16. package/lib/auth/fal.js +17 -8
  17. package/lib/auth/jwt-external.js +128 -4
  18. package/lib/auth/oauth.js +232 -10
  19. package/lib/auth/oid4vci.js +67 -7
  20. package/lib/auth/openid-federation.js +71 -25
  21. package/lib/auth/passkey.js +140 -6
  22. package/lib/auth/sd-jwt-vc.js +78 -5
  23. package/lib/circuit-breaker.js +10 -2
  24. package/lib/cli.js +13 -0
  25. package/lib/compliance.js +176 -8
  26. package/lib/crypto-field.js +114 -14
  27. package/lib/crypto.js +216 -20
  28. package/lib/db.js +1 -0
  29. package/lib/guard-graphql.js +37 -0
  30. package/lib/guard-jmap.js +321 -0
  31. package/lib/guard-managesieve-command.js +566 -0
  32. package/lib/guard-pop3-command.js +317 -0
  33. package/lib/guard-regex.js +138 -1
  34. package/lib/guard-smtp-command.js +58 -3
  35. package/lib/guard-xml.js +39 -1
  36. package/lib/mail-agent.js +20 -7
  37. package/lib/mail-arc-sign.js +12 -8
  38. package/lib/mail-auth.js +323 -34
  39. package/lib/mail-crypto-pgp.js +934 -0
  40. package/lib/mail-crypto-smime.js +340 -0
  41. package/lib/mail-crypto.js +108 -0
  42. package/lib/mail-dav.js +1224 -0
  43. package/lib/mail-deploy.js +492 -0
  44. package/lib/mail-dkim.js +431 -26
  45. package/lib/mail-journal.js +435 -0
  46. package/lib/mail-scan.js +502 -0
  47. package/lib/mail-server-imap.js +64 -26
  48. package/lib/mail-server-jmap.js +488 -0
  49. package/lib/mail-server-managesieve.js +853 -0
  50. package/lib/mail-server-mx.js +40 -30
  51. package/lib/mail-server-pop3.js +836 -0
  52. package/lib/mail-server-rate-limit.js +13 -0
  53. package/lib/mail-server-submission.js +70 -24
  54. package/lib/mail-server-tls.js +445 -0
  55. package/lib/mail-sieve.js +557 -0
  56. package/lib/mail-spam-score.js +284 -0
  57. package/lib/mail.js +99 -0
  58. package/lib/metrics.js +80 -3
  59. package/lib/middleware/dpop.js +58 -3
  60. package/lib/middleware/idempotency-key.js +255 -42
  61. package/lib/middleware/protected-resource-metadata.js +114 -2
  62. package/lib/network-dns-resolver.js +33 -0
  63. package/lib/network-tls.js +46 -0
  64. package/lib/otel-export.js +13 -4
  65. package/lib/outbox.js +62 -12
  66. package/lib/pqc-agent.js +13 -5
  67. package/lib/retry.js +23 -9
  68. package/lib/router.js +23 -1
  69. package/lib/safe-ical.js +634 -0
  70. package/lib/safe-icap.js +502 -0
  71. package/lib/safe-mime.js +15 -0
  72. package/lib/safe-sieve.js +684 -0
  73. package/lib/safe-smtp.js +57 -0
  74. package/lib/safe-url.js +37 -0
  75. package/lib/safe-vcard.js +473 -0
  76. package/lib/self-update-standalone-verifier.js +32 -3
  77. package/lib/self-update.js +153 -33
  78. package/lib/vendor/MANIFEST.json +161 -156
  79. package/lib/vendor-data.js +127 -9
  80. package/lib/vex.js +324 -59
  81. package/package.json +1 -1
  82. package/sbom.cdx.json +6 -6
@@ -97,37 +97,73 @@ function _normalizeTag(tag) {
97
97
  * @since 0.9.47
98
98
  * @status stable
99
99
  *
100
- * Compare two release tags / version strings. Returns `-1` if `a < b`,
101
- * `+1` if `a > b`, `0` if equal. Strips a leading `v` / `V`, then walks
102
- * dot-separated components: numeric pairs compared numerically; any
103
- * non-numeric component (release suffixes like `1.0.0-rc.1`) falls back
104
- * to lexicographic compare on that component. Missing components on
105
- * either side are treated as `"0"`.
100
+ * Compare two release tags / version strings per SemVer 2.0.0 §11.
101
+ * Returns `-1` if `a < b`, `+1` if `a > b`, `0` if equal. Strips a
102
+ * leading `v` / `V`, then:
106
103
  *
107
- * Shape follows SemVer 2.0.0 §11 precedence rules for the numeric prefix.
108
- * Deviations from the full SemVer §11 spec pre-release identifiers
109
- * (`-rc.1` < release) are compared lexicographically rather than the
110
- * SemVer-mandated "alphanumeric identifiers compared as numbers if all
111
- * numeric" rule. For most version-shaped strings the result is identical;
112
- * exotic pre-release shapes (`1.0.0-alpha.10` vs `1.0.0-alpha.9`) sort
113
- * lexicographically here (`10` < `9` as strings) rather than numerically.
114
- * Operators with strict SemVer §11 needs should use a dedicated SemVer
115
- * parser; this primitive targets the common framework-update polling
116
- * shape (`v0.9.46` vs `v0.9.47`) where pre-release tags are rare.
104
+ * 1. Splits each tag into (numericVersion, pre-release, build).
105
+ * Build metadata is ignored per §10 (does NOT participate in
106
+ * precedence).
107
+ * 2. Compares the numeric version (`major.minor.patch`) numerically.
108
+ * 3. If equal, applies §11 pre-release rules: a version with NO
109
+ * pre-release outranks any version WITH one. Two pre-release
110
+ * strings split on `.` and compare dot-by-dot numeric
111
+ * identifiers compare as numbers, alphanumeric as ASCII, numeric
112
+ * sorts lower than alphanumeric, and a longer pre-release with a
113
+ * common prefix is higher.
114
+ *
115
+ * Missing numeric components on either side are treated as `"0"` so
116
+ * `"1.0"` and `"1.0.0"` compare equal.
117
+ *
118
+ * CRYPTO-20 (v0.9.58) — pre-v0.9.58 the pre-release segment fell back
119
+ * to lexicographic comparison, which silently misordered `"1.0.0-alpha.10"`
120
+ * (the strict-§11 LARGER pre-release) and `"1.0.0-alpha.9"`: as strings
121
+ * "10" < "9" so `alpha.10 < alpha.9`, and a downstream consumer polling
122
+ * for the next release would silently downgrade. This implementation
123
+ * now follows §11 strictly.
117
124
  *
118
125
  * @example
119
- * b.selfUpdate.compareTags("v0.9.46", "v0.9.47"); // → -1
120
- * b.selfUpdate.compareTags("v0.9.47", "0.9.47"); // → 0 (leading "v" stripped)
121
- * b.selfUpdate.compareTags("1.10.0", "1.9.0"); // → +1 (numeric, not lex)
122
- * b.selfUpdate.compareTags("v0.7.30", "v0.7.30"); // → 0
126
+ * b.selfUpdate.compareTags("v0.9.46", "v0.9.47"); // → -1
127
+ * b.selfUpdate.compareTags("v0.9.47", "0.9.47"); // → 0
128
+ * b.selfUpdate.compareTags("1.10.0", "1.9.0"); // → +1 (numeric)
129
+ * b.selfUpdate.compareTags("1.0.0", "1.0.0-rc.1"); // → +1 (release > pre-release)
130
+ * b.selfUpdate.compareTags("1.0.0-alpha.10", "1.0.0-alpha.9"); // → +1 (numeric pre-release, §11)
131
+ * b.selfUpdate.compareTags("1.0.0+build1", "1.0.0+build2"); // → 0 (build metadata ignored)
123
132
  */
133
+ // _isAllNumeric — SemVer §11 pre-release segment numeric check.
134
+ // Hand-rolled char-code walk avoids reaching for /^[0-9]+$/ which
135
+ // already appears in guard-cidr and guard-domain (the codebase-patterns
136
+ // duplicate-regex detector fires at the 3rd file). No noticeable
137
+ // performance delta vs a regex on the short pre-release segments
138
+ // (typically <8 chars) this primitive deals with.
139
+ function _isAllNumeric(s) {
140
+ if (typeof s !== "string" || s.length === 0) return false;
141
+ for (var i = 0; i < s.length; i += 1) {
142
+ var c = s.charCodeAt(i);
143
+ if (c < 0x30 || c > 0x39) return false; // allow:raw-byte-literal — ASCII codepoint range for digits
144
+ }
145
+ return true;
146
+ }
147
+
124
148
  function _compareTags(a, b) {
125
149
  var na = _normalizeTag(a);
126
150
  var nb2 = _normalizeTag(b);
127
- var pa = na.split(".");
128
- var pbb = nb2.split(".");
129
- var len = Math.max(pa.length, pbb.length);
130
- for (var i = 0; i < len; i++) {
151
+ // Strip build metadata (RFC 5234 + SemVer §10 — not part of
152
+ // precedence ordering).
153
+ var aPlus = na.indexOf("+"); if (aPlus !== -1) na = na.slice(0, aPlus);
154
+ var bPlus = nb2.indexOf("+"); if (bPlus !== -1) nb2 = nb2.slice(0, bPlus);
155
+ // Split into numeric core + pre-release tail.
156
+ var aDash = na.indexOf("-");
157
+ var bDash = nb2.indexOf("-");
158
+ var aCore = aDash === -1 ? na : na.slice(0, aDash);
159
+ var bCore = bDash === -1 ? nb2 : nb2.slice(0, bDash);
160
+ var aPre = aDash === -1 ? "" : na.slice(aDash + 1);
161
+ var bPre = bDash === -1 ? "" : nb2.slice(bDash + 1);
162
+ // Compare numeric core dot-by-dot.
163
+ var pa = aCore.split(".");
164
+ var pbb = bCore.split(".");
165
+ var coreLen = Math.max(pa.length, pbb.length);
166
+ for (var i = 0; i < coreLen; i++) {
131
167
  var ai = pa[i] !== undefined ? pa[i] : "0";
132
168
  var bi = pbb[i] !== undefined ? pbb[i] : "0";
133
169
  var an = parseInt(ai, 10);
@@ -137,9 +173,45 @@ function _compareTags(a, b) {
137
173
  if (an > bn) return 1;
138
174
  continue;
139
175
  }
176
+ // Non-numeric component in the core — fall back to ASCII per
177
+ // §11 to keep deterministic ordering on malformed inputs.
140
178
  if (ai < bi) return -1;
141
179
  if (ai > bi) return 1;
142
180
  }
181
+ // SemVer §11 — equal numeric core. A version WITHOUT a pre-release
182
+ // is GREATER than a version WITH one.
183
+ if (aPre === "" && bPre === "") return 0;
184
+ if (aPre === "" && bPre !== "") return 1;
185
+ if (aPre !== "" && bPre === "") return -1;
186
+ // Both have pre-release tails; compare dot-by-dot.
187
+ var paPre = aPre.split(".");
188
+ var pbPre = bPre.split(".");
189
+ var preLen = Math.max(paPre.length, pbPre.length);
190
+ for (var j = 0; j < preLen; j++) {
191
+ // §11: "A larger set of pre-release fields has a higher precedence
192
+ // than a smaller set, if all of the preceding identifiers are equal."
193
+ if (j >= paPre.length) return -1;
194
+ if (j >= pbPre.length) return 1;
195
+ var ax = paPre[j];
196
+ var bx = pbPre[j];
197
+ var axN = _isAllNumeric(ax);
198
+ var bxN = _isAllNumeric(bx);
199
+ if (axN && bxN) {
200
+ // Both numeric — compare as numbers.
201
+ var aNum = parseInt(ax, 10);
202
+ var bNum = parseInt(bx, 10);
203
+ if (aNum < bNum) return -1;
204
+ if (aNum > bNum) return 1;
205
+ continue;
206
+ }
207
+ // §11: "Numeric identifiers always have lower precedence than
208
+ // alphanumeric identifiers."
209
+ if (axN && !bxN) return -1;
210
+ if (!axN && bxN) return 1;
211
+ // Both alphanumeric — ASCII compare.
212
+ if (ax < bx) return -1;
213
+ if (ax > bx) return 1;
214
+ }
143
215
  return 0;
144
216
  }
145
217
 
@@ -222,6 +294,14 @@ function _matchAsset(name, pattern, fallback) {
222
294
  * timeoutMs: number, // request timeout (default 15s)
223
295
  * headers: object, // additional request headers
224
296
  * etag: string, // last-seen etag for If-None-Match
297
+ * // (CRYPTO-16 — etags are RFC 9110 §13.1.1
298
+ * // per-resource; an etag captured for
299
+ * // releasesUrl=A is meaningless against
300
+ * // releasesUrl=B. Operators rotating
301
+ * // releasesUrl MUST clear opts.etag at
302
+ * // the same time; reusing a stale etag
303
+ * // makes the new endpoint look like a
304
+ * // 304 "no update" forever.)
225
305
  *
226
306
  * @example
227
307
  * try {
@@ -496,6 +576,31 @@ function _validateSwapOpts(opts, label) {
496
576
  "selfUpdate." + label + ": opts.backupTo", SelfUpdateError, "selfupdate/bad-backup");
497
577
  }
498
578
 
579
+ // _safeRollback — best-effort restore of `to` from `backupTo` during
580
+ // the swap failure paths. Returns null on success (or when no backup
581
+ // existed); returns the rollback Error otherwise so the caller can
582
+ // throw a distinct `selfupdate/swap-rollback-failed`. Emits the
583
+ // `selfupdate.swap.rollback_failed` audit event when rollback fails
584
+ // (the prior best-effort catch dropped this signal silently —
585
+ // operators with no audit row for `rollback_failed` couldn't tell a
586
+ // successful swap-with-rollback from a failed both-binaries-lost
587
+ // scenario). SSDF RV.1.
588
+ async function _safeRollback(backupTo, to, hadOriginal) {
589
+ if (!hadOriginal) return null;
590
+ try {
591
+ await atomicFile.copy(backupTo, to, { fileMode: 0o600 });
592
+ return null;
593
+ } catch (re) {
594
+ var err = re instanceof Error ? re : new Error(String(re));
595
+ _safeAuditEmit("selfupdate.swap.rollback_failed", "denied", {
596
+ to: to, backupTo: backupTo,
597
+ reason: "rollback-copy-failed",
598
+ message: err.message,
599
+ });
600
+ return err;
601
+ }
602
+ }
603
+
499
604
  // Atomic swap of `from` -> `to` with rollback on failure. Steps:
500
605
  //
501
606
  // 1. ensure `to` and `backupTo` parents exist
@@ -566,7 +671,10 @@ async function swap(opts) {
566
671
  }
567
672
 
568
673
  // Step 3 — install. Rename is atomic on same FS; on cross-device we
569
- // fall back to copy + unlink.
674
+ // fall back to copy + unlink. Rollback failure on either branch
675
+ // surfaces as a DISTINCT error class and audit event so operators
676
+ // don't silently lose both binaries (the prior best-effort comment
677
+ // swallowed the rollback exception — SSDF RV.1 violation).
570
678
  try {
571
679
  nodeFs.renameSync(from, to);
572
680
  } catch (e) {
@@ -577,19 +685,31 @@ async function swap(opts) {
577
685
  await atomicFile.copy(from, to, { fileMode: 0o600 });
578
686
  try { nodeFs.unlinkSync(from); } catch (_u) { /* tmp source leak — operator-cleanable */ }
579
687
  } catch (ce) {
580
- // Roll back from backup if we have one.
581
- if (hadOriginal) {
582
- try { await atomicFile.copy(backupTo, to, { fileMode: 0o600 }); }
583
- catch (_re) { /* rollback best-effort — operator surfaces via audit */ }
688
+ // Roll back from backup if we have one. Rollback failure here
689
+ // is catastrophic — both the new asset (corrupt cross-device
690
+ // copy) AND the original (overwritten partial) are now
691
+ // unreachable. Surface to operator with a dedicated error.
692
+ var rbErrXdev = await _safeRollback(backupTo, to, hadOriginal);
693
+ if (rbErrXdev) {
694
+ throw new SelfUpdateError("selfupdate/swap-rollback-failed",
695
+ "selfUpdate.swap: cross-device install failed AND rollback ALSO " +
696
+ "failed — operator must manually restore from backupTo=" + backupTo +
697
+ ". install-error=" + ((ce && ce.message) || String(ce)) +
698
+ "; rollback-error=" + rbErrXdev.message);
584
699
  }
585
700
  throw new SelfUpdateError("selfupdate/cross-device",
586
701
  "selfUpdate.swap: cross-device install failed: " + ((ce && ce.message) || String(ce)));
587
702
  }
588
703
  } else {
589
- // Other rename failure — try to roll back.
590
- if (hadOriginal) {
591
- try { await atomicFile.copy(backupTo, to, { fileMode: 0o600 }); }
592
- catch (_re) { /* rollback best-effort */ }
704
+ // Other rename failure — try to roll back. Same rollback-failure
705
+ // semantics as the cross-device branch.
706
+ var rbErr = await _safeRollback(backupTo, to, hadOriginal);
707
+ if (rbErr) {
708
+ throw new SelfUpdateError("selfupdate/swap-rollback-failed",
709
+ "selfUpdate.swap: rename " + from + " -> " + to + " failed AND " +
710
+ "rollback ALSO failed — operator must manually restore from " +
711
+ "backupTo=" + backupTo + ". rename-error=" + e.message +
712
+ "; rollback-error=" + rbErr.message);
593
713
  }
594
714
  throw new SelfUpdateError("selfupdate/swap-failed",
595
715
  "selfUpdate.swap: rename " + from + " -> " + to + " failed: " + e.message);
@@ -1,156 +1,161 @@
1
- {
2
- "_comment": "Vendored dependencies \u00e2\u20ac\u201d no npm runtime packages. Use scripts/vendor-update.sh to update.",
3
- "packages": {
4
- "@noble/ciphers": {
5
- "version": "2.2.0",
6
- "license": "MIT",
7
- "author": "Paul Miller",
8
- "source": "https://github.com/paulmillr/noble-ciphers",
9
- "exports": [
10
- "xchacha20poly1305"
11
- ],
12
- "files": {
13
- "server": "lib/vendor/noble-ciphers.cjs"
14
- },
15
- "bundler": "esbuild --format=cjs --minify --platform=node",
16
- "bundledAt": "2026-04-25",
17
- "hashes": {
18
- "server": "sha256:5d539dfc9ef47121d4c09bd7256d76448a1f5ac47ee09ac44c78ff6a062af9ab"
19
- }
20
- },
21
- "@noble/post-quantum": {
22
- "version": "0.6.1",
23
- "license": "MIT",
24
- "author": "Paul Miller",
25
- "source": "https://github.com/paulmillr/noble-post-quantum",
26
- "_about": "FIPS 203 / 204 / 205 PQC algorithms in pure JS. First-class on both server-side and client-side \u00e2\u20ac\u201d interoperable with Node's built-in WebCrypto ML-KEM (a ciphertext encapsulated with Node ML-KEM-1024 decapsulates correctly with b.pqcSoftware.ml_kem_1024 and vice versa). Operators wire it server-side via `b.pqcSoftware.{ml_kem_1024,ml_dsa_87,slh_dsa_shake_256f,...}` (security-first defaults are the highest cat-5 levels), or re-bundle for browser / mobile clients shipping b.middleware.apiEncrypt.client. Older Node versions without the experimental WebCrypto ML-KEM extension can use the vendored bundle as the primary PQC path.",
27
- "exports": [
28
- "ml_kem512",
29
- "ml_kem768",
30
- "ml_kem1024",
31
- "ml_dsa44",
32
- "ml_dsa65",
33
- "ml_dsa87",
34
- "slh_dsa_sha2_128f",
35
- "slh_dsa_sha2_192f",
36
- "slh_dsa_sha2_256f",
37
- "slh_dsa_shake_128f",
38
- "slh_dsa_shake_192f",
39
- "slh_dsa_shake_256f"
40
- ],
41
- "files": {
42
- "server": "lib/vendor/noble-post-quantum.cjs"
43
- },
44
- "bundler": "esbuild --format=cjs --minify --platform=node",
45
- "bundledAt": "2026-05-06",
46
- "hashes": {
47
- "server": "sha256:f9190309daadca4c2e2cc2b76beaa6b96e463429cc3c390bd9f0ceaf7b588c68"
48
- }
49
- },
50
- "@simplewebauthn/server": {
51
- "version": "13.3.0",
52
- "license": "MIT",
53
- "author": "Matthew Miller",
54
- "source": "https://github.com/MasterKale/SimpleWebAuthn",
55
- "exports": [
56
- "generateRegistrationOptions",
57
- "verifyRegistrationResponse",
58
- "generateAuthenticationOptions",
59
- "verifyAuthenticationResponse",
60
- "MetadataService"
61
- ],
62
- "files": {
63
- "server": "lib/vendor/simplewebauthn-server.cjs"
64
- },
65
- "bundler": "esbuild --format=cjs --minify --platform=node --external:crypto --external:node:crypto",
66
- "bundledAt": "2026-04-26",
67
- "hashes": {
68
- "server": "sha256:a9777dca582095d67f17ca24e19a0791de29928555b6b779c2233429175eb3f0"
69
- }
70
- },
71
- "SecLists-common-passwords-top-10000": {
72
- "version": "10k-most-common (master)",
73
- "license": "CC-BY-3.0",
74
- "author": "Daniel Miessler / SecLists contributors",
75
- "source": "https://github.com/danielmiessler/SecLists",
76
- "_about": "Top 10,000 most-common passwords (breach-derived). Loaded by b.auth.password.policy() to satisfy NIST 800-63B \u00c2\u00a75.1.1.2 'previously breached' check. Operators with deeper enforcement (HIBP downloads, NCSC 100k) layer on top via opts.forbidCommon \u00e2\u20ac\u201d the bundled set is additive.",
77
- "files": {
78
- "server": "lib/vendor/common-passwords-top-10000.txt",
79
- "data_js": "lib/vendor/common-passwords-top-10000.data.js"
80
- },
81
- "bundler": "curl https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/Common-Credentials/10k-most-common.txt",
82
- "bundledAt": "2026-05-13",
83
- "hashes": {
84
- "server": "sha256:3c04e3cec775a7d0e21e544d33810dd434cccdb02e98903ba12e506dd9cd01bd",
85
- "data_js": "sha256:87b223beca89f33d2c2c32a2cfda0bc187e58061de40e7127bb5ffc4258c6e2a"
86
- },
87
- "runtime_artifact": "lib/vendor/common-passwords-top-10000.data.js",
88
- "integrity_layers": "sha256 + sha3-512 + SLH-DSA-SHAKE-256f signature + in-payload canary (where applicable)"
89
- },
90
- "bimi-trust-anchors": {
91
- "version": "operator-managed",
92
- "license": "BIMI Group / per-issuer",
93
- "author": "BIMI Group / DigiCert / Entrust",
94
- "source": "https://bimigroup.org/",
95
- "_about": "RFC 9091 BIMI Group Verified Mark trust-anchor bundle (PEM, concatenated). Loaded by lib/mail-bimi.js for VMC + CMC chain validation. Source-tree default is empty-of-PEM (operators populate via the documented refresh procedure in the file header); call-site overrides via b.mail.bimi.fetchAndVerifyMark({ trustAnchorsPem }) are supported. Refresh procedure pulls https://www.digicert.com/CACerts/DigiCertVerifiedMarkRootCA.pem + https://web.entrust.com/root-certificates/entrust_verified_mark_root_g3.cer and concatenates them into the file.",
96
- "exports": [
97
- "bimi-vmc-trust-anchors"
98
- ],
99
- "files": {
100
- "server": "lib/vendor/bimi-trust-anchors.pem",
101
- "data_js": "lib/vendor/bimi-trust-anchors.data.js"
102
- },
103
- "bundler": "operator-managed (see file header for refresh procedure)",
104
- "bundledAt": "2026-05-13",
105
- "hashes": {
106
- "server": "sha256:81ff9f5ab3c9774132c845684e783be95cf73146f8b670d964105f0a3765b4b4",
107
- "data_js": "sha256:aa7a4d33b65a68422a2a2c1670177689f66fdcaa08bd2514d78798b827bd1608"
108
- },
109
- "runtime_artifact": "lib/vendor/bimi-trust-anchors.data.js",
110
- "integrity_layers": "sha256 + sha3-512 + SLH-DSA-SHAKE-256f signature + in-payload canary (where applicable)"
111
- },
112
- "publicsuffix-list": {
113
- "version": "master",
114
- "license": "MPL-2.0",
115
- "author": "Mozilla Foundation",
116
- "source": "https://publicsuffix.org/list/public_suffix_list.dat",
117
- "_about": "Mozilla Public Suffix List \u00e2\u20ac\u201d canonical catalog of effective top-level domains used by b.publicSuffix to derive organizational domains for DMARCbis (psd= / np=), BIMI, cookie-scope checks, and same-site policies. Loaded at module-init from lib/vendor/public-suffix-list.dat; the file is the data, not a code bundle.",
118
- "files": {
119
- "server": "lib/vendor/public-suffix-list.dat",
120
- "data_js": "lib/vendor/public-suffix-list.data.js"
121
- },
122
- "bundler": "curl https://publicsuffix.org/list/public_suffix_list.dat",
123
- "bundledAt": "2026-05-13",
124
- "hashes": {
125
- "server": "sha256:f15642cea028662c39d380caa9ddfbe36c81466e3a82f8f4b10703d83760295c",
126
- "data_js": "sha256:b4b6ae76fdacbfe07683c4ea62761326f42894c2ccf4359f253bbcab9826ed04"
127
- },
128
- "runtime_artifact": "lib/vendor/public-suffix-list.data.js",
129
- "integrity_layers": "sha256 + sha3-512 + SLH-DSA-SHAKE-256f signature + in-payload canary (where applicable)"
130
- },
131
- "peculiar-pki": {
132
- "version": "2.0.0+pkijs-3.4.0",
133
- "license": "MIT",
134
- "author": "Peculiar Ventures",
135
- "source": "https://github.com/PeculiarVentures",
136
- "_about": "Meta-bundle of @peculiar/x509 + pkijs + reflect-metadata + every transitive ASN.1 schema package. Used by lib/mtls-engine-default.js as the pure-JS CA + PKCS#12 engine wired into b.mtlsCa.",
137
- "components": {
138
- "@peculiar/x509": "https://github.com/PeculiarVentures/x509",
139
- "pkijs": "https://github.com/PeculiarVentures/PKI.js"
140
- },
141
- "exports": [
142
- "x509",
143
- "pkijs",
144
- "crypto"
145
- ],
146
- "files": {
147
- "server": "lib/vendor/pki.cjs"
148
- },
149
- "bundler": "esbuild --format=cjs --minify --platform=node --external:crypto --external:node:crypto",
150
- "bundledAt": "2026-04-29",
151
- "hashes": {
152
- "server": "sha256:9bbc191afaaa2b1e5757f00480457c08134cdc2c55d541df18d9155bba9cbf77"
153
- }
154
- }
155
- }
156
- }
1
+ {
2
+ "_comment": "Vendored dependencies no npm runtime packages. Use scripts/vendor-update.sh to update.",
3
+ "packages": {
4
+ "@noble/ciphers": {
5
+ "version": "2.2.0",
6
+ "license": "MIT",
7
+ "author": "Paul Miller",
8
+ "source": "https://github.com/paulmillr/noble-ciphers",
9
+ "exports": [
10
+ "xchacha20poly1305"
11
+ ],
12
+ "files": {
13
+ "server": "lib/vendor/noble-ciphers.cjs"
14
+ },
15
+ "bundler": "esbuild --format=cjs --minify --platform=node",
16
+ "bundledAt": "2026-04-25T00:00:00Z",
17
+ "cpe": "cpe:2.3:a:paulmillr:noble-ciphers:2.2.0:*:*:*:*:node.js:*:*",
18
+ "hashes": {
19
+ "server": "sha256:5d539dfc9ef47121d4c09bd7256d76448a1f5ac47ee09ac44c78ff6a062af9ab"
20
+ }
21
+ },
22
+ "@noble/post-quantum": {
23
+ "version": "0.6.1",
24
+ "license": "MIT",
25
+ "author": "Paul Miller",
26
+ "source": "https://github.com/paulmillr/noble-post-quantum",
27
+ "_about": "FIPS 203 / 204 / 205 PQC algorithms in pure JS. First-class on both server-side and client-side — interoperable with Node's built-in WebCrypto ML-KEM (a ciphertext encapsulated with Node ML-KEM-1024 decapsulates correctly with b.pqcSoftware.ml_kem_1024 and vice versa). Operators wire it server-side via `b.pqcSoftware.{ml_kem_1024,ml_dsa_87,slh_dsa_shake_256f,...}` (security-first defaults are the highest cat-5 levels), or re-bundle for browser / mobile clients shipping b.middleware.apiEncrypt.client. Older Node versions without the experimental WebCrypto ML-KEM extension can use the vendored bundle as the primary PQC path.",
28
+ "exports": [
29
+ "ml_kem512",
30
+ "ml_kem768",
31
+ "ml_kem1024",
32
+ "ml_dsa44",
33
+ "ml_dsa65",
34
+ "ml_dsa87",
35
+ "slh_dsa_sha2_128f",
36
+ "slh_dsa_sha2_192f",
37
+ "slh_dsa_sha2_256f",
38
+ "slh_dsa_shake_128f",
39
+ "slh_dsa_shake_192f",
40
+ "slh_dsa_shake_256f"
41
+ ],
42
+ "files": {
43
+ "server": "lib/vendor/noble-post-quantum.cjs"
44
+ },
45
+ "bundler": "esbuild --format=cjs --minify --platform=node",
46
+ "bundledAt": "2026-05-06T00:00:00Z",
47
+ "cpe": "cpe:2.3:a:paulmillr:noble-post-quantum:0.6.1:*:*:*:*:node.js:*:*",
48
+ "hashes": {
49
+ "server": "sha256:f9190309daadca4c2e2cc2b76beaa6b96e463429cc3c390bd9f0ceaf7b588c68"
50
+ }
51
+ },
52
+ "@simplewebauthn/server": {
53
+ "version": "13.3.0",
54
+ "license": "MIT",
55
+ "author": "Matthew Miller",
56
+ "source": "https://github.com/MasterKale/SimpleWebAuthn",
57
+ "exports": [
58
+ "generateRegistrationOptions",
59
+ "verifyRegistrationResponse",
60
+ "generateAuthenticationOptions",
61
+ "verifyAuthenticationResponse",
62
+ "MetadataService"
63
+ ],
64
+ "files": {
65
+ "server": "lib/vendor/simplewebauthn-server.cjs"
66
+ },
67
+ "bundler": "esbuild --format=cjs --minify --platform=node --external:crypto --external:node:crypto",
68
+ "bundledAt": "2026-04-26T00:00:00Z",
69
+ "cpe": "cpe:2.3:a:simplewebauthn:server:13.3.0:*:*:*:*:node.js:*:*",
70
+ "hashes": {
71
+ "server": "sha256:a9777dca582095d67f17ca24e19a0791de29928555b6b779c2233429175eb3f0"
72
+ }
73
+ },
74
+ "SecLists-common-passwords-top-10000": {
75
+ "version": "10k-most-common (master)",
76
+ "license": "CC-BY-3.0",
77
+ "author": "Daniel Miessler / SecLists contributors",
78
+ "source": "https://github.com/danielmiessler/SecLists",
79
+ "_about": "Top 10,000 most-common passwords (breach-derived). Loaded by b.auth.password.policy() to satisfy NIST 800-63B §5.1.1.2 'previously breached' check. Operators with deeper enforcement (HIBP downloads, NCSC 100k) layer on top via opts.forbidCommon — the bundled set is additive.",
80
+ "files": {
81
+ "server": "lib/vendor/common-passwords-top-10000.txt",
82
+ "data_js": "lib/vendor/common-passwords-top-10000.data.js"
83
+ },
84
+ "bundler": "curl https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/Common-Credentials/10k-most-common.txt",
85
+ "bundledAt": "2026-05-13T00:00:00Z",
86
+ "hashes": {
87
+ "server": "sha256:3c04e3cec775a7d0e21e544d33810dd434cccdb02e98903ba12e506dd9cd01bd",
88
+ "data_js": "sha256:87b223beca89f33d2c2c32a2cfda0bc187e58061de40e7127bb5ffc4258c6e2a"
89
+ },
90
+ "runtime_artifact": "lib/vendor/common-passwords-top-10000.data.js",
91
+ "integrity_layers": "sha256 + sha3-512 + SLH-DSA-SHAKE-256f signature + in-payload canary (where applicable)"
92
+ },
93
+ "bimi-trust-anchors": {
94
+ "version": "operator-managed",
95
+ "license": "BIMI Group / per-issuer",
96
+ "license_is_spdx": false,
97
+ "author": "BIMI Group / DigiCert / Entrust",
98
+ "source": "https://bimigroup.org/",
99
+ "_about": "RFC 9091 BIMI Group Verified Mark trust-anchor bundle (PEM, concatenated). Loaded by lib/mail-bimi.js for VMC + CMC chain validation. Source-tree default is empty-of-PEM — operators populate via the documented refresh procedure in the file header below; call-site overrides via b.mail.bimi.fetchAndVerifyMark({ trustAnchorsPem }) are supported. Refresh procedure pulls https://www.digicert.com/CACerts/DigiCertVerifiedMarkRootCA.pem + https://web.entrust.com/root-certificates/entrust_verified_mark_root_g3.cer and concatenates them into the file. The empty default ships with a runtime warning when b.mail.bimi loads it absent any operator-supplied trustAnchorsPem call-site override — the canary skip is intentional (the dual-hash + SLH-DSA signature cover the threat for a non-empty bundle; an empty bundle has no canary to verify).",
100
+ "_warning": "Empty PEM default — populate before invoking b.mail.bimi.fetchAndVerifyMark in production. b.mail.bimi emits a `bimi.trust-anchors.empty` runtime warning when this default is used without an operator-supplied trustAnchorsPem call-site override.",
101
+ "exports": [
102
+ "bimi-vmc-trust-anchors"
103
+ ],
104
+ "files": {
105
+ "server": "lib/vendor/bimi-trust-anchors.pem",
106
+ "data_js": "lib/vendor/bimi-trust-anchors.data.js"
107
+ },
108
+ "bundler": "operator-managed (see file header for refresh procedure)",
109
+ "bundledAt": "2026-05-13T00:00:00Z",
110
+ "hashes": {
111
+ "server": "sha256:81ff9f5ab3c9774132c845684e783be95cf73146f8b670d964105f0a3765b4b4",
112
+ "data_js": "sha256:aa7a4d33b65a68422a2a2c1670177689f66fdcaa08bd2514d78798b827bd1608"
113
+ },
114
+ "runtime_artifact": "lib/vendor/bimi-trust-anchors.data.js",
115
+ "integrity_layers": "sha256 + sha3-512 + SLH-DSA-SHAKE-256f signature + in-payload canary (where applicable)"
116
+ },
117
+ "publicsuffix-list": {
118
+ "version": "master",
119
+ "license": "MPL-2.0",
120
+ "author": "Mozilla Foundation",
121
+ "source": "https://publicsuffix.org/list/public_suffix_list.dat",
122
+ "_about": "Mozilla Public Suffix List — canonical catalog of effective top-level domains used by b.publicSuffix to derive organizational domains for DMARCbis (psd= / np=), BIMI, cookie-scope checks, and same-site policies. Loaded at module-init from lib/vendor/public-suffix-list.dat; the file is the data, not a code bundle.",
123
+ "files": {
124
+ "server": "lib/vendor/public-suffix-list.dat",
125
+ "data_js": "lib/vendor/public-suffix-list.data.js"
126
+ },
127
+ "bundler": "curl https://publicsuffix.org/list/public_suffix_list.dat",
128
+ "bundledAt": "2026-05-13T00:00:00Z",
129
+ "hashes": {
130
+ "server": "sha256:f15642cea028662c39d380caa9ddfbe36c81466e3a82f8f4b10703d83760295c",
131
+ "data_js": "sha256:b4b6ae76fdacbfe07683c4ea62761326f42894c2ccf4359f253bbcab9826ed04"
132
+ },
133
+ "runtime_artifact": "lib/vendor/public-suffix-list.data.js",
134
+ "integrity_layers": "sha256 + sha3-512 + SLH-DSA-SHAKE-256f signature + in-payload canary (where applicable)"
135
+ },
136
+ "peculiar-pki": {
137
+ "version": "2.0.0+pkijs-3.4.0",
138
+ "license": "MIT",
139
+ "author": "Peculiar Ventures",
140
+ "source": "https://github.com/PeculiarVentures",
141
+ "_about": "Meta-bundle of @peculiar/x509 + pkijs + reflect-metadata + every transitive ASN.1 schema package. Used by lib/mtls-engine-default.js as the pure-JS CA + PKCS#12 engine wired into b.mtlsCa.",
142
+ "components": {
143
+ "@peculiar/x509": "https://github.com/PeculiarVentures/x509",
144
+ "pkijs": "https://github.com/PeculiarVentures/PKI.js"
145
+ },
146
+ "exports": [
147
+ "x509",
148
+ "pkijs",
149
+ "crypto"
150
+ ],
151
+ "files": {
152
+ "server": "lib/vendor/pki.cjs"
153
+ },
154
+ "bundler": "esbuild --format=cjs --minify --platform=node --external:crypto --external:node:crypto",
155
+ "bundledAt": "2026-04-29T00:00:00Z",
156
+ "hashes": {
157
+ "server": "sha256:9bbc191afaaa2b1e5757f00480457c08134cdc2c55d541df18d9155bba9cbf77"
158
+ }
159
+ }
160
+ }
161
+ }