mask-privacy 4.0.0 → 4.2.0
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/dist/index.d.mts +37 -31
- package/dist/index.d.ts +37 -31
- package/dist/index.js +794 -370
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +767 -342
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
- package/src/config.ts +5 -0
- package/src/core/crypto.ts +171 -87
- package/src/core/exceptions.ts +25 -0
- package/src/core/ff1.ts +196 -0
- package/src/core/fpe.ts +97 -175
- package/src/core/fpe_utils.ts +57 -11
- package/src/core/key_provider.ts +80 -0
- package/src/core/vault.ts +152 -78
- package/src/telemetry/audit_logger.ts +136 -16
- package/tests/bijective_fpe.test.ts +16 -12
- package/tests/fpe.test.ts +17 -8
- package/tests/security_hardening.test.ts +117 -0
- package/tests/vault.test.ts +67 -0
- package/tests/vault_backends.test.ts +7 -7
package/dist/index.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var process2 = require('process');
|
|
4
|
-
var
|
|
4
|
+
var path2 = require('path');
|
|
5
5
|
var os = require('os');
|
|
6
|
-
var
|
|
6
|
+
var cryptoNode = require('crypto');
|
|
7
|
+
var fs = require('fs');
|
|
7
8
|
var buffer = require('buffer');
|
|
8
9
|
var stream = require('stream');
|
|
9
10
|
var https = require('https');
|
|
10
11
|
var http2 = require('http2');
|
|
11
|
-
var
|
|
12
|
+
var fs2 = require('fs/promises');
|
|
12
13
|
var http = require('http');
|
|
13
14
|
var url = require('url');
|
|
14
|
-
var fs = require('fs');
|
|
15
15
|
var child_process = require('child_process');
|
|
16
16
|
var util = require('util');
|
|
17
17
|
|
|
@@ -36,11 +36,12 @@ function _interopNamespace(e) {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
var process2__namespace = /*#__PURE__*/_interopNamespace(process2);
|
|
39
|
-
var
|
|
39
|
+
var path2__namespace = /*#__PURE__*/_interopNamespace(path2);
|
|
40
40
|
var os__namespace = /*#__PURE__*/_interopNamespace(os);
|
|
41
|
-
var
|
|
41
|
+
var cryptoNode__namespace = /*#__PURE__*/_interopNamespace(cryptoNode);
|
|
42
|
+
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
42
43
|
var http2__default = /*#__PURE__*/_interopDefault(http2);
|
|
43
|
-
var
|
|
44
|
+
var fs2__default = /*#__PURE__*/_interopDefault(fs2);
|
|
44
45
|
|
|
45
46
|
var __create = Object.create;
|
|
46
47
|
var __defProp = Object.defineProperty;
|
|
@@ -128,6 +129,11 @@ var init_config = __esm({
|
|
|
128
129
|
get MASK_ENCRYPTION_KEY() {
|
|
129
130
|
return process2__namespace.env.MASK_ENCRYPTION_KEY || null;
|
|
130
131
|
},
|
|
132
|
+
// JSON map of keyId -> base64 key string for key rotation, e.g. {"v1":"...","v2":"..."}
|
|
133
|
+
// The last entry in the map is treated as the active (encryption) key.
|
|
134
|
+
get MASK_KEYRING() {
|
|
135
|
+
return process2__namespace.env.MASK_KEYRING || null;
|
|
136
|
+
},
|
|
131
137
|
get MASK_MASTER_KEY() {
|
|
132
138
|
return process2__namespace.env.MASK_MASTER_KEY || process2__namespace.env.MASK_ENCRYPTION_KEY || "";
|
|
133
139
|
},
|
|
@@ -140,6 +146,9 @@ var init_config = __esm({
|
|
|
140
146
|
get MASK_BLIND_INDEX_SALT() {
|
|
141
147
|
return process2__namespace.env.MASK_BLIND_INDEX_SALT || "mask-blind-index";
|
|
142
148
|
},
|
|
149
|
+
get MASK_KDF_SALT() {
|
|
150
|
+
return process2__namespace.env.MASK_KDF_SALT || "mask-kdf-v4-argon2id";
|
|
151
|
+
},
|
|
143
152
|
get VAULT_TOKEN() {
|
|
144
153
|
return process2__namespace.env.VAULT_TOKEN || null;
|
|
145
154
|
},
|
|
@@ -156,6 +165,9 @@ var init_config = __esm({
|
|
|
156
165
|
get MASK_VAULT_CLEANUP_FREQUENCY() {
|
|
157
166
|
return getEnvFloat("MASK_VAULT_CLEANUP_FREQUENCY", 0.01);
|
|
158
167
|
},
|
|
168
|
+
get MASK_VAULT_MAX_MEMORY_KEYS() {
|
|
169
|
+
return getEnvInt("MASK_VAULT_MAX_MEMORY_KEYS", 1e5);
|
|
170
|
+
},
|
|
159
171
|
// --- BACKEND CONNECTIONS ---
|
|
160
172
|
get MASK_REDIS_URL() {
|
|
161
173
|
return process2__namespace.env.MASK_REDIS_URL || "redis://localhost:6379/0";
|
|
@@ -195,7 +207,7 @@ var init_config = __esm({
|
|
|
195
207
|
return process2__namespace.env.MASK_SCANNER_URL || "http://localhost:5001/analyze";
|
|
196
208
|
},
|
|
197
209
|
get MASK_MODEL_CACHE_DIR() {
|
|
198
|
-
return process2__namespace.env.MASK_MODEL_CACHE_DIR ||
|
|
210
|
+
return process2__namespace.env.MASK_MODEL_CACHE_DIR || path2__namespace.join(os__namespace.homedir(), ".cache", "mask");
|
|
199
211
|
},
|
|
200
212
|
// --- TELEMETRY & AUDIT ---
|
|
201
213
|
get MASK_AUDIT_LOG_STRICT() {
|
|
@@ -220,6 +232,16 @@ var init_key_provider = __esm({
|
|
|
220
232
|
"src/core/key_provider.ts"() {
|
|
221
233
|
init_config();
|
|
222
234
|
BaseKeyProvider = class {
|
|
235
|
+
/**
|
|
236
|
+
* Return a JSON keyring string (e.g. from KMS / Secrets Manager), or null
|
|
237
|
+
* to fall back to the MASK_KEYRING environment variable.
|
|
238
|
+
*
|
|
239
|
+
* Override in KMS-backed providers to source the full keyring from a
|
|
240
|
+
* secure external store, removing the need for MASK_KEYRING in env vars.
|
|
241
|
+
*/
|
|
242
|
+
getKeyring() {
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
223
245
|
};
|
|
224
246
|
EnvKeyProvider = class extends BaseKeyProvider {
|
|
225
247
|
async getEncryptionKey() {
|
|
@@ -235,13 +257,17 @@ var init_key_provider = __esm({
|
|
|
235
257
|
let key = config.MASK_MASTER_KEY;
|
|
236
258
|
return key || null;
|
|
237
259
|
}
|
|
260
|
+
/** Return MASK_KEYRING from environment (default behaviour). */
|
|
261
|
+
async getKeyring() {
|
|
262
|
+
return config.MASK_KEYRING || null;
|
|
263
|
+
}
|
|
238
264
|
};
|
|
239
265
|
providerInstance = null;
|
|
240
266
|
}
|
|
241
267
|
});
|
|
242
268
|
|
|
243
269
|
// src/core/exceptions.ts
|
|
244
|
-
exports.MaskError = void 0; exports.MaskVaultConnectionError = void 0; exports.MaskDecryptionError = void 0; exports.MaskNLPTimeout = void 0; exports.MaskSecurityError = void 0;
|
|
270
|
+
exports.MaskError = void 0; exports.MaskVaultConnectionError = void 0; exports.MaskDecryptionError = void 0; exports.MaskNLPTimeout = void 0; exports.MaskSecurityError = void 0; var TokenCollisionError;
|
|
245
271
|
var init_exceptions = __esm({
|
|
246
272
|
"src/core/exceptions.ts"() {
|
|
247
273
|
exports.MaskError = class extends Error {
|
|
@@ -259,6 +285,185 @@ var init_exceptions = __esm({
|
|
|
259
285
|
};
|
|
260
286
|
exports.MaskSecurityError = class extends exports.MaskError {
|
|
261
287
|
};
|
|
288
|
+
TokenCollisionError = class extends exports.MaskError {
|
|
289
|
+
constructor(token, existingHash, incomingHash) {
|
|
290
|
+
super(
|
|
291
|
+
`Token collision detected for token '${token}'. Existing plaintext hash '${existingHash.slice(0, 8)}\u2026' conflicts with incoming hash '${incomingHash.slice(0, 8)}\u2026'. Increase token entropy or adjust tenant salt configuration.`
|
|
292
|
+
);
|
|
293
|
+
this.token = token;
|
|
294
|
+
this.existingHash = existingHash;
|
|
295
|
+
this.incomingHash = incomingHash;
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
var FF1;
|
|
301
|
+
var init_ff1 = __esm({
|
|
302
|
+
"src/core/ff1.ts"() {
|
|
303
|
+
FF1 = class {
|
|
304
|
+
constructor(key, tweak, radix) {
|
|
305
|
+
this.chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
306
|
+
this.key = key;
|
|
307
|
+
this.tweak = tweak;
|
|
308
|
+
this.radix = radix;
|
|
309
|
+
if (radix > this.chars.length) {
|
|
310
|
+
throw new Error(`Radix ${radix} not supported`);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
_prf(x6) {
|
|
314
|
+
const cipher = cryptoNode__namespace.createCipheriv("aes-256-cbc", this.key, Buffer.alloc(16, 0));
|
|
315
|
+
cipher.setAutoPadding(false);
|
|
316
|
+
return Buffer.concat([cipher.update(x6), cipher.final()]).subarray(-16);
|
|
317
|
+
}
|
|
318
|
+
_ciph(x6) {
|
|
319
|
+
const cipher = cryptoNode__namespace.createCipheriv("aes-256-ecb", this.key, null);
|
|
320
|
+
cipher.setAutoPadding(false);
|
|
321
|
+
return Buffer.concat([cipher.update(x6), cipher.final()]);
|
|
322
|
+
}
|
|
323
|
+
_strToInt(s6) {
|
|
324
|
+
let n6 = 0n;
|
|
325
|
+
const r6 = BigInt(this.radix);
|
|
326
|
+
for (let i6 = 0; i6 < s6.length; i6++) {
|
|
327
|
+
n6 = n6 * r6 + BigInt(this.chars.indexOf(s6[i6]));
|
|
328
|
+
}
|
|
329
|
+
return n6;
|
|
330
|
+
}
|
|
331
|
+
_intToStr(num, length) {
|
|
332
|
+
if (num === 0n) {
|
|
333
|
+
return this.chars[0].repeat(length);
|
|
334
|
+
}
|
|
335
|
+
let digits = [];
|
|
336
|
+
let n6 = num;
|
|
337
|
+
const r6 = BigInt(this.radix);
|
|
338
|
+
while (n6 > 0n) {
|
|
339
|
+
digits.push(this.chars[Number(n6 % r6)]);
|
|
340
|
+
n6 /= r6;
|
|
341
|
+
}
|
|
342
|
+
let s6 = digits.reverse().join("");
|
|
343
|
+
while (s6.length < length) s6 = this.chars[0] + s6;
|
|
344
|
+
return s6;
|
|
345
|
+
}
|
|
346
|
+
_bigintToBuffer(num, bytes) {
|
|
347
|
+
const buf = Buffer.alloc(bytes);
|
|
348
|
+
let n6 = num;
|
|
349
|
+
for (let i6 = bytes - 1; i6 >= 0; i6--) {
|
|
350
|
+
buf[i6] = Number(n6 & 0xFFn);
|
|
351
|
+
n6 >>= 8n;
|
|
352
|
+
}
|
|
353
|
+
return buf;
|
|
354
|
+
}
|
|
355
|
+
encrypt(X) {
|
|
356
|
+
const n6 = X.length;
|
|
357
|
+
const t6 = this.tweak.length;
|
|
358
|
+
if (n6 < 2) return X;
|
|
359
|
+
const u6 = Math.floor(n6 / 2);
|
|
360
|
+
const v7 = n6 - u6;
|
|
361
|
+
let A3 = X.substring(0, u6);
|
|
362
|
+
let B3 = X.substring(u6);
|
|
363
|
+
const b6 = Math.ceil(Math.ceil(v7 * Math.log2(this.radix)) / 8);
|
|
364
|
+
const d6 = 4 * Math.ceil(b6 / 4) + 4;
|
|
365
|
+
const P2 = Buffer.alloc(16);
|
|
366
|
+
P2[0] = 1;
|
|
367
|
+
P2[1] = 2;
|
|
368
|
+
P2[2] = 1;
|
|
369
|
+
P2.writeUIntBE(this.radix, 3, 3);
|
|
370
|
+
P2[6] = 10;
|
|
371
|
+
P2[7] = u6 % 256;
|
|
372
|
+
P2.writeUInt32BE(n6, 8);
|
|
373
|
+
P2.writeUInt32BE(t6, 12);
|
|
374
|
+
for (let i6 = 0; i6 < 10; i6++) {
|
|
375
|
+
const m6 = i6 % 2 === 0 ? u6 : v7;
|
|
376
|
+
const padLen = ((-t6 - b6 - 1) % 16 + 16) % 16;
|
|
377
|
+
const Q2 = Buffer.alloc(t6 + padLen + 1 + b6);
|
|
378
|
+
this.tweak.copy(Q2, 0);
|
|
379
|
+
Q2[t6 + padLen] = i6;
|
|
380
|
+
this._bigintToBuffer(this._strToInt(B3), b6).copy(Q2, t6 + padLen + 1);
|
|
381
|
+
const R2 = this._prf(Buffer.concat([P2, Q2]));
|
|
382
|
+
let S2 = Buffer.from(R2);
|
|
383
|
+
let j6 = 1;
|
|
384
|
+
while (S2.length < d6) {
|
|
385
|
+
const xorBlock = Buffer.alloc(16);
|
|
386
|
+
const jBuf = Buffer.alloc(16);
|
|
387
|
+
jBuf.writeUInt32BE(j6, 12);
|
|
388
|
+
for (let k6 = 0; k6 < 16; k6++) xorBlock[k6] = R2[k6] ^ jBuf[k6];
|
|
389
|
+
S2 = Buffer.concat([S2, this._ciph(xorBlock)]);
|
|
390
|
+
j6++;
|
|
391
|
+
}
|
|
392
|
+
S2 = S2.subarray(0, d6);
|
|
393
|
+
let y3 = 0n;
|
|
394
|
+
for (let k6 = 0; k6 < S2.length; k6++) {
|
|
395
|
+
y3 = (y3 << 8n) + BigInt(S2[k6]);
|
|
396
|
+
}
|
|
397
|
+
const modulo = BigInt(this.radix) ** BigInt(m6);
|
|
398
|
+
const c6 = (this._strToInt(A3) + y3) % modulo;
|
|
399
|
+
const C3 = this._intToStr(c6, m6);
|
|
400
|
+
A3 = B3;
|
|
401
|
+
B3 = C3;
|
|
402
|
+
}
|
|
403
|
+
return A3 + B3;
|
|
404
|
+
}
|
|
405
|
+
decrypt(X) {
|
|
406
|
+
const n6 = X.length;
|
|
407
|
+
const t6 = this.tweak.length;
|
|
408
|
+
if (n6 < 2) return X;
|
|
409
|
+
const u6 = Math.floor(n6 / 2);
|
|
410
|
+
const v7 = n6 - u6;
|
|
411
|
+
let A3 = X.substring(0, u6);
|
|
412
|
+
let B3 = X.substring(u6);
|
|
413
|
+
if (n6 % 2 !== 0) {
|
|
414
|
+
const temp = A3;
|
|
415
|
+
A3 = B3;
|
|
416
|
+
B3 = temp;
|
|
417
|
+
}
|
|
418
|
+
const b6 = Math.ceil(Math.ceil(v7 * Math.log2(this.radix)) / 8);
|
|
419
|
+
const d6 = 4 * Math.ceil(b6 / 4) + 4;
|
|
420
|
+
const P2 = Buffer.alloc(16);
|
|
421
|
+
P2[0] = 1;
|
|
422
|
+
P2[1] = 2;
|
|
423
|
+
P2[2] = 1;
|
|
424
|
+
P2.writeUIntBE(this.radix, 3, 3);
|
|
425
|
+
P2[6] = 10;
|
|
426
|
+
P2[7] = u6 % 256;
|
|
427
|
+
P2.writeUInt32BE(n6, 8);
|
|
428
|
+
P2.writeUInt32BE(t6, 12);
|
|
429
|
+
for (let i6 = 9; i6 >= 0; i6--) {
|
|
430
|
+
const m6 = i6 % 2 === 0 ? u6 : v7;
|
|
431
|
+
const padLen = ((-t6 - b6 - 1) % 16 + 16) % 16;
|
|
432
|
+
const Q2 = Buffer.alloc(t6 + padLen + 1 + b6);
|
|
433
|
+
this.tweak.copy(Q2, 0);
|
|
434
|
+
Q2[t6 + padLen] = i6;
|
|
435
|
+
this._bigintToBuffer(this._strToInt(A3), b6).copy(Q2, t6 + padLen + 1);
|
|
436
|
+
const R2 = this._prf(Buffer.concat([P2, Q2]));
|
|
437
|
+
let S2 = Buffer.from(R2);
|
|
438
|
+
let j6 = 1;
|
|
439
|
+
while (S2.length < d6) {
|
|
440
|
+
const xorBlock = Buffer.alloc(16);
|
|
441
|
+
const jBuf = Buffer.alloc(16);
|
|
442
|
+
jBuf.writeUInt32BE(j6, 12);
|
|
443
|
+
for (let k6 = 0; k6 < 16; k6++) xorBlock[k6] = R2[k6] ^ jBuf[k6];
|
|
444
|
+
S2 = Buffer.concat([S2, this._ciph(xorBlock)]);
|
|
445
|
+
j6++;
|
|
446
|
+
}
|
|
447
|
+
S2 = S2.subarray(0, d6);
|
|
448
|
+
let y3 = 0n;
|
|
449
|
+
for (let k6 = 0; k6 < S2.length; k6++) {
|
|
450
|
+
y3 = (y3 << 8n) + BigInt(S2[k6]);
|
|
451
|
+
}
|
|
452
|
+
const modulo = BigInt(this.radix) ** BigInt(m6);
|
|
453
|
+
let c6 = (this._strToInt(B3) - y3) % modulo;
|
|
454
|
+
if (c6 < 0n) c6 += modulo;
|
|
455
|
+
const C3 = this._intToStr(c6, m6);
|
|
456
|
+
B3 = A3;
|
|
457
|
+
A3 = C3;
|
|
458
|
+
}
|
|
459
|
+
if (n6 % 2 !== 0) {
|
|
460
|
+
const temp = A3;
|
|
461
|
+
A3 = B3;
|
|
462
|
+
B3 = temp;
|
|
463
|
+
}
|
|
464
|
+
return A3 + B3;
|
|
465
|
+
}
|
|
466
|
+
};
|
|
262
467
|
}
|
|
263
468
|
});
|
|
264
469
|
|
|
@@ -485,13 +690,13 @@ function looksLikeToken(value) {
|
|
|
485
690
|
if (/^\+[1-9]\d{0,3}-555-\d{7}$/.test(v7)) {
|
|
486
691
|
return true;
|
|
487
692
|
}
|
|
488
|
-
if (
|
|
693
|
+
if (/^\d{3}-\d{2}-\d{4}$/.test(v7)) {
|
|
489
694
|
return true;
|
|
490
695
|
}
|
|
491
|
-
if (
|
|
696
|
+
if (/^\d{4}-\d{4}-\d{4}-\d{4}$/.test(v7)) {
|
|
492
697
|
return true;
|
|
493
698
|
}
|
|
494
|
-
if (v7.
|
|
699
|
+
if (v7.length === 9 && /^\d+$/.test(v7)) {
|
|
495
700
|
return true;
|
|
496
701
|
}
|
|
497
702
|
if (v7.length === 9 && v7.startsWith("000") && /[A-Z]$/.test(v7)) {
|
|
@@ -515,11 +720,28 @@ function looksLikeToken(value) {
|
|
|
515
720
|
}
|
|
516
721
|
return false;
|
|
517
722
|
}
|
|
723
|
+
function isUnambiguouslySafeToken(value) {
|
|
724
|
+
if (typeof value !== "string") return false;
|
|
725
|
+
const v7 = value.trim();
|
|
726
|
+
if (v7.startsWith("tkn-") && v7.includes("@")) {
|
|
727
|
+
const parts = v7.split("@");
|
|
728
|
+
if (parts.length === 2 && parts[0].length >= 12 && parts[1].includes(".")) {
|
|
729
|
+
return true;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
if (/^\+[1-9]\d{0,3}-555-\d{7}$/.test(v7)) return true;
|
|
733
|
+
if (/^000\d{5}[A-Z]$/.test(v7)) return true;
|
|
734
|
+
if (/^[A-Z]{2}00[A-F0-9]{4,16}$/.test(v7)) return true;
|
|
735
|
+
if (/^<(PER|LOC|ORG):[^>]+>$/.test(v7)) return true;
|
|
736
|
+
if (v7.startsWith("[TKN-") && v7.endsWith("]")) return true;
|
|
737
|
+
if (/^[A-Z][a-zA-Z, ]+-[0-9]{3,4}$/.test(v7)) return true;
|
|
738
|
+
return false;
|
|
739
|
+
}
|
|
518
740
|
var TOKEN_PATTERN;
|
|
519
741
|
var init_fpe_utils = __esm({
|
|
520
742
|
"src/core/fpe_utils.ts"() {
|
|
521
743
|
TOKEN_PATTERN = new RegExp(
|
|
522
|
-
"tkn-[a-f0-9]{8,64}@[A-Za-z0-9.\\-]+\\.[A-Za-z]{2,}|\\+[1-9]\\d{0,3}-555-\\d{7}
|
|
744
|
+
"tkn-[a-f0-9]{8,64}@[A-Za-z0-9.\\-]+\\.[A-Za-z]{2,}|\\+[1-9]\\d{0,3}-555-\\d{7}|\\d{3}-\\d{2}-\\d{4}|\\d{4}-\\d{4}-\\d{4}-\\d{4}|\\b\\d{9}\\b|\\b000\\d{5}[A-Z]\\b|[A-Z]{2}00[A-F0-9]{4,16}|<(?:PER|LOC|ORG):[^>]+>|\\b[A-Z][a-zA-Z, ]+-[0-9]{3,4}\\b|\\[TKN-[^\\]]+\\]",
|
|
523
745
|
// Opaque
|
|
524
746
|
"g"
|
|
525
747
|
);
|
|
@@ -534,12 +756,10 @@ async function _getMasterKey() {
|
|
|
534
756
|
}
|
|
535
757
|
if (!raw) {
|
|
536
758
|
if (config.MASK_DEV_MODE) {
|
|
537
|
-
raw =
|
|
759
|
+
raw = cryptoNode__namespace.randomBytes(32).toString("hex");
|
|
538
760
|
process.env.MASK_MASTER_KEY = raw;
|
|
539
761
|
} else {
|
|
540
|
-
throw new exports.MaskSecurityError(
|
|
541
|
-
"MASK_MASTER_KEY not set. Set it or use MASK_DEV_MODE=true for dev."
|
|
542
|
-
);
|
|
762
|
+
throw new exports.MaskSecurityError("MASK_MASTER_KEY not set.");
|
|
543
763
|
}
|
|
544
764
|
}
|
|
545
765
|
_masterKey = Buffer.from(raw, "utf-8");
|
|
@@ -549,38 +769,34 @@ async function _getMasterKey() {
|
|
|
549
769
|
function resetMasterKey() {
|
|
550
770
|
_masterKey = null;
|
|
551
771
|
}
|
|
552
|
-
async function
|
|
772
|
+
async function _getAesKey() {
|
|
553
773
|
const masterKey = await _getMasterKey();
|
|
554
|
-
|
|
555
|
-
return digest.slice(0, n6);
|
|
774
|
+
return cryptoNode__namespace.createHmac("sha256", masterKey).update(config.MASK_TENANT_ID, "utf-8").digest();
|
|
556
775
|
}
|
|
557
|
-
async function
|
|
776
|
+
async function _hmacHex(plaintext, n6 = 8) {
|
|
558
777
|
const masterKey = await _getMasterKey();
|
|
559
|
-
const
|
|
560
|
-
|
|
561
|
-
for (let i6 = 0; i6 < 16; i6++) {
|
|
562
|
-
result = result << 8n | BigInt(raw[i6]);
|
|
563
|
-
}
|
|
564
|
-
return result;
|
|
565
|
-
}
|
|
566
|
-
async function _hmacDigits(plaintext, n6, offset = 0) {
|
|
567
|
-
const salted = offset ? `${plaintext}::${offset}` : plaintext;
|
|
568
|
-
const seed = await _hmacInt(salted);
|
|
569
|
-
const modulus = 10n ** BigInt(n6);
|
|
570
|
-
return (seed % modulus).toString().padStart(n6, "0");
|
|
778
|
+
const digest = cryptoNode__namespace.createHmac("sha256", masterKey).update(plaintext, "utf-8").digest("hex");
|
|
779
|
+
return digest.slice(0, n6);
|
|
571
780
|
}
|
|
572
781
|
async function _getBijectiveTweak() {
|
|
573
|
-
const masterKey = await _getMasterKey();
|
|
574
|
-
let base = config.MASK_TENANT_ID;
|
|
575
782
|
if (config.MASK_SALT_ROTATION !== "NONE") {
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
} else if (config.MASK_SALT_ROTATION === "YEARLY") {
|
|
580
|
-
base += `-${now.getUTCFullYear()}`;
|
|
581
|
-
}
|
|
783
|
+
console.warn(
|
|
784
|
+
`[mask] MASK_SALT_ROTATION=${config.MASK_SALT_ROTATION} is deprecated and ignored. Time-based tweaks caused permanent data loss on month/year rollovers. Use MASK_KEYRING for key rotation instead.`
|
|
785
|
+
);
|
|
582
786
|
}
|
|
583
|
-
|
|
787
|
+
const masterKey = await _getMasterKey();
|
|
788
|
+
return cryptoNode__namespace.createHmac("sha256", masterKey).update(config.MASK_TENANT_ID, "utf-8").digest();
|
|
789
|
+
}
|
|
790
|
+
async function _encryptBijectiveFF1(text) {
|
|
791
|
+
const canonical = text.toLowerCase().trim();
|
|
792
|
+
const hash = cryptoNode__namespace.createHash("sha256").update(canonical, "utf-8").digest();
|
|
793
|
+
const inputInt = hash.readBigUInt64BE(0);
|
|
794
|
+
const inputStr = inputInt.toString().padStart(20, "0");
|
|
795
|
+
const aesKey = await _getAesKey();
|
|
796
|
+
const tweak = await _getBijectiveTweak();
|
|
797
|
+
const engine = new FF1(aesKey, tweak, 10);
|
|
798
|
+
const cipherStr = engine.encrypt(inputStr);
|
|
799
|
+
return BigInt(cipherStr) % 2n ** 64n;
|
|
584
800
|
}
|
|
585
801
|
function _renderBijectivePerson(bits) {
|
|
586
802
|
const firstIdx = Number(bits & 0x7FFn);
|
|
@@ -628,7 +844,10 @@ function _computeLuhnDigit(partialNum) {
|
|
|
628
844
|
function _computeEsIdCheck(num) {
|
|
629
845
|
return "TRWAGMYFPDXBNJZSQVHLCKE"[num % 23];
|
|
630
846
|
}
|
|
631
|
-
|
|
847
|
+
function _stripCcSeparators(text) {
|
|
848
|
+
return text.replace(/[\s\-]/g, "");
|
|
849
|
+
}
|
|
850
|
+
async function generateDPToken(rawText, entityType = "UNKNOWN") {
|
|
632
851
|
const text = rawText.trim();
|
|
633
852
|
let type = (entityType || "UNKNOWN").toUpperCase();
|
|
634
853
|
if (type === "UNKNOWN") {
|
|
@@ -648,49 +867,73 @@ async function generateFPEToken(rawText, entityType = "UNKNOWN") {
|
|
|
648
867
|
if (type === "PHONE_NUMBER" || type === "PHONE_NUM" || type === "PHONE_NUM_INTL") {
|
|
649
868
|
const m6 = text.match(/^\+([1-9]\d{0,3})/);
|
|
650
869
|
const cc = m6 ? m6[1] : "1";
|
|
651
|
-
|
|
870
|
+
const digits = text.replace(/\D/g, "");
|
|
871
|
+
if (digits.length >= 7) {
|
|
872
|
+
const last7 = digits.slice(-7);
|
|
873
|
+
const engine = new FF1(await _getAesKey(), Buffer.from("PHONE"), 10);
|
|
874
|
+
const enc = engine.encrypt(last7);
|
|
875
|
+
return `+${cc}-555-${enc}`;
|
|
876
|
+
}
|
|
652
877
|
}
|
|
653
878
|
if (type === "US_SSN") {
|
|
654
|
-
|
|
879
|
+
const digits = text.replace(/-/g, "");
|
|
880
|
+
if (digits.length === 9) {
|
|
881
|
+
const engine = new FF1(await _getAesKey(), Buffer.from("US_SSN"), 10);
|
|
882
|
+
const enc = engine.encrypt(digits);
|
|
883
|
+
return `${enc.slice(0, 3)}-${enc.slice(3, 5)}-${enc.slice(5, 9)}`;
|
|
884
|
+
}
|
|
655
885
|
}
|
|
656
886
|
if (type === "CREDIT_CARD" || type === "CREDIT_CARD_NUMBER") {
|
|
657
|
-
const
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
887
|
+
const digits = _stripCcSeparators(text);
|
|
888
|
+
if (digits.length === 16) {
|
|
889
|
+
const bin6 = digits.slice(0, 6);
|
|
890
|
+
const last4 = digits.slice(12, 16);
|
|
891
|
+
const middle6 = digits.slice(6, 12);
|
|
892
|
+
const engine = new FF1(await _getAesKey(), Buffer.from("CREDIT_CARD"), 10);
|
|
893
|
+
const encMiddle = engine.encrypt(middle6);
|
|
894
|
+
const base15 = bin6 + encMiddle + last4.slice(0, 3);
|
|
895
|
+
const checkDig = _computeLuhnDigit(base15);
|
|
896
|
+
const full = bin6 + encMiddle + last4.slice(0, 3) + checkDig;
|
|
897
|
+
return `${full.slice(0, 4)}-${full.slice(4, 8)}-${full.slice(8, 12)}-${full.slice(12, 16)}`;
|
|
898
|
+
} else {
|
|
899
|
+
const fallbackDigits = digits.padEnd(16, "0").slice(0, 16);
|
|
900
|
+
const engine = new FF1(await _getAesKey(), Buffer.from("CREDIT_CARD"), 10);
|
|
901
|
+
const encMiddle = engine.encrypt(fallbackDigits.slice(6, 12));
|
|
902
|
+
const full = fallbackDigits.slice(0, 6) + encMiddle + fallbackDigits.slice(12);
|
|
903
|
+
return `${full.slice(0, 4)}-${full.slice(4, 8)}-${full.slice(8, 12)}-${full.slice(12, 16)}`;
|
|
904
|
+
}
|
|
661
905
|
}
|
|
662
906
|
if (type === "US_ROUTING_NUMBER" || type === "US_ABA_ROUTING") {
|
|
663
|
-
|
|
907
|
+
if (text.length === 9 && /^\d+$/.test(text)) {
|
|
908
|
+
const engine = new FF1(await _getAesKey(), Buffer.from("US_ROUTING"), 10);
|
|
909
|
+
return engine.encrypt(text);
|
|
910
|
+
}
|
|
664
911
|
}
|
|
665
912
|
if (type === "INTL_BANK_IBAN" || type === "IBAN_CODE") {
|
|
666
913
|
const countryCode = text.length >= 2 && /[a-zA-Z]{2}/.test(text.slice(0, 2)) ? text.slice(0, 2).toUpperCase() : "US";
|
|
667
914
|
return `${countryCode}00${(await _hmacHex(text, 8)).toUpperCase()}`;
|
|
668
915
|
}
|
|
669
916
|
if (type === "ES_ID" || type === "ES_DNI") {
|
|
670
|
-
|
|
671
|
-
|
|
917
|
+
let digits = text.toUpperCase().replace(/[A-Z]/g, "");
|
|
918
|
+
if (digits) {
|
|
919
|
+
digits = digits.padStart(8, "0");
|
|
920
|
+
const engine = new FF1(await _getAesKey(), Buffer.from("ES_ID"), 10);
|
|
921
|
+
const enc = engine.encrypt(digits.slice(-5));
|
|
922
|
+
const tokenDigits = `000${enc}`;
|
|
923
|
+
return tokenDigits + _computeEsIdCheck(parseInt(tokenDigits, 10));
|
|
924
|
+
}
|
|
672
925
|
}
|
|
673
926
|
if (type === "PERSON" || type === "PERSON_NAME") {
|
|
674
927
|
if (config.MASK_BIJECTIVE_MODE) {
|
|
675
|
-
const
|
|
676
|
-
|
|
677
|
-
const inputInt = hash.readBigUInt64BE(0);
|
|
678
|
-
const masterKey = await _getMasterKey();
|
|
679
|
-
const engine = new FF1(masterKey.slice(0, 16), await _getBijectiveTweak());
|
|
680
|
-
const cipher = engine.encrypt(inputInt);
|
|
681
|
-
return _renderBijectivePerson(cipher);
|
|
928
|
+
const cipherBits = await _encryptBijectiveFF1(text);
|
|
929
|
+
return _renderBijectivePerson(cipherBits);
|
|
682
930
|
}
|
|
683
931
|
return `[TKN-PERSON-${await _hmacHex(text)}]`;
|
|
684
932
|
}
|
|
685
933
|
if (type === "LOCATION" || type === "PHYS_ADDRESS") {
|
|
686
934
|
if (config.MASK_BIJECTIVE_MODE) {
|
|
687
|
-
const
|
|
688
|
-
|
|
689
|
-
const inputInt = hash.readBigUInt64BE(0);
|
|
690
|
-
const masterKey = await _getMasterKey();
|
|
691
|
-
const engine = new FF1(masterKey.slice(0, 16), await _getBijectiveTweak());
|
|
692
|
-
const cipher = engine.encrypt(inputInt);
|
|
693
|
-
return _renderBijectiveLocation(cipher);
|
|
935
|
+
const cipherBits = await _encryptBijectiveFF1(text);
|
|
936
|
+
return _renderBijectiveLocation(cipherBits);
|
|
694
937
|
}
|
|
695
938
|
return `[TKN-LOC-${await _hmacHex(text)}]`;
|
|
696
939
|
}
|
|
@@ -699,12 +942,13 @@ async function generateFPEToken(rawText, entityType = "UNKNOWN") {
|
|
|
699
942
|
}
|
|
700
943
|
return `[TKN-${await _hmacHex(text)}]`;
|
|
701
944
|
}
|
|
702
|
-
var _masterKey, _EMAIL_RE, _PHONE_RE, _SSN_RE, _CC_RE, _ROUTING_RE, _ES_ID_RE, _IBAN_RE
|
|
945
|
+
var _masterKey, _EMAIL_RE, _PHONE_RE, _SSN_RE, _CC_RE, _ROUTING_RE, _ES_ID_RE, _IBAN_RE; exports.generateFPEToken = void 0;
|
|
703
946
|
var init_fpe = __esm({
|
|
704
947
|
"src/core/fpe.ts"() {
|
|
705
948
|
init_config();
|
|
706
949
|
init_key_provider();
|
|
707
950
|
init_exceptions();
|
|
951
|
+
init_ff1();
|
|
708
952
|
init_synthesisLibrary();
|
|
709
953
|
init_fpe_utils();
|
|
710
954
|
_masterKey = null;
|
|
@@ -715,49 +959,7 @@ var init_fpe = __esm({
|
|
|
715
959
|
_ROUTING_RE = /^\d{9}$/;
|
|
716
960
|
_ES_ID_RE = /^(?:\d{8}[A-Z]|[XYZ]\d{7}[A-Z])$/;
|
|
717
961
|
_IBAN_RE = /^[A-Z]{2}\d{2}[A-Z0-9]{4,30}$/;
|
|
718
|
-
|
|
719
|
-
/** NIST SP 800-38G FF1 implementation (simplified for 64-bit domains). */
|
|
720
|
-
constructor(key, tweak) {
|
|
721
|
-
this.key = key;
|
|
722
|
-
this.tweak = tweak;
|
|
723
|
-
}
|
|
724
|
-
encrypt(n6) {
|
|
725
|
-
let A3 = n6 >> 32n;
|
|
726
|
-
let B3 = n6 & 0xFFFFFFFFn;
|
|
727
|
-
const radix = 2n ** 32n;
|
|
728
|
-
for (let i6 = 0; i6 < 10; i6++) {
|
|
729
|
-
const tweakInfoBuffer = Buffer.alloc(8);
|
|
730
|
-
tweakInfoBuffer.writeUInt32BE(i6, 0);
|
|
731
|
-
tweakInfoBuffer.writeUInt32BE(Number(B3), 4);
|
|
732
|
-
const tweakInfoCombined = Buffer.concat([this.tweak, tweakInfoBuffer]);
|
|
733
|
-
const h6 = crypto2__namespace.createHmac("sha256", this.key).update(tweakInfoCombined).digest();
|
|
734
|
-
const roundVal = BigInt(h6.readUInt32BE(0));
|
|
735
|
-
const Anext = B3;
|
|
736
|
-
const Bnext = (A3 + roundVal) % radix;
|
|
737
|
-
A3 = Anext;
|
|
738
|
-
B3 = Bnext;
|
|
739
|
-
}
|
|
740
|
-
return A3 << 32n | B3;
|
|
741
|
-
}
|
|
742
|
-
decrypt(n6) {
|
|
743
|
-
let A3 = n6 >> 32n;
|
|
744
|
-
let B3 = n6 & 0xFFFFFFFFn;
|
|
745
|
-
const radix = 2n ** 32n;
|
|
746
|
-
for (let i6 = 9; i6 >= 0; i6--) {
|
|
747
|
-
const tweakInfoBuffer = Buffer.alloc(8);
|
|
748
|
-
tweakInfoBuffer.writeUInt32BE(i6, 0);
|
|
749
|
-
tweakInfoBuffer.writeUInt32BE(Number(A3), 4);
|
|
750
|
-
const tweakInfoCombined = Buffer.concat([this.tweak, tweakInfoBuffer]);
|
|
751
|
-
const h6 = crypto2__namespace.createHmac("sha256", this.key).update(tweakInfoCombined).digest();
|
|
752
|
-
const roundVal = BigInt(h6.readUInt32BE(0));
|
|
753
|
-
const Bprev = A3;
|
|
754
|
-
const Aprev = (B3 - roundVal + radix) % radix;
|
|
755
|
-
A3 = Aprev;
|
|
756
|
-
B3 = Bprev;
|
|
757
|
-
}
|
|
758
|
-
return A3 << 32n | B3;
|
|
759
|
-
}
|
|
760
|
-
};
|
|
962
|
+
exports.generateFPEToken = generateDPToken;
|
|
761
963
|
}
|
|
762
964
|
});
|
|
763
965
|
|
|
@@ -774,39 +976,39 @@ var require_core = __commonJS({
|
|
|
774
976
|
}
|
|
775
977
|
})(exports2, function() {
|
|
776
978
|
var CryptoJS = CryptoJS || (function(Math2, undefined2) {
|
|
777
|
-
var
|
|
979
|
+
var crypto7;
|
|
778
980
|
if (typeof window !== "undefined" && window.crypto) {
|
|
779
|
-
|
|
981
|
+
crypto7 = window.crypto;
|
|
780
982
|
}
|
|
781
983
|
if (typeof self !== "undefined" && self.crypto) {
|
|
782
|
-
|
|
984
|
+
crypto7 = self.crypto;
|
|
783
985
|
}
|
|
784
986
|
if (typeof globalThis !== "undefined" && globalThis.crypto) {
|
|
785
|
-
|
|
987
|
+
crypto7 = globalThis.crypto;
|
|
786
988
|
}
|
|
787
|
-
if (!
|
|
788
|
-
|
|
989
|
+
if (!crypto7 && typeof window !== "undefined" && window.msCrypto) {
|
|
990
|
+
crypto7 = window.msCrypto;
|
|
789
991
|
}
|
|
790
|
-
if (!
|
|
791
|
-
|
|
992
|
+
if (!crypto7 && typeof global !== "undefined" && global.crypto) {
|
|
993
|
+
crypto7 = global.crypto;
|
|
792
994
|
}
|
|
793
|
-
if (!
|
|
995
|
+
if (!crypto7 && typeof __require === "function") {
|
|
794
996
|
try {
|
|
795
|
-
|
|
997
|
+
crypto7 = __require("crypto");
|
|
796
998
|
} catch (err2) {
|
|
797
999
|
}
|
|
798
1000
|
}
|
|
799
1001
|
var cryptoSecureRandomInt = function() {
|
|
800
|
-
if (
|
|
801
|
-
if (typeof
|
|
1002
|
+
if (crypto7) {
|
|
1003
|
+
if (typeof crypto7.getRandomValues === "function") {
|
|
802
1004
|
try {
|
|
803
|
-
return
|
|
1005
|
+
return crypto7.getRandomValues(new Uint32Array(1))[0];
|
|
804
1006
|
} catch (err2) {
|
|
805
1007
|
}
|
|
806
1008
|
}
|
|
807
|
-
if (typeof
|
|
1009
|
+
if (typeof crypto7.randomBytes === "function") {
|
|
808
1010
|
try {
|
|
809
|
-
return
|
|
1011
|
+
return crypto7.randomBytes(4).readInt32LE();
|
|
810
1012
|
} catch (err2) {
|
|
811
1013
|
}
|
|
812
1014
|
}
|
|
@@ -3072,7 +3274,7 @@ var require_fernet = __commonJS({
|
|
|
3072
3274
|
var Base64 = require_enc_base64();
|
|
3073
3275
|
var HmacSHA256 = require_hmac_sha256();
|
|
3074
3276
|
var URLBase64 = require_urlsafe_base642();
|
|
3075
|
-
var
|
|
3277
|
+
var crypto7 = __require("crypto");
|
|
3076
3278
|
String.prototype.lpad = function(padString, length) {
|
|
3077
3279
|
var str = this;
|
|
3078
3280
|
while (str.length < length) str = padString + str;
|
|
@@ -3099,7 +3301,7 @@ var require_fernet = __commonJS({
|
|
|
3099
3301
|
return hex;
|
|
3100
3302
|
};
|
|
3101
3303
|
var randomHex = function(size) {
|
|
3102
|
-
return
|
|
3304
|
+
return crypto7.randomBytes(128 / 8).toString("hex");
|
|
3103
3305
|
};
|
|
3104
3306
|
var setIV = function setIV2(iv_array) {
|
|
3105
3307
|
if (iv_array) {
|
|
@@ -3182,24 +3384,28 @@ function getCryptoEngine() {
|
|
|
3182
3384
|
async function getCryptoEngineAsync() {
|
|
3183
3385
|
return await CryptoEngine.getInstanceAsync();
|
|
3184
3386
|
}
|
|
3185
|
-
var GCM_IV_BYTES, GCM_AUTH_TAG_BYTES, GCM_ALGORITHM, AES_GCM_PREFIX, _CryptoEngine, CryptoEngine;
|
|
3387
|
+
var AES_KEY_BYTES, GCM_IV_BYTES, GCM_AUTH_TAG_BYTES, GCM_ALGORITHM, AES_V2_PREFIX, AES_GCM_PREFIX, AES_GCM_LEGACY_PREFIX, _CryptoEngine, CryptoEngine;
|
|
3186
3388
|
var init_crypto = __esm({
|
|
3187
3389
|
"src/core/crypto.ts"() {
|
|
3188
3390
|
init_config();
|
|
3189
3391
|
init_key_provider();
|
|
3190
3392
|
init_exceptions();
|
|
3393
|
+
AES_KEY_BYTES = 32;
|
|
3191
3394
|
GCM_IV_BYTES = 12;
|
|
3192
3395
|
GCM_AUTH_TAG_BYTES = 16;
|
|
3193
3396
|
GCM_ALGORITHM = "aes-256-gcm";
|
|
3194
|
-
|
|
3397
|
+
AES_V2_PREFIX = "aes:v2:";
|
|
3398
|
+
AES_GCM_PREFIX = "aes:v1:";
|
|
3399
|
+
AES_GCM_LEGACY_PREFIX = "aes:";
|
|
3195
3400
|
_CryptoEngine = class _CryptoEngine {
|
|
3196
3401
|
constructor() {
|
|
3197
|
-
this.
|
|
3402
|
+
this._keyring = /* @__PURE__ */ new Map();
|
|
3403
|
+
this._activeKeyId = "default";
|
|
3198
3404
|
this._indexSecret = null;
|
|
3199
3405
|
}
|
|
3200
|
-
/**
|
|
3406
|
+
/**
|
|
3201
3407
|
* Return the singleton instance, initialising it if necessary.
|
|
3202
|
-
*
|
|
3408
|
+
* Async because Argon2id key derivation is async.
|
|
3203
3409
|
*/
|
|
3204
3410
|
static async getInstanceAsync() {
|
|
3205
3411
|
if (this._instance === null) {
|
|
@@ -3215,33 +3421,96 @@ var init_crypto = __esm({
|
|
|
3215
3421
|
}
|
|
3216
3422
|
return this._instance;
|
|
3217
3423
|
}
|
|
3218
|
-
/** Clear the singleton
|
|
3424
|
+
/** Clear the singleton (useful for key rotation / tests). */
|
|
3219
3425
|
static reset() {
|
|
3220
3426
|
this._instance = null;
|
|
3221
3427
|
}
|
|
3428
|
+
async _deriveAesKey(rawKey, keyId) {
|
|
3429
|
+
let argon2;
|
|
3430
|
+
try {
|
|
3431
|
+
argon2 = __require("argon2");
|
|
3432
|
+
} catch (e6) {
|
|
3433
|
+
throw new Error(
|
|
3434
|
+
"The 'argon2' package is required for Mask SDK cryptographic operations. Install with: npm install argon2"
|
|
3435
|
+
);
|
|
3436
|
+
}
|
|
3437
|
+
const kdfSaltStr = config.MASK_KDF_SALT + "-" + config.MASK_TENANT_ID + "-" + keyId;
|
|
3438
|
+
const kdfSaltBytes = cryptoNode__namespace.createHash("sha256").update(kdfSaltStr).digest().subarray(0, 16);
|
|
3439
|
+
return await argon2.hash(rawKey, {
|
|
3440
|
+
type: argon2.argon2id,
|
|
3441
|
+
memoryCost: 19456,
|
|
3442
|
+
timeCost: 2,
|
|
3443
|
+
parallelism: 1,
|
|
3444
|
+
hashLength: AES_KEY_BYTES,
|
|
3445
|
+
salt: kdfSaltBytes,
|
|
3446
|
+
raw: true
|
|
3447
|
+
});
|
|
3448
|
+
}
|
|
3222
3449
|
async _init() {
|
|
3450
|
+
let argon2;
|
|
3451
|
+
try {
|
|
3452
|
+
argon2 = __require("argon2");
|
|
3453
|
+
} catch (e6) {
|
|
3454
|
+
throw new Error("The 'argon2' package is required. Install with: npm install argon2");
|
|
3455
|
+
}
|
|
3223
3456
|
const provider = getKeyProvider();
|
|
3224
|
-
const
|
|
3225
|
-
let
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
);
|
|
3457
|
+
const rawKeys = /* @__PURE__ */ new Map();
|
|
3458
|
+
let activeKeyId = "default";
|
|
3459
|
+
const keyringJson = await provider.getKeyring();
|
|
3460
|
+
if (keyringJson) {
|
|
3461
|
+
let parsed;
|
|
3462
|
+
try {
|
|
3463
|
+
parsed = JSON.parse(keyringJson);
|
|
3464
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
3465
|
+
throw new Error("MASK_KEYRING must be a non-empty JSON object.");
|
|
3466
|
+
}
|
|
3467
|
+
} catch (e6) {
|
|
3468
|
+
throw new Error(`Invalid MASK_KEYRING format: ${e6}`);
|
|
3237
3469
|
}
|
|
3470
|
+
const entries = Object.entries(parsed);
|
|
3471
|
+
if (entries.length === 0) throw new Error("MASK_KEYRING must contain at least one key.");
|
|
3472
|
+
for (const [kid, k6] of entries) rawKeys.set(kid, k6);
|
|
3473
|
+
activeKeyId = entries[entries.length - 1][0];
|
|
3238
3474
|
} else {
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3475
|
+
const keyFromProvider = await provider.getEncryptionKey();
|
|
3476
|
+
let key;
|
|
3477
|
+
if (!keyFromProvider) {
|
|
3478
|
+
if (config.MASK_DEV_MODE) {
|
|
3479
|
+
key = cryptoNode__namespace.randomBytes(32).toString("base64");
|
|
3480
|
+
process.env.MASK_ENCRYPTION_KEY = key;
|
|
3481
|
+
console.warn(
|
|
3482
|
+
"MASK_DEV_MODE is enabled. Using a generated throwaway key. DO NOT USE THIS IN PRODUCTION \u2014 tokens will be lost on restart."
|
|
3483
|
+
);
|
|
3484
|
+
} else {
|
|
3485
|
+
throw new Error(
|
|
3486
|
+
"MASK_ENCRYPTION_KEY or MASK_KEYRING is not set. Set one of these, or set MASK_DEV_MODE=true for ephemeral use."
|
|
3487
|
+
);
|
|
3488
|
+
}
|
|
3489
|
+
} else {
|
|
3490
|
+
key = keyFromProvider;
|
|
3491
|
+
}
|
|
3492
|
+
rawKeys.set("default", key);
|
|
3493
|
+
activeKeyId = "default";
|
|
3494
|
+
}
|
|
3495
|
+
this._keyring = /* @__PURE__ */ new Map();
|
|
3496
|
+
for (const [kid, rawKey] of rawKeys) {
|
|
3497
|
+
this._keyring.set(kid, await this._deriveAesKey(rawKey, kid));
|
|
3498
|
+
}
|
|
3499
|
+
this._activeKeyId = activeKeyId;
|
|
3500
|
+
const rawKeysArr = Array.from(rawKeys.values());
|
|
3501
|
+
const lastRawKey = rawKeysArr[rawKeysArr.length - 1];
|
|
3502
|
+
const masterKey = await provider.getMasterKey() || lastRawKey;
|
|
3503
|
+
const indexSaltStr = config.MASK_BLIND_INDEX_SALT + "-" + config.MASK_TENANT_ID;
|
|
3504
|
+
const indexSaltBytes = cryptoNode__namespace.createHash("sha256").update(indexSaltStr).digest().subarray(0, 16);
|
|
3505
|
+
this._indexSecret = await argon2.hash(masterKey, {
|
|
3506
|
+
type: argon2.argon2id,
|
|
3507
|
+
memoryCost: 19456,
|
|
3508
|
+
timeCost: 2,
|
|
3509
|
+
parallelism: 1,
|
|
3510
|
+
hashLength: AES_KEY_BYTES,
|
|
3511
|
+
salt: indexSaltBytes,
|
|
3512
|
+
raw: true
|
|
3513
|
+
});
|
|
3245
3514
|
}
|
|
3246
3515
|
/** Return the secret used for HMAC-based blind indexing. */
|
|
3247
3516
|
async getIndexSecret() {
|
|
@@ -3250,36 +3519,56 @@ var init_crypto = __esm({
|
|
|
3250
3519
|
}
|
|
3251
3520
|
return this._indexSecret;
|
|
3252
3521
|
}
|
|
3522
|
+
/** Encrypt plaintext using the active keyring key.
|
|
3523
|
+
* Envelope format: aes:v2:{keyId}:{base64(iv+authTag+ciphertext)}
|
|
3524
|
+
*/
|
|
3253
3525
|
encrypt(plaintext) {
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
const
|
|
3259
|
-
const
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
]);
|
|
3526
|
+
const aesKey = this._keyring.get(this._activeKeyId);
|
|
3527
|
+
if (!aesKey) {
|
|
3528
|
+
throw new Error(`CryptoEngine: active key ID '${this._activeKeyId}' not found in keyring.`);
|
|
3529
|
+
}
|
|
3530
|
+
const iv = cryptoNode__namespace.randomBytes(GCM_IV_BYTES);
|
|
3531
|
+
const cipher = cryptoNode__namespace.createCipheriv(GCM_ALGORITHM, aesKey, iv);
|
|
3532
|
+
const plaintextBuf = Buffer.from(plaintext, "utf8");
|
|
3533
|
+
const encrypted = Buffer.concat([cipher.update(plaintextBuf), cipher.final()]);
|
|
3263
3534
|
const authTag = cipher.getAuthTag();
|
|
3535
|
+
plaintextBuf.fill(0);
|
|
3264
3536
|
const combined = Buffer.concat([iv, authTag, encrypted]);
|
|
3265
|
-
return
|
|
3537
|
+
return `${AES_V2_PREFIX}${this._activeKeyId}:${combined.toString("base64")}`;
|
|
3266
3538
|
}
|
|
3539
|
+
/** Decrypt ciphertext. Supports all historical envelope formats. */
|
|
3267
3540
|
decrypt(ciphertext) {
|
|
3268
|
-
if (
|
|
3269
|
-
throw new Error("CryptoEngine not initialised.
|
|
3541
|
+
if (this._keyring.size === 0) {
|
|
3542
|
+
throw new Error("CryptoEngine not initialised.");
|
|
3270
3543
|
}
|
|
3271
3544
|
try {
|
|
3545
|
+
if (ciphertext.startsWith(AES_V2_PREFIX)) {
|
|
3546
|
+
const rest = ciphertext.slice(AES_V2_PREFIX.length);
|
|
3547
|
+
const sep3 = rest.indexOf(":");
|
|
3548
|
+
if (sep3 === -1) throw new Error("Malformed aes:v2 envelope: missing key ID separator.");
|
|
3549
|
+
const keyId = rest.slice(0, sep3);
|
|
3550
|
+
const b64 = rest.slice(sep3 + 1);
|
|
3551
|
+
return this._decryptAesGcm(keyId, b64);
|
|
3552
|
+
}
|
|
3272
3553
|
if (ciphertext.startsWith(AES_GCM_PREFIX)) {
|
|
3273
|
-
return this._decryptAesGcm(ciphertext.slice(AES_GCM_PREFIX.length));
|
|
3554
|
+
return this._decryptAesGcm("default", ciphertext.slice(AES_GCM_PREFIX.length));
|
|
3555
|
+
}
|
|
3556
|
+
if (ciphertext.startsWith(AES_GCM_LEGACY_PREFIX)) {
|
|
3557
|
+
return this._decryptAesGcm("default", ciphertext.slice(AES_GCM_LEGACY_PREFIX.length));
|
|
3274
3558
|
}
|
|
3275
3559
|
return this._decryptLegacyFernet(ciphertext);
|
|
3276
3560
|
} catch (e6) {
|
|
3277
|
-
console.error("Failed to decrypt vault payload. Check your MASK_ENCRYPTION_KEY. Inner error:", e6);
|
|
3561
|
+
console.error("Failed to decrypt vault payload. Check your MASK_ENCRYPTION_KEY / MASK_KEYRING. Inner error:", e6);
|
|
3278
3562
|
throw new exports.MaskDecryptionError("Decryption failed");
|
|
3279
3563
|
}
|
|
3280
3564
|
}
|
|
3281
|
-
|
|
3282
|
-
|
|
3565
|
+
_decryptAesGcm(keyId, b64) {
|
|
3566
|
+
const aesKey = this._keyring.get(keyId);
|
|
3567
|
+
if (!aesKey) {
|
|
3568
|
+
throw new exports.MaskDecryptionError(
|
|
3569
|
+
`No key found for key ID '${keyId}'. Ensure the key is present in MASK_KEYRING.`
|
|
3570
|
+
);
|
|
3571
|
+
}
|
|
3283
3572
|
const combined = Buffer.from(b64, "base64");
|
|
3284
3573
|
if (combined.length < GCM_IV_BYTES + GCM_AUTH_TAG_BYTES) {
|
|
3285
3574
|
throw new Error("Ciphertext too short for AES-GCM");
|
|
@@ -3287,22 +3576,11 @@ var init_crypto = __esm({
|
|
|
3287
3576
|
const iv = combined.subarray(0, GCM_IV_BYTES);
|
|
3288
3577
|
const authTag = combined.subarray(GCM_IV_BYTES, GCM_IV_BYTES + GCM_AUTH_TAG_BYTES);
|
|
3289
3578
|
const encrypted = combined.subarray(GCM_IV_BYTES + GCM_AUTH_TAG_BYTES);
|
|
3290
|
-
const decipher =
|
|
3579
|
+
const decipher = cryptoNode__namespace.createDecipheriv(GCM_ALGORITHM, aesKey, iv);
|
|
3291
3580
|
decipher.setAuthTag(authTag);
|
|
3292
|
-
const decrypted = Buffer.concat([
|
|
3293
|
-
decipher.update(encrypted),
|
|
3294
|
-
decipher.final()
|
|
3295
|
-
]);
|
|
3581
|
+
const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
|
|
3296
3582
|
return decrypted.toString("utf8");
|
|
3297
3583
|
}
|
|
3298
|
-
/**
|
|
3299
|
-
* Attempt to decrypt a legacy Fernet-format token.
|
|
3300
|
-
*
|
|
3301
|
-
* Fernet format: Version (1) || Timestamp (8) || IV (16) || Ciphertext (var) || HMAC (32)
|
|
3302
|
-
* All base64url-encoded.
|
|
3303
|
-
*
|
|
3304
|
-
* We try to use the `fernet` npm package if available, otherwise throw.
|
|
3305
|
-
*/
|
|
3306
3584
|
_decryptLegacyFernet(ciphertext) {
|
|
3307
3585
|
let fernet;
|
|
3308
3586
|
try {
|
|
@@ -3330,8 +3608,6 @@ var init_crypto = __esm({
|
|
|
3330
3608
|
CryptoEngine = _CryptoEngine;
|
|
3331
3609
|
}
|
|
3332
3610
|
});
|
|
3333
|
-
|
|
3334
|
-
// src/telemetry/audit_logger.ts
|
|
3335
3611
|
function _getLogLevel() {
|
|
3336
3612
|
const env3 = config.MASK_LOG_LEVEL;
|
|
3337
3613
|
return env3 in LOG_LEVELS ? env3 : "info";
|
|
@@ -3365,16 +3641,15 @@ function getLogger(name) {
|
|
|
3365
3641
|
error: (...args) => _log("error", ...args)
|
|
3366
3642
|
};
|
|
3367
3643
|
}
|
|
3368
|
-
function _makeEvent(action, token, dataType, agent = "", tool = "", extra = null) {
|
|
3644
|
+
function _makeEvent(action, token, dataType, agent = "", tool = "", extra = null, instanceId = "") {
|
|
3369
3645
|
const event = {
|
|
3370
3646
|
ts: Date.now() / 1e3,
|
|
3371
3647
|
action,
|
|
3372
|
-
// "encode" | "decode" | "expired" | "error"
|
|
3373
3648
|
token,
|
|
3374
3649
|
data_type: dataType,
|
|
3375
|
-
// "email" | "phone" | "ssn" | "opaque"
|
|
3376
3650
|
agent,
|
|
3377
|
-
tool
|
|
3651
|
+
tool,
|
|
3652
|
+
instance_id: instanceId
|
|
3378
3653
|
};
|
|
3379
3654
|
if (extra) {
|
|
3380
3655
|
Object.assign(event, _deepMask(extra));
|
|
@@ -3384,7 +3659,7 @@ function _makeEvent(action, token, dataType, agent = "", tool = "", extra = null
|
|
|
3384
3659
|
function _deepMask(obj) {
|
|
3385
3660
|
if (obj === null || obj === void 0) return obj;
|
|
3386
3661
|
if (typeof obj === "string") {
|
|
3387
|
-
return
|
|
3662
|
+
return isUnambiguouslySafeToken(obj) ? obj : "[REDACTED]";
|
|
3388
3663
|
}
|
|
3389
3664
|
if (typeof obj !== "object") return obj;
|
|
3390
3665
|
if (Array.isArray(obj)) {
|
|
@@ -3418,6 +3693,10 @@ var init_audit_logger = __esm({
|
|
|
3418
3693
|
this._shutdownRegistered = false;
|
|
3419
3694
|
this._maxBufferSize = config.MASK_AUDIT_MAX_BUFFER_SIZE;
|
|
3420
3695
|
this._strictMode = config.MASK_AUDIT_LOG_STRICT;
|
|
3696
|
+
const rawKey = process.env.MASK_MASTER_KEY || process.env.MASK_ENCRYPTION_KEY || "";
|
|
3697
|
+
this._signingKey = cryptoNode__namespace.createHash("sha256").update(rawKey).digest();
|
|
3698
|
+
this._instanceId = cryptoNode__namespace.randomUUID();
|
|
3699
|
+
this._prevSig = cryptoNode__namespace.createHmac("sha256", this._signingKey).update(this._instanceId, "utf-8").digest("hex");
|
|
3421
3700
|
}
|
|
3422
3701
|
static getInstance() {
|
|
3423
3702
|
if (this._instance === null) {
|
|
@@ -3425,16 +3704,46 @@ var init_audit_logger = __esm({
|
|
|
3425
3704
|
}
|
|
3426
3705
|
return this._instance;
|
|
3427
3706
|
}
|
|
3707
|
+
_getOverflowPath() {
|
|
3708
|
+
const d6 = process.env.MASK_SECURE_AUDIT_LOG_DIR || __require("os").tmpdir();
|
|
3709
|
+
return path2__namespace.join(d6, `mask_audit_overflow_${this._instanceId}.ndjson`);
|
|
3710
|
+
}
|
|
3711
|
+
_writeOverflow(event) {
|
|
3712
|
+
try {
|
|
3713
|
+
fs__namespace.appendFileSync(this._getOverflowPath(), JSON.stringify(event) + "\n", "utf-8");
|
|
3714
|
+
} catch {
|
|
3715
|
+
}
|
|
3716
|
+
}
|
|
3717
|
+
_consumeOverflow(events) {
|
|
3718
|
+
const overflowPath = this._getOverflowPath();
|
|
3719
|
+
if (!fs__namespace.existsSync(overflowPath)) return;
|
|
3720
|
+
const processingPath = overflowPath + ".processing";
|
|
3721
|
+
try {
|
|
3722
|
+
fs__namespace.renameSync(overflowPath, processingPath);
|
|
3723
|
+
} catch {
|
|
3724
|
+
return;
|
|
3725
|
+
}
|
|
3726
|
+
try {
|
|
3727
|
+
const content = fs__namespace.readFileSync(processingPath, "utf-8");
|
|
3728
|
+
for (const line of content.split("\n")) {
|
|
3729
|
+
if (line.trim()) events.push(JSON.parse(line));
|
|
3730
|
+
}
|
|
3731
|
+
fs__namespace.unlinkSync(processingPath);
|
|
3732
|
+
} catch (e6) {
|
|
3733
|
+
_logger.error(`Failed to consume overflow: ${e6}`);
|
|
3734
|
+
}
|
|
3735
|
+
}
|
|
3428
3736
|
log(action, token, dataType = "opaque", agent = "", tool = "", extra = {}) {
|
|
3429
|
-
const event = _makeEvent(action, token, dataType, agent, tool, extra);
|
|
3737
|
+
const event = _makeEvent(action, token, dataType, agent, tool, extra, this._instanceId);
|
|
3430
3738
|
if (this._buffer.length >= this._maxBufferSize) {
|
|
3431
3739
|
if (!this._bufferFullWarned) {
|
|
3432
3740
|
_logger.warn(
|
|
3433
|
-
`AuditLogger buffer full (max=${this._maxBufferSize}).
|
|
3741
|
+
`AuditLogger buffer full (max=${this._maxBufferSize}). Spooling to disk overflow to prevent OOM.`
|
|
3434
3742
|
);
|
|
3435
3743
|
this._bufferFullWarned = true;
|
|
3436
3744
|
}
|
|
3437
|
-
this.
|
|
3745
|
+
this._writeOverflow(event);
|
|
3746
|
+
return;
|
|
3438
3747
|
}
|
|
3439
3748
|
this._buffer.push(event);
|
|
3440
3749
|
}
|
|
@@ -3464,27 +3773,84 @@ var init_audit_logger = __esm({
|
|
|
3464
3773
|
await this._flush();
|
|
3465
3774
|
}
|
|
3466
3775
|
async _flush() {
|
|
3467
|
-
if (this._isFlushing
|
|
3776
|
+
if (this._isFlushing) return;
|
|
3468
3777
|
this._isFlushing = true;
|
|
3469
3778
|
try {
|
|
3470
3779
|
const events = [...this._buffer];
|
|
3471
3780
|
this._buffer = [];
|
|
3472
3781
|
this._bufferFullWarned = false;
|
|
3782
|
+
this._consumeOverflow(events);
|
|
3783
|
+
if (events.length === 0) return;
|
|
3784
|
+
const secureLogDir = process.env.MASK_SECURE_AUDIT_LOG_DIR || "";
|
|
3785
|
+
let secureStream = null;
|
|
3786
|
+
if (secureLogDir) {
|
|
3787
|
+
fs__namespace.mkdirSync(secureLogDir, { recursive: true });
|
|
3788
|
+
const dateStr = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
3789
|
+
const filePath = path2__namespace.join(secureLogDir, `mask-audit-${dateStr}.ndjson`);
|
|
3790
|
+
try {
|
|
3791
|
+
secureStream = fs__namespace.createWriteStream(filePath, { flags: "a" });
|
|
3792
|
+
} catch {
|
|
3793
|
+
}
|
|
3794
|
+
}
|
|
3473
3795
|
for (const evt of events) {
|
|
3474
|
-
const
|
|
3475
|
-
|
|
3796
|
+
const body = JSON.stringify(evt, (_, v7) => typeof v7 === "bigint" ? v7.toString() : v7);
|
|
3797
|
+
const sigInput = Buffer.from(this._prevSig + body, "utf-8");
|
|
3798
|
+
const sig = cryptoNode__namespace.createHmac("sha256", this._signingKey).update(sigInput).digest("hex");
|
|
3799
|
+
const signedLine = JSON.stringify({
|
|
3800
|
+
...evt,
|
|
3801
|
+
prev_sig: this._prevSig,
|
|
3802
|
+
sig
|
|
3803
|
+
}, (_, v7) => typeof v7 === "bigint" ? v7.toString() : v7);
|
|
3804
|
+
this._prevSig = sig;
|
|
3805
|
+
console.info(signedLine);
|
|
3806
|
+
if (secureStream) {
|
|
3807
|
+
secureStream.write(signedLine + "\n");
|
|
3808
|
+
}
|
|
3809
|
+
}
|
|
3810
|
+
if (secureStream) {
|
|
3811
|
+
secureStream.end();
|
|
3476
3812
|
}
|
|
3477
3813
|
} finally {
|
|
3478
3814
|
this._isFlushing = false;
|
|
3479
3815
|
}
|
|
3480
3816
|
}
|
|
3481
|
-
/** Synchronous flush for use in signal handlers where async is unreliable.
|
|
3817
|
+
/** Synchronous flush for use in signal handlers where async is unreliable.
|
|
3818
|
+
*
|
|
3819
|
+
* Computes HMAC signatures to maintain chain integrity and writes to the
|
|
3820
|
+
* secure ndjson audit file (MASK_SECURE_AUDIT_LOG_DIR) if configured,
|
|
3821
|
+
* ensuring SOC 2 tamper-evidence guarantees hold through process shutdown.
|
|
3822
|
+
*/
|
|
3482
3823
|
_flushSync() {
|
|
3483
3824
|
if (this._buffer.length === 0) return;
|
|
3484
3825
|
const events = [...this._buffer];
|
|
3485
3826
|
this._buffer = [];
|
|
3827
|
+
const secureLogDir = process.env.MASK_SECURE_AUDIT_LOG_DIR || "";
|
|
3828
|
+
let secureFilePath = null;
|
|
3829
|
+
if (secureLogDir) {
|
|
3830
|
+
try {
|
|
3831
|
+
fs__namespace.mkdirSync(secureLogDir, { recursive: true });
|
|
3832
|
+
const dateStr = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
3833
|
+
secureFilePath = path2__namespace.join(secureLogDir, `mask-audit-${dateStr}.ndjson`);
|
|
3834
|
+
} catch {
|
|
3835
|
+
}
|
|
3836
|
+
}
|
|
3486
3837
|
for (const evt of events) {
|
|
3487
|
-
|
|
3838
|
+
const body = JSON.stringify(evt, (_, v7) => typeof v7 === "bigint" ? v7.toString() : v7);
|
|
3839
|
+
const sigInput = Buffer.from(this._prevSig + body, "utf-8");
|
|
3840
|
+
const sig = cryptoNode__namespace.createHmac("sha256", this._signingKey).update(sigInput).digest("hex");
|
|
3841
|
+
const signedLine = JSON.stringify({
|
|
3842
|
+
...evt,
|
|
3843
|
+
prev_sig: this._prevSig,
|
|
3844
|
+
sig
|
|
3845
|
+
}, (_, v7) => typeof v7 === "bigint" ? v7.toString() : v7);
|
|
3846
|
+
this._prevSig = sig;
|
|
3847
|
+
process.stdout.write(signedLine + "\n");
|
|
3848
|
+
if (secureFilePath) {
|
|
3849
|
+
try {
|
|
3850
|
+
fs__namespace.appendFileSync(secureFilePath, signedLine + "\n", { encoding: "utf-8" });
|
|
3851
|
+
} catch {
|
|
3852
|
+
}
|
|
3853
|
+
}
|
|
3488
3854
|
}
|
|
3489
3855
|
}
|
|
3490
3856
|
};
|
|
@@ -3536,7 +3902,7 @@ var init_search = __esm({
|
|
|
3536
3902
|
static async getBucketIndex(bucketVal) {
|
|
3537
3903
|
const engine = await getCryptoEngine();
|
|
3538
3904
|
const secret = await engine.getIndexSecret();
|
|
3539
|
-
return
|
|
3905
|
+
return cryptoNode__namespace.createHmac("sha256", secret).update(bucketVal).digest("hex");
|
|
3540
3906
|
}
|
|
3541
3907
|
};
|
|
3542
3908
|
}
|
|
@@ -15682,9 +16048,9 @@ var init_createPaginator = __esm({
|
|
|
15682
16048
|
command = withCommand(command) ?? command;
|
|
15683
16049
|
return await client.send(command, ...args);
|
|
15684
16050
|
};
|
|
15685
|
-
get = (fromObject,
|
|
16051
|
+
get = (fromObject, path4) => {
|
|
15686
16052
|
let cursor = fromObject;
|
|
15687
|
-
const pathComponents =
|
|
16053
|
+
const pathComponents = path4.split(".");
|
|
15688
16054
|
for (const step of pathComponents) {
|
|
15689
16055
|
if (!cursor || typeof cursor !== "object") {
|
|
15690
16056
|
return void 0;
|
|
@@ -16295,12 +16661,12 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
16295
16661
|
const password = request2.password ?? "";
|
|
16296
16662
|
auth = `${username}:${password}`;
|
|
16297
16663
|
}
|
|
16298
|
-
let
|
|
16664
|
+
let path4 = request2.path;
|
|
16299
16665
|
if (queryString) {
|
|
16300
|
-
|
|
16666
|
+
path4 += `?${queryString}`;
|
|
16301
16667
|
}
|
|
16302
16668
|
if (request2.fragment) {
|
|
16303
|
-
|
|
16669
|
+
path4 += `#${request2.fragment}`;
|
|
16304
16670
|
}
|
|
16305
16671
|
let hostname = request2.hostname ?? "";
|
|
16306
16672
|
if (hostname[0] === "[" && hostname.endsWith("]")) {
|
|
@@ -16312,7 +16678,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
16312
16678
|
headers: request2.headers,
|
|
16313
16679
|
host: hostname,
|
|
16314
16680
|
method: request2.method,
|
|
16315
|
-
path:
|
|
16681
|
+
path: path4,
|
|
16316
16682
|
port: request2.port,
|
|
16317
16683
|
agent,
|
|
16318
16684
|
auth
|
|
@@ -16619,16 +16985,16 @@ var init_node_http2_handler = __esm({
|
|
|
16619
16985
|
reject(err2);
|
|
16620
16986
|
};
|
|
16621
16987
|
const queryString = buildQueryString(query || {});
|
|
16622
|
-
let
|
|
16988
|
+
let path4 = request2.path;
|
|
16623
16989
|
if (queryString) {
|
|
16624
|
-
|
|
16990
|
+
path4 += `?${queryString}`;
|
|
16625
16991
|
}
|
|
16626
16992
|
if (request2.fragment) {
|
|
16627
|
-
|
|
16993
|
+
path4 += `#${request2.fragment}`;
|
|
16628
16994
|
}
|
|
16629
16995
|
const req = session.request({
|
|
16630
16996
|
...request2.headers,
|
|
16631
|
-
[http2.constants.HTTP2_HEADER_PATH]:
|
|
16997
|
+
[http2.constants.HTTP2_HEADER_PATH]: path4,
|
|
16632
16998
|
[http2.constants.HTTP2_HEADER_METHOD]: method
|
|
16633
16999
|
});
|
|
16634
17000
|
session.ref();
|
|
@@ -18077,10 +18443,10 @@ var init_date_utils = __esm({
|
|
|
18077
18443
|
};
|
|
18078
18444
|
}
|
|
18079
18445
|
});
|
|
18080
|
-
var
|
|
18446
|
+
var randomUUID2;
|
|
18081
18447
|
var init_randomUUID = __esm({
|
|
18082
18448
|
"node_modules/@smithy/uuid/dist-es/randomUUID.js"() {
|
|
18083
|
-
|
|
18449
|
+
randomUUID2 = cryptoNode__namespace.default.randomUUID.bind(cryptoNode__namespace.default);
|
|
18084
18450
|
}
|
|
18085
18451
|
});
|
|
18086
18452
|
|
|
@@ -18091,8 +18457,8 @@ var init_v4 = __esm({
|
|
|
18091
18457
|
init_randomUUID();
|
|
18092
18458
|
decimalToHex = Array.from({ length: 256 }, (_, i6) => i6.toString(16).padStart(2, "0"));
|
|
18093
18459
|
v4 = () => {
|
|
18094
|
-
if (
|
|
18095
|
-
return
|
|
18460
|
+
if (randomUUID2) {
|
|
18461
|
+
return randomUUID2();
|
|
18096
18462
|
}
|
|
18097
18463
|
const rnds = new Uint8Array(16);
|
|
18098
18464
|
crypto.getRandomValues(rnds);
|
|
@@ -18830,11 +19196,11 @@ var init_HttpBindingProtocol = __esm({
|
|
|
18830
19196
|
const opTraits = translateTraits(operationSchema.traits);
|
|
18831
19197
|
if (opTraits.http) {
|
|
18832
19198
|
request2.method = opTraits.http[0];
|
|
18833
|
-
const [
|
|
19199
|
+
const [path4, search] = opTraits.http[1].split("?");
|
|
18834
19200
|
if (request2.path == "/") {
|
|
18835
|
-
request2.path =
|
|
19201
|
+
request2.path = path4;
|
|
18836
19202
|
} else {
|
|
18837
|
-
request2.path +=
|
|
19203
|
+
request2.path += path4;
|
|
18838
19204
|
}
|
|
18839
19205
|
const traitSearchParams = new URLSearchParams(search ?? "");
|
|
18840
19206
|
Object.assign(query, Object.fromEntries(traitSearchParams));
|
|
@@ -19867,18 +20233,18 @@ var getAttrPathList;
|
|
|
19867
20233
|
var init_getAttrPathList = __esm({
|
|
19868
20234
|
"node_modules/@smithy/util-endpoints/dist-es/lib/getAttrPathList.js"() {
|
|
19869
20235
|
init_types2();
|
|
19870
|
-
getAttrPathList = (
|
|
19871
|
-
const parts =
|
|
20236
|
+
getAttrPathList = (path4) => {
|
|
20237
|
+
const parts = path4.split(".");
|
|
19872
20238
|
const pathList = [];
|
|
19873
20239
|
for (const part of parts) {
|
|
19874
20240
|
const squareBracketIndex = part.indexOf("[");
|
|
19875
20241
|
if (squareBracketIndex !== -1) {
|
|
19876
20242
|
if (part.indexOf("]") !== part.length - 1) {
|
|
19877
|
-
throw new EndpointError(`Path: '${
|
|
20243
|
+
throw new EndpointError(`Path: '${path4}' does not end with ']'`);
|
|
19878
20244
|
}
|
|
19879
20245
|
const arrayIndex = part.slice(squareBracketIndex + 1, -1);
|
|
19880
20246
|
if (Number.isNaN(parseInt(arrayIndex))) {
|
|
19881
|
-
throw new EndpointError(`Invalid array index: '${arrayIndex}' in path: '${
|
|
20247
|
+
throw new EndpointError(`Invalid array index: '${arrayIndex}' in path: '${path4}'`);
|
|
19882
20248
|
}
|
|
19883
20249
|
if (squareBracketIndex !== 0) {
|
|
19884
20250
|
pathList.push(part.slice(0, squareBracketIndex));
|
|
@@ -19899,9 +20265,9 @@ var init_getAttr = __esm({
|
|
|
19899
20265
|
"node_modules/@smithy/util-endpoints/dist-es/lib/getAttr.js"() {
|
|
19900
20266
|
init_types2();
|
|
19901
20267
|
init_getAttrPathList();
|
|
19902
|
-
getAttr = (value,
|
|
20268
|
+
getAttr = (value, path4) => getAttrPathList(path4).reduce((acc, index) => {
|
|
19903
20269
|
if (typeof acc !== "object") {
|
|
19904
|
-
throw new EndpointError(`Index '${index}' in '${
|
|
20270
|
+
throw new EndpointError(`Index '${index}' in '${path4}' not found in '${JSON.stringify(value)}'`);
|
|
19905
20271
|
} else if (Array.isArray(acc)) {
|
|
19906
20272
|
return acc[parseInt(index)];
|
|
19907
20273
|
}
|
|
@@ -19943,8 +20309,8 @@ var init_parseURL = __esm({
|
|
|
19943
20309
|
return value;
|
|
19944
20310
|
}
|
|
19945
20311
|
if (typeof value === "object" && "hostname" in value) {
|
|
19946
|
-
const { hostname: hostname2, port, protocol: protocol2 = "", path:
|
|
19947
|
-
const url = new URL(`${protocol2}//${hostname2}${port ? `:${port}` : ""}${
|
|
20312
|
+
const { hostname: hostname2, port, protocol: protocol2 = "", path: path4 = "", query = {} } = value;
|
|
20313
|
+
const url = new URL(`${protocol2}//${hostname2}${port ? `:${port}` : ""}${path4}`);
|
|
19948
20314
|
url.search = Object.entries(query).map(([k6, v7]) => `${k6}=${v7}`).join("&");
|
|
19949
20315
|
return url;
|
|
19950
20316
|
}
|
|
@@ -21699,10 +22065,10 @@ ${longDate}
|
|
|
21699
22065
|
${credentialScope}
|
|
21700
22066
|
${toHex(hashedRequest)}`;
|
|
21701
22067
|
}
|
|
21702
|
-
getCanonicalPath({ path:
|
|
22068
|
+
getCanonicalPath({ path: path4 }) {
|
|
21703
22069
|
if (this.uriEscapePath) {
|
|
21704
22070
|
const normalizedPathSegments = [];
|
|
21705
|
-
for (const pathSegment of
|
|
22071
|
+
for (const pathSegment of path4.split("/")) {
|
|
21706
22072
|
if (pathSegment?.length === 0)
|
|
21707
22073
|
continue;
|
|
21708
22074
|
if (pathSegment === ".")
|
|
@@ -21713,11 +22079,11 @@ ${toHex(hashedRequest)}`;
|
|
|
21713
22079
|
normalizedPathSegments.push(pathSegment);
|
|
21714
22080
|
}
|
|
21715
22081
|
}
|
|
21716
|
-
const normalizedPath = `${
|
|
22082
|
+
const normalizedPath = `${path4?.startsWith("/") ? "/" : ""}${normalizedPathSegments.join("/")}${normalizedPathSegments.length > 0 && path4?.endsWith("/") ? "/" : ""}`;
|
|
21717
22083
|
const doubleEncoded = escapeUri(normalizedPath);
|
|
21718
22084
|
return doubleEncoded.replace(/%2F/g, "/");
|
|
21719
22085
|
}
|
|
21720
|
-
return
|
|
22086
|
+
return path4;
|
|
21721
22087
|
}
|
|
21722
22088
|
validateResolvedCredentials(credentials) {
|
|
21723
22089
|
if (typeof credentials !== "object" || typeof credentials.accessKeyId !== "string" || typeof credentials.secretAccessKey !== "string") {
|
|
@@ -27712,8 +28078,8 @@ var init_createConfigValueProvider = __esm({
|
|
|
27712
28078
|
return endpoint.url.href;
|
|
27713
28079
|
}
|
|
27714
28080
|
if ("hostname" in endpoint) {
|
|
27715
|
-
const { protocol, hostname, port, path:
|
|
27716
|
-
return `${protocol}//${hostname}${port ? ":" + port : ""}${
|
|
28081
|
+
const { protocol, hostname, port, path: path4 } = endpoint;
|
|
28082
|
+
return `${protocol}//${hostname}${port ? ":" + port : ""}${path4}`;
|
|
27717
28083
|
}
|
|
27718
28084
|
}
|
|
27719
28085
|
return endpoint;
|
|
@@ -27771,7 +28137,7 @@ var init_getHomeDir = __esm({
|
|
|
27771
28137
|
return "DEFAULT";
|
|
27772
28138
|
};
|
|
27773
28139
|
getHomeDir = () => {
|
|
27774
|
-
const { HOME, USERPROFILE, HOMEPATH, HOMEDRIVE = `C:${
|
|
28140
|
+
const { HOME, USERPROFILE, HOMEPATH, HOMEDRIVE = `C:${path2.sep}` } = process.env;
|
|
27775
28141
|
if (HOME)
|
|
27776
28142
|
return HOME;
|
|
27777
28143
|
if (USERPROFILE)
|
|
@@ -27800,9 +28166,9 @@ var init_getSSOTokenFilepath = __esm({
|
|
|
27800
28166
|
"node_modules/@smithy/shared-ini-file-loader/dist-es/getSSOTokenFilepath.js"() {
|
|
27801
28167
|
init_getHomeDir();
|
|
27802
28168
|
getSSOTokenFilepath = (id) => {
|
|
27803
|
-
const hasher =
|
|
28169
|
+
const hasher = cryptoNode.createHash("sha1");
|
|
27804
28170
|
const cacheName = hasher.update(id).digest("hex");
|
|
27805
|
-
return
|
|
28171
|
+
return path2.join(getHomeDir(), ".aws", "sso", "cache", `${cacheName}.json`);
|
|
27806
28172
|
};
|
|
27807
28173
|
}
|
|
27808
28174
|
});
|
|
@@ -27816,7 +28182,7 @@ var init_getSSOTokenFromFile = __esm({
|
|
|
27816
28182
|
return tokenIntercept[id];
|
|
27817
28183
|
}
|
|
27818
28184
|
const ssoTokenFilepath = getSSOTokenFilepath(id);
|
|
27819
|
-
const ssoTokenText = await
|
|
28185
|
+
const ssoTokenText = await fs2.readFile(ssoTokenFilepath, "utf8");
|
|
27820
28186
|
return JSON.parse(ssoTokenText);
|
|
27821
28187
|
};
|
|
27822
28188
|
}
|
|
@@ -27857,7 +28223,7 @@ var init_getConfigFilepath = __esm({
|
|
|
27857
28223
|
"node_modules/@smithy/shared-ini-file-loader/dist-es/getConfigFilepath.js"() {
|
|
27858
28224
|
init_getHomeDir();
|
|
27859
28225
|
ENV_CONFIG_PATH = "AWS_CONFIG_FILE";
|
|
27860
|
-
getConfigFilepath = () => process.env[ENV_CONFIG_PATH] ||
|
|
28226
|
+
getConfigFilepath = () => process.env[ENV_CONFIG_PATH] || path2.join(getHomeDir(), ".aws", "config");
|
|
27861
28227
|
}
|
|
27862
28228
|
});
|
|
27863
28229
|
var ENV_CREDENTIALS_PATH, getCredentialsFilepath;
|
|
@@ -27865,7 +28231,7 @@ var init_getCredentialsFilepath = __esm({
|
|
|
27865
28231
|
"node_modules/@smithy/shared-ini-file-loader/dist-es/getCredentialsFilepath.js"() {
|
|
27866
28232
|
init_getHomeDir();
|
|
27867
28233
|
ENV_CREDENTIALS_PATH = "AWS_SHARED_CREDENTIALS_FILE";
|
|
27868
|
-
getCredentialsFilepath = () => process.env[ENV_CREDENTIALS_PATH] ||
|
|
28234
|
+
getCredentialsFilepath = () => process.env[ENV_CREDENTIALS_PATH] || path2.join(getHomeDir(), ".aws", "credentials");
|
|
27869
28235
|
}
|
|
27870
28236
|
});
|
|
27871
28237
|
|
|
@@ -27929,14 +28295,14 @@ var init_readFile = __esm({
|
|
|
27929
28295
|
"node_modules/@smithy/shared-ini-file-loader/dist-es/readFile.js"() {
|
|
27930
28296
|
filePromises = {};
|
|
27931
28297
|
fileIntercept = {};
|
|
27932
|
-
readFile2 = (
|
|
27933
|
-
if (fileIntercept[
|
|
27934
|
-
return fileIntercept[
|
|
28298
|
+
readFile2 = (path4, options) => {
|
|
28299
|
+
if (fileIntercept[path4] !== void 0) {
|
|
28300
|
+
return fileIntercept[path4];
|
|
27935
28301
|
}
|
|
27936
|
-
if (!filePromises[
|
|
27937
|
-
filePromises[
|
|
28302
|
+
if (!filePromises[path4] || options?.ignoreCache) {
|
|
28303
|
+
filePromises[path4] = fs2.readFile(path4, "utf8");
|
|
27938
28304
|
}
|
|
27939
|
-
return filePromises[
|
|
28305
|
+
return filePromises[path4];
|
|
27940
28306
|
};
|
|
27941
28307
|
}
|
|
27942
28308
|
});
|
|
@@ -27957,11 +28323,11 @@ var init_loadSharedConfigFiles = __esm({
|
|
|
27957
28323
|
const relativeHomeDirPrefix = "~/";
|
|
27958
28324
|
let resolvedFilepath = filepath;
|
|
27959
28325
|
if (filepath.startsWith(relativeHomeDirPrefix)) {
|
|
27960
|
-
resolvedFilepath =
|
|
28326
|
+
resolvedFilepath = path2.join(homeDir, filepath.slice(2));
|
|
27961
28327
|
}
|
|
27962
28328
|
let resolvedConfigFilepath = configFilepath;
|
|
27963
28329
|
if (configFilepath.startsWith(relativeHomeDirPrefix)) {
|
|
27964
|
-
resolvedConfigFilepath =
|
|
28330
|
+
resolvedConfigFilepath = path2.join(homeDir, configFilepath.slice(2));
|
|
27965
28331
|
}
|
|
27966
28332
|
const parsedFiles = await Promise.all([
|
|
27967
28333
|
readFile2(resolvedConfigFilepath, {
|
|
@@ -28045,8 +28411,8 @@ var init_externalDataInterceptor = __esm({
|
|
|
28045
28411
|
getFileRecord() {
|
|
28046
28412
|
return fileIntercept;
|
|
28047
28413
|
},
|
|
28048
|
-
interceptFile(
|
|
28049
|
-
fileIntercept[
|
|
28414
|
+
interceptFile(path4, contents) {
|
|
28415
|
+
fileIntercept[path4] = Promise.resolve(contents);
|
|
28050
28416
|
},
|
|
28051
28417
|
getTokenRecord() {
|
|
28052
28418
|
return tokenIntercept;
|
|
@@ -33844,7 +34210,7 @@ Set AWS_CONTAINER_CREDENTIALS_FULL_URI or AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
|
|
|
33844
34210
|
if (token) {
|
|
33845
34211
|
request2.headers.Authorization = token;
|
|
33846
34212
|
} else if (tokenFile) {
|
|
33847
|
-
request2.headers.Authorization = (await
|
|
34213
|
+
request2.headers.Authorization = (await fs2__default.default.readFile(tokenFile)).toString();
|
|
33848
34214
|
}
|
|
33849
34215
|
try {
|
|
33850
34216
|
const result = await requestHandler.handle(request2);
|
|
@@ -34226,10 +34592,10 @@ var init_getNodeModulesParentDirs = __esm({
|
|
|
34226
34592
|
if (!dirname2) {
|
|
34227
34593
|
return [cwd];
|
|
34228
34594
|
}
|
|
34229
|
-
const normalizedPath =
|
|
34230
|
-
const parts = normalizedPath.split(
|
|
34595
|
+
const normalizedPath = path2.normalize(dirname2);
|
|
34596
|
+
const parts = normalizedPath.split(path2.sep);
|
|
34231
34597
|
const nodeModulesIndex = parts.indexOf("node_modules");
|
|
34232
|
-
const parentDir = nodeModulesIndex !== -1 ? parts.slice(0, nodeModulesIndex).join(
|
|
34598
|
+
const parentDir = nodeModulesIndex !== -1 ? parts.slice(0, nodeModulesIndex).join(path2.sep) : normalizedPath;
|
|
34233
34599
|
if (cwd === parentDir) {
|
|
34234
34600
|
return [cwd];
|
|
34235
34601
|
}
|
|
@@ -34281,7 +34647,7 @@ var init_getTypeScriptUserAgentPair = __esm({
|
|
|
34281
34647
|
init_getNodeModulesParentDirs();
|
|
34282
34648
|
init_getSanitizedDevTypeScriptVersion();
|
|
34283
34649
|
init_getSanitizedTypeScriptVersion();
|
|
34284
|
-
TS_PACKAGE_JSON =
|
|
34650
|
+
TS_PACKAGE_JSON = path2.join("node_modules", "typescript", "package.json");
|
|
34285
34651
|
getTypeScriptUserAgentPair = async () => {
|
|
34286
34652
|
if (tscVersion === null) {
|
|
34287
34653
|
return void 0;
|
|
@@ -34302,8 +34668,8 @@ var init_getTypeScriptUserAgentPair = __esm({
|
|
|
34302
34668
|
let versionFromApp;
|
|
34303
34669
|
for (const nodeModulesParentDir of nodeModulesParentDirs) {
|
|
34304
34670
|
try {
|
|
34305
|
-
const appPackageJsonPath =
|
|
34306
|
-
const packageJson = await
|
|
34671
|
+
const appPackageJsonPath = path2.join(nodeModulesParentDir, "package.json");
|
|
34672
|
+
const packageJson = await fs2.readFile(appPackageJsonPath, "utf-8");
|
|
34307
34673
|
const { dependencies, devDependencies } = JSON.parse(packageJson);
|
|
34308
34674
|
const version = devDependencies?.typescript ?? dependencies?.typescript;
|
|
34309
34675
|
if (typeof version !== "string") {
|
|
@@ -34321,8 +34687,8 @@ var init_getTypeScriptUserAgentPair = __esm({
|
|
|
34321
34687
|
let versionFromNodeModules;
|
|
34322
34688
|
for (const nodeModulesParentDir of nodeModulesParentDirs) {
|
|
34323
34689
|
try {
|
|
34324
|
-
const tsPackageJsonPath =
|
|
34325
|
-
const packageJson = await
|
|
34690
|
+
const tsPackageJsonPath = path2.join(nodeModulesParentDir, TS_PACKAGE_JSON);
|
|
34691
|
+
const packageJson = await fs2.readFile(tsPackageJsonPath, "utf-8");
|
|
34326
34692
|
const { version } = JSON.parse(packageJson);
|
|
34327
34693
|
const sanitizedVersion2 = getSanitizedTypeScriptVersion(version);
|
|
34328
34694
|
if (typeof sanitizedVersion2 !== "string") {
|
|
@@ -34465,7 +34831,7 @@ var init_dist_es46 = __esm({
|
|
|
34465
34831
|
return Promise.resolve(this.hash.digest());
|
|
34466
34832
|
}
|
|
34467
34833
|
reset() {
|
|
34468
|
-
this.hash = this.secret ?
|
|
34834
|
+
this.hash = this.secret ? cryptoNode.createHmac(this.algorithmIdentifier, castSourceData(this.secret)) : cryptoNode.createHash(this.algorithmIdentifier);
|
|
34469
34835
|
}
|
|
34470
34836
|
};
|
|
34471
34837
|
}
|
|
@@ -38690,7 +39056,7 @@ var init_LoginCredentialsFetcher = __esm({
|
|
|
38690
39056
|
}
|
|
38691
39057
|
async saveToken(token) {
|
|
38692
39058
|
const tokenFilePath = this.getTokenFilePath();
|
|
38693
|
-
const directory =
|
|
39059
|
+
const directory = path2.dirname(tokenFilePath);
|
|
38694
39060
|
try {
|
|
38695
39061
|
await fs.promises.mkdir(directory, { recursive: true });
|
|
38696
39062
|
} catch (error) {
|
|
@@ -38698,10 +39064,10 @@ var init_LoginCredentialsFetcher = __esm({
|
|
|
38698
39064
|
await fs.promises.writeFile(tokenFilePath, JSON.stringify(token, null, 2), "utf8");
|
|
38699
39065
|
}
|
|
38700
39066
|
getTokenFilePath() {
|
|
38701
|
-
const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ??
|
|
39067
|
+
const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ?? path2.join(os.homedir(), ".aws", "login", "cache");
|
|
38702
39068
|
const loginSessionBytes = Buffer.from(this.loginSession, "utf8");
|
|
38703
|
-
const loginSessionSha256 =
|
|
38704
|
-
return
|
|
39069
|
+
const loginSessionSha256 = cryptoNode.createHash("sha256").update(loginSessionBytes).digest("hex");
|
|
39070
|
+
return path2.join(directory, `${loginSessionSha256}.json`);
|
|
38705
39071
|
}
|
|
38706
39072
|
derToRawSignature(derSignature) {
|
|
38707
39073
|
let offset = 2;
|
|
@@ -38745,12 +39111,12 @@ var init_LoginCredentialsFetcher = __esm({
|
|
|
38745
39111
|
async generateDpop(method = "POST", endpoint) {
|
|
38746
39112
|
const token = await this.loadToken();
|
|
38747
39113
|
try {
|
|
38748
|
-
const privateKey =
|
|
39114
|
+
const privateKey = cryptoNode.createPrivateKey({
|
|
38749
39115
|
key: token.dpopKey,
|
|
38750
39116
|
format: "pem",
|
|
38751
39117
|
type: "sec1"
|
|
38752
39118
|
});
|
|
38753
|
-
const publicKey =
|
|
39119
|
+
const publicKey = cryptoNode.createPublicKey(privateKey);
|
|
38754
39120
|
const publicDer = publicKey.export({ format: "der", type: "spki" });
|
|
38755
39121
|
let pointStart = -1;
|
|
38756
39122
|
for (let i6 = 0; i6 < publicDer.length; i6++) {
|
|
@@ -38780,7 +39146,7 @@ var init_LoginCredentialsFetcher = __esm({
|
|
|
38780
39146
|
const headerB64 = Buffer.from(JSON.stringify(header)).toString("base64url");
|
|
38781
39147
|
const payloadB64 = Buffer.from(JSON.stringify(payload)).toString("base64url");
|
|
38782
39148
|
const message = `${headerB64}.${payloadB64}`;
|
|
38783
|
-
const asn1Signature =
|
|
39149
|
+
const asn1Signature = cryptoNode.sign("sha256", Buffer.from(message), privateKey);
|
|
38784
39150
|
const rawSignature = this.derToRawSignature(asn1Signature);
|
|
38785
39151
|
const signatureB64 = rawSignature.toString("base64url");
|
|
38786
39152
|
return `${message}.${signatureB64}`;
|
|
@@ -43316,9 +43682,28 @@ function _getFailStrategy() {
|
|
|
43316
43682
|
function _hashPlaintext(plaintext, secret) {
|
|
43317
43683
|
const trimmed = plaintext.trim();
|
|
43318
43684
|
if (secret) {
|
|
43319
|
-
return
|
|
43685
|
+
return cryptoNode__namespace.createHmac("sha256", secret).update(trimmed, "utf-8").digest("hex");
|
|
43686
|
+
}
|
|
43687
|
+
return cryptoNode__namespace.createHash("sha256").update(trimmed, "utf-8").digest("hex");
|
|
43688
|
+
}
|
|
43689
|
+
function _vaultKey(token) {
|
|
43690
|
+
return `mask:${config.MASK_TENANT_ID}:${token}`;
|
|
43691
|
+
}
|
|
43692
|
+
function _vaultRevKey(ptHash) {
|
|
43693
|
+
return `mask-rev:${config.MASK_TENANT_ID}:${ptHash}`;
|
|
43694
|
+
}
|
|
43695
|
+
function _vaultHashKey(token) {
|
|
43696
|
+
return `mask-hash:${config.MASK_TENANT_ID}:${token}`;
|
|
43697
|
+
}
|
|
43698
|
+
function _unwrapPayload(raw) {
|
|
43699
|
+
if (raw && raw.startsWith("{")) {
|
|
43700
|
+
try {
|
|
43701
|
+
const obj = JSON.parse(raw);
|
|
43702
|
+
if (obj.ct) return obj.ct;
|
|
43703
|
+
} catch {
|
|
43704
|
+
}
|
|
43320
43705
|
}
|
|
43321
|
-
return
|
|
43706
|
+
return raw;
|
|
43322
43707
|
}
|
|
43323
43708
|
function getVault() {
|
|
43324
43709
|
if (_vaultInstance === null) {
|
|
@@ -43359,10 +43744,17 @@ async function encode(rawText, options = {}) {
|
|
|
43359
43744
|
return existingToken;
|
|
43360
43745
|
}
|
|
43361
43746
|
}
|
|
43362
|
-
const token = await
|
|
43747
|
+
const token = await generateDPToken(text, options.entityType || "UNKNOWN");
|
|
43363
43748
|
const ciphertext = cryptoEngine.encrypt(text);
|
|
43749
|
+
const existingCiphertext = await vault.retrieve(token);
|
|
43750
|
+
if (existingCiphertext !== null) {
|
|
43751
|
+
const existingHash = await vault.getPtHashForToken(token);
|
|
43752
|
+
if (existingHash && existingHash !== ptHash) {
|
|
43753
|
+
throw new TokenCollisionError(token, existingHash, ptHash);
|
|
43754
|
+
}
|
|
43755
|
+
}
|
|
43364
43756
|
const ttl = options.ttl || DEFAULT_TTL;
|
|
43365
|
-
await vault.store(token, ciphertext, ttl, ptHash);
|
|
43757
|
+
await vault.store(token, ciphertext, ttl, ptHash, options.metadata || null);
|
|
43366
43758
|
if (options.searchBuckets && options.searchBuckets.length > 0) {
|
|
43367
43759
|
for (const bType of options.searchBuckets) {
|
|
43368
43760
|
let bucketVal;
|
|
@@ -43384,8 +43776,8 @@ async function decode(token) {
|
|
|
43384
43776
|
throw new DecodeError("Token not found or expired");
|
|
43385
43777
|
}
|
|
43386
43778
|
try {
|
|
43387
|
-
const
|
|
43388
|
-
const result =
|
|
43779
|
+
const crypto7 = await getCryptoEngineAsync();
|
|
43780
|
+
const result = crypto7.decrypt(ciphertext);
|
|
43389
43781
|
getAuditLogger().log("decode", token);
|
|
43390
43782
|
return result;
|
|
43391
43783
|
} catch (e6) {
|
|
@@ -43437,14 +43829,15 @@ var init_vault = __esm({
|
|
|
43437
43829
|
MemoryVault = class extends BaseVault {
|
|
43438
43830
|
constructor() {
|
|
43439
43831
|
super();
|
|
43832
|
+
this._cleanupTimer = null;
|
|
43440
43833
|
this._store = /* @__PURE__ */ new Map();
|
|
43441
43834
|
this._reverseStore = /* @__PURE__ */ new Map();
|
|
43835
|
+
this._cleanupTimer = setInterval(() => this._cleanup(), 6e4);
|
|
43836
|
+
if (this._cleanupTimer && typeof this._cleanupTimer.unref === "function") {
|
|
43837
|
+
this._cleanupTimer.unref();
|
|
43838
|
+
}
|
|
43442
43839
|
}
|
|
43443
43840
|
_cleanup() {
|
|
43444
|
-
const cleanupFreq = config.MASK_VAULT_CLEANUP_FREQUENCY;
|
|
43445
|
-
if (Math.random() > cleanupFreq) {
|
|
43446
|
-
return;
|
|
43447
|
-
}
|
|
43448
43841
|
const now = Date.now() / 1e3;
|
|
43449
43842
|
for (const [token, entry] of this._store.entries()) {
|
|
43450
43843
|
if (now > entry.expiry) {
|
|
@@ -43455,27 +43848,41 @@ var init_vault = __esm({
|
|
|
43455
43848
|
}
|
|
43456
43849
|
}
|
|
43457
43850
|
}
|
|
43458
|
-
async store(token,
|
|
43459
|
-
this.
|
|
43851
|
+
async store(token, ciphertext, ttlSeconds, ptHash = null, metadata = null) {
|
|
43852
|
+
if (!this._store.has(token) && this._store.size >= config.MASK_VAULT_MAX_MEMORY_KEYS) {
|
|
43853
|
+
const firstKey = this._store.keys().next().value;
|
|
43854
|
+
if (firstKey !== void 0) {
|
|
43855
|
+
const oldEntry = this._store.get(firstKey);
|
|
43856
|
+
this._store.delete(firstKey);
|
|
43857
|
+
if (oldEntry?.ptHash && this._reverseStore.get(oldEntry.ptHash) === firstKey) {
|
|
43858
|
+
this._reverseStore.delete(oldEntry.ptHash);
|
|
43859
|
+
}
|
|
43860
|
+
}
|
|
43861
|
+
}
|
|
43862
|
+
const existing = this._store.get(token);
|
|
43863
|
+
if (existing) this._store.delete(token);
|
|
43460
43864
|
this._store.set(token, {
|
|
43461
|
-
plaintext,
|
|
43865
|
+
plaintext: ciphertext,
|
|
43462
43866
|
expiry: Date.now() / 1e3 + ttlSeconds,
|
|
43463
|
-
ptHash
|
|
43867
|
+
ptHash,
|
|
43868
|
+
metadata: { ...existing?.metadata || {}, ...metadata || {} }
|
|
43464
43869
|
});
|
|
43465
43870
|
if (ptHash) {
|
|
43466
43871
|
this._reverseStore.set(ptHash, token);
|
|
43467
43872
|
}
|
|
43468
43873
|
}
|
|
43469
43874
|
async getTokenByPlaintextHash(ptHash) {
|
|
43470
|
-
this._cleanup();
|
|
43471
43875
|
const token = this._reverseStore.get(ptHash);
|
|
43472
43876
|
if (token && this._store.has(token)) {
|
|
43473
43877
|
return token;
|
|
43474
43878
|
}
|
|
43475
43879
|
return null;
|
|
43476
43880
|
}
|
|
43881
|
+
async getPtHashForToken(token) {
|
|
43882
|
+
const entry = this._store.get(token);
|
|
43883
|
+
return entry?.ptHash ?? null;
|
|
43884
|
+
}
|
|
43477
43885
|
async retrieve(token) {
|
|
43478
|
-
this._cleanup();
|
|
43479
43886
|
const entry = this._store.get(token);
|
|
43480
43887
|
if (!entry) {
|
|
43481
43888
|
return null;
|
|
@@ -43531,13 +43938,14 @@ var init_vault = __esm({
|
|
|
43531
43938
|
throw new exports.MaskVaultConnectionError(`Failed to connect to Redis: ${e6}`);
|
|
43532
43939
|
}
|
|
43533
43940
|
}
|
|
43534
|
-
async store(token, ciphertext, ttlSeconds, ptHash = null) {
|
|
43941
|
+
async store(token, ciphertext, ttlSeconds, ptHash = null, metadata = null) {
|
|
43535
43942
|
try {
|
|
43536
43943
|
const pipeline = this._client.pipeline();
|
|
43537
|
-
|
|
43944
|
+
const payload = metadata ? JSON.stringify({ ct: ciphertext, meta: metadata }) : ciphertext;
|
|
43945
|
+
pipeline.set(_vaultKey(token), payload, "EX", ttlSeconds);
|
|
43538
43946
|
if (ptHash) {
|
|
43539
|
-
pipeline.set(
|
|
43540
|
-
pipeline.set(
|
|
43947
|
+
pipeline.set(_vaultRevKey(ptHash), token, "EX", ttlSeconds);
|
|
43948
|
+
pipeline.set(_vaultHashKey(token), ptHash, "EX", ttlSeconds);
|
|
43541
43949
|
}
|
|
43542
43950
|
const results = await pipeline.exec();
|
|
43543
43951
|
if (results) {
|
|
@@ -43549,14 +43957,21 @@ var init_vault = __esm({
|
|
|
43549
43957
|
throw new exports.MaskVaultConnectionError(`Redis error: ${e6}`);
|
|
43550
43958
|
}
|
|
43551
43959
|
}
|
|
43960
|
+
async getPtHashForToken(token) {
|
|
43961
|
+
try {
|
|
43962
|
+
return await this._client.get(_vaultHashKey(token));
|
|
43963
|
+
} catch {
|
|
43964
|
+
return null;
|
|
43965
|
+
}
|
|
43966
|
+
}
|
|
43552
43967
|
async getTokenByPlaintextHash(ptHash) {
|
|
43553
43968
|
try {
|
|
43554
|
-
const token = await this._client.get(
|
|
43969
|
+
const token = await this._client.get(_vaultRevKey(ptHash));
|
|
43555
43970
|
if (token) {
|
|
43556
|
-
if (await this._client.exists(
|
|
43971
|
+
if (await this._client.exists(_vaultKey(token))) {
|
|
43557
43972
|
return token;
|
|
43558
43973
|
} else {
|
|
43559
|
-
await this._client.del(
|
|
43974
|
+
await this._client.del(_vaultRevKey(ptHash));
|
|
43560
43975
|
}
|
|
43561
43976
|
}
|
|
43562
43977
|
return null;
|
|
@@ -43569,7 +43984,8 @@ var init_vault = __esm({
|
|
|
43569
43984
|
}
|
|
43570
43985
|
async retrieve(token) {
|
|
43571
43986
|
try {
|
|
43572
|
-
|
|
43987
|
+
const raw = await this._client.get(_vaultKey(token));
|
|
43988
|
+
return raw ? _unwrapPayload(raw) : null;
|
|
43573
43989
|
} catch (e6) {
|
|
43574
43990
|
if (_getFailStrategy() === "closed") {
|
|
43575
43991
|
throw new exports.MaskVaultConnectionError(`Redis read failed: ${e6}`);
|
|
@@ -43579,12 +43995,12 @@ var init_vault = __esm({
|
|
|
43579
43995
|
}
|
|
43580
43996
|
async delete(token) {
|
|
43581
43997
|
try {
|
|
43582
|
-
const ptHash = await this._client.get(
|
|
43998
|
+
const ptHash = await this._client.get(_vaultHashKey(token));
|
|
43583
43999
|
const pipeline = this._client.pipeline();
|
|
43584
|
-
pipeline.del(
|
|
43585
|
-
pipeline.del(
|
|
44000
|
+
pipeline.del(_vaultKey(token));
|
|
44001
|
+
pipeline.del(_vaultHashKey(token));
|
|
43586
44002
|
if (ptHash) {
|
|
43587
|
-
pipeline.del(
|
|
44003
|
+
pipeline.del(_vaultRevKey(ptHash));
|
|
43588
44004
|
}
|
|
43589
44005
|
await pipeline.exec();
|
|
43590
44006
|
} catch (e6) {
|
|
@@ -43623,39 +44039,26 @@ var init_vault = __esm({
|
|
|
43623
44039
|
this._client = DynamoDBDocument.from(baseClient);
|
|
43624
44040
|
console.info(`DynamoDBVault connected to table ${this._tableName} in ${this._region}`);
|
|
43625
44041
|
}
|
|
43626
|
-
async store(token, ciphertext, ttlSeconds, ptHash = null) {
|
|
44042
|
+
async store(token, ciphertext, ttlSeconds, ptHash = null, metadata = null) {
|
|
43627
44043
|
const { TransactWriteCommand, PutCommand } = __require("@aws-sdk/lib-dynamodb");
|
|
43628
44044
|
const now = Math.floor(Date.now() / 1e3);
|
|
43629
44045
|
const ttlVal = now + ttlSeconds;
|
|
43630
|
-
const
|
|
43631
|
-
token:
|
|
44046
|
+
const primaryItem = {
|
|
44047
|
+
token: _vaultKey(token),
|
|
43632
44048
|
ciphertext,
|
|
43633
|
-
ttl: ttlVal
|
|
43634
|
-
ptr_hash: ptHash || void 0
|
|
44049
|
+
ttl: ttlVal
|
|
43635
44050
|
};
|
|
44051
|
+
if (ptHash) primaryItem.ptr_hash = ptHash;
|
|
44052
|
+
if (metadata) primaryItem.meta_json = JSON.stringify(metadata);
|
|
43636
44053
|
if (ptHash) {
|
|
43637
44054
|
try {
|
|
43638
44055
|
await this._client.send(new TransactWriteCommand({
|
|
43639
44056
|
TransactItems: [
|
|
44057
|
+
{ Put: { TableName: this._tableName, Item: primaryItem } },
|
|
43640
44058
|
{
|
|
43641
44059
|
Put: {
|
|
43642
44060
|
TableName: this._tableName,
|
|
43643
|
-
Item: {
|
|
43644
|
-
token: `mask:${token}`,
|
|
43645
|
-
ciphertext,
|
|
43646
|
-
ttl: ttlVal,
|
|
43647
|
-
ptr_hash: ptHash
|
|
43648
|
-
}
|
|
43649
|
-
}
|
|
43650
|
-
},
|
|
43651
|
-
{
|
|
43652
|
-
Put: {
|
|
43653
|
-
TableName: this._tableName,
|
|
43654
|
-
Item: {
|
|
43655
|
-
token: `mask-rev:${ptHash}`,
|
|
43656
|
-
ciphertext: token,
|
|
43657
|
-
ttl: ttlVal
|
|
43658
|
-
}
|
|
44061
|
+
Item: { token: _vaultRevKey(ptHash), ciphertext: token, ttl: ttlVal }
|
|
43659
44062
|
}
|
|
43660
44063
|
}
|
|
43661
44064
|
]
|
|
@@ -43666,7 +44069,7 @@ var init_vault = __esm({
|
|
|
43666
44069
|
}
|
|
43667
44070
|
} else {
|
|
43668
44071
|
try {
|
|
43669
|
-
await this._client.send(new PutCommand({ TableName: this._tableName, Item:
|
|
44072
|
+
await this._client.send(new PutCommand({ TableName: this._tableName, Item: primaryItem }));
|
|
43670
44073
|
} catch (e6) {
|
|
43671
44074
|
throw new exports.MaskVaultConnectionError(`DynamoDB individual write failed: ${e6}`);
|
|
43672
44075
|
}
|
|
@@ -43678,12 +44081,12 @@ var init_vault = __esm({
|
|
|
43678
44081
|
const now = Math.floor(Date.now() / 1e3);
|
|
43679
44082
|
const resp = await this._client.send(new GetCommand({
|
|
43680
44083
|
TableName: this._tableName,
|
|
43681
|
-
Key: { token:
|
|
44084
|
+
Key: { token: _vaultRevKey(ptHash) }
|
|
43682
44085
|
}));
|
|
43683
44086
|
const item = resp.Item;
|
|
43684
44087
|
if (!item) return null;
|
|
43685
44088
|
if (now > (item.ttl || 0)) {
|
|
43686
|
-
await this._client.send(new DeleteCommand({ TableName: this._tableName, Key: { token:
|
|
44089
|
+
await this._client.send(new DeleteCommand({ TableName: this._tableName, Key: { token: _vaultRevKey(ptHash) } }));
|
|
43687
44090
|
return null;
|
|
43688
44091
|
}
|
|
43689
44092
|
const token = item.ciphertext;
|
|
@@ -43699,16 +44102,16 @@ var init_vault = __esm({
|
|
|
43699
44102
|
const now = Math.floor(Date.now() / 1e3);
|
|
43700
44103
|
const resp = await this._client.send(new GetCommand({
|
|
43701
44104
|
TableName: this._tableName,
|
|
43702
|
-
Key: { token:
|
|
44105
|
+
Key: { token: _vaultKey(token) }
|
|
43703
44106
|
}));
|
|
43704
44107
|
const item = resp.Item;
|
|
43705
44108
|
if (!item) return null;
|
|
43706
44109
|
if (now > (item.ttl || 0)) {
|
|
43707
44110
|
const ptHash = item.ptr_hash;
|
|
43708
44111
|
if (ptHash) {
|
|
43709
|
-
await this._client.send(new DeleteCommand({ TableName: this._tableName, Key: { token:
|
|
44112
|
+
await this._client.send(new DeleteCommand({ TableName: this._tableName, Key: { token: _vaultRevKey(ptHash) } }));
|
|
43710
44113
|
}
|
|
43711
|
-
await this._client.send(new DeleteCommand({ TableName: this._tableName, Key: { token:
|
|
44114
|
+
await this._client.send(new DeleteCommand({ TableName: this._tableName, Key: { token: _vaultKey(token) } }));
|
|
43712
44115
|
return null;
|
|
43713
44116
|
}
|
|
43714
44117
|
return item.ciphertext;
|
|
@@ -43717,18 +44120,30 @@ var init_vault = __esm({
|
|
|
43717
44120
|
return null;
|
|
43718
44121
|
}
|
|
43719
44122
|
}
|
|
44123
|
+
async getPtHashForToken(token) {
|
|
44124
|
+
try {
|
|
44125
|
+
const { GetCommand } = __require("@aws-sdk/lib-dynamodb");
|
|
44126
|
+
const resp = await this._client.send(new GetCommand({
|
|
44127
|
+
TableName: this._tableName,
|
|
44128
|
+
Key: { token: _vaultKey(token) }
|
|
44129
|
+
}));
|
|
44130
|
+
return resp.Item?.ptr_hash ?? null;
|
|
44131
|
+
} catch {
|
|
44132
|
+
return null;
|
|
44133
|
+
}
|
|
44134
|
+
}
|
|
43720
44135
|
async delete(token) {
|
|
43721
44136
|
try {
|
|
43722
44137
|
const { GetCommand, DeleteCommand } = __require("@aws-sdk/lib-dynamodb");
|
|
43723
44138
|
const resp = await this._client.send(new GetCommand({
|
|
43724
44139
|
TableName: this._tableName,
|
|
43725
|
-
Key: { token:
|
|
44140
|
+
Key: { token: _vaultKey(token) }
|
|
43726
44141
|
}));
|
|
43727
44142
|
const item = resp.Item;
|
|
43728
44143
|
if (item && item.ptr_hash) {
|
|
43729
|
-
await this._client.send(new DeleteCommand({ TableName: this._tableName, Key: { token:
|
|
44144
|
+
await this._client.send(new DeleteCommand({ TableName: this._tableName, Key: { token: _vaultRevKey(item.ptr_hash) } }));
|
|
43730
44145
|
}
|
|
43731
|
-
await this._client.send(new DeleteCommand({ TableName: this._tableName, Key: { token:
|
|
44146
|
+
await this._client.send(new DeleteCommand({ TableName: this._tableName, Key: { token: _vaultKey(token) } }));
|
|
43732
44147
|
} catch (e6) {
|
|
43733
44148
|
if (_getFailStrategy() === "closed") throw new exports.MaskVaultConnectionError(`DynamoDB delete failed: ${e6}`);
|
|
43734
44149
|
}
|
|
@@ -43747,20 +44162,29 @@ var init_vault = __esm({
|
|
|
43747
44162
|
throw new exports.MaskVaultConnectionError(`Failed to connect to Memcached: ${e6}`);
|
|
43748
44163
|
}
|
|
43749
44164
|
}
|
|
43750
|
-
async store(token, ciphertext, ttlSeconds, ptHash = null) {
|
|
44165
|
+
async store(token, ciphertext, ttlSeconds, ptHash = null, metadata = null) {
|
|
43751
44166
|
try {
|
|
43752
|
-
|
|
44167
|
+
const payload = metadata ? JSON.stringify({ ct: ciphertext, meta: metadata }) : ciphertext;
|
|
44168
|
+
await this._client.set(_vaultKey(token), Buffer.from(payload), { expires: ttlSeconds });
|
|
43753
44169
|
if (ptHash) {
|
|
43754
|
-
await this._client.set(
|
|
43755
|
-
await this._client.set(
|
|
44170
|
+
await this._client.set(_vaultRevKey(ptHash), Buffer.from(token), { expires: ttlSeconds });
|
|
44171
|
+
await this._client.set(_vaultHashKey(token), Buffer.from(ptHash), { expires: ttlSeconds });
|
|
43756
44172
|
}
|
|
43757
44173
|
} catch (e6) {
|
|
43758
44174
|
throw new exports.MaskVaultConnectionError(`Memcached error: ${e6}`);
|
|
43759
44175
|
}
|
|
43760
44176
|
}
|
|
44177
|
+
async getPtHashForToken(token) {
|
|
44178
|
+
try {
|
|
44179
|
+
const { value } = await this._client.get(_vaultHashKey(token));
|
|
44180
|
+
return value ? value.toString() : null;
|
|
44181
|
+
} catch {
|
|
44182
|
+
return null;
|
|
44183
|
+
}
|
|
44184
|
+
}
|
|
43761
44185
|
async getTokenByPlaintextHash(ptHash) {
|
|
43762
44186
|
try {
|
|
43763
|
-
const { value } = await this._client.get(
|
|
44187
|
+
const { value } = await this._client.get(_vaultRevKey(ptHash));
|
|
43764
44188
|
if (!value) return null;
|
|
43765
44189
|
const token = value.toString();
|
|
43766
44190
|
return await this.retrieve(token) !== null ? token : null;
|
|
@@ -43771,8 +44195,9 @@ var init_vault = __esm({
|
|
|
43771
44195
|
}
|
|
43772
44196
|
async retrieve(token) {
|
|
43773
44197
|
try {
|
|
43774
|
-
const { value } = await this._client.get(
|
|
43775
|
-
|
|
44198
|
+
const { value } = await this._client.get(_vaultKey(token));
|
|
44199
|
+
if (!value) return null;
|
|
44200
|
+
return _unwrapPayload(value.toString());
|
|
43776
44201
|
} catch (e6) {
|
|
43777
44202
|
if (_getFailStrategy() === "closed") throw new exports.MaskVaultConnectionError(`Memcached read failed: ${e6}`);
|
|
43778
44203
|
return null;
|
|
@@ -43780,12 +44205,12 @@ var init_vault = __esm({
|
|
|
43780
44205
|
}
|
|
43781
44206
|
async delete(token) {
|
|
43782
44207
|
try {
|
|
43783
|
-
const { value } = await this._client.get(
|
|
44208
|
+
const { value } = await this._client.get(_vaultHashKey(token));
|
|
43784
44209
|
const ptHash = value ? value.toString() : null;
|
|
43785
|
-
await this._client.delete(
|
|
43786
|
-
await this._client.delete(
|
|
44210
|
+
await this._client.delete(_vaultKey(token));
|
|
44211
|
+
await this._client.delete(_vaultHashKey(token));
|
|
43787
44212
|
if (ptHash) {
|
|
43788
|
-
await this._client.delete(
|
|
44213
|
+
await this._client.delete(_vaultRevKey(ptHash));
|
|
43789
44214
|
}
|
|
43790
44215
|
} catch (e6) {
|
|
43791
44216
|
if (_getFailStrategy() === "closed") throw new exports.MaskVaultConnectionError(`Memcached delete failed: ${e6}`);
|
|
@@ -53503,11 +53928,11 @@ var require_mime_types = __commonJS({
|
|
|
53503
53928
|
}
|
|
53504
53929
|
return exts[0];
|
|
53505
53930
|
}
|
|
53506
|
-
function lookup(
|
|
53507
|
-
if (!
|
|
53931
|
+
function lookup(path4) {
|
|
53932
|
+
if (!path4 || typeof path4 !== "string") {
|
|
53508
53933
|
return false;
|
|
53509
53934
|
}
|
|
53510
|
-
var extension2 = extname("x." +
|
|
53935
|
+
var extension2 = extname("x." + path4).toLowerCase().substr(1);
|
|
53511
53936
|
if (!extension2) {
|
|
53512
53937
|
return false;
|
|
53513
53938
|
}
|
|
@@ -54574,13 +54999,13 @@ var require_form_data = __commonJS({
|
|
|
54574
54999
|
"node_modules/form-data/lib/form_data.js"(exports2, module) {
|
|
54575
55000
|
var CombinedStream = require_combined_stream();
|
|
54576
55001
|
var util = __require("util");
|
|
54577
|
-
var
|
|
55002
|
+
var path4 = __require("path");
|
|
54578
55003
|
var http = __require("http");
|
|
54579
55004
|
var https = __require("https");
|
|
54580
55005
|
var parseUrl2 = __require("url").parse;
|
|
54581
|
-
var
|
|
55006
|
+
var fs4 = __require("fs");
|
|
54582
55007
|
var Stream = __require("stream").Stream;
|
|
54583
|
-
var
|
|
55008
|
+
var crypto7 = __require("crypto");
|
|
54584
55009
|
var mime = require_mime_types();
|
|
54585
55010
|
var asynckit = require_asynckit();
|
|
54586
55011
|
var setToStringTag = require_es_set_tostringtag();
|
|
@@ -54645,7 +55070,7 @@ var require_form_data = __commonJS({
|
|
|
54645
55070
|
if (value.end != void 0 && value.end != Infinity && value.start != void 0) {
|
|
54646
55071
|
callback(null, value.end + 1 - (value.start ? value.start : 0));
|
|
54647
55072
|
} else {
|
|
54648
|
-
|
|
55073
|
+
fs4.stat(value.path, function(err2, stat) {
|
|
54649
55074
|
if (err2) {
|
|
54650
55075
|
callback(err2);
|
|
54651
55076
|
return;
|
|
@@ -54702,11 +55127,11 @@ var require_form_data = __commonJS({
|
|
|
54702
55127
|
FormData2.prototype._getContentDisposition = function(value, options) {
|
|
54703
55128
|
var filename;
|
|
54704
55129
|
if (typeof options.filepath === "string") {
|
|
54705
|
-
filename =
|
|
55130
|
+
filename = path4.normalize(options.filepath).replace(/\\/g, "/");
|
|
54706
55131
|
} else if (options.filename || value && (value.name || value.path)) {
|
|
54707
|
-
filename =
|
|
55132
|
+
filename = path4.basename(options.filename || value && (value.name || value.path));
|
|
54708
55133
|
} else if (value && value.readable && hasOwn(value, "httpVersion")) {
|
|
54709
|
-
filename =
|
|
55134
|
+
filename = path4.basename(value.client._httpMessage.path || "");
|
|
54710
55135
|
}
|
|
54711
55136
|
if (filename) {
|
|
54712
55137
|
return 'filename="' + filename + '"';
|
|
@@ -54786,7 +55211,7 @@ var require_form_data = __commonJS({
|
|
|
54786
55211
|
return Buffer.concat([dataBuffer, Buffer.from(this._lastBoundary())]);
|
|
54787
55212
|
};
|
|
54788
55213
|
FormData2.prototype._generateBoundary = function() {
|
|
54789
|
-
this._boundary = "--------------------------" +
|
|
55214
|
+
this._boundary = "--------------------------" + crypto7.randomBytes(12).toString("hex");
|
|
54790
55215
|
};
|
|
54791
55216
|
FormData2.prototype.getLengthSync = function() {
|
|
54792
55217
|
var knownLength = this._overheadLength + this._valueLength;
|
|
@@ -55476,7 +55901,7 @@ var require_follow_redirects = __commonJS({
|
|
|
55476
55901
|
var require_axios = __commonJS({
|
|
55477
55902
|
"node_modules/axios/dist/node/axios.cjs"(exports2, module) {
|
|
55478
55903
|
var FormData$1 = require_form_data();
|
|
55479
|
-
var
|
|
55904
|
+
var crypto7 = __require("crypto");
|
|
55480
55905
|
var url = __require("url");
|
|
55481
55906
|
var proxyFromEnv = require_proxy_from_env();
|
|
55482
55907
|
var http = __require("http");
|
|
@@ -55491,7 +55916,7 @@ var require_axios = __commonJS({
|
|
|
55491
55916
|
return e6 && typeof e6 === "object" && "default" in e6 ? e6 : { "default": e6 };
|
|
55492
55917
|
}
|
|
55493
55918
|
var FormData__default = /* @__PURE__ */ _interopDefaultLegacy(FormData$1);
|
|
55494
|
-
var crypto__default = /* @__PURE__ */ _interopDefaultLegacy(
|
|
55919
|
+
var crypto__default = /* @__PURE__ */ _interopDefaultLegacy(crypto7);
|
|
55495
55920
|
var url__default = /* @__PURE__ */ _interopDefaultLegacy(url);
|
|
55496
55921
|
var proxyFromEnv__default = /* @__PURE__ */ _interopDefaultLegacy(proxyFromEnv);
|
|
55497
55922
|
var http__default = /* @__PURE__ */ _interopDefaultLegacy(http);
|
|
@@ -56010,9 +56435,9 @@ var require_axios = __commonJS({
|
|
|
56010
56435
|
function removeBrackets(key) {
|
|
56011
56436
|
return utils$1.endsWith(key, "[]") ? key.slice(0, -2) : key;
|
|
56012
56437
|
}
|
|
56013
|
-
function renderKey(
|
|
56014
|
-
if (!
|
|
56015
|
-
return
|
|
56438
|
+
function renderKey(path4, key, dots) {
|
|
56439
|
+
if (!path4) return key;
|
|
56440
|
+
return path4.concat(key).map(function each(token, i6) {
|
|
56016
56441
|
token = removeBrackets(token);
|
|
56017
56442
|
return !dots && i6 ? "[" + token + "]" : token;
|
|
56018
56443
|
}).join(dots ? "." : "");
|
|
@@ -56065,13 +56490,13 @@ var require_axios = __commonJS({
|
|
|
56065
56490
|
}
|
|
56066
56491
|
return value;
|
|
56067
56492
|
}
|
|
56068
|
-
function defaultVisitor(value, key,
|
|
56493
|
+
function defaultVisitor(value, key, path4) {
|
|
56069
56494
|
let arr = value;
|
|
56070
56495
|
if (utils$1.isReactNative(formData) && utils$1.isReactNativeBlob(value)) {
|
|
56071
|
-
formData.append(renderKey(
|
|
56496
|
+
formData.append(renderKey(path4, key, dots), convertValue(value));
|
|
56072
56497
|
return false;
|
|
56073
56498
|
}
|
|
56074
|
-
if (value && !
|
|
56499
|
+
if (value && !path4 && typeof value === "object") {
|
|
56075
56500
|
if (utils$1.endsWith(key, "{}")) {
|
|
56076
56501
|
key = metaTokens ? key : key.slice(0, -2);
|
|
56077
56502
|
value = JSON.stringify(value);
|
|
@@ -56090,7 +56515,7 @@ var require_axios = __commonJS({
|
|
|
56090
56515
|
if (isVisitable(value)) {
|
|
56091
56516
|
return true;
|
|
56092
56517
|
}
|
|
56093
|
-
formData.append(renderKey(
|
|
56518
|
+
formData.append(renderKey(path4, key, dots), convertValue(value));
|
|
56094
56519
|
return false;
|
|
56095
56520
|
}
|
|
56096
56521
|
const stack = [];
|
|
@@ -56099,16 +56524,16 @@ var require_axios = __commonJS({
|
|
|
56099
56524
|
convertValue,
|
|
56100
56525
|
isVisitable
|
|
56101
56526
|
});
|
|
56102
|
-
function build(value,
|
|
56527
|
+
function build(value, path4) {
|
|
56103
56528
|
if (utils$1.isUndefined(value)) return;
|
|
56104
56529
|
if (stack.indexOf(value) !== -1) {
|
|
56105
|
-
throw Error("Circular reference detected in " +
|
|
56530
|
+
throw Error("Circular reference detected in " + path4.join("."));
|
|
56106
56531
|
}
|
|
56107
56532
|
stack.push(value);
|
|
56108
56533
|
utils$1.forEach(value, function each(el, key) {
|
|
56109
|
-
const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key) ? key.trim() : key,
|
|
56534
|
+
const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key) ? key.trim() : key, path4, exposedHelpers);
|
|
56110
56535
|
if (result === true) {
|
|
56111
|
-
build(el,
|
|
56536
|
+
build(el, path4 ? path4.concat(key) : [key]);
|
|
56112
56537
|
}
|
|
56113
56538
|
});
|
|
56114
56539
|
stack.pop();
|
|
@@ -56296,7 +56721,7 @@ var require_axios = __commonJS({
|
|
|
56296
56721
|
};
|
|
56297
56722
|
function toURLEncodedForm(data, options) {
|
|
56298
56723
|
return toFormData(data, new platform2.classes.URLSearchParams(), {
|
|
56299
|
-
visitor: function(value, key,
|
|
56724
|
+
visitor: function(value, key, path4, helpers) {
|
|
56300
56725
|
if (platform2.isNode && utils$1.isBuffer(value)) {
|
|
56301
56726
|
this.append(key, value.toString("base64"));
|
|
56302
56727
|
return false;
|
|
@@ -56324,11 +56749,11 @@ var require_axios = __commonJS({
|
|
|
56324
56749
|
return obj;
|
|
56325
56750
|
}
|
|
56326
56751
|
function formDataToJSON(formData) {
|
|
56327
|
-
function buildPath(
|
|
56328
|
-
let name =
|
|
56752
|
+
function buildPath(path4, value, target, index) {
|
|
56753
|
+
let name = path4[index++];
|
|
56329
56754
|
if (name === "__proto__") return true;
|
|
56330
56755
|
const isNumericKey = Number.isFinite(+name);
|
|
56331
|
-
const isLast = index >=
|
|
56756
|
+
const isLast = index >= path4.length;
|
|
56332
56757
|
name = !name && utils$1.isArray(target) ? target.length : name;
|
|
56333
56758
|
if (isLast) {
|
|
56334
56759
|
if (utils$1.hasOwnProp(target, name)) {
|
|
@@ -56341,7 +56766,7 @@ var require_axios = __commonJS({
|
|
|
56341
56766
|
if (!target[name] || !utils$1.isObject(target[name])) {
|
|
56342
56767
|
target[name] = [];
|
|
56343
56768
|
}
|
|
56344
|
-
const result = buildPath(
|
|
56769
|
+
const result = buildPath(path4, value, target[name], index);
|
|
56345
56770
|
if (result && utils$1.isArray(target[name])) {
|
|
56346
56771
|
target[name] = arrayToObject(target[name]);
|
|
56347
56772
|
}
|
|
@@ -57652,9 +58077,9 @@ var require_axios = __commonJS({
|
|
|
57652
58077
|
auth = urlUsername + ":" + urlPassword;
|
|
57653
58078
|
}
|
|
57654
58079
|
auth && headers.delete("authorization");
|
|
57655
|
-
let
|
|
58080
|
+
let path4;
|
|
57656
58081
|
try {
|
|
57657
|
-
|
|
58082
|
+
path4 = buildURL(
|
|
57658
58083
|
parsed.pathname + parsed.search,
|
|
57659
58084
|
config2.params,
|
|
57660
58085
|
config2.paramsSerializer
|
|
@@ -57672,7 +58097,7 @@ var require_axios = __commonJS({
|
|
|
57672
58097
|
false
|
|
57673
58098
|
);
|
|
57674
58099
|
const options = {
|
|
57675
|
-
path:
|
|
58100
|
+
path: path4,
|
|
57676
58101
|
method,
|
|
57677
58102
|
headers: headers.toJSON(),
|
|
57678
58103
|
agents: { http: config2.httpAgent, https: config2.httpsAgent },
|
|
@@ -57917,14 +58342,14 @@ var require_axios = __commonJS({
|
|
|
57917
58342
|
var cookies = platform2.hasStandardBrowserEnv ? (
|
|
57918
58343
|
// Standard browser envs support document.cookie
|
|
57919
58344
|
{
|
|
57920
|
-
write(name, value, expires,
|
|
58345
|
+
write(name, value, expires, path4, domain, secure, sameSite) {
|
|
57921
58346
|
if (typeof document === "undefined") return;
|
|
57922
58347
|
const cookie = [`${name}=${encodeURIComponent(value)}`];
|
|
57923
58348
|
if (utils$1.isNumber(expires)) {
|
|
57924
58349
|
cookie.push(`expires=${new Date(expires).toUTCString()}`);
|
|
57925
58350
|
}
|
|
57926
|
-
if (utils$1.isString(
|
|
57927
|
-
cookie.push(`path=${
|
|
58351
|
+
if (utils$1.isString(path4)) {
|
|
58352
|
+
cookie.push(`path=${path4}`);
|
|
57928
58353
|
}
|
|
57929
58354
|
if (utils$1.isString(domain)) {
|
|
57930
58355
|
cookie.push(`domain=${domain}`);
|
|
@@ -59270,7 +59695,7 @@ var init_transformers_scanner = __esm({
|
|
|
59270
59695
|
);
|
|
59271
59696
|
}
|
|
59272
59697
|
if (!this._pool) {
|
|
59273
|
-
const workerPath =
|
|
59698
|
+
const workerPath = path2__namespace.resolve(__dirname, "nlp_worker.js");
|
|
59274
59699
|
const maxThreads = Math.max(1, Math.min(os__namespace.cpus().length - 1, 4));
|
|
59275
59700
|
this._pool = new Piscina({
|
|
59276
59701
|
filename: workerPath,
|
|
@@ -59867,12 +60292,12 @@ var MaskClient = class _MaskClient {
|
|
|
59867
60292
|
*/
|
|
59868
60293
|
static async create(options = {}) {
|
|
59869
60294
|
const vault = options.vault || getVault();
|
|
59870
|
-
const
|
|
60295
|
+
const crypto7 = options.crypto || await getCryptoEngineAsync();
|
|
59871
60296
|
const scanner = options.scanner || getScanner();
|
|
59872
60297
|
const auditLogger = options.auditLogger || getAuditLogger();
|
|
59873
60298
|
return new _MaskClient({
|
|
59874
60299
|
vault,
|
|
59875
|
-
crypto:
|
|
60300
|
+
crypto: crypto7,
|
|
59876
60301
|
scanner,
|
|
59877
60302
|
auditLogger,
|
|
59878
60303
|
ttl: options.ttl
|
|
@@ -59893,7 +60318,7 @@ var MaskClient = class _MaskClient {
|
|
|
59893
60318
|
this.logger.log("encode", existingToken, "opaque");
|
|
59894
60319
|
return existingToken;
|
|
59895
60320
|
}
|
|
59896
|
-
const token = await generateFPEToken(text);
|
|
60321
|
+
const token = await exports.generateFPEToken(text);
|
|
59897
60322
|
const ciphertext = this.crypto.encrypt(text);
|
|
59898
60323
|
await this.vault.store(token, ciphertext, this.ttl, ptHash);
|
|
59899
60324
|
this.logger.log("encode", token);
|
|
@@ -60017,7 +60442,6 @@ exports.decode = decode;
|
|
|
60017
60442
|
exports.detectEntitiesWithConfidence = detectEntitiesWithConfidence;
|
|
60018
60443
|
exports.detokenizeText = detokenizeText;
|
|
60019
60444
|
exports.encode = encode;
|
|
60020
|
-
exports.generateFPEToken = generateFPEToken;
|
|
60021
60445
|
exports.getScanner = getScanner;
|
|
60022
60446
|
exports.getVault = getVault;
|
|
60023
60447
|
exports.looksLikeToken = looksLikeToken;
|