@blamejs/core 0.7.23 → 0.7.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/lib/retention.js +43 -2
- package/package.json +1 -1
- package/sbom.cyclonedx.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.7.x
|
|
10
10
|
|
|
11
|
+
- **0.7.24** (2026-05-05) — `b.retention.complianceFloor` accessor for regulatory minimum-retention windows. **Surface**: `b.retention.complianceFloor(posture, candidateTtlMs?)` returns the effective TTL that meets-or-exceeds the regulatory floor; throws `retention/unknown-posture` on unknown names. **`b.retention.COMPLIANCE_RETENTION_FLOOR_MS`** exposes the per-posture minimums for compliance audit visibility: `pci-dss` 365 days (PCI-DSS Req 10.7.1), `hipaa` 6 years (45 CFR §164.316(b)(2)), `sox` 7 years (Sarbanes-Oxley §802), `soc2` 1 year, `dora` 5 years (DORA Article 17). When `candidateTtlMs` exceeds the floor it wins; when it's below, the floor takes over. Smoke 8488 / wiki e2e 178 / Linux container smoke 8488 / Linux container wiki e2e 178 / eslint clean / api-snapshot baseline refreshed.
|
|
12
|
+
|
|
11
13
|
- **0.7.23** (2026-05-05) — DNS-over-HTTPS default-on. **Default-on DoH for outbound DNS** — `lib/network-dns.js` now uses Cloudflare DoH (`https://cloudflare-dns.com/dns-query`) for hostname resolution by default when neither `useDnsOverHttps()` nor `useDnsOverTls()` has been called explicitly. Privacy-respecting (encrypted DNS over TLS to a non-ISP resolver), aligned with Core Rule §3 ("security defaults are not opt-in"). **Local-form hosts route through node:dns** — RFC 6761 / 6762 special-form names (`localhost`, `*.localhost`, `*.local`, `*.test`, `*.invalid`, `*.internal`, `*.intranet`, `*.lan`, `*.home`, `*.corp`) AND IP literals skip DoH and use node:dns directly so `/etc/hosts` lookups + dev workflows continue to resolve correctly. **Operator opt-out via `b.network.dns.useSystemResolver()`** — split-horizon / internal-DNS deployments call this once at boot and every lookup routes through the OS resolver thereafter. **Env override `BLAMEJS_DNS_TRANSPORT`** — operators set `system` (force OS resolver), `dot` (force Cloudflare DNS-over-TLS at 1.1.1.1:853), or leave unset (default DoH). Smoke 8478 / wiki e2e 178 / Linux container smoke 8478 / Linux container wiki e2e 178 / eslint clean / api-snapshot baseline refreshed.
|
|
12
14
|
|
|
13
15
|
- **0.7.22** (2026-05-05) — DKIM dual-signer + soc2-cc7 → soc2 posture rename. **`b.mail.dkim.dualSigner`** — RFC 8463 §3 transition signer that produces messages with BOTH a legacy RSA-SHA-256 DKIM-Signature AND an Ed25519-SHA-256 DKIM-Signature header. Receivers without Ed25519 support validate the RSA signature; receivers that prefer Ed25519 validate the post-quantum-friendlier signature. Operators rolling off RSA-SHA-256 wire `b.mail.dkim.dualSigner({ domain, rsa: { selector, privateKey }, eddsa: { selector, privateKey } })` and pass the result anywhere a regular DKIM signer is accepted; `sign()` produces a wire with two `DKIM-Signature` headers. Both signers are constructed eagerly at create-time (configuration errors surface at boot, not at first send). **soc2-cc7 → soc2 posture rename** — every guard's compliance posture name changes from `"soc2-cc7"` to `"soc2"`. The CC7-specific scoping was misleading (SOC 2 controls span CC1–CC9; the existing posture wasn't CC7-specific). Operators with `compliancePosture: "soc2-cc7"` MUST update to `compliancePosture: "soc2"` — the old name now throws `unknown compliance posture`. Smoke 8478 / wiki e2e 178 / Linux container smoke 8478 / Linux container wiki e2e 178 / eslint clean / api-snapshot baseline refreshed.
|
package/lib/retention.js
CHANGED
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
* write. This is the escape hatch; the table+ageField+ttlMs shape
|
|
56
56
|
* covers the common case.
|
|
57
57
|
*/
|
|
58
|
+
var C = require("./constants");
|
|
58
59
|
var lazyRequire = require("./lazy-require");
|
|
59
60
|
var validateOpts = require("./validate-opts");
|
|
60
61
|
var { defineClass } = require("./framework-error");
|
|
@@ -433,7 +434,47 @@ function create(opts) {
|
|
|
433
434
|
return { declare: declare, run: run, runAll: runAll, preview: preview, list: list };
|
|
434
435
|
}
|
|
435
436
|
|
|
437
|
+
// Audit-log retention floors per regulatory posture. These are the
|
|
438
|
+
// MINIMUMS — operators may declare longer windows but cannot declare
|
|
439
|
+
// shorter ones. Operator-facing helper for compliance audit.
|
|
440
|
+
//
|
|
441
|
+
// PCI-DSS Requirement 10.7.1 — 12 months online (active accessible)
|
|
442
|
+
// HIPAA 45 CFR §164.316(b)(2) — 6 years from creation
|
|
443
|
+
// SOX (Sarbanes-Oxley) §802 — 7 years for audit-relevant records
|
|
444
|
+
// GDPR Art. 5(1)(e) — no fixed minimum; operator declares
|
|
445
|
+
// SOC 2 (CC1–CC9) — 1 year typical; auditor-driven
|
|
446
|
+
// DORA Art. 17 (incident logs) — 5 years
|
|
447
|
+
var COMPLIANCE_RETENTION_FLOOR_MS = Object.freeze({
|
|
448
|
+
"pci-dss": C.TIME.days(365), // 12 months
|
|
449
|
+
"hipaa": C.TIME.days(365 * 6), // 6 years
|
|
450
|
+
"sox": C.TIME.days(365 * 7), // 7 years
|
|
451
|
+
"soc2": C.TIME.days(365), // 1 year
|
|
452
|
+
"dora": C.TIME.days(365 * 5), // 5 years (Article 17 incident logs)
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
// Operator passes a posture name + a candidate ttlMs; returns the
|
|
456
|
+
// effective ttl that meets-or-exceeds the floor. Throws if posture is
|
|
457
|
+
// unknown so typos surface at config time.
|
|
458
|
+
function complianceFloor(posture, candidateTtlMs) {
|
|
459
|
+
if (typeof posture !== "string") {
|
|
460
|
+
throw new RetentionError("retention/bad-posture",
|
|
461
|
+
"complianceFloor: posture must be a string, got " + JSON.stringify(posture));
|
|
462
|
+
}
|
|
463
|
+
var floor = COMPLIANCE_RETENTION_FLOOR_MS[posture];
|
|
464
|
+
if (floor === undefined) {
|
|
465
|
+
throw new RetentionError("retention/unknown-posture",
|
|
466
|
+
"complianceFloor: unknown posture '" + posture + "'; expected one of " +
|
|
467
|
+
Object.keys(COMPLIANCE_RETENTION_FLOOR_MS).join(", "));
|
|
468
|
+
}
|
|
469
|
+
if (typeof candidateTtlMs !== "number" || !isFinite(candidateTtlMs) || candidateTtlMs <= 0) {
|
|
470
|
+
return floor;
|
|
471
|
+
}
|
|
472
|
+
return candidateTtlMs > floor ? candidateTtlMs : floor;
|
|
473
|
+
}
|
|
474
|
+
|
|
436
475
|
module.exports = {
|
|
437
|
-
create:
|
|
438
|
-
|
|
476
|
+
create: create,
|
|
477
|
+
complianceFloor: complianceFloor,
|
|
478
|
+
COMPLIANCE_RETENTION_FLOOR_MS: COMPLIANCE_RETENTION_FLOOR_MS,
|
|
479
|
+
RetentionError: RetentionError,
|
|
439
480
|
};
|
package/package.json
CHANGED
package/sbom.cyclonedx.json
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
|
|
3
3
|
"bomFormat": "CycloneDX",
|
|
4
4
|
"specVersion": "1.5",
|
|
5
|
-
"serialNumber": "urn:uuid:
|
|
5
|
+
"serialNumber": "urn:uuid:942606f7-1484-4ac3-9332-63f73e25256f",
|
|
6
6
|
"version": 1,
|
|
7
7
|
"metadata": {
|
|
8
|
-
"timestamp": "2026-05-05T06:
|
|
8
|
+
"timestamp": "2026-05-05T06:51:47.053Z",
|
|
9
9
|
"lifecycles": [
|
|
10
10
|
{
|
|
11
11
|
"phase": "build"
|
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
}
|
|
20
20
|
],
|
|
21
21
|
"component": {
|
|
22
|
-
"bom-ref": "@blamejs/core@0.7.
|
|
22
|
+
"bom-ref": "@blamejs/core@0.7.24",
|
|
23
23
|
"type": "library",
|
|
24
24
|
"name": "blamejs",
|
|
25
|
-
"version": "0.7.
|
|
25
|
+
"version": "0.7.24",
|
|
26
26
|
"scope": "required",
|
|
27
27
|
"author": "blamejs contributors",
|
|
28
28
|
"description": "The Node framework that owns its stack.",
|
|
29
|
-
"purl": "pkg:npm/%40blamejs/core@0.7.
|
|
29
|
+
"purl": "pkg:npm/%40blamejs/core@0.7.24",
|
|
30
30
|
"properties": [],
|
|
31
31
|
"externalReferences": [
|
|
32
32
|
{
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"components": [],
|
|
55
55
|
"dependencies": [
|
|
56
56
|
{
|
|
57
|
-
"ref": "@blamejs/core@0.7.
|
|
57
|
+
"ref": "@blamejs/core@0.7.24",
|
|
58
58
|
"dependsOn": []
|
|
59
59
|
}
|
|
60
60
|
]
|