@yuneta/gobj-js 7.26.18 → 7.26.20
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/README.md +14 -1
- package/dist/gobj-js.cjs.js +112 -18
- package/dist/gobj-js.cjs.js.map +1 -1
- package/dist/gobj-js.cjs.min.js +962 -906
- package/dist/gobj-js.cjs.min.js.map +1 -1
- package/dist/gobj-js.es.js +112 -18
- package/dist/gobj-js.es.js.map +1 -1
- package/dist/gobj-js.es.min.js +983 -927
- package/dist/gobj-js.es.min.js.map +1 -1
- package/dist/gobj-js.iife.js +112 -18
- package/dist/gobj-js.iife.js.map +1 -1
- package/dist/gobj-js.iife.min.js +962 -906
- package/dist/gobj-js.iife.min.js.map +1 -1
- package/dist/gobj-js.umd.js +112 -18
- package/dist/gobj-js.umd.js.map +1 -1
- package/dist/gobj-js.umd.min.js +962 -906
- package/dist/gobj-js.umd.min.js.map +1 -1
- package/package.json +1 -1
package/dist/gobj-js.iife.js
CHANGED
|
@@ -3337,18 +3337,23 @@ var gobjJs = (function(exports) {
|
|
|
3337
3337
|
} else output = args.map((arg) => typeof arg === "object" ? log_stringify(arg) : log_string(arg)).join(" ");
|
|
3338
3338
|
return output;
|
|
3339
3339
|
}
|
|
3340
|
-
var __in_log_function__ = false;
|
|
3341
3340
|
function call_log_function(fn, ...args) {
|
|
3342
|
-
if (__in_log_function__) return;
|
|
3343
|
-
__in_log_function__ = true;
|
|
3344
3341
|
try {
|
|
3345
3342
|
fn(...args);
|
|
3346
3343
|
} catch (e) {
|
|
3347
3344
|
try {
|
|
3348
3345
|
_console.error("a log function threw:", e);
|
|
3349
3346
|
} catch (e2) {}
|
|
3347
|
+
}
|
|
3348
|
+
}
|
|
3349
|
+
var __in_remote_log__ = false;
|
|
3350
|
+
function call_remote_log_function(fn, ...args) {
|
|
3351
|
+
if (__in_remote_log__) return;
|
|
3352
|
+
__in_remote_log__ = true;
|
|
3353
|
+
try {
|
|
3354
|
+
call_log_function(fn, ...args);
|
|
3350
3355
|
} finally {
|
|
3351
|
-
|
|
3356
|
+
__in_remote_log__ = false;
|
|
3352
3357
|
}
|
|
3353
3358
|
}
|
|
3354
3359
|
function log_error(format, ...args) {
|
|
@@ -3359,7 +3364,7 @@ var gobjJs = (function(exports) {
|
|
|
3359
3364
|
if (console_wants("error", msg)) call_log_function(f_error, "%c" + hora + " ERROR: " + String(msg), "color:red");
|
|
3360
3365
|
} else {
|
|
3361
3366
|
if (console_wants("error", msg)) _console.error("%c" + hora + " ERROR: " + String(msg), "color:red");
|
|
3362
|
-
|
|
3367
|
+
call_remote_log_function(f_error, `${hora} ERROR: ${String(msg)}`);
|
|
3363
3368
|
}
|
|
3364
3369
|
}
|
|
3365
3370
|
emit_log_callback("error", msg, hora);
|
|
@@ -3372,7 +3377,7 @@ var gobjJs = (function(exports) {
|
|
|
3372
3377
|
if (console_wants("warning", msg)) call_log_function(f_warning, "%c" + hora + " WARNING: " + String(msg), "color:yellow");
|
|
3373
3378
|
} else {
|
|
3374
3379
|
if (console_wants("warning", msg)) _console.warn("%c" + hora + " WARNING: " + String(msg), "color:yellow");
|
|
3375
|
-
|
|
3380
|
+
call_remote_log_function(f_warning, `${hora} WARNING: ${String(msg)}`);
|
|
3376
3381
|
}
|
|
3377
3382
|
}
|
|
3378
3383
|
emit_log_callback("warning", msg, hora);
|
|
@@ -3432,6 +3437,11 @@ var gobjJs = (function(exports) {
|
|
|
3432
3437
|
"sessionkey",
|
|
3433
3438
|
"authdata"
|
|
3434
3439
|
];
|
|
3440
|
+
var SECRET_NAME_SEGMENTS = /* @__PURE__ */ new Set([
|
|
3441
|
+
"pass",
|
|
3442
|
+
"pin",
|
|
3443
|
+
"otp"
|
|
3444
|
+
]);
|
|
3435
3445
|
var NOT_SECRET_SEGMENTS = /* @__PURE__ */ new Set([
|
|
3436
3446
|
"endpoint",
|
|
3437
3447
|
"url",
|
|
@@ -3464,10 +3474,16 @@ var gobjJs = (function(exports) {
|
|
|
3464
3474
|
if (typeof name !== "string" || name.length < 3) return false;
|
|
3465
3475
|
let lower = name.toLowerCase();
|
|
3466
3476
|
let hit = false;
|
|
3467
|
-
for (const
|
|
3477
|
+
for (const segment of lower.split(/[^a-z0-9]+/)) if (SECRET_NAME_SEGMENTS.has(segment)) {
|
|
3468
3478
|
hit = true;
|
|
3469
3479
|
break;
|
|
3470
3480
|
}
|
|
3481
|
+
if (!hit) {
|
|
3482
|
+
for (const part of SECRET_NAME_PARTS) if (lower.indexOf(part) >= 0) {
|
|
3483
|
+
hit = true;
|
|
3484
|
+
break;
|
|
3485
|
+
}
|
|
3486
|
+
}
|
|
3471
3487
|
if (!hit) {
|
|
3472
3488
|
let joined = lower.replace(/[_\-. \t]/g, "");
|
|
3473
3489
|
for (const part of SECRET_NAME_JOINED) if (joined.indexOf(part) >= 0) {
|
|
@@ -3505,17 +3521,63 @@ var gobjJs = (function(exports) {
|
|
|
3505
3521
|
}
|
|
3506
3522
|
}
|
|
3507
3523
|
/************************************************************
|
|
3524
|
+
* A credential by its SHAPE, whatever names it -- the C kernel's
|
|
3525
|
+
* jwt_len() / bearer_token_len(), the shapes the agent's audit
|
|
3526
|
+
* record redacts:
|
|
3527
|
+
* - a JWT: "eyJ" (the base64url of '{"') at the start of a
|
|
3528
|
+
* word, and three parts of base64url joined by '.'; the dots
|
|
3529
|
+
* at the end of the run are not its own (a JWT ends a
|
|
3530
|
+
* sentence: "... eyJ.eyJ.sig.");
|
|
3531
|
+
* - the token after "Bearer " (any case, a word of its own).
|
|
3532
|
+
************************************************************/
|
|
3533
|
+
function is_ascii_alnum_code(code) {
|
|
3534
|
+
return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122;
|
|
3535
|
+
}
|
|
3536
|
+
function is_base64url_code(code) {
|
|
3537
|
+
return is_ascii_alnum_code(code) || code === 45 || code === 95;
|
|
3538
|
+
}
|
|
3539
|
+
function jwt_len(str, p) {
|
|
3540
|
+
if (str.length - p < 3 || str[p] !== "e" || str[p + 1] !== "y" || str[p + 2] !== "J") return 0;
|
|
3541
|
+
if (p > 0 && (is_base64url_code(str.charCodeAt(p - 1)) || str[p - 1] === ".")) return 0;
|
|
3542
|
+
let e = p;
|
|
3543
|
+
let dots = 0;
|
|
3544
|
+
while (e < str.length && (is_base64url_code(str.charCodeAt(e)) || str[e] === ".")) {
|
|
3545
|
+
if (str[e] === ".") dots++;
|
|
3546
|
+
e++;
|
|
3547
|
+
}
|
|
3548
|
+
while (str[e - 1] === ".") {
|
|
3549
|
+
e--;
|
|
3550
|
+
dots--;
|
|
3551
|
+
}
|
|
3552
|
+
return dots === 2 ? e - p : 0;
|
|
3553
|
+
}
|
|
3554
|
+
var BEARER_STOPS = " \r\n'\",;}]\0";
|
|
3555
|
+
function bearer_token(str, p) {
|
|
3556
|
+
const word_len = 6;
|
|
3557
|
+
if (str.length - p <= word_len || str.slice(p, p + word_len).toLowerCase() !== "bearer") return [0, 0];
|
|
3558
|
+
if (p > 0 && is_ascii_alnum_code(str.charCodeAt(p - 1))) return [0, 0];
|
|
3559
|
+
let t = p + word_len;
|
|
3560
|
+
if (str[t] !== " " && str[t] !== " ") return [0, 0];
|
|
3561
|
+
while (t < str.length && (str[t] === " " || str[t] === " ")) t++;
|
|
3562
|
+
let e = t;
|
|
3563
|
+
while (e < str.length && BEARER_STOPS.indexOf(str[e]) < 0) e++;
|
|
3564
|
+
return [t - p, e - t];
|
|
3565
|
+
}
|
|
3566
|
+
/************************************************************
|
|
3508
3567
|
* A text (a command line) with the value of every "name=value"
|
|
3509
3568
|
* whose name is a secret's written as "********", quoted or not
|
|
3510
3569
|
* (and the "value" of a write-attr whose attribute names a
|
|
3511
|
-
* secret)
|
|
3512
|
-
*
|
|
3570
|
+
* secret); and a JWT or the token after "Bearer ", wherever they
|
|
3571
|
+
* are, whatever names them. The rest as it is. Return null when
|
|
3572
|
+
* there was nothing to mask. As the C kernel's
|
|
3573
|
+
* mask_secrets_inline().
|
|
3513
3574
|
************************************************************/
|
|
3514
3575
|
var MASK_MAX_NAME = 128;
|
|
3515
3576
|
var MASK_MAX_BYTES = 4194304;
|
|
3516
3577
|
var MASK_TOO_LARGE = "<not shown: too large to mask>";
|
|
3517
3578
|
function mask_secrets_inline(str) {
|
|
3518
|
-
if (typeof str !== "string"
|
|
3579
|
+
if (typeof str !== "string") return null;
|
|
3580
|
+
if (str.indexOf("=") < 0 && str.indexOf("eyJ") < 0 && !/bearer/i.test(str)) return null;
|
|
3519
3581
|
if (str.length > MASK_MAX_BYTES) return MASK_TOO_LARGE;
|
|
3520
3582
|
let value_is_secret = false;
|
|
3521
3583
|
let re_attr = /(^|[ \t])attribute=["']?([^ \t"']*)/g;
|
|
@@ -3539,6 +3601,18 @@ var gobjJs = (function(exports) {
|
|
|
3539
3601
|
if (!outer && (p === 0 || str[p - 1] === " " || str[p - 1] === " " || str[p - 1] === "=")) outer = c;
|
|
3540
3602
|
else if (c === outer && is_blank_or_end(p + 1)) outer = "";
|
|
3541
3603
|
}
|
|
3604
|
+
let shape = c === "e" ? jwt_len(str, p) : 0;
|
|
3605
|
+
let token_offset = 0;
|
|
3606
|
+
if (c === "b" || c === "B") [token_offset, shape] = bearer_token(str, p);
|
|
3607
|
+
if (shape) {
|
|
3608
|
+
parts.push(str.substring(copied, p + token_offset));
|
|
3609
|
+
parts.push("********");
|
|
3610
|
+
p += token_offset + shape;
|
|
3611
|
+
copied = p;
|
|
3612
|
+
changed = true;
|
|
3613
|
+
word = p;
|
|
3614
|
+
continue;
|
|
3615
|
+
}
|
|
3542
3616
|
if (c !== "=") {
|
|
3543
3617
|
p++;
|
|
3544
3618
|
continue;
|
|
@@ -3575,7 +3649,8 @@ var gobjJs = (function(exports) {
|
|
|
3575
3649
|
* value of a key with a secret's name is "********", whatever
|
|
3576
3650
|
* its type (not an absent one, a null or an empty string); so is
|
|
3577
3651
|
* the "value" of a dict whose "attribute" names a secret; and a
|
|
3578
|
-
* string is masked as mask_secrets_inline()
|
|
3652
|
+
* string, under any key, is masked as mask_secrets_inline() (a
|
|
3653
|
+
* JWT, a "Bearer" token, a secret name=value). Return a masked
|
|
3579
3654
|
* copy, or `jn` itself when there was nothing to mask. As the C
|
|
3580
3655
|
* kernel's json_mask_secrets().
|
|
3581
3656
|
*
|
|
@@ -3604,7 +3679,7 @@ var gobjJs = (function(exports) {
|
|
|
3604
3679
|
return MASK_TOO_LARGE;
|
|
3605
3680
|
}
|
|
3606
3681
|
budget.left -= jn.length;
|
|
3607
|
-
let masked = mask_secrets_inline(jn);
|
|
3682
|
+
let masked = mask_secrets_inline(jn.indexOf("\0") >= 0 ? jn.replace(/\u0000/g, " ") : jn);
|
|
3608
3683
|
return masked !== null ? masked : jn;
|
|
3609
3684
|
}
|
|
3610
3685
|
let is_array = Array.isArray(jn);
|
|
@@ -7106,15 +7181,34 @@ var gobjJs = (function(exports) {
|
|
|
7106
7181
|
return gobj_save_persistent_attrs(gobj, attr);
|
|
7107
7182
|
}
|
|
7108
7183
|
/***************************************************************
|
|
7109
|
-
* "set" as the C command reads it
|
|
7184
|
+
* "set" as the C command reads it (trace_set_value() of c_yuno.c):
|
|
7185
|
+
* a boolean; an integer in the range of an int (true unless 0); or
|
|
7186
|
+
* text -- set / reset, a JSON integer -?(0|[1-9][0-9]*), or true /
|
|
7187
|
+
* false, yes / no, on / off, any case. null for anything else: a
|
|
7188
|
+
* real (2.5), " 1", "0x1", "1e3", "+5", "007" and "2.5" are refused,
|
|
7189
|
+
* as in C. Up to gobj-js 7.26.19 the text went through Number(),
|
|
7190
|
+
* which took all of them, and "yes" / "on" were refused.
|
|
7110
7191
|
***************************************************************/
|
|
7192
|
+
var INT_MIN = -2147483648;
|
|
7193
|
+
var INT_MAX = 2147483647;
|
|
7111
7194
|
function parse_set(value) {
|
|
7112
7195
|
if (value === true || value === false) return value;
|
|
7113
|
-
|
|
7114
|
-
|
|
7115
|
-
|
|
7116
|
-
|
|
7117
|
-
|
|
7196
|
+
if (typeof value === "number") {
|
|
7197
|
+
if (!Number.isInteger(value) || value < INT_MIN || value > INT_MAX) return null;
|
|
7198
|
+
return value !== 0;
|
|
7199
|
+
}
|
|
7200
|
+
if (typeof value !== "string" || value === "") return null;
|
|
7201
|
+
let v = value.toLowerCase();
|
|
7202
|
+
if (v === "set") return true;
|
|
7203
|
+
if (v === "reset") return false;
|
|
7204
|
+
if (/^-?(0|[1-9][0-9]*)$/.test(value)) {
|
|
7205
|
+
let n = Number(value);
|
|
7206
|
+
if (n < INT_MIN || n > INT_MAX) return null;
|
|
7207
|
+
return n !== 0;
|
|
7208
|
+
}
|
|
7209
|
+
if (v === "true" || v === "yes" || v === "on") return true;
|
|
7210
|
+
if (v === "false" || v === "no" || v === "off") return false;
|
|
7211
|
+
return null;
|
|
7118
7212
|
}
|
|
7119
7213
|
function yuno_prefix() {
|
|
7120
7214
|
return `${gobj_yuno_role()}^${gobj_yuno_name()}`;
|