@blamejs/blamejs-shop 0.2.12 → 0.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/lib/asset-manifest.json +3 -3
- package/lib/storefront.js +1 -1
- package/lib/vendor/MANIFEST.json +2 -2
- package/lib/vendor/blamejs/.github/workflows/actions-lint.yml +71 -23
- package/lib/vendor/blamejs/.github/workflows/cflite_batch.yml +2 -0
- package/lib/vendor/blamejs/.github/workflows/cflite_pr.yml +2 -0
- package/lib/vendor/blamejs/.github/workflows/ci.yml +17 -0
- package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +18 -10
- package/lib/vendor/blamejs/.github/workflows/release-container.yml +29 -16
- package/lib/vendor/blamejs/.github/workflows/sha-to-tag-verify.yml +22 -3
- package/lib/vendor/blamejs/.github/zizmor.yml +29 -0
- package/lib/vendor/blamejs/.pinact.yaml +24 -8
- package/lib/vendor/blamejs/CHANGELOG.md +4 -0
- package/lib/vendor/blamejs/api-snapshot.json +2 -2
- package/lib/vendor/blamejs/lib/archive-wrap.js +1 -1
- package/lib/vendor/blamejs/lib/auth/jwt.js +7 -4
- package/lib/vendor/blamejs/lib/auth/saml.js +2 -2
- package/lib/vendor/blamejs/lib/cose.js +1 -1
- package/lib/vendor/blamejs/lib/did.js +1 -1
- package/lib/vendor/blamejs/lib/guard-archive.js +2 -2
- package/lib/vendor/blamejs/lib/guard-auth.js +5 -5
- package/lib/vendor/blamejs/lib/guard-cidr.js +4 -4
- package/lib/vendor/blamejs/lib/guard-csv.js +6 -6
- package/lib/vendor/blamejs/lib/guard-domain.js +4 -4
- package/lib/vendor/blamejs/lib/guard-email.js +6 -5
- package/lib/vendor/blamejs/lib/guard-filename.js +4 -4
- package/lib/vendor/blamejs/lib/guard-graphql.js +5 -5
- package/lib/vendor/blamejs/lib/guard-html.js +2 -2
- package/lib/vendor/blamejs/lib/guard-image.js +1 -1
- package/lib/vendor/blamejs/lib/guard-json.js +5 -5
- package/lib/vendor/blamejs/lib/guard-jsonpath.js +4 -4
- package/lib/vendor/blamejs/lib/guard-jwt.js +5 -5
- package/lib/vendor/blamejs/lib/guard-markdown.js +6 -6
- package/lib/vendor/blamejs/lib/guard-mime.js +6 -6
- package/lib/vendor/blamejs/lib/guard-oauth.js +5 -5
- package/lib/vendor/blamejs/lib/guard-pdf.js +1 -1
- package/lib/vendor/blamejs/lib/guard-regex.js +4 -4
- package/lib/vendor/blamejs/lib/guard-shell.js +4 -4
- package/lib/vendor/blamejs/lib/guard-svg.js +5 -5
- package/lib/vendor/blamejs/lib/guard-template.js +4 -4
- package/lib/vendor/blamejs/lib/guard-time.js +6 -6
- package/lib/vendor/blamejs/lib/guard-uuid.js +6 -6
- package/lib/vendor/blamejs/lib/guard-xml.js +4 -4
- package/lib/vendor/blamejs/lib/guard-yaml.js +5 -5
- package/lib/vendor/blamejs/lib/link-header.js +3 -2
- package/lib/vendor/blamejs/lib/mail-agent.js +4 -2
- package/lib/vendor/blamejs/lib/middleware/rate-limit.js +2 -2
- package/lib/vendor/blamejs/lib/tsa.js +2 -1
- package/lib/vendor/blamejs/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.13.23.json +42 -0
- package/lib/vendor/blamejs/release-notes/v0.13.24.json +26 -0
- package/lib/vendor/blamejs/test/smoke.js +25 -0
- package/package.json +1 -1
|
@@ -505,7 +505,7 @@ function _detectIssues(input, opts) {
|
|
|
505
505
|
*
|
|
506
506
|
* @opts
|
|
507
507
|
* profile: "strict"|"balanced"|"permissive",
|
|
508
|
-
*
|
|
508
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
509
509
|
* bidiPolicy: "reject"|"strip"|"audit"|"allow",
|
|
510
510
|
* controlPolicy: "reject"|"strip"|"allow",
|
|
511
511
|
* nullBytePolicy: "reject"|"strip"|"allow",
|
|
@@ -568,7 +568,7 @@ function validate(input, opts) {
|
|
|
568
568
|
*
|
|
569
569
|
* @opts
|
|
570
570
|
* profile: "strict"|"balanced"|"permissive",
|
|
571
|
-
*
|
|
571
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
572
572
|
* ...: same shape as b.guardMarkdown.validate opts,
|
|
573
573
|
*
|
|
574
574
|
* @example
|
|
@@ -606,7 +606,7 @@ function sanitize(input, opts) {
|
|
|
606
606
|
* @compliance hipaa, pci-dss, gdpr, soc2
|
|
607
607
|
* @related b.guardMarkdown.validate, b.guardMarkdown.sanitize, b.guardAll.gate, b.staticServe.create
|
|
608
608
|
*
|
|
609
|
-
* Build
|
|
609
|
+
* Build a guard gate whose async `check(ctx)` returns `{ ok, action, issues }`, consumable
|
|
610
610
|
* by `b.guardAll`, `b.staticServe`, `b.fileUpload`, and any host
|
|
611
611
|
* that ingests user-supplied markdown. The gate decodes
|
|
612
612
|
* `ctx.bytes` / `ctx.bodyText`, runs `validate`, and maps
|
|
@@ -617,15 +617,15 @@ function sanitize(input, opts) {
|
|
|
617
617
|
* @opts
|
|
618
618
|
* name: string, // gate label for audit / observability
|
|
619
619
|
* profile: "strict"|"balanced"|"permissive",
|
|
620
|
-
*
|
|
620
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
621
621
|
* ...: same shape as b.guardMarkdown.validate opts,
|
|
622
622
|
*
|
|
623
623
|
* @example
|
|
624
624
|
* var g = b.guardMarkdown.gate({ profile: "strict" });
|
|
625
|
-
* var rv = await g({ bytes: Buffer.from("# hello\n", "utf8") });
|
|
625
|
+
* var rv = await g.check({ bytes: Buffer.from("# hello\n", "utf8") });
|
|
626
626
|
* rv.action; // → "serve"
|
|
627
627
|
*
|
|
628
|
-
* var bad = await g({ bytes: Buffer.from("[x](javascript:1)", "utf8") });
|
|
628
|
+
* var bad = await g.check({ bytes: Buffer.from("[x](javascript:1)", "utf8") });
|
|
629
629
|
* bad.action; // → "refuse"
|
|
630
630
|
*/
|
|
631
631
|
function gate(opts) {
|
|
@@ -369,7 +369,7 @@ function _detectIssues(input, opts) {
|
|
|
369
369
|
*
|
|
370
370
|
* @opts
|
|
371
371
|
* profile: "strict"|"balanced"|"permissive",
|
|
372
|
-
*
|
|
372
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
373
373
|
* bidiPolicy: "reject"|"strip"|"audit"|"allow",
|
|
374
374
|
* controlPolicy: "reject"|"strip"|"allow",
|
|
375
375
|
* nullBytePolicy: "reject"|"strip"|"allow",
|
|
@@ -423,7 +423,7 @@ function validate(input, opts) {
|
|
|
423
423
|
*
|
|
424
424
|
* @opts
|
|
425
425
|
* profile: "strict"|"balanced"|"permissive",
|
|
426
|
-
*
|
|
426
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
427
427
|
* ...: same shape as b.guardMime.validate opts,
|
|
428
428
|
*
|
|
429
429
|
* @example
|
|
@@ -467,7 +467,7 @@ function sanitize(input, opts) {
|
|
|
467
467
|
* @compliance hipaa, pci-dss, gdpr, soc2
|
|
468
468
|
* @related b.guardMime.validate, b.guardMime.sanitize, b.guardAll.gate
|
|
469
469
|
*
|
|
470
|
-
* Build
|
|
470
|
+
* Build a guard gate whose async `check(ctx)` returns `{ ok, action, issues }`, consumable
|
|
471
471
|
* by `b.guardAll`, `b.staticServe`, `b.fileUpload`, and any other
|
|
472
472
|
* host that integrates the guard contract. The gate reads
|
|
473
473
|
* `ctx.identifier` (or `ctx.mime`), runs `validate`, and maps
|
|
@@ -477,15 +477,15 @@ function sanitize(input, opts) {
|
|
|
477
477
|
* @opts
|
|
478
478
|
* name: string, // gate label for audit / observability
|
|
479
479
|
* profile: "strict"|"balanced"|"permissive",
|
|
480
|
-
*
|
|
480
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
481
481
|
* ...: same shape as b.guardMime.validate opts,
|
|
482
482
|
*
|
|
483
483
|
* @example
|
|
484
484
|
* var g = b.guardMime.gate({ profile: "strict" });
|
|
485
|
-
* var rv = await g({ identifier: "application/json" });
|
|
485
|
+
* var rv = await g.check({ identifier: "application/json" });
|
|
486
486
|
* rv.action; // → "serve"
|
|
487
487
|
*
|
|
488
|
-
* var bad = await g({ identifier: "application/x-msdownload" });
|
|
488
|
+
* var bad = await g.check({ identifier: "application/x-msdownload" });
|
|
489
489
|
* bad.action; // → "refuse"
|
|
490
490
|
*/
|
|
491
491
|
function gate(opts) {
|
|
@@ -352,7 +352,7 @@ function _detectIssues(flow, opts) {
|
|
|
352
352
|
* @related b.guardOauth.sanitize, b.guardOauth.gate
|
|
353
353
|
*
|
|
354
354
|
* Apply the full guard-oauth threat catalog to a flow bundle.
|
|
355
|
-
* Returns `{ ok, issues
|
|
355
|
+
* Returns `{ ok, issues }` per
|
|
356
356
|
* `gateContract.aggregateIssues`. Detected classes include
|
|
357
357
|
* `pkce-missing`, `pkce-method` (e.g. plain under require-s256),
|
|
358
358
|
* `state-missing`, `redirect-uri-not-allowed`,
|
|
@@ -365,7 +365,7 @@ function _detectIssues(flow, opts) {
|
|
|
365
365
|
*
|
|
366
366
|
* @opts
|
|
367
367
|
* profile: "strict"|"balanced"|"permissive",
|
|
368
|
-
*
|
|
368
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
369
369
|
* pkcePolicy: "require-s256"|"require-any"|"audit"|"allow",
|
|
370
370
|
* statePolicy: "require"|"audit"|"allow",
|
|
371
371
|
* redirectUriPolicy: "require-exact-allowlist"|"audit"|"allow",
|
|
@@ -427,7 +427,7 @@ function validate(input, opts) {
|
|
|
427
427
|
*
|
|
428
428
|
* @opts
|
|
429
429
|
* profile: "strict"|"balanced"|"permissive",
|
|
430
|
-
*
|
|
430
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
431
431
|
* ...: every guardOauth.validate opt is honored,
|
|
432
432
|
*
|
|
433
433
|
* @example
|
|
@@ -475,7 +475,7 @@ function sanitize(input, opts) {
|
|
|
475
475
|
*
|
|
476
476
|
* @opts
|
|
477
477
|
* profile: "strict"|"balanced"|"permissive",
|
|
478
|
-
*
|
|
478
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
479
479
|
* name: string, // gate label for audit trails
|
|
480
480
|
* ...: every guardOauth.validate opt is honored,
|
|
481
481
|
*
|
|
@@ -484,7 +484,7 @@ function sanitize(input, opts) {
|
|
|
484
484
|
* profile: "strict",
|
|
485
485
|
* allowedRedirectUris: ["https://app.example.com/callback"],
|
|
486
486
|
* });
|
|
487
|
-
* var rv = await oauthGate.
|
|
487
|
+
* var rv = await oauthGate.check({
|
|
488
488
|
* oauthFlow: {
|
|
489
489
|
* response_type: "code",
|
|
490
490
|
* redirect_uri: "https://attacker.example/callback",
|
|
@@ -410,7 +410,7 @@ function sanitize(input, opts) {
|
|
|
410
410
|
*
|
|
411
411
|
* @opts
|
|
412
412
|
* profile: "strict"|"balanced"|"permissive",
|
|
413
|
-
*
|
|
413
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
414
414
|
* name: string,
|
|
415
415
|
* ...: any validate opt
|
|
416
416
|
*
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* Profiles: `strict` / `balanced` / `permissive`. Compliance
|
|
31
31
|
* postures: `hipaa` / `pci-dss` / `gdpr` / `soc2`. Operators
|
|
32
32
|
* select via `{ profile: "strict" }` or
|
|
33
|
-
* `{
|
|
33
|
+
* `{ compliancePosture: "hipaa" }`; postures overlay on top of the
|
|
34
34
|
* profile baseline. Nested-quantifier rejection holds at every
|
|
35
35
|
* profile — the catastrophic class is never an operator opt-in.
|
|
36
36
|
*
|
|
@@ -368,7 +368,7 @@ function _detectNestedExtglob(input, opts, issues) {
|
|
|
368
368
|
*
|
|
369
369
|
* @opts
|
|
370
370
|
* profile: "strict"|"balanced"|"permissive",
|
|
371
|
-
*
|
|
371
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
372
372
|
* bidiPolicy: "reject"|"audit"|"allow",
|
|
373
373
|
* controlPolicy: "reject"|"audit"|"allow",
|
|
374
374
|
* nullBytePolicy: "reject"|"audit"|"allow",
|
|
@@ -422,7 +422,7 @@ function validate(input, opts) {
|
|
|
422
422
|
*
|
|
423
423
|
* @opts
|
|
424
424
|
* profile: "strict"|"balanced"|"permissive",
|
|
425
|
-
*
|
|
425
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
426
426
|
* nestedQuantPolicy: "reject"|"audit"|"allow",
|
|
427
427
|
* alternationQuantPolicy: "reject"|"audit"|"allow",
|
|
428
428
|
* boundedRepeatPolicy: "reject"|"audit"|"allow",
|
|
@@ -477,7 +477,7 @@ function sanitize(input, opts) {
|
|
|
477
477
|
*
|
|
478
478
|
* @opts
|
|
479
479
|
* profile: "strict"|"balanced"|"permissive",
|
|
480
|
-
*
|
|
480
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
481
481
|
* name: string, // override gate name in audit emissions
|
|
482
482
|
* nestedQuantPolicy: "reject"|"audit"|"allow",
|
|
483
483
|
* alternationQuantPolicy: "reject"|"audit"|"allow",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
*
|
|
29
29
|
* Profiles: `strict` / `balanced` / `permissive`. Compliance
|
|
30
30
|
* postures: `hipaa` / `pci-dss` / `gdpr` / `soc2`. Operators select
|
|
31
|
-
* via `{ profile: "strict" }` or `{
|
|
31
|
+
* via `{ profile: "strict" }` or `{ compliancePosture: "hipaa" }`;
|
|
32
32
|
* postures overlay on top of the profile baseline.
|
|
33
33
|
*
|
|
34
34
|
* Shell args cannot be repaired safely — `sanitize` either passes
|
|
@@ -262,7 +262,7 @@ function _detectIssues(input, opts) {
|
|
|
262
262
|
*
|
|
263
263
|
* @opts
|
|
264
264
|
* profile: "strict"|"balanced"|"permissive",
|
|
265
|
-
*
|
|
265
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
266
266
|
* bidiPolicy: "reject"|"audit"|"allow",
|
|
267
267
|
* controlPolicy: "reject"|"audit"|"allow",
|
|
268
268
|
* nullBytePolicy: "reject"|"audit"|"allow",
|
|
@@ -314,7 +314,7 @@ function validate(input, opts) {
|
|
|
314
314
|
*
|
|
315
315
|
* @opts
|
|
316
316
|
* profile: "strict"|"balanced"|"permissive",
|
|
317
|
-
*
|
|
317
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
318
318
|
* posixMetaPolicy: "reject"|"audit"|"allow",
|
|
319
319
|
* cmdMetaPolicy: "reject"|"audit"|"allow",
|
|
320
320
|
* dollarSubstPolicy: "reject"|"audit"|"allow",
|
|
@@ -369,7 +369,7 @@ function sanitize(input, opts) {
|
|
|
369
369
|
*
|
|
370
370
|
* @opts
|
|
371
371
|
* profile: "strict"|"balanced"|"permissive",
|
|
372
|
-
*
|
|
372
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
373
373
|
* name: string, // override gate name in audit emissions
|
|
374
374
|
* posixMetaPolicy: "reject"|"audit"|"allow",
|
|
375
375
|
* cmdMetaPolicy: "reject"|"audit"|"allow",
|
|
@@ -1017,9 +1017,9 @@ function sanitize(input, opts) {
|
|
|
1017
1017
|
* @status stable
|
|
1018
1018
|
* @related b.guardSvg.validate, b.guardSvg.sanitize, b.fileUpload, b.staticServe
|
|
1019
1019
|
*
|
|
1020
|
-
* Build a uniform gate over guard-* family contract. Returns
|
|
1021
|
-
* async
|
|
1022
|
-
* sanitized? }` where `action` is `serve` / `audit-only` /
|
|
1020
|
+
* Build a uniform gate over the guard-* family contract. Returns a
|
|
1021
|
+
* gate whose async `check(ctx)` produces a verdict `{ ok, action,
|
|
1022
|
+
* issues?, sanitized? }` where `action` is `serve` / `audit-only` /
|
|
1023
1023
|
* `sanitize` / `refuse`. SVGZ inputs always refuse — operators
|
|
1024
1024
|
* ungzip and re-gate the inner SVG. External `xlink:href` on
|
|
1025
1025
|
* `<use>` / `<feImage>` refuses under `strict` (SSRF + XSS chain).
|
|
@@ -1042,13 +1042,13 @@ function sanitize(input, opts) {
|
|
|
1042
1042
|
*
|
|
1043
1043
|
* @example
|
|
1044
1044
|
* var g = b.guardSvg.gate({ profile: "strict" });
|
|
1045
|
-
* var verdict = await g({
|
|
1045
|
+
* var verdict = await g.check({
|
|
1046
1046
|
* bytes: Buffer.from('<svg><circle r="10"/></svg>', "utf8"),
|
|
1047
1047
|
* });
|
|
1048
1048
|
* verdict.action; // → "serve"
|
|
1049
1049
|
*
|
|
1050
1050
|
* // Refuses external xlink:href under strict:
|
|
1051
|
-
* var refuse = await g({
|
|
1051
|
+
* var refuse = await g.check({
|
|
1052
1052
|
* bytes: Buffer.from(
|
|
1053
1053
|
* '<svg><use xlink:href="https://evil.example/x.svg#a"/></svg>',
|
|
1054
1054
|
* "utf8"),
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
* Profiles: `strict` / `balanced` / `permissive`. Compliance
|
|
35
35
|
* postures: `hipaa` / `pci-dss` / `gdpr` / `soc2`. Operators
|
|
36
36
|
* select via `{ profile: "strict" }` or
|
|
37
|
-
* `{
|
|
37
|
+
* `{ compliancePosture: "hipaa" }`; postures overlay on top of the
|
|
38
38
|
* profile baseline. Jinja / ERB / Pug shape rejection holds at
|
|
39
39
|
* every profile — the SSTI class is never an operator opt-in.
|
|
40
40
|
*
|
|
@@ -237,7 +237,7 @@ function _detectIssues(input, opts) {
|
|
|
237
237
|
*
|
|
238
238
|
* @opts
|
|
239
239
|
* profile: "strict"|"balanced"|"permissive",
|
|
240
|
-
*
|
|
240
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
241
241
|
* bidiPolicy: "reject"|"audit"|"allow",
|
|
242
242
|
* controlPolicy: "reject"|"audit"|"allow",
|
|
243
243
|
* nullBytePolicy: "reject"|"audit"|"allow",
|
|
@@ -287,7 +287,7 @@ function validate(input, opts) {
|
|
|
287
287
|
*
|
|
288
288
|
* @opts
|
|
289
289
|
* profile: "strict"|"balanced"|"permissive",
|
|
290
|
-
*
|
|
290
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
291
291
|
* jinjaPolicy: "reject"|"audit"|"allow",
|
|
292
292
|
* erbPolicy: "reject"|"audit"|"allow",
|
|
293
293
|
* pugPolicy: "reject"|"audit"|"allow",
|
|
@@ -339,7 +339,7 @@ function sanitize(input, opts) {
|
|
|
339
339
|
*
|
|
340
340
|
* @opts
|
|
341
341
|
* profile: "strict"|"balanced"|"permissive",
|
|
342
|
-
*
|
|
342
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
343
343
|
* name: string, // override gate name in audit emissions
|
|
344
344
|
* jinjaPolicy: "reject"|"audit"|"allow",
|
|
345
345
|
* erbPolicy: "reject"|"audit"|"allow",
|
|
@@ -347,7 +347,7 @@ function _detectIssues(input, opts) {
|
|
|
347
347
|
*
|
|
348
348
|
* @opts
|
|
349
349
|
* profile: "strict"|"balanced"|"permissive",
|
|
350
|
-
*
|
|
350
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
351
351
|
* bidiPolicy: "reject"|"strip"|"audit"|"allow",
|
|
352
352
|
* controlPolicy: "reject"|"strip"|"allow",
|
|
353
353
|
* nullBytePolicy: "reject"|"strip"|"allow",
|
|
@@ -403,7 +403,7 @@ function validate(input, opts) {
|
|
|
403
403
|
*
|
|
404
404
|
* @opts
|
|
405
405
|
* profile: "strict"|"balanced"|"permissive",
|
|
406
|
-
*
|
|
406
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
407
407
|
* ...: same shape as b.guardTime.validate opts,
|
|
408
408
|
*
|
|
409
409
|
* @example
|
|
@@ -442,7 +442,7 @@ function sanitize(input, opts) {
|
|
|
442
442
|
* @compliance hipaa, pci-dss, gdpr, soc2
|
|
443
443
|
* @related b.guardTime.validate, b.guardTime.sanitize, b.guardAll.gate
|
|
444
444
|
*
|
|
445
|
-
* Build
|
|
445
|
+
* Build a guard gate whose async `check(ctx)` returns `{ ok, action, issues }`, consumable
|
|
446
446
|
* by `b.guardAll`, audit pipelines, scheduling primitives, and
|
|
447
447
|
* retention readers. The gate reads `ctx.identifier` (or
|
|
448
448
|
* `ctx.timestamp` / `ctx.time`), runs `validate`, and maps
|
|
@@ -452,15 +452,15 @@ function sanitize(input, opts) {
|
|
|
452
452
|
* @opts
|
|
453
453
|
* name: string, // gate label for audit / observability
|
|
454
454
|
* profile: "strict"|"balanced"|"permissive",
|
|
455
|
-
*
|
|
455
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
456
456
|
* ...: same shape as b.guardTime.validate opts,
|
|
457
457
|
*
|
|
458
458
|
* @example
|
|
459
459
|
* var g = b.guardTime.gate({ profile: "strict" });
|
|
460
|
-
* var rv = await g({ identifier: "2026-05-05T12:34:56Z" });
|
|
460
|
+
* var rv = await g.check({ identifier: "2026-05-05T12:34:56Z" });
|
|
461
461
|
* rv.action; // → "serve"
|
|
462
462
|
*
|
|
463
|
-
* var bad = await g({ identifier: "2026-05-05 12:34:56" });
|
|
463
|
+
* var bad = await g.check({ identifier: "2026-05-05 12:34:56" });
|
|
464
464
|
* bad.action; // → "refuse"
|
|
465
465
|
*/
|
|
466
466
|
function gate(opts) {
|
|
@@ -307,7 +307,7 @@ function _detectIssues(input, opts) {
|
|
|
307
307
|
*
|
|
308
308
|
* @opts
|
|
309
309
|
* profile: "strict"|"balanced"|"permissive",
|
|
310
|
-
*
|
|
310
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
311
311
|
* bidiPolicy: "reject"|"strip"|"audit"|"allow",
|
|
312
312
|
* controlPolicy: "reject"|"strip"|"allow",
|
|
313
313
|
* nullBytePolicy: "reject"|"strip"|"allow",
|
|
@@ -361,7 +361,7 @@ function validate(input, opts) {
|
|
|
361
361
|
*
|
|
362
362
|
* @opts
|
|
363
363
|
* profile: "strict"|"balanced"|"permissive",
|
|
364
|
-
*
|
|
364
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
365
365
|
* ...: same shape as b.guardUuid.validate opts,
|
|
366
366
|
*
|
|
367
367
|
* @example
|
|
@@ -406,7 +406,7 @@ function sanitize(input, opts) {
|
|
|
406
406
|
* @compliance hipaa, pci-dss, gdpr, soc2
|
|
407
407
|
* @related b.guardUuid.validate, b.guardUuid.sanitize, b.guardAll.gate
|
|
408
408
|
*
|
|
409
|
-
* Build
|
|
409
|
+
* Build a guard gate whose async `check(ctx)` returns `{ ok, action, issues }`, consumable
|
|
410
410
|
* by `b.guardAll`, ID validators, and any host that handles
|
|
411
411
|
* UUID-shaped tokens. The gate reads `ctx.identifier` (or
|
|
412
412
|
* `ctx.uuid`), runs `validate`, and maps severity to action: zero
|
|
@@ -416,15 +416,15 @@ function sanitize(input, opts) {
|
|
|
416
416
|
* @opts
|
|
417
417
|
* name: string, // gate label for audit / observability
|
|
418
418
|
* profile: "strict"|"balanced"|"permissive",
|
|
419
|
-
*
|
|
419
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
420
420
|
* ...: same shape as b.guardUuid.validate opts,
|
|
421
421
|
*
|
|
422
422
|
* @example
|
|
423
423
|
* var g = b.guardUuid.gate({ profile: "strict" });
|
|
424
|
-
* var rv = await g({ identifier: "550e8400-e29b-41d4-a716-446655440000" });
|
|
424
|
+
* var rv = await g.check({ identifier: "550e8400-e29b-41d4-a716-446655440000" });
|
|
425
425
|
* rv.action; // → "serve"
|
|
426
426
|
*
|
|
427
|
-
* var bad = await g({ identifier: "{550e8400-e29b-41d4-a716-446655440000}" });
|
|
427
|
+
* var bad = await g.check({ identifier: "{550e8400-e29b-41d4-a716-446655440000}" });
|
|
428
428
|
* bad.action; // → "refuse"
|
|
429
429
|
*/
|
|
430
430
|
function gate(opts) {
|
|
@@ -371,7 +371,7 @@ function _detectIssues(input, opts) {
|
|
|
371
371
|
*
|
|
372
372
|
* Inspect `input` (string of XML source) for the full guard-xml
|
|
373
373
|
* threat catalog without invoking a parser. Returns
|
|
374
|
-
* `{ ok, issues
|
|
374
|
+
* `{ ok, issues }` where `issues` enumerates every
|
|
375
375
|
* DOCTYPE declaration, `<!ENTITY>` definition (including parameter
|
|
376
376
|
* entities), SYSTEM/PUBLIC external-entity reference, XInclude
|
|
377
377
|
* directive, xsi:schemaLocation hint, processing instruction (after
|
|
@@ -388,7 +388,7 @@ function _detectIssues(input, opts) {
|
|
|
388
388
|
*
|
|
389
389
|
* @opts
|
|
390
390
|
* profile: "strict"|"balanced"|"permissive",
|
|
391
|
-
*
|
|
391
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
392
392
|
* doctypePolicy: "reject"|"audit"|"allow",
|
|
393
393
|
* entityPolicy: "reject"|"audit"|"allow",
|
|
394
394
|
* externalEntityPolicy: "reject"|"audit"|"allow",
|
|
@@ -455,7 +455,7 @@ function validate(input, opts) {
|
|
|
455
455
|
*
|
|
456
456
|
* @opts
|
|
457
457
|
* profile: "strict"|"balanced"|"permissive",
|
|
458
|
-
*
|
|
458
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
459
459
|
* bidiPolicy: "reject"|"strip"|"audit"|"allow",
|
|
460
460
|
* controlPolicy: "reject"|"strip"|"allow",
|
|
461
461
|
* nullBytePolicy: "reject"|"strip"|"allow",
|
|
@@ -514,7 +514,7 @@ function sanitize(input, opts) {
|
|
|
514
514
|
*
|
|
515
515
|
* @opts
|
|
516
516
|
* profile: "strict"|"balanced"|"permissive",
|
|
517
|
-
*
|
|
517
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
518
518
|
* name: string, // gate identity for audit / observability
|
|
519
519
|
*
|
|
520
520
|
* @example
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
*
|
|
59
59
|
* Profiles: `strict` / `balanced` / `permissive`. Compliance
|
|
60
60
|
* postures: `hipaa` / `pci-dss` / `gdpr` / `soc2`. Operators select
|
|
61
|
-
* via `{ profile: "strict" }` or `{
|
|
61
|
+
* via `{ profile: "strict" }` or `{ compliancePosture: "hipaa" }`;
|
|
62
62
|
* postures overlay on top of the profile baseline.
|
|
63
63
|
*
|
|
64
64
|
* @card
|
|
@@ -452,7 +452,7 @@ function _detectDuplicateKeysYaml(text) {
|
|
|
452
452
|
*
|
|
453
453
|
* Inspect `input` (string of YAML source) for the full guard-yaml
|
|
454
454
|
* threat catalog without committing to a parsed value. Returns
|
|
455
|
-
* `{ ok, issues
|
|
455
|
+
* `{ ok, issues }` where `issues` is the aggregated
|
|
456
456
|
* detector output — every dangerous-tag prefix, custom-tag use,
|
|
457
457
|
* anchor / alias amplification, multi-document split, Norway-
|
|
458
458
|
* problem implicit boolean, leading-zero octal, merge-key chain,
|
|
@@ -468,7 +468,7 @@ function _detectDuplicateKeysYaml(text) {
|
|
|
468
468
|
*
|
|
469
469
|
* @opts
|
|
470
470
|
* profile: "strict"|"balanced"|"permissive",
|
|
471
|
-
*
|
|
471
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
472
472
|
* tagPolicy: "reject"|"audit"|"allow",
|
|
473
473
|
* aliasPolicy: "reject"|"audit"|"allow",
|
|
474
474
|
* multiDocPolicy: "reject"|"audit"|"allow",
|
|
@@ -535,7 +535,7 @@ function validate(input, opts) {
|
|
|
535
535
|
*
|
|
536
536
|
* @opts
|
|
537
537
|
* profile: "strict"|"balanced"|"permissive",
|
|
538
|
-
*
|
|
538
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
539
539
|
* tagPolicy: "reject"|"audit"|"allow",
|
|
540
540
|
* aliasPolicy: "reject"|"audit"|"allow",
|
|
541
541
|
* maxBytes: number, maxDepth: number, maxNodes: number,
|
|
@@ -586,7 +586,7 @@ function parse(input, opts) {
|
|
|
586
586
|
*
|
|
587
587
|
* @opts
|
|
588
588
|
* profile: "strict"|"balanced"|"permissive",
|
|
589
|
-
*
|
|
589
|
+
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
590
590
|
* name: string, // gate identity for audit / observability
|
|
591
591
|
*
|
|
592
592
|
* @example
|
|
@@ -125,8 +125,9 @@ function _serParam(name, value) {
|
|
|
125
125
|
* Build an HTTP <code>Link</code> header value from an array of
|
|
126
126
|
* <code>{ uri, rel, params? }</code> (or a single such object). The URI
|
|
127
127
|
* is angle-bracketed, <code>rel</code> (string or array) is emitted
|
|
128
|
-
* first, and
|
|
129
|
-
*
|
|
128
|
+
* first, and every parameter value is double-quoted (always valid under
|
|
129
|
+
* RFC 8288, and required for space-separated multi-rel and media-type
|
|
130
|
+
* values like <code>text/html</code>). Useful for emitting standard REST
|
|
130
131
|
* pagination links.
|
|
131
132
|
*
|
|
132
133
|
* @example
|
|
@@ -156,8 +156,10 @@ var COMPOSE_HINT = Object.freeze({
|
|
|
156
156
|
* @related b.mailStore, b.mail.agent.consumer
|
|
157
157
|
*
|
|
158
158
|
* Create the agent facade. Returns an object with read / write / sieve
|
|
159
|
-
* / identity / mdn / export / import
|
|
160
|
-
* synchronous-shaped via promises; writes audit on completion.
|
|
159
|
+
* / identity / mdn / export / import methods. Reads stay
|
|
160
|
+
* synchronous-shaped via promises; writes audit on completion. (The
|
|
161
|
+
* queue consumer is the sibling export <code>b.mail.agent.consumer</code>,
|
|
162
|
+
* not a method on this object.)
|
|
161
163
|
*
|
|
162
164
|
* @opts
|
|
163
165
|
* store: b.mailStore instance, // required
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
* header: true // set X-RateLimit-* response headers
|
|
37
37
|
* skipPaths: [] // string-prefix or regex matchers
|
|
38
38
|
* scope: 'global' | 'per-route' (default 'global')
|
|
39
|
-
* backend: 'memory' (default) | 'cluster' | { take, reset
|
|
39
|
+
* backend: 'memory' (default) | 'cluster' | { take, reset }
|
|
40
40
|
* algorithm: 'token-bucket' (default) | 'fixed-window'
|
|
41
41
|
* // memory backend only; ignored
|
|
42
42
|
* // for cluster backend (which is
|
|
@@ -366,7 +366,7 @@ function _resolveBackend(opts) {
|
|
|
366
366
|
* header: boolean, // default true
|
|
367
367
|
* skipPaths: Array<string|RegExp>,
|
|
368
368
|
* scope: "global"|"per-route",
|
|
369
|
-
* backend: "memory"|"cluster"|{ take, reset
|
|
369
|
+
* backend: "memory"|"cluster"|{ take, reset },
|
|
370
370
|
* algorithm: "token-bucket"|"fixed-window",
|
|
371
371
|
* burst: number,
|
|
372
372
|
* refillPerSecond: number,
|
|
@@ -183,7 +183,8 @@ function buildRequest(data, opts) {
|
|
|
183
183
|
nonce = Buffer.isBuffer(opts.nonce) ? opts.nonce : nodeCrypto.randomBytes(8); // allow:raw-byte-literal — RFC 3161 nonce: 64-bit random
|
|
184
184
|
children.push(asn1.writeInteger(nonce));
|
|
185
185
|
}
|
|
186
|
-
// certReq
|
|
186
|
+
// certReq DEFAULTS TRUE (RFC 3161 §2.4.1) — encode the boolean unless
|
|
187
|
+
// the caller explicitly opts out with certReq:false.
|
|
187
188
|
var certReq = opts.certReq !== false;
|
|
188
189
|
if (certReq) children.push(asn1.writeBoolean(true));
|
|
189
190
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../scripts/release-notes-schema.json",
|
|
3
|
+
"version": "0.13.23",
|
|
4
|
+
"date": "2026-05-28",
|
|
5
|
+
"headline": "Documentation corrected to match actual behavior across several primitives",
|
|
6
|
+
"summary": "A set of JSDoc / doc-comment corrections where the documented contract had drifted from what the code does. No behavior changes — the implementations already behaved as now documented; only the docs were wrong. The most operator-relevant is the JWT signer doc: an expiring token signed without an explicit jti receives an auto-minted 128-bit jti (so the replay-defense path has the jti it needs), which the sign-opts doc previously denied. Also corrected: did.resolve's unsupported-method error now names did:jwk (always supported); b.cose.verify is marked stable to match its stable sign sibling and the CWT / EAT / SCITT / mdoc verifiers built on it; b.linkHeader.serialize's doc now states every parameter value is double-quoted; b.auth.saml verifyResponse's documented return shape now lists inResponseTo and issuer (both always returned); and the rate-limit custom-backend contract drops a gc member the middleware never invoked.",
|
|
7
|
+
"sections": [
|
|
8
|
+
{
|
|
9
|
+
"heading": "Fixed",
|
|
10
|
+
"items": [
|
|
11
|
+
{
|
|
12
|
+
"title": "JWT signer doc now describes the auto-minted jti on expiring tokens",
|
|
13
|
+
"body": "`b.auth.jwt.sign`'s opts doc claimed that omitting `jti` adds no jti. In fact, when a token carries an `exp` and no operator-supplied `jti`, the signer auto-mints a random 128-bit `jti` so a replay-protected token always carries the identifier `verify`'s replay store requires. The doc now describes this; pass an explicit `jti` for a deterministic value. Behavior is unchanged."
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"title": "`b.did.resolve` unsupported-method error now names did:jwk",
|
|
17
|
+
"body": "The thrown error for an unsupported DID method listed only `did:key` and `did:web`, omitting `did:jwk`, which `resolve` fully supports. The message now reads `(did:key, did:jwk, and did:web only)`."
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"title": "`b.cose.verify` marked stable",
|
|
21
|
+
"body": "`b.cose.verify` carried `@status experimental` while its `b.cose.sign` sibling is stable and the CWT / EAT / SCITT / mdoc verifiers that depend on it are stable and shipped. The verifier is the same maturity as the rest of the COSE_Sign1 round-trip; its status now reflects that."
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"title": "`b.linkHeader.serialize` doc matches its quoting behavior",
|
|
25
|
+
"body": "The doc said parameters are token-encoded when they fit RFC 7230 token grammar and double-quoted otherwise. The serializer always double-quotes every value (valid under RFC 8288, and required for space-separated multi-rel and media-type values). The doc now states that."
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"title": "`b.auth.saml` verifyResponse documented return shape lists all fields",
|
|
29
|
+
"body": "The prose and the example each omitted a different field that `verifyResponse` always returns. The documented shape now lists all of `nameId`, `nameIdFormat`, `sessionIndex`, `attributes`, `audience`, `inResponseTo`, and `issuer`."
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"title": "rate-limit custom-backend contract is `{ take, reset }`",
|
|
33
|
+
"body": "The custom-backend opts doc listed a `gc` member that the middleware never reads or invokes (the runtime contract is `take` / `reset` / `close`, and the error message already said `{ take, reset }`). The documented shape now matches; an operator-supplied `gc` was always silently ignored."
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"title": "`b.mail.agent.create` doc no longer lists consumer as a method",
|
|
37
|
+
"body": "The created agent's method list named `consumer`, which is not a method on the returned object — the queue consumer is the sibling export `b.mail.agent.consumer`. The doc now says so."
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../scripts/release-notes-schema.json",
|
|
3
|
+
"version": "0.13.24",
|
|
4
|
+
"date": "2026-05-28",
|
|
5
|
+
"headline": "`b.guard*` docs corrected: the compliance-posture opt key, the gate API, and validate return shapes",
|
|
6
|
+
"summary": "Documentation corrections across the b.guard* family. The most consequential: the posture-selection option was documented as `compliance:` in many guards' @opts, but the working key is `compliancePosture:` — passing the documented `{ compliance: \"hipaa\" }` was silently ignored, so a compliance posture (e.g. HIPAA PII redaction) never activated. If you select a posture via the gate/validate/sanitize options, use `compliancePosture:`; `compliance:` had no effect. The guard docs now name the correct key uniformly. Also corrected: gate examples and prose that invoked the gate as a callable or via `.run` / `.inspect` (the gate is an object whose method is `.check(ctx)`), and validate() return shapes that listed `severities` / `summary` / `refusal` fields the function never returned (it returns `{ ok, issues }`).",
|
|
7
|
+
"sections": [
|
|
8
|
+
{
|
|
9
|
+
"heading": "Fixed",
|
|
10
|
+
"items": [
|
|
11
|
+
{
|
|
12
|
+
"title": "guard posture option is `compliancePosture:`, not `compliance:`",
|
|
13
|
+
"body": "Many `b.guard*` primitives documented the compliance-posture selector as `compliance: \"hipaa\"|\"pci-dss\"|\"gdpr\"|\"soc2\"` in their `@opts`, but the family resolver reads `compliancePosture:`. Passing `{ compliance: \"hipaa\" }` was accepted and silently ignored — the posture overlay (e.g. CSV `piiPolicy: \"redact\"` under HIPAA) never applied, leaving the default policy in force. The docs across the guard family now name `compliancePosture:` consistently (the key the resolver and `b.guardX.compliancePosture(name)` already used). Action: if you selected a posture with `compliance:`, switch to `compliancePosture:` — the posture was not taking effect before."
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"title": "guard gate is an object with `.check(ctx)`, not a callable",
|
|
17
|
+
"body": "Several guards' gate `@example`s and prose invoked the gate as a function (`g({...})`), via `.run(...)`, or via `.inspect(...)`, and a few described it as \"an async function\". `b.guardX.gate(opts)` returns an object whose async method is `.check(ctx)`; the examples and prose now use `.check`, so they run as written."
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"title": "guard validate() returns `{ ok, issues }`",
|
|
21
|
+
"body": "Several guards documented `validate()` as returning `{ ok, issues, severities }`, `{ ok, issues, summary }`, or `{ ok, issues, refusal? }`. The function returns `{ ok, issues }` (each issue carries its own `severity` / `kind`); the documented extra top-level fields were never present. The docs now state the actual shape."
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
@@ -472,6 +472,31 @@ function _checkChangelogInSync() {
|
|
|
472
472
|
await _runLayer(5, path.join(__dirname, "50-integration.js"), "Layer 5");
|
|
473
473
|
|
|
474
474
|
console.log("OK — " + helpers.getChecks() + " checks passed (" + (Date.now() - smokeStart) + "ms total)");
|
|
475
|
+
|
|
476
|
+
// Deterministic exit on success. The .catch() below exits 1 on
|
|
477
|
+
// failure; the success path historically fell through and relied on
|
|
478
|
+
// the event loop draining on its own. A lingering handle (a forked-
|
|
479
|
+
// child stdio pipe, a Layer-5 integration server whose socket did not
|
|
480
|
+
// fully close, an unref-missed timer) then keeps the process alive
|
|
481
|
+
// after the suite finished, burning the CI job's timeout budget until
|
|
482
|
+
// the runner cancels it — observed on the slow macos-latest runner
|
|
483
|
+
// (OK printed, ~3.5 min idle, job-timeout cancel). Reap it here: if
|
|
484
|
+
// anything still holds the loop open, name the handle kinds so a real
|
|
485
|
+
// resource leak surfaces in the log rather than being silently masked,
|
|
486
|
+
// then exit 0.
|
|
487
|
+
var _stdio = [process.stdout, process.stderr, process.stdin];
|
|
488
|
+
var _lingering = (typeof process._getActiveHandles === "function"
|
|
489
|
+
? process._getActiveHandles() : []).filter(function (h) { return _stdio.indexOf(h) === -1; });
|
|
490
|
+
if (_lingering.length > 0) {
|
|
491
|
+
var _kinds = {};
|
|
492
|
+
_lingering.forEach(function (h) {
|
|
493
|
+
var name = (h && h.constructor && h.constructor.name) || typeof h;
|
|
494
|
+
_kinds[name] = (_kinds[name] || 0) + 1;
|
|
495
|
+
});
|
|
496
|
+
console.error("smoke: " + _lingering.length + " handle(s) still open after pass — forcing exit. kinds: " +
|
|
497
|
+
Object.keys(_kinds).map(function (k) { return k + "x" + _kinds[k]; }).join(", "));
|
|
498
|
+
}
|
|
499
|
+
process.exit(0);
|
|
475
500
|
})().catch(function (err) {
|
|
476
501
|
console.error("SMOKE TEST FAILED:", err.message);
|
|
477
502
|
console.error(err.stack);
|