@blamejs/core 0.9.46 → 0.10.1

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 (78) hide show
  1. package/CHANGELOG.md +951 -893
  2. package/index.js +30 -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 +67 -5
  23. package/lib/circuit-breaker.js +10 -2
  24. package/lib/compliance.js +176 -8
  25. package/lib/crypto-field.js +114 -14
  26. package/lib/crypto.js +216 -20
  27. package/lib/db.js +1 -0
  28. package/lib/guard-imap-command.js +335 -0
  29. package/lib/guard-jmap.js +321 -0
  30. package/lib/guard-managesieve-command.js +566 -0
  31. package/lib/guard-pop3-command.js +317 -0
  32. package/lib/guard-smtp-command.js +58 -3
  33. package/lib/mail-agent.js +20 -7
  34. package/lib/mail-arc-sign.js +12 -8
  35. package/lib/mail-auth.js +323 -34
  36. package/lib/mail-crypto-pgp.js +934 -0
  37. package/lib/mail-crypto-smime.js +340 -0
  38. package/lib/mail-crypto.js +108 -0
  39. package/lib/mail-dav.js +1224 -0
  40. package/lib/mail-deploy.js +492 -0
  41. package/lib/mail-dkim.js +431 -26
  42. package/lib/mail-journal.js +435 -0
  43. package/lib/mail-scan.js +502 -0
  44. package/lib/mail-server-imap.js +1102 -0
  45. package/lib/mail-server-jmap.js +488 -0
  46. package/lib/mail-server-managesieve.js +853 -0
  47. package/lib/mail-server-mx.js +164 -34
  48. package/lib/mail-server-pop3.js +836 -0
  49. package/lib/mail-server-rate-limit.js +269 -0
  50. package/lib/mail-server-submission.js +1032 -0
  51. package/lib/mail-server-tls.js +445 -0
  52. package/lib/mail-sieve.js +557 -0
  53. package/lib/mail-spam-score.js +284 -0
  54. package/lib/mail.js +99 -0
  55. package/lib/metrics.js +130 -10
  56. package/lib/middleware/dpop.js +58 -3
  57. package/lib/middleware/idempotency-key.js +255 -42
  58. package/lib/middleware/protected-resource-metadata.js +114 -2
  59. package/lib/network-dns-resolver.js +33 -0
  60. package/lib/network-tls.js +46 -0
  61. package/lib/outbox.js +62 -12
  62. package/lib/pqc-agent.js +13 -5
  63. package/lib/retry.js +23 -9
  64. package/lib/router.js +23 -1
  65. package/lib/safe-ical.js +634 -0
  66. package/lib/safe-icap.js +502 -0
  67. package/lib/safe-mime.js +15 -0
  68. package/lib/safe-sieve.js +684 -0
  69. package/lib/safe-smtp.js +57 -0
  70. package/lib/safe-url.js +37 -0
  71. package/lib/safe-vcard.js +473 -0
  72. package/lib/self-update-standalone-verifier.js +32 -3
  73. package/lib/self-update.js +168 -17
  74. package/lib/vendor/MANIFEST.json +161 -156
  75. package/lib/vendor-data.js +127 -9
  76. package/lib/vex.js +324 -59
  77. package/package.json +1 -1
  78. package/sbom.cdx.json +6 -6
@@ -86,21 +86,84 @@ function _safeAuditEmit(action, outcome, metadata) {
86
86
  }
87
87
 
88
88
  // ---- semver-shaped comparison (tag_name like "v0.7.30" or "0.7.30") ----
89
- // Strips a leading "v" / "V" then parses dot-separated numeric components.
90
- // Non-numeric components are compared lexicographically (handles release
91
- // suffixes like "1.0.0-rc.1" by falling back to string comparison after
92
- // the matching numeric prefix). Returns -1 / 0 / +1.
93
89
  function _normalizeTag(tag) {
94
90
  if (typeof tag !== "string") return "";
95
91
  return tag.replace(/^v/i, "").trim();
96
92
  }
