@blamejs/core 0.9.7 → 0.9.9
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/index.js +2 -0
- package/lib/auth/password.js +5 -4
- package/lib/cli.js +9 -3
- package/lib/db-schema.js +4 -1
- package/lib/external-db-migrate.js +4 -1
- package/lib/mail-bimi.js +8 -9
- package/lib/migrations.js +3 -1
- package/lib/public-suffix.js +19 -30
- package/lib/seeders.js +3 -1
- package/lib/vendor/.vendor-data-pubkey +4 -0
- package/lib/vendor/MANIFEST.json +156 -144
- package/lib/vendor/bimi-trust-anchors.data.js +68 -0
- package/lib/vendor/common-passwords-top-10000.data.js +1325 -0
- package/lib/vendor/common-passwords-top-10000.txt +2 -0
- package/lib/vendor/public-suffix-list.dat +6 -0
- package/lib/vendor/public-suffix-list.data.js +5881 -0
- package/lib/vendor/vendor-data-pubkey.js +16 -0
- package/lib/vendor-data.js +363 -0
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,8 @@ upgrading across more than a few patches at a time.
|
|
|
8
8
|
|
|
9
9
|
## v0.9.x
|
|
10
10
|
|
|
11
|
+
- v0.9.9 (2026-05-13) — **`b.vendorData`: replace dynamic `require(variable)` with static literal-string requires so SEA / esbuild / pkg bundling actually works**. v0.9.8 shipped `b.vendorData` to remove `__dirname`-relative `fs.readFileSync` calls and make the loader packaging-mode-invariant. The implementation looked up each `.data.js` module via `require(entry.module)` where `entry.module` was read from a frozen lookup table — a *dynamic* require, opaque to every bundler's static-analysis pass. esbuild, webpack, ncc, rollup, pkg, nexe, Bun's bundler, and Deno's bundler all trace `require("./literal")` calls; none of them trace `require(variable)`. Result: the three `.data.js` payload modules never made it into SEA / pkg / esbuild bundles, defeating the v0.9.8 promise at boot ("vendor-data/module-missing" thrown by every consumer that bundled the framework). v0.9.9 replaces the lookup with a `_MODULES` table whose three values are each a top-level `var X = require("./vendor/<name>.data")` — literal string, statically traceable. Caught by hermitstash-sync operator review post-v0.9.8 publish. Net surface change: zero (the public `b.vendorData.get` / `getAsString` / `verifyAll` / `inventory` shape is identical); the fix is internal-only. **New codebase-patterns drift detector** `testNoDynamicRequires` refuses any future `require(variable)` in `lib/`; legitimate operator-extensibility points (`b.cli`, migrations, seeders) carry an explicit `allow:dynamic-require` marker with rationale. **Operators upgrade from v0.9.8 to v0.9.9 if they bundle the framework via SEA / esbuild / pkg / Bun-compile** — direct `node` consumers were unaffected (Node's runtime require always resolves dynamic strings correctly).
|
|
12
|
+
- v0.9.8 (2026-05-13) — **`b.vendorData` — packaging-mode-invariant + signed + canary-guarded loader for vendored data files**. The three plaintext vendor data files (`public-suffix-list.dat`, `common-passwords-top-10000.txt`, `bimi-trust-anchors.pem`) are now loaded via inline `Buffer.from(base64)` modules (`<name>.data.js`), eliminating the `__dirname`-relative `fs.readFileSync` paths that broke under Single Executable Application (SEA), `pkg`, `nexe`, esbuild, Bun compile, Deno compile, and AWS Lambda layer bundling. Every load runs four orthogonal integrity checks before returning a byte: SHA-256 + SHA3-512 + SLH-DSA-SHAKE-256f signature against the maintainer's pinned public key (`lib/vendor/.vendor-data-pubkey`) + in-payload canary entry that the parsed structure must surface. Tamper at any layer throws `VendorDataError` at module-load — fail-fast rather than first-request-touches-PSL surprise. **Public API**: `b.vendorData.get(name)` returns the verified Buffer; `b.vendorData.getAsString(name)` returns UTF-8 string; `b.vendorData.verifyAll()` runs all four layers across every registered vendor data file and is invoked at framework boot; `b.vendorData.inventory()` returns per-file metadata (name, source, fetchedAt, sha256, sha3_512, signedBy, canary, byteLength, description) for compliance reporting + SBOM emission. **Migrated call sites**: `b.publicSuffix` (PSL load), `b.auth.password._loadBundledCommon` (common-passwords), `b.mail.bimi` (trust anchors) now route through `b.vendorData` — removes any downstream consumer's need to patch the loader for SEA / bundler builds. **Maintainer signing infrastructure**: vendor data files signed at refresh time by a maintainer-held SLH-DSA-SHAKE-256f keypair (private key stays in `.keys/` and is never committed; public key ships in `lib/vendor/.vendor-data-pubkey` in every npm tarball). Adds a fourth orthogonal trust root alongside SSH-signed release tags + SLSA L3 npm provenance + Sigstore-keyless SBOM signatures. **MANIFEST.json**: per-vendor-data entry gains `runtime_artifact` + `integrity_layers` + dual-file `hashes` (raw `.dat/.txt/.pem` + companion `.data.js`). **New scripts**: `scripts/vendor-data-keygen.js` (one-time keypair generation), `scripts/vendor-data-gen.js` (generator invoked by `scripts/vendor-update.sh --refresh-data`).
|
|
11
13
|
- v0.9.7 (2026-05-13) — **SECURITY.md: release-tag verification path documented + signed-tag invariant from v0.9.7+**. SECURITY.md gains a "Verifying release authenticity" section documenting how operators verify a release tag's authenticity independently of GitHub's UI. The maintainer Ed25519 SSH signing key fingerprint (`SHA256:5oF/XWhFpMde9TRfEX2GAHiApAq/MXOS4vti5zQbD7g`) is published alongside the public-key retrieval URL (`https://github.com/dotCooCoo.keys`) and a `git tag -v` recipe that bypasses the "Verified" badge. From v0.9.7 onward, every release tag is an annotated SSH-signed tag; the repository's `release-tags` ruleset's `required_signatures` rule refuses any unsigned or lightweight tag push at the server side. Earlier tags (v0.9.6 and prior) remain as lightweight commits and don't verify via `git tag -v`; they continue to verify via the SLSA L3 npm provenance + Sigstore-keyless SBOM signatures already attached to those releases (the `cosign verify-blob` recipe is in the same SECURITY.md section). No framework-surface changes; this release ships the documentation + invariant only.
|
|
12
14
|
- v0.9.6 (2026-05-12) — **`b.vex` (OASIS CSAF 2.1 VEX) + framework-control compliance posture sweep**. *(PR feedback: CSAF-conformance fixes folded in pre-merge — `cwes` is now a list per §3.2.3.4 instead of a singleton `cwe` field; CWE alone is no longer accepted as a vulnerability identity per §3.2.3.2 (operator supplies `cveId` or `ids[]: [{ systemName, text }]` per §3.2.3.5); TLP allowlist corrected to TLP 2.0 (FIRST 2022) per §3.2.1.12.1.1 — `CLEAR / GREEN / AMBER / AMBER+STRICT / RED` (added the previously-omitted `AMBER+STRICT` restriction tier and removed the legacy TLP 1.0 `WHITE` label, which was renamed `CLEAR` in TLP 2.0). Public opt name `cwe` is now `cweId` to mirror `cveId`; this is a v0.9.6 surface that never shipped to npm so the rename is not a breaking change.)* Closes the framework-side findings from the 2026-05-11 exceptd framework-gap-analysis (49 gaps across CVE-triage / framework-compliance / threat-modeling / AI-security / identity-assurance / crypto-posture / supply-chain / sector-specific). **`b.vex.statement({ cveId, status, productIds, justification?, impactStatement?, references?, firstReleased?, lastUpdated? })`** builds an OASIS CSAF 2.1 §3.2.3 vulnerability statement with `product_status` keyed by status enum (`known_not_affected` / `affected` / `fixed` / `under_investigation`), `flags[].label` for §3.2.2.7 justifications (`component_not_present` / `vulnerable_code_not_present` / `vulnerable_code_not_in_execute_path` / `vulnerable_code_cannot_be_controlled_by_adversary` / `inline_mitigations_already_exist`), and `notes[].text` for impact narrative. Refuses missing CVE/CWE id, malformed CVE shape, unknown status, missing productIds, and `known_not_affected` without justification. **`b.vex.document({ documentId, title, publisher, trackingId, trackingVersion, currentReleaseDate, initialReleaseDate, statements, tlp? })`** assembles the §3.2 CSAF document envelope with category `csaf_vex`, csaf_version `2.1`, publisher category `vendor`, tracking status `final`, and `distribution.tlp.label` (default `CLEAR`; refuses non-TLP labels). **`b.vex.serialize(doc)`** routes through `b.canonicalJson.stringify` for byte-stable sorted-key output then re-indents at 2 spaces for human-diffable artifacts. Exports `STATUS_VALUES` / `JUSTIFICATION_VALUES` / `TLP_LABELS` / `CSAF_VERSION` / `VexError`. **25 new compliance postures** added to `b.compliance.KNOWN_POSTURES` (with matching `POSTURE_DEFAULTS` cascade entries): `nist-800-53` (NIST SP 800-53 Rev 5 control catalog), `nist-ai-rmf-1.0` (NIST AI Risk Management Framework 1.0), `iso-42001-2023` (AI management systems), `iso-23894-2023` (AI risk management guidance), `owasp-llm-top-10-2025` (LLM application risk catalog), `owasp-asvs-v5.0` (Application Security Verification Standard v5.0), `nist-800-218-ssdf` (Secure Software Development Framework), `nist-800-82-r3` (industrial control systems), `nist-800-63b-rev4` (digital identity authenticator guidance), `iec-62443-3-3` (industrial security), `fedramp-rev5-moderate` (federal cloud baseline), `hipaa-security-rule` (45 CFR §164.302-318 administrative + technical safeguards), `hitrust-csf-v11.4` (healthcare common security framework), `nerc-cip-007-6` (bulk electric system cyber asset security), `psd2-rts-sca` (PSD2 Regulatory Technical Standards for Strong Customer Authentication), `swift-cscf-v2026` (SWIFT Customer Security Controls Framework 2026), `slsa-v1.0-build-l3` (SLSA build-track L3 provenance), `vex-csaf-2.1` (the standard `b.vex` emits), `cyclonedx-v1.6` (already shipped via `sbom.cdx.json`), `spdx-v3.0` (SPDX 3.0 software bill of materials), `owasp-wstg-v5` (Web Security Testing Guide v5), `ptes` (Penetration Testing Execution Standard), `nist-800-115` (technical guide to information security testing), `cwe-top-25-2024` (CWE most dangerous software weaknesses 2024), `cis-controls-v8` (Center for Internet Security Critical Controls v8), `cmmc-2.0-level-2` (DoD CMMC Level 2 advanced; complements the existing `cmmc-2.0` posture). Each cascade entry encodes the regime's data-tier mandate (encrypted backups + signed audit chain + TLS 1.3 minimum + vacuum-after-erase where applicable).
|
|
13
15
|
- v0.9.5 (2026-05-12) — **Fix-up for v0.9.3 + v0.9.4 audit-derived primitives** (five reported reachability/contract bugs). (1) **`b.middleware.dpop` `trustForwardedHeaders` was unreachable** — the v0.9.4 X-Forwarded-* trust gate added the option to `_reconstructHtu` but the `create()` validateOpts whitelist still rejected unknown keys. Operators behind a trusted reverse proxy got `unknown-option` instead of the documented opt-in, leaving valid DPoP proofs failing htu matching. The whitelist now includes `trustForwardedHeaders`. (2) **`b.auth.jwt.verifyExternal` `allowKidlessJwks` was unreachable** — same shape, fixed the same way. (3) **OAuth `allowKidlessJwks` didn't reach token-exchange flows** — pre-v0.9.5 the opt was per-`verifyIdToken`-call, but `_normalizeTokens()` (called from `exchangeCode` / `pollDeviceCode` / `exchangeToken` / `refreshAccessToken`) passed a reduced `{ nonce, skipNonceCheck }` shape that dropped the operator opt. Surface promoted to client-level: pass `b.auth.oauth.create({ allowKidlessJwks: true })` once and it threads through every code path that lands on the verifier. The per-call `vopts.allowKidlessJwks` continues to work for direct `verifyIdToken` callers. (4) **`b.auth.oauth.refreshAccessToken` `checkAndInsert` return-value contract inverted** — pre-v0.9.5 interpreted `true` as "already seen → replay" but the framework-wide `checkAndInsert` contract (`b.nonceStore`, `b.auth.jwt`) is the opposite: `true` = unseen-and-now-inserted (first sighting), `false` = already-present (replay). Operators reusing an existing `b.nonceStore`-style backend got every first refresh attempt rejected as token theft, breaking normal refresh flows. The handler now normalizes `inserted === false` → `alreadySeen = true`, consistent with the rest of the framework. (5) **`b.auth.ciba` `_intervalState` memory leak on error paths** — pre-v0.9.5 entries were only deleted on successful token issuance; denied / expired auth requests, and ping/push delivery modes that never call `pollToken` successfully, left permanent entries causing unbounded growth in long-running processes. Now entries carry an `expireAtMs` derived from the IdP-supplied `expires_in` of the auth_req_id, and an opportunistic sweep runs on every `_registerInitialInterval` call (no separate timer needed). Terminal CIBA errors (`expired_token` / `access_denied` / `invalid_grant` / `transaction_failed`) also delete the entry immediately on the error path.
|
package/index.js
CHANGED
|
@@ -149,6 +149,7 @@ var cdnCacheControl = require("./lib/cdn-cache-control");
|
|
|
149
149
|
var clientHints = require("./lib/client-hints");
|
|
150
150
|
var structuredFields = require("./lib/structured-fields");
|
|
151
151
|
var vex = require("./lib/vex");
|
|
152
|
+
var vendorData = require("./lib/vendor-data");
|
|
152
153
|
var serverTiming = require("./lib/server-timing");
|
|
153
154
|
var earlyHints = require("./lib/early-hints");
|
|
154
155
|
var gateContract = require("./lib/gate-contract");
|
|
@@ -385,6 +386,7 @@ module.exports = {
|
|
|
385
386
|
clientHints: clientHints,
|
|
386
387
|
structuredFields: structuredFields,
|
|
387
388
|
vex: vex,
|
|
389
|
+
vendorData: vendorData,
|
|
388
390
|
serverTiming: serverTiming,
|
|
389
391
|
earlyHints: earlyHints,
|
|
390
392
|
gateContract: gateContract,
|
package/lib/auth/password.js
CHANGED
|
@@ -207,13 +207,14 @@ var POLICY_PROFILES = Object.freeze({
|
|
|
207
207
|
// Operators wanting deeper enforcement supply opts.forbidCommon (set
|
|
208
208
|
// of additional plaintexts) and/or opts.forbidCommonExtra (operator's
|
|
209
209
|
// own breach list); both layer additively on top of the bundled set.
|
|
210
|
-
var
|
|
211
|
-
var fs = require("node:fs");
|
|
210
|
+
var vendorData = require("../vendor-data");
|
|
212
211
|
var _bundledCommonPasswords = null;
|
|
213
212
|
function _loadBundledCommon() {
|
|
214
213
|
if (_bundledCommonPasswords) return _bundledCommonPasswords;
|
|
215
|
-
|
|
216
|
-
|
|
214
|
+
// b.vendorData verifies the dual-hash + SLH-DSA signature + in-payload
|
|
215
|
+
// canary before returning the bytes. Packaging-mode-invariant — no
|
|
216
|
+
// __dirname-relative file lookup that breaks under SEA / pkg / bundler.
|
|
217
|
+
var text = vendorData.getAsString("common-passwords-top-10000");
|
|
217
218
|
var set = new Set();
|
|
218
219
|
var lines = text.split(/\r?\n/);
|
|
219
220
|
for (var i = 0; i < lines.length; i++) {
|
package/lib/cli.js
CHANGED
|
@@ -426,14 +426,20 @@ var API_SNAPSHOT_USAGE = [
|
|
|
426
426
|
].join("\n");
|
|
427
427
|
|
|
428
428
|
function _resolveTargetModule(modulePath, ctx) {
|
|
429
|
-
// Default: load index.js from the framework root (one level up from lib/cli.js)
|
|
429
|
+
// Default: load index.js from the framework root (one level up from lib/cli.js).
|
|
430
|
+
// Dynamic require by design — the CLI loads either the framework root index.js
|
|
431
|
+
// or an operator-supplied module path from the command line. Operator-
|
|
432
|
+
// extensibility surfaces by definition can't be statically traced by a
|
|
433
|
+
// bundler — anyone bundling this CLI surface into SEA/pkg accepts that
|
|
434
|
+
// runtime --module=<path> arguments won't resolve. Internal framework
|
|
435
|
+
// code never reaches this path.
|
|
430
436
|
if (!modulePath) {
|
|
431
437
|
var root = path.resolve(__dirname, "..");
|
|
432
|
-
return require(path.join(root, "index.js"));
|
|
438
|
+
return require(path.join(root, "index.js")); // allow:dynamic-require — operator-extensibility entry point
|
|
433
439
|
}
|
|
434
440
|
var abs = path.isAbsolute(modulePath) ? modulePath : path.resolve(ctx.cwd, modulePath);
|
|
435
441
|
delete require.cache[require.resolve(abs)];
|
|
436
|
-
return require(abs);
|
|
442
|
+
return require(abs); // allow:dynamic-require — operator-extensibility entry point
|
|
437
443
|
}
|
|
438
444
|
|
|
439
445
|
function _runApiSnapshot(args, ctx) {
|
package/lib/db-schema.js
CHANGED
|
@@ -283,7 +283,10 @@ function runMigrations(database, migrationDir) {
|
|
|
283
283
|
var fullPath = path.join(migrationDir, file);
|
|
284
284
|
var mig;
|
|
285
285
|
try {
|
|
286
|
-
|
|
286
|
+
// Operator-supplied migration file — by definition not statically
|
|
287
|
+
// require-able by a bundler. Anyone bundling this surface into SEA
|
|
288
|
+
// accepts that runtime migration loading won't resolve.
|
|
289
|
+
mig = require(fullPath); // allow:dynamic-require — operator-supplied migration
|
|
287
290
|
} catch (e) {
|
|
288
291
|
throw new Error("migration '" + file + "' failed to load: " + e.message);
|
|
289
292
|
}
|
|
@@ -290,7 +290,10 @@ function _loadMigration(file, dir) {
|
|
|
290
290
|
// new content. Matches lib/migrations.js semantics.
|
|
291
291
|
try { delete require.cache[require.resolve(fullPath)]; } catch (_e) { /* not yet cached */ }
|
|
292
292
|
var mod;
|
|
293
|
-
|
|
293
|
+
// Operator-supplied migration file — dynamic by design, won't survive
|
|
294
|
+
// SEA / pkg bundling. External DB migration tooling is host-CLI scope,
|
|
295
|
+
// not framework-internal scope.
|
|
296
|
+
try { mod = require(fullPath); } // allow:dynamic-require — operator-supplied migration
|
|
294
297
|
catch (e) {
|
|
295
298
|
throw _err("externaldb-migrate/load-failed",
|
|
296
299
|
"migration '" + file + "' failed to load: " + ((e && e.message) || String(e)));
|
package/lib/mail-bimi.js
CHANGED
|
@@ -50,8 +50,6 @@
|
|
|
50
50
|
var dns = require("node:dns");
|
|
51
51
|
var nodeCrypto = require("node:crypto");
|
|
52
52
|
var dnsPromises = dns.promises;
|
|
53
|
-
var fs = require("node:fs");
|
|
54
|
-
var nodePath = require("node:path");
|
|
55
53
|
|
|
56
54
|
var asn1 = require("./asn1-der");
|
|
57
55
|
var C = require("./constants");
|
|
@@ -112,15 +110,16 @@ var CMC_POLICY_OID = "1.3.6.1.4.1.53087.1.2";
|
|
|
112
110
|
// RFC 3709 4.2 — the logotype extension OID.
|
|
113
111
|
var ID_PE_LOGOTYPE = "1.3.6.1.5.5.7.1.12";
|
|
114
112
|
|
|
115
|
-
// Vendored BIMI Group trust anchors.
|
|
116
|
-
//
|
|
117
|
-
//
|
|
118
|
-
//
|
|
119
|
-
//
|
|
120
|
-
|
|
113
|
+
// Vendored BIMI Group trust anchors. Loaded via b.vendorData which
|
|
114
|
+
// dual-hash + SLH-DSA-SHAKE-256f-signature-verifies before returning
|
|
115
|
+
// the bytes. The vendor file may be empty-of-PEM in source trees
|
|
116
|
+
// (operators populate via the documented refresh procedure);
|
|
117
|
+
// fetchAndVerifyMark refuses to validate if both the vendored bundle
|
|
118
|
+
// is empty and the call-site `trustAnchorsPem` opt is absent.
|
|
119
|
+
var vendorData = require("./vendor-data");
|
|
121
120
|
var _vendoredTrustAnchorsPem = "";
|
|
122
121
|
try {
|
|
123
|
-
_vendoredTrustAnchorsPem =
|
|
122
|
+
_vendoredTrustAnchorsPem = vendorData.getAsString("bimi-trust-anchors");
|
|
124
123
|
} catch (_e) {
|
|
125
124
|
_vendoredTrustAnchorsPem = "";
|
|
126
125
|
}
|
package/lib/migrations.js
CHANGED
|
@@ -241,7 +241,9 @@ function _loadMigration(file, dir) {
|
|
|
241
241
|
// keeps test fixtures sane.
|
|
242
242
|
try { delete require.cache[require.resolve(fullPath)]; } catch (_e) { /* not yet cached */ }
|
|
243
243
|
var mod;
|
|
244
|
-
|
|
244
|
+
// Operator-supplied migration — dynamic by design, can't be bundle-
|
|
245
|
+
// traced. Host-CLI scope; deploying via SEA / pkg drops this surface.
|
|
246
|
+
try { mod = require(fullPath); } // allow:dynamic-require — operator-supplied migration
|
|
245
247
|
catch (e) {
|
|
246
248
|
throw new MigrationError("migrations/load-failed",
|
|
247
249
|
"migration '" + file + "' failed to load: " + ((e && e.message) || String(e)),
|
package/lib/public-suffix.js
CHANGED
|
@@ -52,18 +52,17 @@
|
|
|
52
52
|
* before lookup. Bad inputs throw `PublicSuffixError`.
|
|
53
53
|
*/
|
|
54
54
|
|
|
55
|
-
var fs = require("node:fs");
|
|
56
|
-
var nodePath = require("node:path");
|
|
57
|
-
var nodeCrypto = require("node:crypto");
|
|
58
55
|
var nodeUrl = require("node:url");
|
|
56
|
+
var vendorData = require("./vendor-data");
|
|
57
|
+
var pslDataModule = require("./vendor/public-suffix-list.data");
|
|
59
58
|
var { PublicSuffixError } = require("./framework-error");
|
|
60
59
|
|
|
61
|
-
// Vendored PSL data file.
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
|
|
60
|
+
// Vendored PSL data file. Loaded via b.vendorData which inlines the
|
|
61
|
+
// bytes as a CommonJS module, dual-hash + SLH-DSA-SHAKE-256f-signature
|
|
62
|
+
// verifies on first access, and carries an in-payload canary the
|
|
63
|
+
// PSL parser must observe. Packaging-mode-invariant — survives SEA,
|
|
64
|
+
// pkg, nexe, esbuild bundles, Lambda layers, Bun/Deno compile. See
|
|
65
|
+
// lib/vendor-data.js for the integrity surface.
|
|
67
66
|
|
|
68
67
|
function _err(code, message) {
|
|
69
68
|
return new PublicSuffixError(code, message);
|
|
@@ -185,34 +184,24 @@ var _sourceMeta;
|
|
|
185
184
|
(function _init() {
|
|
186
185
|
var raw;
|
|
187
186
|
try {
|
|
188
|
-
raw =
|
|
187
|
+
raw = vendorData.get("public-suffix-list");
|
|
189
188
|
} catch (e) {
|
|
190
189
|
throw _err("public-suffix/not-loaded",
|
|
191
|
-
"publicSuffix: vendored PSL data
|
|
192
|
-
"
|
|
190
|
+
"publicSuffix: vendored PSL data not loadable via b.vendorData " +
|
|
191
|
+
"(" + (e && e.message ? e.message : "unknown error") + ")");
|
|
193
192
|
}
|
|
194
|
-
var sha256 = nodeCrypto.createHash("sha256").update(raw).digest("hex");
|
|
195
193
|
var parsed = _parsePsl(raw.toString("utf8"));
|
|
196
194
|
_data = parsed;
|
|
197
|
-
//
|
|
198
|
-
//
|
|
199
|
-
//
|
|
200
|
-
//
|
|
201
|
-
var
|
|
202
|
-
try {
|
|
203
|
-
var manifestPath = nodePath.join(__dirname, "vendor", "MANIFEST.json");
|
|
204
|
-
var manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8")); // allow:bare-json-parse — MANIFEST.json is a framework-internal vendored file checked in alongside code; never from operator / network input
|
|
205
|
-
var entry = manifest && manifest.packages && manifest.packages["publicsuffix-list"];
|
|
206
|
-
if (entry && typeof entry.bundledAt === "string") vendoredAt = entry.bundledAt;
|
|
207
|
-
} catch (_e) {
|
|
208
|
-
// Manifest missing / malformed — continue with vendoredAt =
|
|
209
|
-
// "unknown". This is observability-only metadata; a request-path
|
|
210
|
-
// failure here would punish operators for a non-fatal drift.
|
|
211
|
-
}
|
|
195
|
+
// Provenance comes from the .data.js module's own metadata, which
|
|
196
|
+
// carries sha256 + sha3-512 + signing public-key fingerprint +
|
|
197
|
+
// upstream fetchedAt timestamp. All four were verified by
|
|
198
|
+
// vendorData.get() before the bytes reached this caller.
|
|
199
|
+
var meta = pslDataModule.metadata;
|
|
212
200
|
_sourceMeta = Object.freeze({
|
|
213
|
-
vendoredAt:
|
|
201
|
+
vendoredAt: meta.fetchedAt,
|
|
214
202
|
entries: parsed.entries,
|
|
215
|
-
sha256: sha256,
|
|
203
|
+
sha256: meta.sha256,
|
|
204
|
+
signedBy: meta.publicKeyFingerprint,
|
|
216
205
|
});
|
|
217
206
|
})();
|
|
218
207
|
|
package/lib/seeders.js
CHANGED
|
@@ -176,7 +176,9 @@ function _loadSeed(rootDir, env, file) {
|
|
|
176
176
|
// between calls picks it up. Production restarts the process anyway.
|
|
177
177
|
try { delete require.cache[require.resolve(fullPath)]; } catch (_e) { /* not yet cached */ }
|
|
178
178
|
var mod;
|
|
179
|
-
|
|
179
|
+
// Operator-supplied seed — dynamic by design, can't be bundle-traced.
|
|
180
|
+
// Host-CLI scope; deploying via SEA / pkg drops this surface.
|
|
181
|
+
try { mod = require(fullPath); } // allow:dynamic-require — operator-supplied seed
|
|
180
182
|
catch (e) {
|
|
181
183
|
throw _err("LOAD_FAILED",
|
|
182
184
|
"seed '" + env + "/" + file + "' failed to load: " + ((e && e.message) || String(e)));
|
package/lib/vendor/MANIFEST.json
CHANGED
|
@@ -1,144 +1,156 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_comment": "Vendored dependencies
|
|
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
|
|
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
|
|
77
|
-
"files": {
|
|
78
|
-
"server": "lib/vendor/common-passwords-top-10000.txt"
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
"
|
|
88
|
-
"
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
"
|
|
92
|
-
"
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
"
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
"
|
|
100
|
-
|
|
101
|
-
"
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
"
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
"
|
|
110
|
-
"
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
"
|
|
114
|
-
"
|
|
115
|
-
"
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
"
|
|
123
|
-
"
|
|
124
|
-
"
|
|
125
|
-
|
|
126
|
-
"
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
"
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
"
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
"
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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
|
+
}
|