@blamejs/core 0.13.43 → 0.13.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 +2 -0
- package/lib/a2a.js +11 -11
- package/lib/agent-snapshot.js +1 -1
- package/lib/ai-capability.js +20 -20
- package/lib/ai-dp.js +17 -17
- package/lib/ai-input.js +3 -3
- package/lib/ai-pref.js +9 -9
- package/lib/ai-quota.js +17 -17
- package/lib/arg-parser.js +38 -38
- package/lib/audit-sign.js +4 -4
- package/lib/auth/acr-vocabulary.js +4 -4
- package/lib/auth/auth-time-tracker.js +1 -1
- package/lib/auth/elevation-grant.js +10 -10
- package/lib/auth/step-up-policy.js +12 -12
- package/lib/auth/step-up.js +15 -15
- package/lib/boot-gates.js +6 -6
- package/lib/budr.js +6 -6
- package/lib/content-credentials.js +13 -13
- package/lib/dark-patterns.js +15 -15
- package/lib/ddl-change-control.js +37 -37
- package/lib/dr-runbook.js +7 -7
- package/lib/fapi2.js +9 -9
- package/lib/fdx.js +7 -7
- package/lib/graphql-federation.js +2 -2
- package/lib/iab-mspa.js +5 -5
- package/lib/iab-tcf.js +18 -18
- package/lib/mcp.js +13 -13
- package/lib/middleware/require-step-up.js +3 -3
- package/lib/sec-cyber.js +3 -3
- package/lib/sse.js +14 -14
- package/lib/tcpa-10dlc.js +5 -5
- package/lib/tenant-quota.js +18 -18
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/lib/arg-parser.js
CHANGED
|
@@ -53,17 +53,17 @@ function _isPlainNonEmpty(s) {
|
|
|
53
53
|
|
|
54
54
|
function _validateFlagName(name) {
|
|
55
55
|
if (!_isPlainNonEmpty(name)) {
|
|
56
|
-
throw new ArgParserError("
|
|
56
|
+
throw new ArgParserError("arg-parser/flag-name-invalid",
|
|
57
57
|
"flag name must be a non-empty string");
|
|
58
58
|
}
|
|
59
59
|
if (FORBIDDEN_NAMES.indexOf(name) !== -1) {
|
|
60
|
-
throw new ArgParserError("
|
|
60
|
+
throw new ArgParserError("arg-parser/flag-name-forbidden",
|
|
61
61
|
"flag name '" + name + "' is reserved");
|
|
62
62
|
}
|
|
63
63
|
// ASCII-only kebab-/snake-case identifier. Keeps every flag name safe
|
|
64
64
|
// to embed in help text and prevents `--foo$bar=baz` style oddities.
|
|
65
65
|
if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name)) {
|
|
66
|
-
throw new ArgParserError("
|
|
66
|
+
throw new ArgParserError("arg-parser/flag-name-shape",
|
|
67
67
|
"flag name '" + name + "' must match [a-zA-Z][a-zA-Z0-9_-]*");
|
|
68
68
|
}
|
|
69
69
|
}
|
|
@@ -71,26 +71,26 @@ function _validateFlagName(name) {
|
|
|
71
71
|
function _validateAlias(alias, ownerName) {
|
|
72
72
|
if (alias === undefined || alias === null) return;
|
|
73
73
|
if (typeof alias !== "string" || alias.length !== 1 || !/^[a-zA-Z]$/.test(alias)) {
|
|
74
|
-
throw new ArgParserError("
|
|
74
|
+
throw new ArgParserError("arg-parser/alias-shape",
|
|
75
75
|
"flag '" + ownerName + "' alias must be a single letter [a-zA-Z]");
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
function _validateFlagSpec(spec, ownerLabel) {
|
|
80
80
|
if (!spec || typeof spec !== "object") {
|
|
81
|
-
throw new ArgParserError("
|
|
81
|
+
throw new ArgParserError("arg-parser/flag-spec-invalid",
|
|
82
82
|
ownerLabel + ": flag spec must be an object");
|
|
83
83
|
}
|
|
84
84
|
_validateFlagName(spec.name);
|
|
85
85
|
_validateAlias(spec.alias, spec.name);
|
|
86
86
|
var type = spec.type || "string";
|
|
87
87
|
if (SUPPORTED_TYPES.indexOf(type) === -1) {
|
|
88
|
-
throw new ArgParserError("
|
|
88
|
+
throw new ArgParserError("arg-parser/flag-type-unsupported",
|
|
89
89
|
ownerLabel + ": flag '" + spec.name +
|
|
90
90
|
"' type '" + type + "' must be one of " + SUPPORTED_TYPES.join(", "));
|
|
91
91
|
}
|
|
92
92
|
if (spec.description !== undefined && typeof spec.description !== "string") {
|
|
93
|
-
throw new ArgParserError("
|
|
93
|
+
throw new ArgParserError("arg-parser/flag-description-invalid",
|
|
94
94
|
ownerLabel + ": flag '" + spec.name + "' description must be a string");
|
|
95
95
|
}
|
|
96
96
|
}
|
|
@@ -101,7 +101,7 @@ function _coerceValue(spec, raw, label) {
|
|
|
101
101
|
if (type === "number") {
|
|
102
102
|
var n = Number(raw);
|
|
103
103
|
if (!isFinite(n)) {
|
|
104
|
-
throw new ArgParserError("
|
|
104
|
+
throw new ArgParserError("arg-parser/value-not-number",
|
|
105
105
|
label + " '" + spec.name + "' expected a number, got " + JSON.stringify(raw));
|
|
106
106
|
}
|
|
107
107
|
return n;
|
|
@@ -112,7 +112,7 @@ function _coerceValue(spec, raw, label) {
|
|
|
112
112
|
var s = String(raw).toLowerCase();
|
|
113
113
|
if (s === "true" || s === "1" || s === "yes") return true;
|
|
114
114
|
if (s === "false" || s === "0" || s === "no") return false;
|
|
115
|
-
throw new ArgParserError("
|
|
115
|
+
throw new ArgParserError("arg-parser/value-not-boolean",
|
|
116
116
|
label + " '" + spec.name + "' expected boolean, got " + JSON.stringify(raw));
|
|
117
117
|
}
|
|
118
118
|
if (type === "list") {
|
|
@@ -121,7 +121,7 @@ function _coerceValue(spec, raw, label) {
|
|
|
121
121
|
return s2.indexOf(",") === -1 ? [s2] : s2.split(",");
|
|
122
122
|
}
|
|
123
123
|
// Unreachable: validated at create-time.
|
|
124
|
-
throw new ArgParserError("
|
|
124
|
+
throw new ArgParserError("arg-parser/type-unreachable",
|
|
125
125
|
"unsupported flag type '" + type + "'");
|
|
126
126
|
}
|
|
127
127
|
|
|
@@ -132,13 +132,13 @@ function _buildFlagIndex(flagSpecs, ownerLabel) {
|
|
|
132
132
|
var spec = flagSpecs[i];
|
|
133
133
|
_validateFlagSpec(spec, ownerLabel);
|
|
134
134
|
if (byName[spec.name]) {
|
|
135
|
-
throw new ArgParserError("
|
|
135
|
+
throw new ArgParserError("arg-parser/flag-duplicate",
|
|
136
136
|
ownerLabel + ": flag '" + spec.name + "' declared twice");
|
|
137
137
|
}
|
|
138
138
|
byName[spec.name] = spec;
|
|
139
139
|
if (spec.alias) {
|
|
140
140
|
if (byAlias[spec.alias]) {
|
|
141
|
-
throw new ArgParserError("
|
|
141
|
+
throw new ArgParserError("arg-parser/alias-duplicate",
|
|
142
142
|
ownerLabel + ": alias '-" + spec.alias + "' declared twice");
|
|
143
143
|
}
|
|
144
144
|
byAlias[spec.alias] = spec;
|
|
@@ -232,12 +232,12 @@ function _renderCommandHelp(parser, command) {
|
|
|
232
232
|
// command-name (the first non-flag token, when commands are configured).
|
|
233
233
|
function _splitArgv(parser, argv) {
|
|
234
234
|
if (!Array.isArray(argv)) {
|
|
235
|
-
throw new ArgParserError("
|
|
235
|
+
throw new ArgParserError("arg-parser/argv-not-array",
|
|
236
236
|
"argv must be an array of strings");
|
|
237
237
|
}
|
|
238
238
|
for (var n = 0; n < argv.length; n++) {
|
|
239
239
|
if (typeof argv[n] !== "string") {
|
|
240
|
-
throw new ArgParserError("
|
|
240
|
+
throw new ArgParserError("arg-parser/argv-element-not-string",
|
|
241
241
|
"argv[" + n + "] must be a string");
|
|
242
242
|
}
|
|
243
243
|
}
|
|
@@ -256,7 +256,7 @@ function _splitArgv(parser, argv) {
|
|
|
256
256
|
if (!parser.commands.byName[name]) {
|
|
257
257
|
// Surface help / version as built-ins even when no command matches.
|
|
258
258
|
if (name === "help") return { command: "__help__", pre: argv.slice(0, i), rest: argv.slice(i + 1) };
|
|
259
|
-
throw new ArgParserError("
|
|
259
|
+
throw new ArgParserError("arg-parser/unknown-command",
|
|
260
260
|
"unknown command '" + name + "'");
|
|
261
261
|
}
|
|
262
262
|
return { command: name, pre: argv.slice(0, i), rest: argv.slice(i + 1) };
|
|
@@ -299,7 +299,7 @@ function _consumeFlags(index, tokens) {
|
|
|
299
299
|
if (tok.indexOf("--") === 0) {
|
|
300
300
|
var rest = tok.slice(2);
|
|
301
301
|
if (FORBIDDEN_NAMES.indexOf(rest.split("=")[0]) !== -1) {
|
|
302
|
-
throw new ArgParserError("
|
|
302
|
+
throw new ArgParserError("arg-parser/argv-forbidden-name",
|
|
303
303
|
"flag '--" + rest.split("=")[0] + "' is reserved");
|
|
304
304
|
}
|
|
305
305
|
var eq = rest.indexOf("=");
|
|
@@ -313,7 +313,7 @@ function _consumeFlags(index, tokens) {
|
|
|
313
313
|
}
|
|
314
314
|
spec = index.byName[nm];
|
|
315
315
|
if (!spec) {
|
|
316
|
-
throw new ArgParserError("
|
|
316
|
+
throw new ArgParserError("arg-parser/unknown-flag",
|
|
317
317
|
"unknown flag '--" + nm + "'");
|
|
318
318
|
}
|
|
319
319
|
} else if (tok.indexOf("-") === 0 && tok.length >= 2) {
|
|
@@ -329,12 +329,12 @@ function _consumeFlags(index, tokens) {
|
|
|
329
329
|
ach = alias;
|
|
330
330
|
}
|
|
331
331
|
if (ach.length !== 1) {
|
|
332
|
-
throw new ArgParserError("
|
|
332
|
+
throw new ArgParserError("arg-parser/short-flag-shape",
|
|
333
333
|
"short flag '" + tok + "' must be a single letter (use --long-form for multi-char names)");
|
|
334
334
|
}
|
|
335
335
|
spec = index.byAlias[ach];
|
|
336
336
|
if (!spec) {
|
|
337
|
-
throw new ArgParserError("
|
|
337
|
+
throw new ArgParserError("arg-parser/unknown-alias",
|
|
338
338
|
"unknown short flag '-" + ach + "'");
|
|
339
339
|
}
|
|
340
340
|
} else {
|
|
@@ -349,7 +349,7 @@ function _consumeFlags(index, tokens) {
|
|
|
349
349
|
} else {
|
|
350
350
|
if (!hasInlineValue) {
|
|
351
351
|
if (i + 1 >= tokens.length) {
|
|
352
|
-
throw new ArgParserError("
|
|
352
|
+
throw new ArgParserError("arg-parser/value-missing",
|
|
353
353
|
"flag '--" + spec.name + "' requires a value");
|
|
354
354
|
}
|
|
355
355
|
rawValue = tokens[++i];
|
|
@@ -377,7 +377,7 @@ function _applyDefaultsAndRequired(specs, flags, ownerLabel) {
|
|
|
377
377
|
for (var k = 0; k < specs.length; k++) {
|
|
378
378
|
var s = specs[k];
|
|
379
379
|
if (s.required && flags[s.name] === undefined) {
|
|
380
|
-
throw new ArgParserError("
|
|
380
|
+
throw new ArgParserError("arg-parser/missing-required",
|
|
381
381
|
ownerLabel + ": flag '--" + s.name + "' is required");
|
|
382
382
|
}
|
|
383
383
|
}
|
|
@@ -385,23 +385,23 @@ function _applyDefaultsAndRequired(specs, flags, ownerLabel) {
|
|
|
385
385
|
|
|
386
386
|
function _validateCommandSpec(cmd) {
|
|
387
387
|
if (!cmd || typeof cmd !== "object") {
|
|
388
|
-
throw new ArgParserError("
|
|
388
|
+
throw new ArgParserError("arg-parser/command-spec-invalid",
|
|
389
389
|
"command spec must be an object");
|
|
390
390
|
}
|
|
391
391
|
if (!_isPlainNonEmpty(cmd.name)) {
|
|
392
|
-
throw new ArgParserError("
|
|
392
|
+
throw new ArgParserError("arg-parser/command-name-invalid",
|
|
393
393
|
"command name must be a non-empty string");
|
|
394
394
|
}
|
|
395
395
|
if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(cmd.name)) {
|
|
396
|
-
throw new ArgParserError("
|
|
396
|
+
throw new ArgParserError("arg-parser/command-name-shape",
|
|
397
397
|
"command name '" + cmd.name + "' must match [a-zA-Z][a-zA-Z0-9_-]*");
|
|
398
398
|
}
|
|
399
399
|
if (cmd.handler !== undefined && typeof cmd.handler !== "function") {
|
|
400
|
-
throw new ArgParserError("
|
|
400
|
+
throw new ArgParserError("arg-parser/command-handler-not-function",
|
|
401
401
|
"command '" + cmd.name + "' handler must be a function");
|
|
402
402
|
}
|
|
403
403
|
if (cmd.description !== undefined && typeof cmd.description !== "string") {
|
|
404
|
-
throw new ArgParserError("
|
|
404
|
+
throw new ArgParserError("arg-parser/command-description-invalid",
|
|
405
405
|
"command '" + cmd.name + "' description must be a string");
|
|
406
406
|
}
|
|
407
407
|
}
|
|
@@ -465,29 +465,29 @@ function _validateCommandSpec(cmd) {
|
|
|
465
465
|
*/
|
|
466
466
|
function create(opts) {
|
|
467
467
|
if (!opts || typeof opts !== "object") {
|
|
468
|
-
throw new ArgParserError("
|
|
468
|
+
throw new ArgParserError("arg-parser/opts-required",
|
|
469
469
|
"argParser.create requires an opts object");
|
|
470
470
|
}
|
|
471
471
|
var programName = opts.programName;
|
|
472
472
|
if (programName !== undefined && typeof programName !== "string") {
|
|
473
|
-
throw new ArgParserError("
|
|
473
|
+
throw new ArgParserError("arg-parser/program-name-invalid",
|
|
474
474
|
"programName must be a string");
|
|
475
475
|
}
|
|
476
476
|
var description = opts.description;
|
|
477
477
|
if (description !== undefined && typeof description !== "string") {
|
|
478
|
-
throw new ArgParserError("
|
|
478
|
+
throw new ArgParserError("arg-parser/description-invalid",
|
|
479
479
|
"description must be a string");
|
|
480
480
|
}
|
|
481
481
|
var topFlagsSpec = opts.flags || [];
|
|
482
482
|
if (!Array.isArray(topFlagsSpec)) {
|
|
483
|
-
throw new ArgParserError("
|
|
483
|
+
throw new ArgParserError("arg-parser/flags-not-array",
|
|
484
484
|
"flags must be an array");
|
|
485
485
|
}
|
|
486
486
|
var topFlags = _buildFlagIndex(topFlagsSpec, "top-level");
|
|
487
487
|
|
|
488
488
|
var commandsSpec = opts.commands || [];
|
|
489
489
|
if (!Array.isArray(commandsSpec)) {
|
|
490
|
-
throw new ArgParserError("
|
|
490
|
+
throw new ArgParserError("arg-parser/commands-not-array",
|
|
491
491
|
"commands must be an array");
|
|
492
492
|
}
|
|
493
493
|
var commandsByName = Object.create(null);
|
|
@@ -496,12 +496,12 @@ function create(opts) {
|
|
|
496
496
|
var c = commandsSpec[i];
|
|
497
497
|
_validateCommandSpec(c);
|
|
498
498
|
if (commandsByName[c.name]) {
|
|
499
|
-
throw new ArgParserError("
|
|
499
|
+
throw new ArgParserError("arg-parser/command-duplicate",
|
|
500
500
|
"command '" + c.name + "' declared twice");
|
|
501
501
|
}
|
|
502
502
|
var cmdFlagsSpec = c.flags || [];
|
|
503
503
|
if (!Array.isArray(cmdFlagsSpec)) {
|
|
504
|
-
throw new ArgParserError("
|
|
504
|
+
throw new ArgParserError("arg-parser/command-flags-not-array",
|
|
505
505
|
"command '" + c.name + "' flags must be an array");
|
|
506
506
|
}
|
|
507
507
|
var cmdFlags = _buildFlagIndex(cmdFlagsSpec, "command '" + c.name + "'");
|
|
@@ -526,7 +526,7 @@ function create(opts) {
|
|
|
526
526
|
if (commandName) {
|
|
527
527
|
var cmd = commandsByName[commandName];
|
|
528
528
|
if (!cmd) {
|
|
529
|
-
throw new ArgParserError("
|
|
529
|
+
throw new ArgParserError("arg-parser/help-unknown-command",
|
|
530
530
|
"no command named '" + commandName + "'");
|
|
531
531
|
}
|
|
532
532
|
return _renderCommandHelp(parser, cmd);
|
|
@@ -645,7 +645,7 @@ function create(opts) {
|
|
|
645
645
|
*/
|
|
646
646
|
function parseRaw(argv) {
|
|
647
647
|
if (!Array.isArray(argv)) {
|
|
648
|
-
throw new ArgParserError("
|
|
648
|
+
throw new ArgParserError("arg-parser/argv-not-array",
|
|
649
649
|
"argv must be an array of strings");
|
|
650
650
|
}
|
|
651
651
|
var pos = [];
|
|
@@ -653,7 +653,7 @@ function parseRaw(argv) {
|
|
|
653
653
|
for (var i = 0; i < argv.length; i++) {
|
|
654
654
|
var tok = argv[i];
|
|
655
655
|
if (typeof tok !== "string") {
|
|
656
|
-
throw new ArgParserError("
|
|
656
|
+
throw new ArgParserError("arg-parser/argv-element-not-string",
|
|
657
657
|
"argv[" + i + "] must be a string");
|
|
658
658
|
}
|
|
659
659
|
if (tok === "--") {
|
|
@@ -673,14 +673,14 @@ function parseRaw(argv) {
|
|
|
673
673
|
val = true;
|
|
674
674
|
}
|
|
675
675
|
if (FORBIDDEN_NAMES.indexOf(name) !== -1) {
|
|
676
|
-
throw new ArgParserError("
|
|
676
|
+
throw new ArgParserError("arg-parser/argv-forbidden-name",
|
|
677
677
|
"flag '--" + name + "' is reserved");
|
|
678
678
|
}
|
|
679
679
|
flags[name] = val;
|
|
680
680
|
} else if (tok.indexOf("-") === 0 && tok.length === 2) {
|
|
681
681
|
var s = tok.slice(1);
|
|
682
682
|
if (FORBIDDEN_NAMES.indexOf(s) !== -1) {
|
|
683
|
-
throw new ArgParserError("
|
|
683
|
+
throw new ArgParserError("arg-parser/argv-forbidden-name",
|
|
684
684
|
"flag '-" + s + "' is reserved");
|
|
685
685
|
}
|
|
686
686
|
flags[s] = true;
|
package/lib/audit-sign.js
CHANGED
|
@@ -178,13 +178,13 @@ var pendingNewKeyAlg = null;
|
|
|
178
178
|
async function init(opts) {
|
|
179
179
|
if (initialized) return;
|
|
180
180
|
if (!opts || !opts.dataDir) {
|
|
181
|
-
throw new AuditSignError("
|
|
181
|
+
throw new AuditSignError("audit-sign/bad-init",
|
|
182
182
|
"auditSign.init({ dataDir }) is required");
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
var mode = (opts.mode || "wrapped").toLowerCase();
|
|
186
186
|
if (mode !== "wrapped" && mode !== "plaintext") {
|
|
187
|
-
throw new AuditSignError("
|
|
187
|
+
throw new AuditSignError("audit-sign/bad-mode",
|
|
188
188
|
"auditSign.init: mode must be 'wrapped' or 'plaintext'");
|
|
189
189
|
}
|
|
190
190
|
// Algorithm-on-generate. Validated against the supported list so
|
|
@@ -192,7 +192,7 @@ async function init(opts) {
|
|
|
192
192
|
// deeper in nodeCrypto.
|
|
193
193
|
var alg = (opts.algorithm || DEFAULT_SIGNING_ALG).toLowerCase();
|
|
194
194
|
if (SUPPORTED_SIGNING_ALGS.indexOf(alg) === -1) {
|
|
195
|
-
throw new AuditSignError("
|
|
195
|
+
throw new AuditSignError("audit-sign/bad-algorithm",
|
|
196
196
|
"auditSign.init: algorithm must be one of " +
|
|
197
197
|
SUPPORTED_SIGNING_ALGS.join(", ") + " (got: " + alg + ")");
|
|
198
198
|
}
|
|
@@ -341,7 +341,7 @@ async function _initFirstRunWrapped() {
|
|
|
341
341
|
|
|
342
342
|
function _requireInit() {
|
|
343
343
|
if (!initialized) {
|
|
344
|
-
throw new AuditSignError("
|
|
344
|
+
throw new AuditSignError("audit-sign/not-initialized",
|
|
345
345
|
"auditSign.init() must be awaited before sign/verify");
|
|
346
346
|
}
|
|
347
347
|
}
|
|
@@ -144,14 +144,14 @@ function register(opts) {
|
|
|
144
144
|
opts = opts || {};
|
|
145
145
|
validateOpts(opts, ["value", "rank"], "auth.acr.register");
|
|
146
146
|
validateOpts.requireNonEmptyString(opts.value, "register: value",
|
|
147
|
-
AuthError, "auth-
|
|
147
|
+
AuthError, "auth-step-up/bad-acr");
|
|
148
148
|
if (typeof opts.rank !== "number" || !isFinite(opts.rank)) {
|
|
149
|
-
throw new AuthError("auth-
|
|
149
|
+
throw new AuthError("auth-step-up/bad-rank",
|
|
150
150
|
"auth.acr.register: rank must be a finite number — got " +
|
|
151
151
|
JSON.stringify(opts.rank));
|
|
152
152
|
}
|
|
153
153
|
if (opts.rank < 0 || opts.rank > 100) {
|
|
154
|
-
throw new AuthError("auth-
|
|
154
|
+
throw new AuthError("auth-step-up/bad-rank",
|
|
155
155
|
"auth.acr.register: rank must be in [0, 100] — got " + opts.rank);
|
|
156
156
|
}
|
|
157
157
|
_registry[opts.value] = opts.rank;
|
|
@@ -192,7 +192,7 @@ function meets(presented, required) {
|
|
|
192
192
|
var rp = rankOf(presented);
|
|
193
193
|
var rr = rankOf(required);
|
|
194
194
|
if (rr === -1) {
|
|
195
|
-
throw new AuthError("auth-
|
|
195
|
+
throw new AuthError("auth-step-up/unknown-acr",
|
|
196
196
|
"auth.acr.meets: required acr is not registered (call b.auth.acr.register first): " +
|
|
197
197
|
JSON.stringify(required));
|
|
198
198
|
}
|
|
@@ -58,7 +58,7 @@ function ageSec(claims, now) {
|
|
|
58
58
|
|
|
59
59
|
function freshEnough(claims, maxAgeSec, now) {
|
|
60
60
|
if (typeof maxAgeSec !== "number" || !isFinite(maxAgeSec) || maxAgeSec < 0) {
|
|
61
|
-
throw new AuthError("auth-
|
|
61
|
+
throw new AuthError("auth-step-up/bad-max-age",
|
|
62
62
|
"auth.authTime.freshEnough: maxAgeSec must be a finite number >= 0 — got " +
|
|
63
63
|
JSON.stringify(maxAgeSec));
|
|
64
64
|
}
|
|
@@ -58,7 +58,7 @@ function _ensureSigningKey() {
|
|
|
58
58
|
|
|
59
59
|
function setSigningKey(keyBuffer) {
|
|
60
60
|
if (!Buffer.isBuffer(keyBuffer) || keyBuffer.length < MIN_KEY_BYTES) {
|
|
61
|
-
throw new AuthError("auth-
|
|
61
|
+
throw new AuthError("auth-step-up/bad-key",
|
|
62
62
|
"auth.stepUp.grant.setSigningKey: keyBuffer must be a Buffer of >= " +
|
|
63
63
|
MIN_KEY_BYTES + " bytes");
|
|
64
64
|
}
|
|
@@ -92,37 +92,37 @@ function create(opts) {
|
|
|
92
92
|
"ttlSec", "audience", "now",
|
|
93
93
|
], "auth.stepUp.grant.create");
|
|
94
94
|
validateOpts.requireNonEmptyString(opts.subject,
|
|
95
|
-
"grant.create: subject", AuthError, "auth-
|
|
95
|
+
"grant.create: subject", AuthError, "auth-step-up/bad-grant");
|
|
96
96
|
validateOpts.requireNonEmptyString(opts.scope,
|
|
97
|
-
"grant.create: scope", AuthError, "auth-
|
|
97
|
+
"grant.create: scope", AuthError, "auth-step-up/bad-grant");
|
|
98
98
|
if (opts.acr != null) {
|
|
99
99
|
validateOpts.requireNonEmptyString(opts.acr,
|
|
100
|
-
"grant.create: acr", AuthError, "auth-
|
|
100
|
+
"grant.create: acr", AuthError, "auth-step-up/bad-grant");
|
|
101
101
|
}
|
|
102
102
|
if (opts.amr != null) {
|
|
103
103
|
if (!Array.isArray(opts.amr)) {
|
|
104
|
-
throw new AuthError("auth-
|
|
104
|
+
throw new AuthError("auth-step-up/bad-grant",
|
|
105
105
|
"grant.create: amr must be an array — got " + typeof opts.amr);
|
|
106
106
|
}
|
|
107
107
|
for (var i = 0; i < opts.amr.length; i += 1) {
|
|
108
108
|
if (typeof opts.amr[i] !== "string") {
|
|
109
|
-
throw new AuthError("auth-
|
|
109
|
+
throw new AuthError("auth-step-up/bad-grant",
|
|
110
110
|
"grant.create: amr[" + i + "] must be a string");
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
if (opts.audience != null) {
|
|
115
115
|
validateOpts.requireNonEmptyString(opts.audience,
|
|
116
|
-
"grant.create: audience", AuthError, "auth-
|
|
116
|
+
"grant.create: audience", AuthError, "auth-step-up/bad-grant");
|
|
117
117
|
}
|
|
118
118
|
var ttlSec = (typeof opts.ttlSec === "number") ? opts.ttlSec : DEFAULT_TTL_SEC;
|
|
119
119
|
if (!isFinite(ttlSec) || ttlSec < MIN_TTL_SEC) {
|
|
120
|
-
throw new AuthError("auth-
|
|
120
|
+
throw new AuthError("auth-step-up/bad-grant",
|
|
121
121
|
"grant.create: ttlSec must be a finite number >= " +
|
|
122
122
|
MIN_TTL_SEC + " — got " + JSON.stringify(opts.ttlSec));
|
|
123
123
|
}
|
|
124
124
|
if (ttlSec > MAX_TTL_SEC) {
|
|
125
|
-
throw new AuthError("auth-
|
|
125
|
+
throw new AuthError("auth-step-up/bad-grant",
|
|
126
126
|
"grant.create: ttlSec must be <= " + MAX_TTL_SEC +
|
|
127
127
|
" (1h hard ceiling) — got " + ttlSec);
|
|
128
128
|
}
|
|
@@ -247,7 +247,7 @@ function revoke(jti, opts) {
|
|
|
247
247
|
opts = opts || {};
|
|
248
248
|
validateOpts(opts, ["reason"], "auth.stepUp.grant.revoke");
|
|
249
249
|
if (typeof jti !== "string" || jti.length === 0) {
|
|
250
|
-
throw new AuthError("auth-
|
|
250
|
+
throw new AuthError("auth-step-up/bad-jti",
|
|
251
251
|
"grant.revoke: jti must be a non-empty string — got " + JSON.stringify(jti));
|
|
252
252
|
}
|
|
253
253
|
_revokedSet[jti] = true;
|
|
@@ -59,7 +59,7 @@ function _mkNode(spec) {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
function acr(value) {
|
|
62
|
-
validateOpts.requireNonEmptyString(value, "policy.acr: value", AuthError, "auth-
|
|
62
|
+
validateOpts.requireNonEmptyString(value, "policy.acr: value", AuthError, "auth-step-up/bad-acr");
|
|
63
63
|
return _mkNode({
|
|
64
64
|
kind: "acr",
|
|
65
65
|
value: value,
|
|
@@ -76,12 +76,12 @@ function acr(value) {
|
|
|
76
76
|
|
|
77
77
|
function acrAny(values) {
|
|
78
78
|
if (!Array.isArray(values) || values.length === 0) {
|
|
79
|
-
throw new AuthError("auth-
|
|
79
|
+
throw new AuthError("auth-step-up/bad-policy",
|
|
80
80
|
"policy.acrAny: values must be a non-empty array");
|
|
81
81
|
}
|
|
82
82
|
for (var i = 0; i < values.length; i += 1) {
|
|
83
83
|
validateOpts.requireNonEmptyString(values[i],
|
|
84
|
-
"policy.acrAny: values[" + i + "]", AuthError, "auth-
|
|
84
|
+
"policy.acrAny: values[" + i + "]", AuthError, "auth-step-up/bad-acr");
|
|
85
85
|
}
|
|
86
86
|
var copy = values.slice();
|
|
87
87
|
return _mkNode({
|
|
@@ -100,12 +100,12 @@ function acrAny(values) {
|
|
|
100
100
|
|
|
101
101
|
function amr(required) {
|
|
102
102
|
if (!Array.isArray(required) || required.length === 0) {
|
|
103
|
-
throw new AuthError("auth-
|
|
103
|
+
throw new AuthError("auth-step-up/bad-policy",
|
|
104
104
|
"policy.amr: required must be a non-empty array");
|
|
105
105
|
}
|
|
106
106
|
for (var i = 0; i < required.length; i += 1) {
|
|
107
107
|
validateOpts.requireNonEmptyString(required[i],
|
|
108
|
-
"policy.amr: required[" + i + "]", AuthError, "auth-
|
|
108
|
+
"policy.amr: required[" + i + "]", AuthError, "auth-step-up/bad-amr");
|
|
109
109
|
}
|
|
110
110
|
var copy = required.slice();
|
|
111
111
|
return _mkNode({
|
|
@@ -138,7 +138,7 @@ function phishingResistant() {
|
|
|
138
138
|
|
|
139
139
|
function maxAge(seconds) {
|
|
140
140
|
if (typeof seconds !== "number" || !isFinite(seconds) || seconds < 0) {
|
|
141
|
-
throw new AuthError("auth-
|
|
141
|
+
throw new AuthError("auth-step-up/bad-policy",
|
|
142
142
|
"policy.maxAge: seconds must be a finite number >= 0 — got " +
|
|
143
143
|
JSON.stringify(seconds));
|
|
144
144
|
}
|
|
@@ -157,9 +157,9 @@ function maxAge(seconds) {
|
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
function custom(name, fn) {
|
|
160
|
-
validateOpts.requireNonEmptyString(name, "policy.custom: name", AuthError, "auth-
|
|
160
|
+
validateOpts.requireNonEmptyString(name, "policy.custom: name", AuthError, "auth-step-up/bad-policy");
|
|
161
161
|
if (typeof fn !== "function") {
|
|
162
|
-
throw new AuthError("auth-
|
|
162
|
+
throw new AuthError("auth-step-up/bad-policy",
|
|
163
163
|
"policy.custom: fn must be a function — got " + typeof fn);
|
|
164
164
|
}
|
|
165
165
|
return _mkNode({
|
|
@@ -171,7 +171,7 @@ function custom(name, fn) {
|
|
|
171
171
|
return { ok: ok, atom: "custom:" + name, reason: ok ? null : "custom predicate '" + name + "' returned false" };
|
|
172
172
|
},
|
|
173
173
|
_toReq: function () {
|
|
174
|
-
throw new AuthError("auth-
|
|
174
|
+
throw new AuthError("auth-step-up/policy-no-challenge",
|
|
175
175
|
"policy.custom: cannot translate to RFC 9470 challenge — wrap in .or() with a translatable atom or use .middleware({ requirement: ... })");
|
|
176
176
|
},
|
|
177
177
|
});
|
|
@@ -231,7 +231,7 @@ function _not(inner) {
|
|
|
231
231
|
return { ok: !i.ok, atom: "not(" + i.atom + ")", reason: i.ok ? "not(" + i.atom + ") matched" : null };
|
|
232
232
|
},
|
|
233
233
|
_toReq: function () {
|
|
234
|
-
throw new AuthError("auth-
|
|
234
|
+
throw new AuthError("auth-step-up/policy-no-challenge",
|
|
235
235
|
"policy.not: cannot translate to RFC 9470 challenge");
|
|
236
236
|
},
|
|
237
237
|
});
|
|
@@ -241,7 +241,7 @@ function _mergeAnd(a, b) {
|
|
|
241
241
|
var out = {};
|
|
242
242
|
if (a.acr || b.acr) {
|
|
243
243
|
if (a.acr && b.acr && a.acr !== b.acr) {
|
|
244
|
-
throw new AuthError("auth-
|
|
244
|
+
throw new AuthError("auth-step-up/policy-conflict",
|
|
245
245
|
"policy.and: conflicting acr requirements " +
|
|
246
246
|
JSON.stringify(a.acr) + " and " + JSON.stringify(b.acr));
|
|
247
247
|
}
|
|
@@ -311,7 +311,7 @@ var PRESETS = {
|
|
|
311
311
|
|
|
312
312
|
function preset(name) {
|
|
313
313
|
if (!Object.prototype.hasOwnProperty.call(PRESETS, name)) {
|
|
314
|
-
throw new AuthError("auth-
|
|
314
|
+
throw new AuthError("auth-step-up/bad-preset",
|
|
315
315
|
"policy.preset: unknown preset " + JSON.stringify(name) +
|
|
316
316
|
" — valid presets: " + Object.keys(PRESETS).join(", "));
|
|
317
317
|
}
|
package/lib/auth/step-up.js
CHANGED
|
@@ -87,11 +87,11 @@ function _quote(value) {
|
|
|
87
87
|
for (var i = 0; i < value.length; i += 1) {
|
|
88
88
|
var code = value.charCodeAt(i);
|
|
89
89
|
if (code < 32 || code === 127) { // allow:raw-byte-literal — ASCII control codepoints
|
|
90
|
-
throw new AuthError("auth-
|
|
90
|
+
throw new AuthError("auth-step-up/bad-challenge",
|
|
91
91
|
"challenge value contains control character at index " + i);
|
|
92
92
|
}
|
|
93
93
|
if (value.charAt(i) === '"' || value.charAt(i) === "\\") {
|
|
94
|
-
throw new AuthError("auth-
|
|
94
|
+
throw new AuthError("auth-step-up/bad-challenge",
|
|
95
95
|
"challenge value contains illegal character " +
|
|
96
96
|
JSON.stringify(value.charAt(i)) + " at index " + i);
|
|
97
97
|
}
|
|
@@ -101,7 +101,7 @@ function _quote(value) {
|
|
|
101
101
|
|
|
102
102
|
function _validateRequirement(requirement, label) {
|
|
103
103
|
if (!requirement || typeof requirement !== "object") {
|
|
104
|
-
throw new AuthError("auth-
|
|
104
|
+
throw new AuthError("auth-step-up/bad-requirement",
|
|
105
105
|
label + ": requirement must be an object — got " +
|
|
106
106
|
JSON.stringify(requirement));
|
|
107
107
|
}
|
|
@@ -111,39 +111,39 @@ function _validateRequirement(requirement, label) {
|
|
|
111
111
|
], label);
|
|
112
112
|
if (requirement.acr != null) {
|
|
113
113
|
validateOpts.requireNonEmptyString(requirement.acr,
|
|
114
|
-
label + ": acr", AuthError, "auth-
|
|
114
|
+
label + ": acr", AuthError, "auth-step-up/bad-acr");
|
|
115
115
|
}
|
|
116
116
|
if (requirement.acrValues != null) {
|
|
117
117
|
if (!Array.isArray(requirement.acrValues) || requirement.acrValues.length === 0) {
|
|
118
|
-
throw new AuthError("auth-
|
|
118
|
+
throw new AuthError("auth-step-up/bad-acr",
|
|
119
119
|
label + ": acrValues must be a non-empty string array");
|
|
120
120
|
}
|
|
121
121
|
for (var i = 0; i < requirement.acrValues.length; i += 1) {
|
|
122
122
|
validateOpts.requireNonEmptyString(requirement.acrValues[i],
|
|
123
|
-
label + ": acrValues[" + i + "]", AuthError, "auth-
|
|
123
|
+
label + ": acrValues[" + i + "]", AuthError, "auth-step-up/bad-acr");
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
126
|
if (requirement.maxAge != null) {
|
|
127
127
|
if (typeof requirement.maxAge !== "number" || !isFinite(requirement.maxAge) ||
|
|
128
128
|
requirement.maxAge < 0) {
|
|
129
|
-
throw new AuthError("auth-
|
|
129
|
+
throw new AuthError("auth-step-up/bad-max-age",
|
|
130
130
|
label + ": maxAge must be a finite number >= 0 — got " +
|
|
131
131
|
JSON.stringify(requirement.maxAge));
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
if (requirement.requiredAmr != null) {
|
|
135
135
|
if (!Array.isArray(requirement.requiredAmr)) {
|
|
136
|
-
throw new AuthError("auth-
|
|
136
|
+
throw new AuthError("auth-step-up/bad-amr",
|
|
137
137
|
label + ": requiredAmr must be a string array");
|
|
138
138
|
}
|
|
139
139
|
for (var j = 0; j < requirement.requiredAmr.length; j += 1) {
|
|
140
140
|
validateOpts.requireNonEmptyString(requirement.requiredAmr[j],
|
|
141
|
-
label + ": requiredAmr[" + j + "]", AuthError, "auth-
|
|
141
|
+
label + ": requiredAmr[" + j + "]", AuthError, "auth-step-up/bad-amr");
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
if (requirement.phishingResistant != null &&
|
|
145
145
|
typeof requirement.phishingResistant !== "boolean") {
|
|
146
|
-
throw new AuthError("auth-
|
|
146
|
+
throw new AuthError("auth-step-up/bad-requirement",
|
|
147
147
|
label + ": phishingResistant must be boolean — got " +
|
|
148
148
|
JSON.stringify(requirement.phishingResistant));
|
|
149
149
|
}
|
|
@@ -274,29 +274,29 @@ function buildChallenge(opts) {
|
|
|
274
274
|
// Hot-path callers wrap this in try/catch.
|
|
275
275
|
function parseAuthorizationDetails(value) {
|
|
276
276
|
if (typeof value !== "string") {
|
|
277
|
-
throw new AuthError("auth-
|
|
277
|
+
throw new AuthError("auth-step-up/bad-rar",
|
|
278
278
|
"parseAuthorizationDetails: value must be a JSON string — got " +
|
|
279
279
|
typeof value);
|
|
280
280
|
}
|
|
281
281
|
var parsed;
|
|
282
282
|
try { parsed = safeJson.parse(value, { maxBytes: C.BYTES.kib(64) }); }
|
|
283
283
|
catch (e) {
|
|
284
|
-
throw new AuthError("auth-
|
|
284
|
+
throw new AuthError("auth-step-up/bad-rar",
|
|
285
285
|
"parseAuthorizationDetails: invalid JSON — " + e.message);
|
|
286
286
|
}
|
|
287
287
|
if (!Array.isArray(parsed)) {
|
|
288
|
-
throw new AuthError("auth-
|
|
288
|
+
throw new AuthError("auth-step-up/bad-rar",
|
|
289
289
|
"parseAuthorizationDetails: value must be a JSON array — got " +
|
|
290
290
|
typeof parsed);
|
|
291
291
|
}
|
|
292
292
|
for (var i = 0; i < parsed.length; i += 1) {
|
|
293
293
|
var entry = parsed[i];
|
|
294
294
|
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
295
|
-
throw new AuthError("auth-
|
|
295
|
+
throw new AuthError("auth-step-up/bad-rar",
|
|
296
296
|
"parseAuthorizationDetails[" + i + "]: must be an object");
|
|
297
297
|
}
|
|
298
298
|
if (typeof entry.type !== "string" || entry.type.length === 0) {
|
|
299
|
-
throw new AuthError("auth-
|
|
299
|
+
throw new AuthError("auth-step-up/bad-rar",
|
|
300
300
|
"parseAuthorizationDetails[" + i + "]: missing required 'type' field");
|
|
301
301
|
}
|
|
302
302
|
}
|