93
+
94
+ /**
95
+ * @primitive b.selfUpdate.compareTags
96
+ * @signature b.selfUpdate.compareTags(a, b)
97
+ * @since 0.9.47
98
+ * @status stable
99
+ *
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:
103
+ *
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.
124
+ *
125
+ * @example
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)
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
+
97
148
  function _compareTags(a, b) {
98
149
  var na = _normalizeTag(a);
99
150
  var nb2 = _normalizeTag(b);
100
- var pa = na.split(".");
101
- var pbb = nb2.split(".");
102
- var len = Math.max(pa.length, pbb.length);
103
- 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++) {
104
167
  var ai = pa[i] !== undefined ? pa[i] : "0";
105
168
  var bi = pbb[i] !== undefined ? pbb[i] : "0";
106
169
  var an = parseInt(ai, 10);
@@ -110,9 +173,45 @@ function _compareTags(a, b) {
110
173
  if (an > bn) return 1;
111
174
  continue;
112
175
  }
176
+ // Non-numeric component in the core — fall back to ASCII per
177
+ // §11 to keep deterministic ordering on malformed inputs.
113
178
  if (ai < bi) return -1;
114
179
  if (ai > bi) return 1;
115
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
+ }
116
215
  return 0;
117
216
  }
118
217
 
@@ -195,6 +294,14 @@ function _matchAsset(name, pattern, fallback) {
195
294
  * timeoutMs: number, // request timeout (default 15s)
196
295
  * headers: object, // additional request headers
197
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.)
198
305
  *
199
306
  * @example
200
307
  * try {
@@ -469,6 +576,31 @@ function _validateSwapOpts(opts, label) {
469
576
  "selfUpdate." + label + ": opts.backupTo", SelfUpdateError, "selfupdate/bad-backup");
470
577
  }
471
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
+
472
604
  // Atomic swap of `from` -> `to` with rollback on failure. Steps:
473
605
  //
474
606
  // 1. ensure `to` and `backupTo` parents exist
@@ -539,7 +671,10 @@ async function swap(opts) {
539
671
  }
540
672
 
541
673
  // Step 3 — install. Rename is atomic on same FS; on cross-device we
542
- // 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).
543
678
  try {
544
679
  nodeFs.renameSync(from, to);
545
680
  } catch (e) {
@@ -550,19 +685,31 @@ async function swap(opts) {
550
685
  await atomicFile.copy(from, to, { fileMode: 0o600 });
551
686
  try { nodeFs.unlinkSync(from); } catch (_u) { /* tmp source leak — operator-cleanable */ }
552
687
  } catch (ce) {
553
- // Roll back from backup if we have one.
554
- if (hadOriginal) {
555
- try { await atomicFile.copy(backupTo, to, { fileMode: 0o600 }); }
556
- 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);
557
699
  }
558
700
  throw new SelfUpdateError("selfupdate/cross-device",
559
701
  "selfUpdate.swap: cross-device install failed: " + ((ce && ce.message) || String(ce)));
560
702
  }
561
703
  } else {
562
- // Other rename failure — try to roll back.
563
- if (hadOriginal) {
564
- try { await atomicFile.copy(backupTo, to, { fileMode: 0o600 }); }
565
- 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);
566
713
  }
567
714
  throw new SelfUpdateError("selfupdate/swap-failed",
568
715
  "selfUpdate.swap: rename " + from + " -> " + to + " failed: " + e.message);
@@ -648,6 +795,10 @@ module.exports = {
648
795
  SelfUpdateError: SelfUpdateError,
649
796
  ALLOWED_HASH_ALGS: ALLOWED_HASH_ALGS,
650
797
  DEFAULT_HASH_ALG: DEFAULT_HASH_ALG,
798
+ // Public surface — same impl as the internal `_compareTags`;
799
+ // downstream consumers replacing one-off compareVersions helpers
800
+ // call this.
801
+ compareTags: _compareTags,
651
802
  // Internal — exposed for the layer-0 test suite only.
652
803
  _compareTags: _compareTags,
653
804
  };
@@ -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
+ }