@blamejs/core 0.18.43 → 0.18.44
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 +106 -0
- package/NOTICE +1 -1
- package/README.md +3 -2
- package/index.js +2 -0
- package/lib/chain-writer.js +103 -4
- package/lib/file-type.js +19 -2
- package/lib/framework-error.js +10 -0
- package/lib/gate-contract.js +255 -12
- package/lib/guard-all.js +1 -0
- package/lib/guard-archive.js +14 -0
- package/lib/guard-auth.js +1 -3
- package/lib/guard-country.js +480 -0
- package/lib/guard-csv.js +5 -0
- package/lib/guard-email.js +7 -7
- package/lib/guard-filename.js +11 -9
- package/lib/guard-graphql.js +1 -3
- package/lib/guard-html.js +6 -7
- package/lib/guard-image.js +15 -1
- package/lib/guard-json.js +3 -7
- package/lib/guard-jwt.js +8 -3
- package/lib/guard-markdown.js +946 -2
- package/lib/guard-oauth.js +1 -3
- package/lib/guard-pdf.js +8 -0
- package/lib/guard-regex.js +5 -4
- package/lib/guard-smtp-command.js +4 -2
- package/lib/guard-sql.js +10 -0
- package/lib/guard-svg.js +2 -1
- package/lib/guard-text.js +10 -0
- package/lib/guard-yaml.js +13 -2
- package/lib/middleware/index.js +3 -0
- package/lib/middleware/shared-secret-header.js +334 -0
- package/lib/time.js +282 -0
- package/lib/vendor/MANIFEST.json +12 -12
- package/lib/vendor/blamejs-pki.cjs +858 -304
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/lib/gate-contract.js
CHANGED
|
@@ -2528,7 +2528,197 @@ function resolveProfileAndPosture(opts, cfg) {
|
|
|
2528
2528
|
}
|
|
2529
2529
|
overlay = Object.assign({}, overlay, cfg.compliancePostures[posture]);
|
|
2530
2530
|
}
|
|
2531
|
-
|
|
2531
|
+
// An explicitly-undefined property means the caller did not set it, not that
|
|
2532
|
+
// the default should be removed. `{ maxBytes: parsedEnvValue }` with the
|
|
2533
|
+
// variable unset is the ordinary way to write it, and a plain Object.assign
|
|
2534
|
+
// copies that undefined straight over the profile's value - after which the
|
|
2535
|
+
// cap is gone and every `measured > undefined` comparison is false. Dropping
|
|
2536
|
+
// undefined here restores the merge everyone already assumes: last one to
|
|
2537
|
+
// actually SET a key wins.
|
|
2538
|
+
var resolved = Object.assign({}, cfg.defaults || {}, overlay, _defined(opts));
|
|
2539
|
+
// The numeric caps are checked HERE, at the one point every entry point
|
|
2540
|
+
// passes through, rather than in the generated validate() alone. A guard's
|
|
2541
|
+
// hand-written entry points - guardMarkdown.render, guardEmail.sanitize,
|
|
2542
|
+
// guardHtml's three - resolve their own opts and then read maxBytes/maxLines
|
|
2543
|
+
// straight out of the result. When the check lived only in validate(), those
|
|
2544
|
+
// paths took `{ maxBytes: "8mb" }` at face value: every `bytes > maxBytes`
|
|
2545
|
+
// comparison against a string is false, so the malformed value did not fall
|
|
2546
|
+
// back to the default, it DISABLED the cap on untrusted input. Checking at
|
|
2547
|
+
// the resolver makes the bypass unreachable by construction, so a guard
|
|
2548
|
+
// cannot grow a new entry point that silently opts out of its own limits.
|
|
2549
|
+
//
|
|
2550
|
+
// Two lists, because they answer two different questions.
|
|
2551
|
+
//
|
|
2552
|
+
// `intOpts` is what the guard AUTHOR declared to be a cap. Zero is not a
|
|
2553
|
+
// setting there — `maxBytes: 0` would refuse every input — so those stay
|
|
2554
|
+
// strictly positive, and the guards that already refuse it keep doing so.
|
|
2555
|
+
//
|
|
2556
|
+
// `nonNegativeOpts` is DERIVED from the defaults, and derivation cannot tell
|
|
2557
|
+
// a cap from a tolerance. `maxRuntimeMs: 0` means "no runtime budget" and
|
|
2558
|
+
// `nbfFutureSlackMs: 0` means "allow no clock slack": ordinary settings that
|
|
2559
|
+
// requiring a positive integer took away. What derivation CAN say is that
|
|
2560
|
+
// the value must still be a non-negative integer, and that is the whole
|
|
2561
|
+
// fail-open class — a string, an Infinity, a NaN, a fraction or a negative
|
|
2562
|
+
// makes every `measured > cap` comparison false and removes the bound.
|
|
2563
|
+
//
|
|
2564
|
+
// An earlier version kept a hand-written list of the options where zero is a
|
|
2565
|
+
// value. That list was the same kind of thing that drifted in the first
|
|
2566
|
+
// place, and it had already missed two.
|
|
2567
|
+
//
|
|
2568
|
+
// This is also why the general resolver must not infer on its own: a consumer
|
|
2569
|
+
// whose defaults hold `{ retries: 3 }` is entitled to `retries: 0`, and only
|
|
2570
|
+
// the caller knows which of its options are limits.
|
|
2571
|
+
if (Array.isArray(cfg.intOpts) && cfg.intOpts.length > 0) {
|
|
2572
|
+
numericBounds.requireAllPositiveFiniteIntIfPresent(resolved, cfg.intOpts,
|
|
2573
|
+
prefix + ".resolveOpts", ErrorClass, prefix + ".bad-opt");
|
|
2574
|
+
}
|
|
2575
|
+
if (Array.isArray(cfg.nonNegativeOpts)) {
|
|
2576
|
+
cfg.nonNegativeOpts.forEach(function (k) {
|
|
2577
|
+
if (resolved[k] === undefined) return;
|
|
2578
|
+
if (Array.isArray(cfg.intOpts) && cfg.intOpts.indexOf(k) !== -1) return;
|
|
2579
|
+
numericBounds.requireNonNegativeFiniteIntIfPresent(resolved[k],
|
|
2580
|
+
prefix + ".resolveOpts " + k, ErrorClass, prefix + ".bad-opt");
|
|
2581
|
+
});
|
|
2582
|
+
}
|
|
2583
|
+
// Options whose value must come from a fixed vocabulary. Checked here, with
|
|
2584
|
+
// the caps, because this is the one point every entry point passes through -
|
|
2585
|
+
// a check on the request path would let a typo through gate construction and
|
|
2586
|
+
// surface it as failing requests instead of a boot error. Read leniently, a
|
|
2587
|
+
// misspelled policy takes whichever branch is not the strict one, so this
|
|
2588
|
+
// fails closed by refusing the value rather than guessing at it.
|
|
2589
|
+
if (cfg.enumOpts && typeof cfg.enumOpts === "object") {
|
|
2590
|
+
Object.keys(cfg.enumOpts).forEach(function (k) {
|
|
2591
|
+
var allowed = cfg.enumOpts[k];
|
|
2592
|
+
var v = resolved[k];
|
|
2593
|
+
if (v === undefined || !Array.isArray(allowed)) return;
|
|
2594
|
+
if (typeof v !== "string" || allowed.indexOf(v) === -1) {
|
|
2595
|
+
throw ErrorClass.factory(prefix + ".bad-opt",
|
|
2596
|
+
prefix + ": " + k + " must be one of " + allowed.join(", ") +
|
|
2597
|
+
"; got " + JSON.stringify(v));
|
|
2598
|
+
}
|
|
2599
|
+
});
|
|
2600
|
+
}
|
|
2601
|
+
return resolved;
|
|
2602
|
+
}
|
|
2603
|
+
|
|
2604
|
+
|
|
2605
|
+
// The own enumerable properties of `o` that were actually given a value. A key
|
|
2606
|
+
// present with the value `undefined` is treated as absent, so it cannot erase
|
|
2607
|
+
// a default it was never meant to touch.
|
|
2608
|
+
function _defined(o) {
|
|
2609
|
+
if (!o || typeof o !== "object") return o;
|
|
2610
|
+
var out = {};
|
|
2611
|
+
Object.keys(o).forEach(function (k) {
|
|
2612
|
+
if (o[k] !== undefined) out[k] = o[k];
|
|
2613
|
+
});
|
|
2614
|
+
return out;
|
|
2615
|
+
}
|
|
2616
|
+
|
|
2617
|
+
/**
|
|
2618
|
+
* @primitive b.gateContract.capKeysOf
|
|
2619
|
+
* @signature b.gateContract.capKeysOf(defaults, declared?)
|
|
2620
|
+
* @since 0.18.44
|
|
2621
|
+
* @status stable
|
|
2622
|
+
* @related b.gateContract.resolveProfileAndPosture, b.gateContract.defineGuard
|
|
2623
|
+
*
|
|
2624
|
+
* The guard option names that must stay non-negative integers: every default
|
|
2625
|
+
* whose value is a positive finite integer, plus any name passed in `declared`.
|
|
2626
|
+
*
|
|
2627
|
+
* Pass the result as `nonNegativeOpts` when binding `resolveProfileAndPosture`
|
|
2628
|
+
* by hand, so the resolver refuses a value given as a string, `Infinity`, a
|
|
2629
|
+
* `NaN`, a fraction or a negative number. Those do not fall back to the
|
|
2630
|
+
* default — every `measured > cap` comparison against them is false, which
|
|
2631
|
+
* removes the limit on untrusted input. A guard built by `defineGuard` gets
|
|
2632
|
+
* this applied for it.
|
|
2633
|
+
*
|
|
2634
|
+
* NON-NEGATIVE rather than positive, because derivation cannot tell a cap from
|
|
2635
|
+
* a tolerance: `maxRuntimeMs: 0` means "no runtime budget" and
|
|
2636
|
+
* `nbfFutureSlackMs: 0` means "allow no clock slack". Declare the options that
|
|
2637
|
+
* are genuinely caps as `intOpts` instead, where zero is refused.
|
|
2638
|
+
*
|
|
2639
|
+
* Derived rather than hand-listed on purpose: a written-out list drifts from
|
|
2640
|
+
* the defaults it mirrors, which is how `maxRuntimeMs` came to be unchecked
|
|
2641
|
+
* across the whole guard family.
|
|
2642
|
+
*
|
|
2643
|
+
* @example
|
|
2644
|
+
* var DEFAULTS = { maxBytes: 1024, mode: "enforce", ratio: 0.5 };
|
|
2645
|
+
* b.gateContract.capKeysOf(DEFAULTS);
|
|
2646
|
+
* // -> ["maxBytes"]
|
|
2647
|
+
*/
|
|
2648
|
+
function capKeysOf(defaults, declared) {
|
|
2649
|
+
return _capKeys(defaults, declared);
|
|
2650
|
+
}
|
|
2651
|
+
|
|
2652
|
+
/**
|
|
2653
|
+
* @primitive b.gateContract.identitySanitize
|
|
2654
|
+
* @signature b.gateContract.identitySanitize(input)
|
|
2655
|
+
* @since 0.18.44
|
|
2656
|
+
* @status stable
|
|
2657
|
+
* @related b.gateContract.defineGuard, b.gateContract.severityDisposition
|
|
2658
|
+
*
|
|
2659
|
+
* The sanitize transform for a guard that refuses rather than repairs.
|
|
2660
|
+
*
|
|
2661
|
+
* Some inputs cannot be safely rewritten: forging a JWT `alg`, editing an OAuth
|
|
2662
|
+
* `state`, rewriting a caller's regular expression or dropping cookies would
|
|
2663
|
+
* disarm the very evidence the guard is inspecting. A guard like that has no
|
|
2664
|
+
* repair to perform, so its transform returns the value unchanged — reached
|
|
2665
|
+
* only when nothing high or critical refused it upstream.
|
|
2666
|
+
*
|
|
2667
|
+
* @example
|
|
2668
|
+
* module.exports = b.gateContract.defineGuard({
|
|
2669
|
+
* name: "auth",
|
|
2670
|
+
* sanitizeTransform: b.gateContract.identitySanitize,
|
|
2671
|
+
* });
|
|
2672
|
+
*/
|
|
2673
|
+
function identitySanitize(input) {
|
|
2674
|
+
return input;
|
|
2675
|
+
}
|
|
2676
|
+
|
|
2677
|
+
/**
|
|
2678
|
+
* @primitive b.gateContract.ctxValueFrom
|
|
2679
|
+
* @signature b.gateContract.ctxValueFrom(ctx, fields)
|
|
2680
|
+
* @since 0.18.44
|
|
2681
|
+
* @status stable
|
|
2682
|
+
* @related b.gateContract.defineGuard, b.gateContract.buildGuardGate
|
|
2683
|
+
*
|
|
2684
|
+
* Read a gate context the way a generated gate does: the first field carrying
|
|
2685
|
+
* a value, or `undefined` when the context carries none of them.
|
|
2686
|
+
*
|
|
2687
|
+
* The distinction is the point. A field that is ABSENT means there is nothing
|
|
2688
|
+
* for this guard to look at; a field PRESENT as an empty string is a value, and
|
|
2689
|
+
* one most validators refuse. An `ctx.a || ctx.b || ""` chain collapses both
|
|
2690
|
+
* into `""`, so a gate written that way serves an empty identifier its own
|
|
2691
|
+
* `validate` rejects. Use this in a hand-written gate and short-circuit only on
|
|
2692
|
+
* `undefined`.
|
|
2693
|
+
*
|
|
2694
|
+
* @example
|
|
2695
|
+
* var name = b.gateContract.ctxValueFrom(ctx, ["filename", "name"]);
|
|
2696
|
+
* if (name === undefined) return { ok: true, action: "serve" };
|
|
2697
|
+
*/
|
|
2698
|
+
function ctxValueFrom(ctx, fields) {
|
|
2699
|
+
return _ctxValueForKind(null, ctx, fields);
|
|
2700
|
+
}
|
|
2701
|
+
|
|
2702
|
+
// The cap keys of a GUARD: every default that is a positive finite integer,
|
|
2703
|
+
// plus anything the spec names outright. These are the caps, budgets and depth
|
|
2704
|
+
// bounds an operator may raise or lower but must not replace with a shape that
|
|
2705
|
+
// silently compares false against everything. Only defineGuard calls this -
|
|
2706
|
+
// the general resolver must not infer the same thing about an arbitrary
|
|
2707
|
+
// consumer's options.
|
|
2708
|
+
function _capKeys(defaults, declared) {
|
|
2709
|
+
var out = [];
|
|
2710
|
+
if (defaults && typeof defaults === "object") {
|
|
2711
|
+
Object.keys(defaults).forEach(function (k) {
|
|
2712
|
+
var v = defaults[k];
|
|
2713
|
+
if (typeof v === "number" && Number.isInteger(v) && v > 0 && Number.isFinite(v)) {
|
|
2714
|
+
out.push(k);
|
|
2715
|
+
}
|
|
2716
|
+
});
|
|
2717
|
+
}
|
|
2718
|
+
if (Array.isArray(declared)) {
|
|
2719
|
+
declared.forEach(function (k) { if (out.indexOf(k) === -1) out.push(k); });
|
|
2720
|
+
}
|
|
2721
|
+
return out;
|
|
2532
2722
|
}
|
|
2533
2723
|
|
|
2534
2724
|
// _warnUnmappedPosture — emit a one-time, grep-able audit warning that a
|
|
@@ -2810,14 +3000,34 @@ var _KIND_CTX_FIELDS = Object.freeze({
|
|
|
2810
3000
|
|
|
2811
3001
|
// override (when given) replaces the per-KIND field table — lets a guard whose
|
|
2812
3002
|
// gate is the standard chain but reads a custom ctx field take the default gate.
|
|
3003
|
+
// Returns the ctx value for this guard's kind, or `undefined` when the ctx
|
|
3004
|
+
// carries none of its fields at all.
|
|
3005
|
+
//
|
|
3006
|
+
// The distinction matters: an ABSENT field means there is nothing for this
|
|
3007
|
+
// guard to look at, while a field PRESENT as an empty string is a value, and
|
|
3008
|
+
// one most guards' validators refuse. Collapsing both to "" made the gate serve
|
|
3009
|
+
// `{ country: "" }` while validate("") reported it - the gate disagreeing with
|
|
3010
|
+
// the validator it is meant to enforce, across seventeen guards.
|
|
3011
|
+
//
|
|
3012
|
+
// A truthy field still wins, and still in declaration order, so a ctx carrying
|
|
3013
|
+
// a real value anywhere resolves exactly as before; the empty case only decides
|
|
3014
|
+
// between "" and undefined.
|
|
2813
3015
|
function _ctxValueForKind(kind, ctx, override) {
|
|
2814
3016
|
ctx = ctx || {};
|
|
2815
3017
|
var fields = override || _KIND_CTX_FIELDS[kind];
|
|
2816
3018
|
if (!fields) return extractBytesAsText(ctx); // content (default)
|
|
3019
|
+
var emptyPresent;
|
|
3020
|
+
var sawEmpty = false;
|
|
2817
3021
|
for (var i = 0; i < fields.length; i += 1) {
|
|
2818
|
-
|
|
3022
|
+
var v = ctx[fields[i]];
|
|
3023
|
+
if (v) return v;
|
|
3024
|
+
if (!sawEmpty && v !== undefined && v !== null &&
|
|
3025
|
+
Object.prototype.hasOwnProperty.call(ctx, fields[i])) {
|
|
3026
|
+
emptyPresent = v;
|
|
3027
|
+
sawEmpty = true;
|
|
3028
|
+
}
|
|
2819
3029
|
}
|
|
2820
|
-
return
|
|
3030
|
+
return sawEmpty ? emptyPresent : undefined;
|
|
2821
3031
|
}
|
|
2822
3032
|
|
|
2823
3033
|
/**
|
|
@@ -2946,6 +3156,19 @@ function defineGuard(spec) {
|
|
|
2946
3156
|
defaults: defaults,
|
|
2947
3157
|
errorClass: ErrorClass,
|
|
2948
3158
|
errCodePrefix: prefix,
|
|
3159
|
+
// What the author declared IS a cap, so zero is refused there.
|
|
3160
|
+
intOpts: Array.isArray(spec.intOpts) ? spec.intOpts : null,
|
|
3161
|
+
// Everything else derived from this guard's own defaults, held only to
|
|
3162
|
+
// "still a non-negative integer". Deriving rather than hand-listing is
|
|
3163
|
+
// what stops the drift that left maxRuntimeMs unchecked in all 27
|
|
3164
|
+
// guards, guard-csv with no list at all, and guard-sql's and guard-svg's
|
|
3165
|
+
// caps unnamed — while leaving `maxRuntimeMs: 0` and the clock-slack
|
|
3166
|
+
// options the settings they have always been. Declared here so both
|
|
3167
|
+
// bind on EVERY path that resolves opts, not just the generated
|
|
3168
|
+
// validate() below.
|
|
3169
|
+
nonNegativeOpts: _capKeys(defaults, spec.intOpts),
|
|
3170
|
+
// Options restricted to a fixed vocabulary, checked at the same funnel.
|
|
3171
|
+
enumOpts: spec.enumOpts || null,
|
|
2949
3172
|
});
|
|
2950
3173
|
};
|
|
2951
3174
|
if (typeof spec.detect === "function") {
|
|
@@ -3104,17 +3327,26 @@ function defineGuard(spec) {
|
|
|
3104
3327
|
// is idempotent over an already-resolved opts, so spec.validate's internal
|
|
3105
3328
|
// resolution stays correct.
|
|
3106
3329
|
function defaultGate(rawOpts) {
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
});
|
|
3330
|
+
// Through the guard's own resolver, not a second copy of its binding. The
|
|
3331
|
+
// copy that used to be here carried no cap or vocabulary list, so building
|
|
3332
|
+
// a gate accepted a malformed limit or a misspelled policy that validate()
|
|
3333
|
+
// would have refused - a misconfiguration surviving boot to fail later on
|
|
3334
|
+
// requests, which is the opposite of what a config-time check is for.
|
|
3335
|
+
var opts = _resolveGuardOpts(rawOpts || {});
|
|
3114
3336
|
var perCtx = spec.defaultGateCheck || function (ctx) {
|
|
3115
3337
|
var value = _ctxValueForKind(spec.kind, ctx, ctxFields);
|
|
3116
|
-
|
|
3117
|
-
|
|
3338
|
+
// Only an ABSENT field short-circuits. A field present as an empty string
|
|
3339
|
+
// is a value, and the validator decides what it is worth - which keeps the
|
|
3340
|
+
// gate's verdict and validate()'s verdict the same answer.
|
|
3341
|
+
if (value === undefined || value === null) return { ok: true, action: "serve" };
|
|
3342
|
+
var rv;
|
|
3343
|
+
try { rv = spec.validate(value, opts); }
|
|
3344
|
+
catch (_e) {
|
|
3345
|
+
// A validator that cannot even parse the value has not approved it.
|
|
3346
|
+
// Letting the throw escape would crash the request this gate exists to
|
|
3347
|
+
// decide, so it becomes the refusal it already means.
|
|
3348
|
+
return { ok: false, action: "refuse" };
|
|
3349
|
+
}
|
|
3118
3350
|
return severityDisposition(rv.issues || []);
|
|
3119
3351
|
};
|
|
3120
3352
|
return buildGuardGate(
|
|
@@ -3128,6 +3360,11 @@ function defineGuard(spec) {
|
|
|
3128
3360
|
var out = {
|
|
3129
3361
|
NAME: spec.name,
|
|
3130
3362
|
KIND: spec.kind,
|
|
3363
|
+
// The options this guard DECLARES to be caps, where zero is refused. Every
|
|
3364
|
+
// other numeric option is derived from the defaults and held only to
|
|
3365
|
+
// "non-negative integer", because derivation cannot tell a cap from a
|
|
3366
|
+
// tolerance. Exposed so the family tests can tell the two apart.
|
|
3367
|
+
INT_OPTS: Object.freeze(Array.isArray(spec.intOpts) ? spec.intOpts.slice() : []),
|
|
3131
3368
|
validate: spec.validate,
|
|
3132
3369
|
resolveOpts: _resolveGuardOpts,
|
|
3133
3370
|
buildProfile: buildProfileFn,
|
|
@@ -3472,6 +3709,12 @@ module.exports = {
|
|
|
3472
3709
|
workerThreadGate: workerThreadGate,
|
|
3473
3710
|
buildProfile: buildProfile,
|
|
3474
3711
|
resolveProfileAndPosture: resolveProfileAndPosture,
|
|
3712
|
+
// For a guard that binds its own resolver instead of going through
|
|
3713
|
+
// defineGuard: the cap keys to declare, derived from its defaults so the
|
|
3714
|
+
// list cannot drift away from them.
|
|
3715
|
+
capKeysOf: capKeysOf,
|
|
3716
|
+
identitySanitize: identitySanitize,
|
|
3717
|
+
ctxValueFrom: ctxValueFrom,
|
|
3475
3718
|
runIssueValidator: runIssueValidator,
|
|
3476
3719
|
buildGuardGate: buildGuardGate,
|
|
3477
3720
|
severityDisposition: severityDisposition,
|
package/lib/guard-all.js
CHANGED
package/lib/guard-archive.js
CHANGED
|
@@ -183,8 +183,20 @@ var DEFAULTS = gateContract.strictDefaults(PROFILES, {
|
|
|
183
183
|
|
|
184
184
|
var COMPLIANCE_POSTURES = gateContract.compliancePostures(PROFILES, { base: 256 });
|
|
185
185
|
|
|
186
|
+
// The options that are genuinely CAPS, where zero is not a setting. This guard
|
|
187
|
+
// builds its own exports rather than going through defineGuard, so it names
|
|
188
|
+
// them here. maxRuntimeMs is deliberately absent: zero there means no runtime
|
|
189
|
+
// budget. See guard-image for the full reasoning.
|
|
190
|
+
var INT_OPTS = ["maxEntries", "maxTotalBytes", "maxEntryBytes",
|
|
191
|
+
"maxCompressionRatio", "maxAggregateRatio"];
|
|
192
|
+
|
|
186
193
|
// ---- Helpers ----
|
|
187
194
|
|
|
195
|
+
// This guard builds its own exports rather than going through defineGuard, so
|
|
196
|
+
// it binds its resolver here and declares its caps here too. The list is
|
|
197
|
+
// DERIVED from DEFAULTS rather than written out, because a hand-kept list is
|
|
198
|
+
// what drifted away from the defaults it was meant to mirror and left limits
|
|
199
|
+
// unchecked across the family.
|
|
188
200
|
function _resolveOpts(opts) {
|
|
189
201
|
return gateContract.resolveProfileAndPosture(opts, {
|
|
190
202
|
profiles: PROFILES,
|
|
@@ -192,6 +204,8 @@ function _resolveOpts(opts) {
|
|
|
192
204
|
defaults: DEFAULTS,
|
|
193
205
|
errorClass: GuardArchiveError,
|
|
194
206
|
errCodePrefix: "archive",
|
|
207
|
+
intOpts: INT_OPTS,
|
|
208
|
+
nonNegativeOpts: gateContract.capKeysOf(DEFAULTS),
|
|
195
209
|
});
|
|
196
210
|
}
|
|
197
211
|
|
package/lib/guard-auth.js
CHANGED
|
@@ -316,9 +316,7 @@ function _detectIssues(bundle, opts) {
|
|
|
316
316
|
// transform is identity — the bundle is returned unchanged when no high/critical
|
|
317
317
|
// issue refused upstream. A non-object input refuses upstream via the high-
|
|
318
318
|
// severity auth.bad-input issue _detectIssues raises.
|
|
319
|
-
|
|
320
|
-
return input;
|
|
321
|
-
}
|
|
319
|
+
var _sanitizeTransform = gateContract.identitySanitize;
|
|
322
320
|
|
|
323
321
|
/**
|
|
324
322
|
* @primitive b.guardAuth.gate
|