mask-privacy 4.1.0 → 4.3.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 +27 -19
- package/dist/index.d.ts +27 -19
- package/dist/index.js +351 -189
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +335 -173
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/config.ts +4 -0
- package/src/core/crypto.ts +152 -103
- package/src/core/fpe.ts +68 -33
- package/src/core/fpe_utils.ts +48 -2
- package/src/core/key_provider.ts +80 -0
- package/src/core/vault.ts +92 -67
- package/src/telemetry/audit_logger.ts +93 -15
- package/tests/bijective_fpe.test.ts +2 -2
- package/tests/compliance_pci.test.ts +53 -0
- package/tests/fpe.test.ts +2 -2
- package/tests/security_hardening.test.ts +91 -0
- package/tests/vault_backends.test.ts +7 -7
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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
6
|
var cryptoNode = require('crypto');
|
|
7
7
|
var fs = require('fs');
|
|
@@ -36,7 +36,7 @@ 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
41
|
var cryptoNode__namespace = /*#__PURE__*/_interopNamespace(cryptoNode);
|
|
42
42
|
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
@@ -129,6 +129,11 @@ var init_config = __esm({
|
|
|
129
129
|
get MASK_ENCRYPTION_KEY() {
|
|
130
130
|
return process2__namespace.env.MASK_ENCRYPTION_KEY || null;
|
|
131
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
|
+
},
|
|
132
137
|
get MASK_MASTER_KEY() {
|
|
133
138
|
return process2__namespace.env.MASK_MASTER_KEY || process2__namespace.env.MASK_ENCRYPTION_KEY || "";
|
|
134
139
|
},
|
|
@@ -160,6 +165,9 @@ var init_config = __esm({
|
|
|
160
165
|
get MASK_VAULT_CLEANUP_FREQUENCY() {
|
|
161
166
|
return getEnvFloat("MASK_VAULT_CLEANUP_FREQUENCY", 0.01);
|
|
162
167
|
},
|
|
168
|
+
get MASK_VAULT_MAX_MEMORY_KEYS() {
|
|
169
|
+
return getEnvInt("MASK_VAULT_MAX_MEMORY_KEYS", 1e5);
|
|
170
|
+
},
|
|
163
171
|
// --- BACKEND CONNECTIONS ---
|
|
164
172
|
get MASK_REDIS_URL() {
|
|
165
173
|
return process2__namespace.env.MASK_REDIS_URL || "redis://localhost:6379/0";
|
|
@@ -199,7 +207,7 @@ var init_config = __esm({
|
|
|
199
207
|
return process2__namespace.env.MASK_SCANNER_URL || "http://localhost:5001/analyze";
|
|
200
208
|
},
|
|
201
209
|
get MASK_MODEL_CACHE_DIR() {
|
|
202
|
-
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");
|
|
203
211
|
},
|
|
204
212
|
// --- TELEMETRY & AUDIT ---
|
|
205
213
|
get MASK_AUDIT_LOG_STRICT() {
|
|
@@ -224,6 +232,16 @@ var init_key_provider = __esm({
|
|
|
224
232
|
"src/core/key_provider.ts"() {
|
|
225
233
|
init_config();
|
|
226
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
|
+
}
|
|
227
245
|
};
|
|
228
246
|
EnvKeyProvider = class extends BaseKeyProvider {
|
|
229
247
|
async getEncryptionKey() {
|
|
@@ -239,6 +257,10 @@ var init_key_provider = __esm({
|
|
|
239
257
|
let key = config.MASK_MASTER_KEY;
|
|
240
258
|
return key || null;
|
|
241
259
|
}
|
|
260
|
+
/** Return MASK_KEYRING from environment (default behaviour). */
|
|
261
|
+
async getKeyring() {
|
|
262
|
+
return config.MASK_KEYRING || null;
|
|
263
|
+
}
|
|
242
264
|
};
|
|
243
265
|
providerInstance = null;
|
|
244
266
|
}
|
|
@@ -692,17 +714,34 @@ function looksLikeToken(value) {
|
|
|
692
714
|
if (v7.includes("-") && v7.length >= 6) {
|
|
693
715
|
const parts = v7.split("-");
|
|
694
716
|
const tag = parts[parts.length - 1];
|
|
695
|
-
if (tag.length
|
|
717
|
+
if (tag.length >= 3 && tag.length <= 10 && /^\d+$/.test(tag)) {
|
|
696
718
|
return true;
|
|
697
719
|
}
|
|
698
720
|
}
|
|
699
721
|
return false;
|
|
700
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,10}$/.test(v7)) return true;
|
|
738
|
+
return false;
|
|
739
|
+
}
|
|
701
740
|
var TOKEN_PATTERN;
|
|
702
741
|
var init_fpe_utils = __esm({
|
|
703
742
|
"src/core/fpe_utils.ts"() {
|
|
704
743
|
TOKEN_PATTERN = new RegExp(
|
|
705
|
-
"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,
|
|
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,10}\\b|\\[TKN-[^\\]]+\\]",
|
|
706
745
|
// Opaque
|
|
707
746
|
"g"
|
|
708
747
|
);
|
|
@@ -732,7 +771,7 @@ function resetMasterKey() {
|
|
|
732
771
|
}
|
|
733
772
|
async function _getAesKey() {
|
|
734
773
|
const masterKey = await _getMasterKey();
|
|
735
|
-
return cryptoNode__namespace.
|
|
774
|
+
return cryptoNode__namespace.createHmac("sha256", masterKey).update(config.MASK_TENANT_ID, "utf-8").digest();
|
|
736
775
|
}
|
|
737
776
|
async function _hmacHex(plaintext, n6 = 8) {
|
|
738
777
|
const masterKey = await _getMasterKey();
|
|
@@ -740,61 +779,57 @@ async function _hmacHex(plaintext, n6 = 8) {
|
|
|
740
779
|
return digest.slice(0, n6);
|
|
741
780
|
}
|
|
742
781
|
async function _getBijectiveTweak() {
|
|
743
|
-
const masterKey = await _getMasterKey();
|
|
744
|
-
let base = config.MASK_TENANT_ID;
|
|
745
782
|
if (config.MASK_SALT_ROTATION !== "NONE") {
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
} else if (config.MASK_SALT_ROTATION === "YEARLY") {
|
|
750
|
-
base += `-${now.getUTCFullYear()}`;
|
|
751
|
-
}
|
|
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
|
+
);
|
|
752
786
|
}
|
|
753
|
-
|
|
787
|
+
const masterKey = await _getMasterKey();
|
|
788
|
+
return cryptoNode__namespace.createHmac("sha256", masterKey).update(config.MASK_TENANT_ID, "utf-8").digest();
|
|
754
789
|
}
|
|
755
790
|
async function _encryptBijectiveFF1(text) {
|
|
756
791
|
const canonical = text.toLowerCase().trim();
|
|
757
792
|
const hash = cryptoNode__namespace.createHash("sha256").update(canonical, "utf-8").digest();
|
|
758
|
-
const
|
|
759
|
-
const
|
|
793
|
+
const hash128 = hash.subarray(0, 16);
|
|
794
|
+
const inputInt = hash128.readBigUInt64BE(0) << 64n | hash128.readBigUInt64BE(8);
|
|
795
|
+
const inputStr = inputInt.toString().padStart(40, "0");
|
|
760
796
|
const aesKey = await _getAesKey();
|
|
761
797
|
const tweak = await _getBijectiveTweak();
|
|
762
798
|
const engine = new FF1(aesKey, tweak, 10);
|
|
763
799
|
const cipherStr = engine.encrypt(inputStr);
|
|
764
|
-
return BigInt(cipherStr)
|
|
800
|
+
return BigInt(cipherStr);
|
|
765
801
|
}
|
|
766
802
|
function _renderBijectivePerson(bits) {
|
|
767
803
|
const firstIdx = Number(bits & 0x7FFn);
|
|
768
804
|
const connIdx = Number(bits >> 11n & 0x3Fn);
|
|
769
805
|
const rootIdx = Number(bits >> 17n & 0xFFFn);
|
|
770
806
|
const suffixIdx = Number(bits >> 29n & 0x1FFn);
|
|
771
|
-
const tag =
|
|
772
|
-
const formatIdx = Number(bits >>
|
|
807
|
+
const tag = bits >> 38n & 0xFFFFFFFFFFn;
|
|
808
|
+
const formatIdx = Number(bits >> 78n & 0xFn);
|
|
773
809
|
const first = FIRST_NAMES[firstIdx % FIRST_NAMES.length];
|
|
774
810
|
const conn = CONNECTORS[connIdx % CONNECTORS.length];
|
|
775
811
|
const root = SURNAME_ROOTS[rootIdx % SURNAME_ROOTS.length];
|
|
776
812
|
const suffix = SURNAME_SUFFIXES[suffixIdx % SURNAME_SUFFIXES.length];
|
|
777
813
|
const surname = `${root}${suffix}`;
|
|
778
|
-
const numeric = tag %
|
|
779
|
-
const paddedNumeric = numeric.toString().padStart(
|
|
814
|
+
const numeric = Number(tag % 10000000000n);
|
|
815
|
+
const paddedNumeric = numeric.toString().padStart(10, "0");
|
|
780
816
|
if (formatIdx === 0) return `${first} ${conn} ${surname}-${paddedNumeric}`;
|
|
781
817
|
if (formatIdx === 1) return `${surname}, ${first}-${paddedNumeric}`;
|
|
782
818
|
if (formatIdx === 2) return `${first[0]}. ${surname}-${paddedNumeric}`;
|
|
783
|
-
if (formatIdx === 3) return `${first} ${surname}-${paddedNumeric}`;
|
|
784
819
|
return `${first} ${surname}-${paddedNumeric}`;
|
|
785
820
|
}
|
|
786
821
|
function _renderBijectiveLocation(bits) {
|
|
787
822
|
const s1 = Number(bits & 0x3FFn);
|
|
788
823
|
const s22 = Number(bits >> 10n & 0x3FFn);
|
|
789
824
|
const s32 = Number(bits >> 20n & 0x3FFn);
|
|
790
|
-
const tag =
|
|
825
|
+
const tag = bits >> 30n & 0xFFFFFFFFFFn;
|
|
791
826
|
const city = `${SYLLABLES[s1 % 1e3]}${SYLLABLES[s22 % 1e3].toLowerCase()}${SYLLABLES[s32 % 1e3].toLowerCase()}`;
|
|
792
|
-
return `${city}-${tag.toString().padStart(
|
|
827
|
+
return `${city}-${Number(tag % 10000000000n).toString().padStart(10, "0")}`;
|
|
793
828
|
}
|
|
794
|
-
function
|
|
795
|
-
const digits =
|
|
829
|
+
function _getLuhnSum(numStr) {
|
|
830
|
+
const digits = numStr.split("").map(Number);
|
|
796
831
|
let sum = 0;
|
|
797
|
-
let shouldDouble =
|
|
832
|
+
let shouldDouble = false;
|
|
798
833
|
for (let i6 = digits.length - 1; i6 >= 0; i6--) {
|
|
799
834
|
let digit = digits[i6];
|
|
800
835
|
if (shouldDouble) {
|
|
@@ -804,7 +839,7 @@ function _computeLuhnDigit(partialNum) {
|
|
|
804
839
|
sum += digit;
|
|
805
840
|
shouldDouble = !shouldDouble;
|
|
806
841
|
}
|
|
807
|
-
return
|
|
842
|
+
return sum;
|
|
808
843
|
}
|
|
809
844
|
function _computeEsIdCheck(num) {
|
|
810
845
|
return "TRWAGMYFPDXBNJZSQVHLCKE"[num % 23];
|
|
@@ -851,14 +886,15 @@ async function generateDPToken(rawText, entityType = "UNKNOWN") {
|
|
|
851
886
|
if (type === "CREDIT_CARD" || type === "CREDIT_CARD_NUMBER") {
|
|
852
887
|
const digits = _stripCcSeparators(text);
|
|
853
888
|
if (digits.length === 16) {
|
|
854
|
-
const
|
|
855
|
-
const
|
|
856
|
-
const
|
|
889
|
+
const prefix6 = digits.slice(0, 6);
|
|
890
|
+
const suffix4 = digits.slice(12, 16);
|
|
891
|
+
const middle5 = digits.slice(6, 11);
|
|
857
892
|
const engine = new FF1(await _getAesKey(), Buffer.from("CREDIT_CARD"), 10);
|
|
858
|
-
const
|
|
859
|
-
const
|
|
860
|
-
const
|
|
861
|
-
const
|
|
893
|
+
const encMiddle5 = engine.encrypt(middle5);
|
|
894
|
+
const draft = prefix6 + encMiddle5 + "0" + suffix4;
|
|
895
|
+
const sum = _getLuhnSum(draft);
|
|
896
|
+
const correction = (10 - sum % 10) % 10;
|
|
897
|
+
const full = prefix6 + encMiddle5 + correction.toString() + suffix4;
|
|
862
898
|
return `${full.slice(0, 4)}-${full.slice(4, 8)}-${full.slice(8, 12)}-${full.slice(12, 16)}`;
|
|
863
899
|
} else {
|
|
864
900
|
const fallbackDigits = digits.padEnd(16, "0").slice(0, 16);
|
|
@@ -3349,24 +3385,28 @@ function getCryptoEngine() {
|
|
|
3349
3385
|
async function getCryptoEngineAsync() {
|
|
3350
3386
|
return await CryptoEngine.getInstanceAsync();
|
|
3351
3387
|
}
|
|
3352
|
-
var GCM_IV_BYTES, GCM_AUTH_TAG_BYTES, GCM_ALGORITHM, AES_GCM_PREFIX, _CryptoEngine, CryptoEngine;
|
|
3388
|
+
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;
|
|
3353
3389
|
var init_crypto = __esm({
|
|
3354
3390
|
"src/core/crypto.ts"() {
|
|
3355
3391
|
init_config();
|
|
3356
3392
|
init_key_provider();
|
|
3357
3393
|
init_exceptions();
|
|
3394
|
+
AES_KEY_BYTES = 32;
|
|
3358
3395
|
GCM_IV_BYTES = 12;
|
|
3359
3396
|
GCM_AUTH_TAG_BYTES = 16;
|
|
3360
3397
|
GCM_ALGORITHM = "aes-256-gcm";
|
|
3361
|
-
|
|
3398
|
+
AES_V2_PREFIX = "aes:v2:";
|
|
3399
|
+
AES_GCM_PREFIX = "aes:v1:";
|
|
3400
|
+
AES_GCM_LEGACY_PREFIX = "aes:";
|
|
3362
3401
|
_CryptoEngine = class _CryptoEngine {
|
|
3363
3402
|
constructor() {
|
|
3364
|
-
this.
|
|
3403
|
+
this._keyring = /* @__PURE__ */ new Map();
|
|
3404
|
+
this._activeKeyId = "default";
|
|
3365
3405
|
this._indexSecret = null;
|
|
3366
3406
|
}
|
|
3367
|
-
/**
|
|
3407
|
+
/**
|
|
3368
3408
|
* Return the singleton instance, initialising it if necessary.
|
|
3369
|
-
*
|
|
3409
|
+
* Async because Argon2id key derivation is async.
|
|
3370
3410
|
*/
|
|
3371
3411
|
static async getInstanceAsync() {
|
|
3372
3412
|
if (this._instance === null) {
|
|
@@ -3382,11 +3422,11 @@ var init_crypto = __esm({
|
|
|
3382
3422
|
}
|
|
3383
3423
|
return this._instance;
|
|
3384
3424
|
}
|
|
3385
|
-
/** Clear the singleton
|
|
3425
|
+
/** Clear the singleton (useful for key rotation / tests). */
|
|
3386
3426
|
static reset() {
|
|
3387
3427
|
this._instance = null;
|
|
3388
3428
|
}
|
|
3389
|
-
async
|
|
3429
|
+
async _deriveAesKey(rawKey, keyId) {
|
|
3390
3430
|
let argon2;
|
|
3391
3431
|
try {
|
|
3392
3432
|
argon2 = __require("argon2");
|
|
@@ -3395,38 +3435,72 @@ var init_crypto = __esm({
|
|
|
3395
3435
|
"The 'argon2' package is required for Mask SDK cryptographic operations. Install with: npm install argon2"
|
|
3396
3436
|
);
|
|
3397
3437
|
}
|
|
3398
|
-
const
|
|
3399
|
-
const keyFromProvider = await provider.getEncryptionKey();
|
|
3400
|
-
let key;
|
|
3401
|
-
if (!keyFromProvider) {
|
|
3402
|
-
if (config.MASK_DEV_MODE) {
|
|
3403
|
-
key = cryptoNode__namespace.randomBytes(32).toString("base64");
|
|
3404
|
-
process.env.MASK_ENCRYPTION_KEY = key;
|
|
3405
|
-
console.warn(
|
|
3406
|
-
"MASK_DEV_MODE is enabled. Using a generated throwaway key. DO NOT USE THIS IN PRODUCTION \u2014 tokens will be lost on restart."
|
|
3407
|
-
);
|
|
3408
|
-
} else {
|
|
3409
|
-
throw new Error(
|
|
3410
|
-
"MASK_ENCRYPTION_KEY is not set. Set MASK_ENCRYPTION_KEY to a valid encryption key, or set MASK_DEV_MODE=true to use an ephemeral throwaway key."
|
|
3411
|
-
);
|
|
3412
|
-
}
|
|
3413
|
-
} else {
|
|
3414
|
-
key = keyFromProvider;
|
|
3415
|
-
}
|
|
3416
|
-
const kdfSaltStr = config.MASK_KDF_SALT + "-" + config.MASK_TENANT_ID;
|
|
3438
|
+
const kdfSaltStr = config.MASK_KDF_SALT + "-" + config.MASK_TENANT_ID + "-" + keyId;
|
|
3417
3439
|
const kdfSaltBytes = cryptoNode__namespace.createHash("sha256").update(kdfSaltStr).digest().subarray(0, 16);
|
|
3418
|
-
|
|
3440
|
+
return await argon2.hash(rawKey, {
|
|
3419
3441
|
type: argon2.argon2id,
|
|
3420
3442
|
memoryCost: 19456,
|
|
3421
|
-
// 19 MiB
|
|
3422
3443
|
timeCost: 2,
|
|
3423
3444
|
parallelism: 1,
|
|
3424
|
-
hashLength:
|
|
3445
|
+
hashLength: AES_KEY_BYTES,
|
|
3425
3446
|
salt: kdfSaltBytes,
|
|
3426
3447
|
raw: true
|
|
3427
|
-
// return a Buffer, not a hash string
|
|
3428
3448
|
});
|
|
3429
|
-
|
|
3449
|
+
}
|
|
3450
|
+
async _init() {
|
|
3451
|
+
let argon2;
|
|
3452
|
+
try {
|
|
3453
|
+
argon2 = __require("argon2");
|
|
3454
|
+
} catch (e6) {
|
|
3455
|
+
throw new Error("The 'argon2' package is required. Install with: npm install argon2");
|
|
3456
|
+
}
|
|
3457
|
+
const provider = getKeyProvider();
|
|
3458
|
+
const rawKeys = /* @__PURE__ */ new Map();
|
|
3459
|
+
let activeKeyId = "default";
|
|
3460
|
+
const keyringJson = await provider.getKeyring();
|
|
3461
|
+
if (keyringJson) {
|
|
3462
|
+
let parsed;
|
|
3463
|
+
try {
|
|
3464
|
+
parsed = JSON.parse(keyringJson);
|
|
3465
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
3466
|
+
throw new Error("MASK_KEYRING must be a non-empty JSON object.");
|
|
3467
|
+
}
|
|
3468
|
+
} catch (e6) {
|
|
3469
|
+
throw new Error(`Invalid MASK_KEYRING format: ${e6}`);
|
|
3470
|
+
}
|
|
3471
|
+
const entries = Object.entries(parsed);
|
|
3472
|
+
if (entries.length === 0) throw new Error("MASK_KEYRING must contain at least one key.");
|
|
3473
|
+
for (const [kid, k6] of entries) rawKeys.set(kid, k6);
|
|
3474
|
+
activeKeyId = entries[entries.length - 1][0];
|
|
3475
|
+
} else {
|
|
3476
|
+
const keyFromProvider = await provider.getEncryptionKey();
|
|
3477
|
+
let key;
|
|
3478
|
+
if (!keyFromProvider) {
|
|
3479
|
+
if (config.MASK_DEV_MODE) {
|
|
3480
|
+
key = cryptoNode__namespace.randomBytes(32).toString("base64");
|
|
3481
|
+
process.env.MASK_ENCRYPTION_KEY = key;
|
|
3482
|
+
console.warn(
|
|
3483
|
+
"MASK_DEV_MODE is enabled. Using a generated throwaway key. DO NOT USE THIS IN PRODUCTION \u2014 tokens will be lost on restart."
|
|
3484
|
+
);
|
|
3485
|
+
} else {
|
|
3486
|
+
throw new Error(
|
|
3487
|
+
"MASK_ENCRYPTION_KEY or MASK_KEYRING is not set. Set one of these, or set MASK_DEV_MODE=true for ephemeral use."
|
|
3488
|
+
);
|
|
3489
|
+
}
|
|
3490
|
+
} else {
|
|
3491
|
+
key = keyFromProvider;
|
|
3492
|
+
}
|
|
3493
|
+
rawKeys.set("default", key);
|
|
3494
|
+
activeKeyId = "default";
|
|
3495
|
+
}
|
|
3496
|
+
this._keyring = /* @__PURE__ */ new Map();
|
|
3497
|
+
for (const [kid, rawKey] of rawKeys) {
|
|
3498
|
+
this._keyring.set(kid, await this._deriveAesKey(rawKey, kid));
|
|
3499
|
+
}
|
|
3500
|
+
this._activeKeyId = activeKeyId;
|
|
3501
|
+
const rawKeysArr = Array.from(rawKeys.values());
|
|
3502
|
+
const lastRawKey = rawKeysArr[rawKeysArr.length - 1];
|
|
3503
|
+
const masterKey = await provider.getMasterKey() || lastRawKey;
|
|
3430
3504
|
const indexSaltStr = config.MASK_BLIND_INDEX_SALT + "-" + config.MASK_TENANT_ID;
|
|
3431
3505
|
const indexSaltBytes = cryptoNode__namespace.createHash("sha256").update(indexSaltStr).digest().subarray(0, 16);
|
|
3432
3506
|
this._indexSecret = await argon2.hash(masterKey, {
|
|
@@ -3434,7 +3508,7 @@ var init_crypto = __esm({
|
|
|
3434
3508
|
memoryCost: 19456,
|
|
3435
3509
|
timeCost: 2,
|
|
3436
3510
|
parallelism: 1,
|
|
3437
|
-
hashLength:
|
|
3511
|
+
hashLength: AES_KEY_BYTES,
|
|
3438
3512
|
salt: indexSaltBytes,
|
|
3439
3513
|
raw: true
|
|
3440
3514
|
});
|
|
@@ -3446,36 +3520,56 @@ var init_crypto = __esm({
|
|
|
3446
3520
|
}
|
|
3447
3521
|
return this._indexSecret;
|
|
3448
3522
|
}
|
|
3523
|
+
/** Encrypt plaintext using the active keyring key.
|
|
3524
|
+
* Envelope format: aes:v2:{keyId}:{base64(iv+authTag+ciphertext)}
|
|
3525
|
+
*/
|
|
3449
3526
|
encrypt(plaintext) {
|
|
3450
|
-
|
|
3451
|
-
|
|
3527
|
+
const aesKey = this._keyring.get(this._activeKeyId);
|
|
3528
|
+
if (!aesKey) {
|
|
3529
|
+
throw new Error(`CryptoEngine: active key ID '${this._activeKeyId}' not found in keyring.`);
|
|
3452
3530
|
}
|
|
3453
3531
|
const iv = cryptoNode__namespace.randomBytes(GCM_IV_BYTES);
|
|
3454
|
-
const cipher = cryptoNode__namespace.createCipheriv(GCM_ALGORITHM,
|
|
3455
|
-
const
|
|
3456
|
-
|
|
3457
|
-
cipher.final()
|
|
3458
|
-
]);
|
|
3532
|
+
const cipher = cryptoNode__namespace.createCipheriv(GCM_ALGORITHM, aesKey, iv);
|
|
3533
|
+
const plaintextBuf = Buffer.from(plaintext, "utf8");
|
|
3534
|
+
const encrypted = Buffer.concat([cipher.update(plaintextBuf), cipher.final()]);
|
|
3459
3535
|
const authTag = cipher.getAuthTag();
|
|
3536
|
+
plaintextBuf.fill(0);
|
|
3460
3537
|
const combined = Buffer.concat([iv, authTag, encrypted]);
|
|
3461
|
-
return
|
|
3538
|
+
return `${AES_V2_PREFIX}${this._activeKeyId}:${combined.toString("base64")}`;
|
|
3462
3539
|
}
|
|
3540
|
+
/** Decrypt ciphertext. Supports all historical envelope formats. */
|
|
3463
3541
|
decrypt(ciphertext) {
|
|
3464
|
-
if (
|
|
3465
|
-
throw new Error("CryptoEngine not initialised.
|
|
3542
|
+
if (this._keyring.size === 0) {
|
|
3543
|
+
throw new Error("CryptoEngine not initialised.");
|
|
3466
3544
|
}
|
|
3467
3545
|
try {
|
|
3546
|
+
if (ciphertext.startsWith(AES_V2_PREFIX)) {
|
|
3547
|
+
const rest = ciphertext.slice(AES_V2_PREFIX.length);
|
|
3548
|
+
const sep3 = rest.indexOf(":");
|
|
3549
|
+
if (sep3 === -1) throw new Error("Malformed aes:v2 envelope: missing key ID separator.");
|
|
3550
|
+
const keyId = rest.slice(0, sep3);
|
|
3551
|
+
const b64 = rest.slice(sep3 + 1);
|
|
3552
|
+
return this._decryptAesGcm(keyId, b64);
|
|
3553
|
+
}
|
|
3468
3554
|
if (ciphertext.startsWith(AES_GCM_PREFIX)) {
|
|
3469
|
-
return this._decryptAesGcm(ciphertext.slice(AES_GCM_PREFIX.length));
|
|
3555
|
+
return this._decryptAesGcm("default", ciphertext.slice(AES_GCM_PREFIX.length));
|
|
3556
|
+
}
|
|
3557
|
+
if (ciphertext.startsWith(AES_GCM_LEGACY_PREFIX)) {
|
|
3558
|
+
return this._decryptAesGcm("default", ciphertext.slice(AES_GCM_LEGACY_PREFIX.length));
|
|
3470
3559
|
}
|
|
3471
3560
|
return this._decryptLegacyFernet(ciphertext);
|
|
3472
3561
|
} catch (e6) {
|
|
3473
|
-
console.error("Failed to decrypt vault payload. Check your MASK_ENCRYPTION_KEY. Inner error:", e6);
|
|
3562
|
+
console.error("Failed to decrypt vault payload. Check your MASK_ENCRYPTION_KEY / MASK_KEYRING. Inner error:", e6);
|
|
3474
3563
|
throw new exports.MaskDecryptionError("Decryption failed");
|
|
3475
3564
|
}
|
|
3476
3565
|
}
|
|
3477
|
-
|
|
3478
|
-
|
|
3566
|
+
_decryptAesGcm(keyId, b64) {
|
|
3567
|
+
const aesKey = this._keyring.get(keyId);
|
|
3568
|
+
if (!aesKey) {
|
|
3569
|
+
throw new exports.MaskDecryptionError(
|
|
3570
|
+
`No key found for key ID '${keyId}'. Ensure the key is present in MASK_KEYRING.`
|
|
3571
|
+
);
|
|
3572
|
+
}
|
|
3479
3573
|
const combined = Buffer.from(b64, "base64");
|
|
3480
3574
|
if (combined.length < GCM_IV_BYTES + GCM_AUTH_TAG_BYTES) {
|
|
3481
3575
|
throw new Error("Ciphertext too short for AES-GCM");
|
|
@@ -3483,22 +3577,11 @@ var init_crypto = __esm({
|
|
|
3483
3577
|
const iv = combined.subarray(0, GCM_IV_BYTES);
|
|
3484
3578
|
const authTag = combined.subarray(GCM_IV_BYTES, GCM_IV_BYTES + GCM_AUTH_TAG_BYTES);
|
|
3485
3579
|
const encrypted = combined.subarray(GCM_IV_BYTES + GCM_AUTH_TAG_BYTES);
|
|
3486
|
-
const decipher = cryptoNode__namespace.createDecipheriv(GCM_ALGORITHM,
|
|
3580
|
+
const decipher = cryptoNode__namespace.createDecipheriv(GCM_ALGORITHM, aesKey, iv);
|
|
3487
3581
|
decipher.setAuthTag(authTag);
|
|
3488
|
-
const decrypted = Buffer.concat([
|
|
3489
|
-
decipher.update(encrypted),
|
|
3490
|
-
decipher.final()
|
|
3491
|
-
]);
|
|
3582
|
+
const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
|
|
3492
3583
|
return decrypted.toString("utf8");
|
|
3493
3584
|
}
|
|
3494
|
-
/**
|
|
3495
|
-
* Attempt to decrypt a legacy Fernet-format token.
|
|
3496
|
-
*
|
|
3497
|
-
* Fernet format: Version (1) || Timestamp (8) || IV (16) || Ciphertext (var) || HMAC (32)
|
|
3498
|
-
* All base64url-encoded.
|
|
3499
|
-
*
|
|
3500
|
-
* We try to use the `fernet` npm package if available, otherwise throw.
|
|
3501
|
-
*/
|
|
3502
3585
|
_decryptLegacyFernet(ciphertext) {
|
|
3503
3586
|
let fernet;
|
|
3504
3587
|
try {
|
|
@@ -3559,16 +3642,15 @@ function getLogger(name) {
|
|
|
3559
3642
|
error: (...args) => _log("error", ...args)
|
|
3560
3643
|
};
|
|
3561
3644
|
}
|
|
3562
|
-
function _makeEvent(action, token, dataType, agent = "", tool = "", extra = null) {
|
|
3645
|
+
function _makeEvent(action, token, dataType, agent = "", tool = "", extra = null, instanceId = "") {
|
|
3563
3646
|
const event = {
|
|
3564
3647
|
ts: Date.now() / 1e3,
|
|
3565
3648
|
action,
|
|
3566
|
-
// "encode" | "decode" | "expired" | "error"
|
|
3567
3649
|
token,
|
|
3568
3650
|
data_type: dataType,
|
|
3569
|
-
// "email" | "phone" | "ssn" | "opaque"
|
|
3570
3651
|
agent,
|
|
3571
|
-
tool
|
|
3652
|
+
tool,
|
|
3653
|
+
instance_id: instanceId
|
|
3572
3654
|
};
|
|
3573
3655
|
if (extra) {
|
|
3574
3656
|
Object.assign(event, _deepMask(extra));
|
|
@@ -3578,7 +3660,7 @@ function _makeEvent(action, token, dataType, agent = "", tool = "", extra = null
|
|
|
3578
3660
|
function _deepMask(obj) {
|
|
3579
3661
|
if (obj === null || obj === void 0) return obj;
|
|
3580
3662
|
if (typeof obj === "string") {
|
|
3581
|
-
return
|
|
3663
|
+
return isUnambiguouslySafeToken(obj) ? obj : "[REDACTED]";
|
|
3582
3664
|
}
|
|
3583
3665
|
if (typeof obj !== "object") return obj;
|
|
3584
3666
|
if (Array.isArray(obj)) {
|
|
@@ -3614,7 +3696,8 @@ var init_audit_logger = __esm({
|
|
|
3614
3696
|
this._strictMode = config.MASK_AUDIT_LOG_STRICT;
|
|
3615
3697
|
const rawKey = process.env.MASK_MASTER_KEY || process.env.MASK_ENCRYPTION_KEY || "";
|
|
3616
3698
|
this._signingKey = cryptoNode__namespace.createHash("sha256").update(rawKey).digest();
|
|
3617
|
-
this.
|
|
3699
|
+
this._instanceId = cryptoNode__namespace.randomUUID();
|
|
3700
|
+
this._prevSig = cryptoNode__namespace.createHmac("sha256", this._signingKey).update(this._instanceId, "utf-8").digest("hex");
|
|
3618
3701
|
}
|
|
3619
3702
|
static getInstance() {
|
|
3620
3703
|
if (this._instance === null) {
|
|
@@ -3622,16 +3705,46 @@ var init_audit_logger = __esm({
|
|
|
3622
3705
|
}
|
|
3623
3706
|
return this._instance;
|
|
3624
3707
|
}
|
|
3708
|
+
_getOverflowPath() {
|
|
3709
|
+
const d6 = process.env.MASK_SECURE_AUDIT_LOG_DIR || __require("os").tmpdir();
|
|
3710
|
+
return path2__namespace.join(d6, `mask_audit_overflow_${this._instanceId}.ndjson`);
|
|
3711
|
+
}
|
|
3712
|
+
_writeOverflow(event) {
|
|
3713
|
+
try {
|
|
3714
|
+
fs__namespace.appendFileSync(this._getOverflowPath(), JSON.stringify(event) + "\n", "utf-8");
|
|
3715
|
+
} catch {
|
|
3716
|
+
}
|
|
3717
|
+
}
|
|
3718
|
+
_consumeOverflow(events) {
|
|
3719
|
+
const overflowPath = this._getOverflowPath();
|
|
3720
|
+
if (!fs__namespace.existsSync(overflowPath)) return;
|
|
3721
|
+
const processingPath = overflowPath + ".processing";
|
|
3722
|
+
try {
|
|
3723
|
+
fs__namespace.renameSync(overflowPath, processingPath);
|
|
3724
|
+
} catch {
|
|
3725
|
+
return;
|
|
3726
|
+
}
|
|
3727
|
+
try {
|
|
3728
|
+
const content = fs__namespace.readFileSync(processingPath, "utf-8");
|
|
3729
|
+
for (const line of content.split("\n")) {
|
|
3730
|
+
if (line.trim()) events.push(JSON.parse(line));
|
|
3731
|
+
}
|
|
3732
|
+
fs__namespace.unlinkSync(processingPath);
|
|
3733
|
+
} catch (e6) {
|
|
3734
|
+
_logger.error(`Failed to consume overflow: ${e6}`);
|
|
3735
|
+
}
|
|
3736
|
+
}
|
|
3625
3737
|
log(action, token, dataType = "opaque", agent = "", tool = "", extra = {}) {
|
|
3626
|
-
const event = _makeEvent(action, token, dataType, agent, tool, extra);
|
|
3738
|
+
const event = _makeEvent(action, token, dataType, agent, tool, extra, this._instanceId);
|
|
3627
3739
|
if (this._buffer.length >= this._maxBufferSize) {
|
|
3628
3740
|
if (!this._bufferFullWarned) {
|
|
3629
3741
|
_logger.warn(
|
|
3630
|
-
`AuditLogger buffer full (max=${this._maxBufferSize}).
|
|
3742
|
+
`AuditLogger buffer full (max=${this._maxBufferSize}). Spooling to disk overflow to prevent OOM.`
|
|
3631
3743
|
);
|
|
3632
3744
|
this._bufferFullWarned = true;
|
|
3633
3745
|
}
|
|
3634
|
-
this.
|
|
3746
|
+
this._writeOverflow(event);
|
|
3747
|
+
return;
|
|
3635
3748
|
}
|
|
3636
3749
|
this._buffer.push(event);
|
|
3637
3750
|
}
|
|
@@ -3661,18 +3774,20 @@ var init_audit_logger = __esm({
|
|
|
3661
3774
|
await this._flush();
|
|
3662
3775
|
}
|
|
3663
3776
|
async _flush() {
|
|
3664
|
-
if (this._isFlushing
|
|
3777
|
+
if (this._isFlushing) return;
|
|
3665
3778
|
this._isFlushing = true;
|
|
3666
3779
|
try {
|
|
3667
3780
|
const events = [...this._buffer];
|
|
3668
3781
|
this._buffer = [];
|
|
3669
3782
|
this._bufferFullWarned = false;
|
|
3783
|
+
this._consumeOverflow(events);
|
|
3784
|
+
if (events.length === 0) return;
|
|
3670
3785
|
const secureLogDir = process.env.MASK_SECURE_AUDIT_LOG_DIR || "";
|
|
3671
3786
|
let secureStream = null;
|
|
3672
3787
|
if (secureLogDir) {
|
|
3673
3788
|
fs__namespace.mkdirSync(secureLogDir, { recursive: true });
|
|
3674
3789
|
const dateStr = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
3675
|
-
const filePath =
|
|
3790
|
+
const filePath = path2__namespace.join(secureLogDir, `mask-audit-${dateStr}.ndjson`);
|
|
3676
3791
|
try {
|
|
3677
3792
|
secureStream = fs__namespace.createWriteStream(filePath, { flags: "a" });
|
|
3678
3793
|
} catch {
|
|
@@ -3700,13 +3815,43 @@ var init_audit_logger = __esm({
|
|
|
3700
3815
|
this._isFlushing = false;
|
|
3701
3816
|
}
|
|
3702
3817
|
}
|
|
3703
|
-
/** Synchronous flush for use in signal handlers where async is unreliable.
|
|
3818
|
+
/** Synchronous flush for use in signal handlers where async is unreliable.
|
|
3819
|
+
*
|
|
3820
|
+
* Computes HMAC signatures to maintain chain integrity and writes to the
|
|
3821
|
+
* secure ndjson audit file (MASK_SECURE_AUDIT_LOG_DIR) if configured,
|
|
3822
|
+
* ensuring SOC 2 tamper-evidence guarantees hold through process shutdown.
|
|
3823
|
+
*/
|
|
3704
3824
|
_flushSync() {
|
|
3705
3825
|
if (this._buffer.length === 0) return;
|
|
3706
3826
|
const events = [...this._buffer];
|
|
3707
3827
|
this._buffer = [];
|
|
3828
|
+
const secureLogDir = process.env.MASK_SECURE_AUDIT_LOG_DIR || "";
|
|
3829
|
+
let secureFilePath = null;
|
|
3830
|
+
if (secureLogDir) {
|
|
3831
|
+
try {
|
|
3832
|
+
fs__namespace.mkdirSync(secureLogDir, { recursive: true });
|
|
3833
|
+
const dateStr = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
3834
|
+
secureFilePath = path2__namespace.join(secureLogDir, `mask-audit-${dateStr}.ndjson`);
|
|
3835
|
+
} catch {
|
|
3836
|
+
}
|
|
3837
|
+
}
|
|
3708
3838
|
for (const evt of events) {
|
|
3709
|
-
|
|
3839
|
+
const body = JSON.stringify(evt, (_, v7) => typeof v7 === "bigint" ? v7.toString() : v7);
|
|
3840
|
+
const sigInput = Buffer.from(this._prevSig + body, "utf-8");
|
|
3841
|
+
const sig = cryptoNode__namespace.createHmac("sha256", this._signingKey).update(sigInput).digest("hex");
|
|
3842
|
+
const signedLine = JSON.stringify({
|
|
3843
|
+
...evt,
|
|
3844
|
+
prev_sig: this._prevSig,
|
|
3845
|
+
sig
|
|
3846
|
+
}, (_, v7) => typeof v7 === "bigint" ? v7.toString() : v7);
|
|
3847
|
+
this._prevSig = sig;
|
|
3848
|
+
process.stdout.write(signedLine + "\n");
|
|
3849
|
+
if (secureFilePath) {
|
|
3850
|
+
try {
|
|
3851
|
+
fs__namespace.appendFileSync(secureFilePath, signedLine + "\n", { encoding: "utf-8" });
|
|
3852
|
+
} catch {
|
|
3853
|
+
}
|
|
3854
|
+
}
|
|
3710
3855
|
}
|
|
3711
3856
|
}
|
|
3712
3857
|
};
|
|
@@ -18299,10 +18444,10 @@ var init_date_utils = __esm({
|
|
|
18299
18444
|
};
|
|
18300
18445
|
}
|
|
18301
18446
|
});
|
|
18302
|
-
var
|
|
18447
|
+
var randomUUID2;
|
|
18303
18448
|
var init_randomUUID = __esm({
|
|
18304
18449
|
"node_modules/@smithy/uuid/dist-es/randomUUID.js"() {
|
|
18305
|
-
|
|
18450
|
+
randomUUID2 = cryptoNode__namespace.default.randomUUID.bind(cryptoNode__namespace.default);
|
|
18306
18451
|
}
|
|
18307
18452
|
});
|
|
18308
18453
|
|
|
@@ -18313,8 +18458,8 @@ var init_v4 = __esm({
|
|
|
18313
18458
|
init_randomUUID();
|
|
18314
18459
|
decimalToHex = Array.from({ length: 256 }, (_, i6) => i6.toString(16).padStart(2, "0"));
|
|
18315
18460
|
v4 = () => {
|
|
18316
|
-
if (
|
|
18317
|
-
return
|
|
18461
|
+
if (randomUUID2) {
|
|
18462
|
+
return randomUUID2();
|
|
18318
18463
|
}
|
|
18319
18464
|
const rnds = new Uint8Array(16);
|
|
18320
18465
|
crypto.getRandomValues(rnds);
|
|
@@ -27993,7 +28138,7 @@ var init_getHomeDir = __esm({
|
|
|
27993
28138
|
return "DEFAULT";
|
|
27994
28139
|
};
|
|
27995
28140
|
getHomeDir = () => {
|
|
27996
|
-
const { HOME, USERPROFILE, HOMEPATH, HOMEDRIVE = `C:${
|
|
28141
|
+
const { HOME, USERPROFILE, HOMEPATH, HOMEDRIVE = `C:${path2.sep}` } = process.env;
|
|
27997
28142
|
if (HOME)
|
|
27998
28143
|
return HOME;
|
|
27999
28144
|
if (USERPROFILE)
|
|
@@ -28024,7 +28169,7 @@ var init_getSSOTokenFilepath = __esm({
|
|
|
28024
28169
|
getSSOTokenFilepath = (id) => {
|
|
28025
28170
|
const hasher = cryptoNode.createHash("sha1");
|
|
28026
28171
|
const cacheName = hasher.update(id).digest("hex");
|
|
28027
|
-
return
|
|
28172
|
+
return path2.join(getHomeDir(), ".aws", "sso", "cache", `${cacheName}.json`);
|
|
28028
28173
|
};
|
|
28029
28174
|
}
|
|
28030
28175
|
});
|
|
@@ -28079,7 +28224,7 @@ var init_getConfigFilepath = __esm({
|
|
|
28079
28224
|
"node_modules/@smithy/shared-ini-file-loader/dist-es/getConfigFilepath.js"() {
|
|
28080
28225
|
init_getHomeDir();
|
|
28081
28226
|
ENV_CONFIG_PATH = "AWS_CONFIG_FILE";
|
|
28082
|
-
getConfigFilepath = () => process.env[ENV_CONFIG_PATH] ||
|
|
28227
|
+
getConfigFilepath = () => process.env[ENV_CONFIG_PATH] || path2.join(getHomeDir(), ".aws", "config");
|
|
28083
28228
|
}
|
|
28084
28229
|
});
|
|
28085
28230
|
var ENV_CREDENTIALS_PATH, getCredentialsFilepath;
|
|
@@ -28087,7 +28232,7 @@ var init_getCredentialsFilepath = __esm({
|
|
|
28087
28232
|
"node_modules/@smithy/shared-ini-file-loader/dist-es/getCredentialsFilepath.js"() {
|
|
28088
28233
|
init_getHomeDir();
|
|
28089
28234
|
ENV_CREDENTIALS_PATH = "AWS_SHARED_CREDENTIALS_FILE";
|
|
28090
|
-
getCredentialsFilepath = () => process.env[ENV_CREDENTIALS_PATH] ||
|
|
28235
|
+
getCredentialsFilepath = () => process.env[ENV_CREDENTIALS_PATH] || path2.join(getHomeDir(), ".aws", "credentials");
|
|
28091
28236
|
}
|
|
28092
28237
|
});
|
|
28093
28238
|
|
|
@@ -28179,11 +28324,11 @@ var init_loadSharedConfigFiles = __esm({
|
|
|
28179
28324
|
const relativeHomeDirPrefix = "~/";
|
|
28180
28325
|
let resolvedFilepath = filepath;
|
|
28181
28326
|
if (filepath.startsWith(relativeHomeDirPrefix)) {
|
|
28182
|
-
resolvedFilepath =
|
|
28327
|
+
resolvedFilepath = path2.join(homeDir, filepath.slice(2));
|
|
28183
28328
|
}
|
|
28184
28329
|
let resolvedConfigFilepath = configFilepath;
|
|
28185
28330
|
if (configFilepath.startsWith(relativeHomeDirPrefix)) {
|
|
28186
|
-
resolvedConfigFilepath =
|
|
28331
|
+
resolvedConfigFilepath = path2.join(homeDir, configFilepath.slice(2));
|
|
28187
28332
|
}
|
|
28188
28333
|
const parsedFiles = await Promise.all([
|
|
28189
28334
|
readFile2(resolvedConfigFilepath, {
|
|
@@ -34448,10 +34593,10 @@ var init_getNodeModulesParentDirs = __esm({
|
|
|
34448
34593
|
if (!dirname2) {
|
|
34449
34594
|
return [cwd];
|
|
34450
34595
|
}
|
|
34451
|
-
const normalizedPath =
|
|
34452
|
-
const parts = normalizedPath.split(
|
|
34596
|
+
const normalizedPath = path2.normalize(dirname2);
|
|
34597
|
+
const parts = normalizedPath.split(path2.sep);
|
|
34453
34598
|
const nodeModulesIndex = parts.indexOf("node_modules");
|
|
34454
|
-
const parentDir = nodeModulesIndex !== -1 ? parts.slice(0, nodeModulesIndex).join(
|
|
34599
|
+
const parentDir = nodeModulesIndex !== -1 ? parts.slice(0, nodeModulesIndex).join(path2.sep) : normalizedPath;
|
|
34455
34600
|
if (cwd === parentDir) {
|
|
34456
34601
|
return [cwd];
|
|
34457
34602
|
}
|
|
@@ -34503,7 +34648,7 @@ var init_getTypeScriptUserAgentPair = __esm({
|
|
|
34503
34648
|
init_getNodeModulesParentDirs();
|
|
34504
34649
|
init_getSanitizedDevTypeScriptVersion();
|
|
34505
34650
|
init_getSanitizedTypeScriptVersion();
|
|
34506
|
-
TS_PACKAGE_JSON =
|
|
34651
|
+
TS_PACKAGE_JSON = path2.join("node_modules", "typescript", "package.json");
|
|
34507
34652
|
getTypeScriptUserAgentPair = async () => {
|
|
34508
34653
|
if (tscVersion === null) {
|
|
34509
34654
|
return void 0;
|
|
@@ -34524,7 +34669,7 @@ var init_getTypeScriptUserAgentPair = __esm({
|
|
|
34524
34669
|
let versionFromApp;
|
|
34525
34670
|
for (const nodeModulesParentDir of nodeModulesParentDirs) {
|
|
34526
34671
|
try {
|
|
34527
|
-
const appPackageJsonPath =
|
|
34672
|
+
const appPackageJsonPath = path2.join(nodeModulesParentDir, "package.json");
|
|
34528
34673
|
const packageJson = await fs2.readFile(appPackageJsonPath, "utf-8");
|
|
34529
34674
|
const { dependencies, devDependencies } = JSON.parse(packageJson);
|
|
34530
34675
|
const version = devDependencies?.typescript ?? dependencies?.typescript;
|
|
@@ -34543,7 +34688,7 @@ var init_getTypeScriptUserAgentPair = __esm({
|
|
|
34543
34688
|
let versionFromNodeModules;
|
|
34544
34689
|
for (const nodeModulesParentDir of nodeModulesParentDirs) {
|
|
34545
34690
|
try {
|
|
34546
|
-
const tsPackageJsonPath =
|
|
34691
|
+
const tsPackageJsonPath = path2.join(nodeModulesParentDir, TS_PACKAGE_JSON);
|
|
34547
34692
|
const packageJson = await fs2.readFile(tsPackageJsonPath, "utf-8");
|
|
34548
34693
|
const { version } = JSON.parse(packageJson);
|
|
34549
34694
|
const sanitizedVersion2 = getSanitizedTypeScriptVersion(version);
|
|
@@ -38912,7 +39057,7 @@ var init_LoginCredentialsFetcher = __esm({
|
|
|
38912
39057
|
}
|
|
38913
39058
|
async saveToken(token) {
|
|
38914
39059
|
const tokenFilePath = this.getTokenFilePath();
|
|
38915
|
-
const directory =
|
|
39060
|
+
const directory = path2.dirname(tokenFilePath);
|
|
38916
39061
|
try {
|
|
38917
39062
|
await fs.promises.mkdir(directory, { recursive: true });
|
|
38918
39063
|
} catch (error) {
|
|
@@ -38920,10 +39065,10 @@ var init_LoginCredentialsFetcher = __esm({
|
|
|
38920
39065
|
await fs.promises.writeFile(tokenFilePath, JSON.stringify(token, null, 2), "utf8");
|
|
38921
39066
|
}
|
|
38922
39067
|
getTokenFilePath() {
|
|
38923
|
-
const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ??
|
|
39068
|
+
const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ?? path2.join(os.homedir(), ".aws", "login", "cache");
|
|
38924
39069
|
const loginSessionBytes = Buffer.from(this.loginSession, "utf8");
|
|
38925
39070
|
const loginSessionSha256 = cryptoNode.createHash("sha256").update(loginSessionBytes).digest("hex");
|
|
38926
|
-
return
|
|
39071
|
+
return path2.join(directory, `${loginSessionSha256}.json`);
|
|
38927
39072
|
}
|
|
38928
39073
|
derToRawSignature(derSignature) {
|
|
38929
39074
|
let offset = 2;
|
|
@@ -43542,6 +43687,25 @@ function _hashPlaintext(plaintext, secret) {
|
|
|
43542
43687
|
}
|
|
43543
43688
|
return cryptoNode__namespace.createHash("sha256").update(trimmed, "utf-8").digest("hex");
|
|
43544
43689
|
}
|
|
43690
|
+
function _vaultKey(token) {
|
|
43691
|
+
return `mask:${config.MASK_TENANT_ID}:${token}`;
|
|
43692
|
+
}
|
|
43693
|
+
function _vaultRevKey(ptHash) {
|
|
43694
|
+
return `mask-rev:${config.MASK_TENANT_ID}:${ptHash}`;
|
|
43695
|
+
}
|
|
43696
|
+
function _vaultHashKey(token) {
|
|
43697
|
+
return `mask-hash:${config.MASK_TENANT_ID}:${token}`;
|
|
43698
|
+
}
|
|
43699
|
+
function _unwrapPayload(raw) {
|
|
43700
|
+
if (raw && raw.startsWith("{")) {
|
|
43701
|
+
try {
|
|
43702
|
+
const obj = JSON.parse(raw);
|
|
43703
|
+
if (obj.ct) return obj.ct;
|
|
43704
|
+
} catch {
|
|
43705
|
+
}
|
|
43706
|
+
}
|
|
43707
|
+
return raw;
|
|
43708
|
+
}
|
|
43545
43709
|
function getVault() {
|
|
43546
43710
|
if (_vaultInstance === null) {
|
|
43547
43711
|
const vaultType = config.MASK_VAULT_TYPE;
|
|
@@ -43666,14 +43830,15 @@ var init_vault = __esm({
|
|
|
43666
43830
|
MemoryVault = class extends BaseVault {
|
|
43667
43831
|
constructor() {
|
|
43668
43832
|
super();
|
|
43833
|
+
this._cleanupTimer = null;
|
|
43669
43834
|
this._store = /* @__PURE__ */ new Map();
|
|
43670
43835
|
this._reverseStore = /* @__PURE__ */ new Map();
|
|
43836
|
+
this._cleanupTimer = setInterval(() => this._cleanup(), 6e4);
|
|
43837
|
+
if (this._cleanupTimer && typeof this._cleanupTimer.unref === "function") {
|
|
43838
|
+
this._cleanupTimer.unref();
|
|
43839
|
+
}
|
|
43671
43840
|
}
|
|
43672
43841
|
_cleanup() {
|
|
43673
|
-
const cleanupFreq = config.MASK_VAULT_CLEANUP_FREQUENCY;
|
|
43674
|
-
if (Math.random() > cleanupFreq) {
|
|
43675
|
-
return;
|
|
43676
|
-
}
|
|
43677
43842
|
const now = Date.now() / 1e3;
|
|
43678
43843
|
for (const [token, entry] of this._store.entries()) {
|
|
43679
43844
|
if (now > entry.expiry) {
|
|
@@ -43685,8 +43850,18 @@ var init_vault = __esm({
|
|
|
43685
43850
|
}
|
|
43686
43851
|
}
|
|
43687
43852
|
async store(token, ciphertext, ttlSeconds, ptHash = null, metadata = null) {
|
|
43688
|
-
this.
|
|
43853
|
+
if (!this._store.has(token) && this._store.size >= config.MASK_VAULT_MAX_MEMORY_KEYS) {
|
|
43854
|
+
const firstKey = this._store.keys().next().value;
|
|
43855
|
+
if (firstKey !== void 0) {
|
|
43856
|
+
const oldEntry = this._store.get(firstKey);
|
|
43857
|
+
this._store.delete(firstKey);
|
|
43858
|
+
if (oldEntry?.ptHash && this._reverseStore.get(oldEntry.ptHash) === firstKey) {
|
|
43859
|
+
this._reverseStore.delete(oldEntry.ptHash);
|
|
43860
|
+
}
|
|
43861
|
+
}
|
|
43862
|
+
}
|
|
43689
43863
|
const existing = this._store.get(token);
|
|
43864
|
+
if (existing) this._store.delete(token);
|
|
43690
43865
|
this._store.set(token, {
|
|
43691
43866
|
plaintext: ciphertext,
|
|
43692
43867
|
expiry: Date.now() / 1e3 + ttlSeconds,
|
|
@@ -43698,7 +43873,6 @@ var init_vault = __esm({
|
|
|
43698
43873
|
}
|
|
43699
43874
|
}
|
|
43700
43875
|
async getTokenByPlaintextHash(ptHash) {
|
|
43701
|
-
this._cleanup();
|
|
43702
43876
|
const token = this._reverseStore.get(ptHash);
|
|
43703
43877
|
if (token && this._store.has(token)) {
|
|
43704
43878
|
return token;
|
|
@@ -43710,7 +43884,6 @@ var init_vault = __esm({
|
|
|
43710
43884
|
return entry?.ptHash ?? null;
|
|
43711
43885
|
}
|
|
43712
43886
|
async retrieve(token) {
|
|
43713
|
-
this._cleanup();
|
|
43714
43887
|
const entry = this._store.get(token);
|
|
43715
43888
|
if (!entry) {
|
|
43716
43889
|
return null;
|
|
@@ -43770,10 +43943,10 @@ var init_vault = __esm({
|
|
|
43770
43943
|
try {
|
|
43771
43944
|
const pipeline = this._client.pipeline();
|
|
43772
43945
|
const payload = metadata ? JSON.stringify({ ct: ciphertext, meta: metadata }) : ciphertext;
|
|
43773
|
-
pipeline.set(
|
|
43946
|
+
pipeline.set(_vaultKey(token), payload, "EX", ttlSeconds);
|
|
43774
43947
|
if (ptHash) {
|
|
43775
|
-
pipeline.set(
|
|
43776
|
-
pipeline.set(
|
|
43948
|
+
pipeline.set(_vaultRevKey(ptHash), token, "EX", ttlSeconds);
|
|
43949
|
+
pipeline.set(_vaultHashKey(token), ptHash, "EX", ttlSeconds);
|
|
43777
43950
|
}
|
|
43778
43951
|
const results = await pipeline.exec();
|
|
43779
43952
|
if (results) {
|
|
@@ -43787,19 +43960,19 @@ var init_vault = __esm({
|
|
|
43787
43960
|
}
|
|
43788
43961
|
async getPtHashForToken(token) {
|
|
43789
43962
|
try {
|
|
43790
|
-
return await this._client.get(
|
|
43963
|
+
return await this._client.get(_vaultHashKey(token));
|
|
43791
43964
|
} catch {
|
|
43792
43965
|
return null;
|
|
43793
43966
|
}
|
|
43794
43967
|
}
|
|
43795
43968
|
async getTokenByPlaintextHash(ptHash) {
|
|
43796
43969
|
try {
|
|
43797
|
-
const token = await this._client.get(
|
|
43970
|
+
const token = await this._client.get(_vaultRevKey(ptHash));
|
|
43798
43971
|
if (token) {
|
|
43799
|
-
if (await this._client.exists(
|
|
43972
|
+
if (await this._client.exists(_vaultKey(token))) {
|
|
43800
43973
|
return token;
|
|
43801
43974
|
} else {
|
|
43802
|
-
await this._client.del(
|
|
43975
|
+
await this._client.del(_vaultRevKey(ptHash));
|
|
43803
43976
|
}
|
|
43804
43977
|
}
|
|
43805
43978
|
return null;
|
|
@@ -43812,7 +43985,8 @@ var init_vault = __esm({
|
|
|
43812
43985
|
}
|
|
43813
43986
|
async retrieve(token) {
|
|
43814
43987
|
try {
|
|
43815
|
-
|
|
43988
|
+
const raw = await this._client.get(_vaultKey(token));
|
|
43989
|
+
return raw ? _unwrapPayload(raw) : null;
|
|
43816
43990
|
} catch (e6) {
|
|
43817
43991
|
if (_getFailStrategy() === "closed") {
|
|
43818
43992
|
throw new exports.MaskVaultConnectionError(`Redis read failed: ${e6}`);
|
|
@@ -43822,12 +43996,12 @@ var init_vault = __esm({
|
|
|
43822
43996
|
}
|
|
43823
43997
|
async delete(token) {
|
|
43824
43998
|
try {
|
|
43825
|
-
const ptHash = await this._client.get(
|
|
43999
|
+
const ptHash = await this._client.get(_vaultHashKey(token));
|
|
43826
44000
|
const pipeline = this._client.pipeline();
|
|
43827
|
-
pipeline.del(
|
|
43828
|
-
pipeline.del(
|
|
44001
|
+
pipeline.del(_vaultKey(token));
|
|
44002
|
+
pipeline.del(_vaultHashKey(token));
|
|
43829
44003
|
if (ptHash) {
|
|
43830
|
-
pipeline.del(
|
|
44004
|
+
pipeline.del(_vaultRevKey(ptHash));
|
|
43831
44005
|
}
|
|
43832
44006
|
await pipeline.exec();
|
|
43833
44007
|
} catch (e6) {
|
|
@@ -43866,39 +44040,26 @@ var init_vault = __esm({
|
|
|
43866
44040
|
this._client = DynamoDBDocument.from(baseClient);
|
|
43867
44041
|
console.info(`DynamoDBVault connected to table ${this._tableName} in ${this._region}`);
|
|
43868
44042
|
}
|
|
43869
|
-
async store(token, ciphertext, ttlSeconds, ptHash = null) {
|
|
44043
|
+
async store(token, ciphertext, ttlSeconds, ptHash = null, metadata = null) {
|
|
43870
44044
|
const { TransactWriteCommand, PutCommand } = __require("@aws-sdk/lib-dynamodb");
|
|
43871
44045
|
const now = Math.floor(Date.now() / 1e3);
|
|
43872
44046
|
const ttlVal = now + ttlSeconds;
|
|
43873
|
-
const
|
|
43874
|
-
token:
|
|
44047
|
+
const primaryItem = {
|
|
44048
|
+
token: _vaultKey(token),
|
|
43875
44049
|
ciphertext,
|
|
43876
|
-
ttl: ttlVal
|
|
43877
|
-
ptr_hash: ptHash || void 0
|
|
44050
|
+
ttl: ttlVal
|
|
43878
44051
|
};
|
|
44052
|
+
if (ptHash) primaryItem.ptr_hash = ptHash;
|
|
44053
|
+
if (metadata) primaryItem.meta_json = JSON.stringify(metadata);
|
|
43879
44054
|
if (ptHash) {
|
|
43880
44055
|
try {
|
|
43881
44056
|
await this._client.send(new TransactWriteCommand({
|
|
43882
44057
|
TransactItems: [
|
|
44058
|
+
{ Put: { TableName: this._tableName, Item: primaryItem } },
|
|
43883
44059
|
{
|
|
43884
44060
|
Put: {
|
|
43885
44061
|
TableName: this._tableName,
|
|
43886
|
-
Item: {
|
|
43887
|
-
token: `mask:${token}`,
|
|
43888
|
-
ciphertext,
|
|
43889
|
-
ttl: ttlVal,
|
|
43890
|
-
ptr_hash: ptHash
|
|
43891
|
-
}
|
|
43892
|
-
}
|
|
43893
|
-
},
|
|
43894
|
-
{
|
|
43895
|
-
Put: {
|
|
43896
|
-
TableName: this._tableName,
|
|
43897
|
-
Item: {
|
|
43898
|
-
token: `mask-rev:${ptHash}`,
|
|
43899
|
-
ciphertext: token,
|
|
43900
|
-
ttl: ttlVal
|
|
43901
|
-
}
|
|
44062
|
+
Item: { token: _vaultRevKey(ptHash), ciphertext: token, ttl: ttlVal }
|
|
43902
44063
|
}
|
|
43903
44064
|
}
|
|
43904
44065
|
]
|
|
@@ -43909,7 +44070,7 @@ var init_vault = __esm({
|
|
|
43909
44070
|
}
|
|
43910
44071
|
} else {
|
|
43911
44072
|
try {
|
|
43912
|
-
await this._client.send(new PutCommand({ TableName: this._tableName, Item:
|
|
44073
|
+
await this._client.send(new PutCommand({ TableName: this._tableName, Item: primaryItem }));
|
|
43913
44074
|
} catch (e6) {
|
|
43914
44075
|
throw new exports.MaskVaultConnectionError(`DynamoDB individual write failed: ${e6}`);
|
|
43915
44076
|
}
|
|
@@ -43921,12 +44082,12 @@ var init_vault = __esm({
|
|
|
43921
44082
|
const now = Math.floor(Date.now() / 1e3);
|
|
43922
44083
|
const resp = await this._client.send(new GetCommand({
|
|
43923
44084
|
TableName: this._tableName,
|
|
43924
|
-
Key: { token:
|
|
44085
|
+
Key: { token: _vaultRevKey(ptHash) }
|
|
43925
44086
|
}));
|
|
43926
44087
|
const item = resp.Item;
|
|
43927
44088
|
if (!item) return null;
|
|
43928
44089
|
if (now > (item.ttl || 0)) {
|
|
43929
|
-
await this._client.send(new DeleteCommand({ TableName: this._tableName, Key: { token:
|
|
44090
|
+
await this._client.send(new DeleteCommand({ TableName: this._tableName, Key: { token: _vaultRevKey(ptHash) } }));
|
|
43930
44091
|
return null;
|
|
43931
44092
|
}
|
|
43932
44093
|
const token = item.ciphertext;
|
|
@@ -43942,16 +44103,16 @@ var init_vault = __esm({
|
|
|
43942
44103
|
const now = Math.floor(Date.now() / 1e3);
|
|
43943
44104
|
const resp = await this._client.send(new GetCommand({
|
|
43944
44105
|
TableName: this._tableName,
|
|
43945
|
-
Key: { token:
|
|
44106
|
+
Key: { token: _vaultKey(token) }
|
|
43946
44107
|
}));
|
|
43947
44108
|
const item = resp.Item;
|
|
43948
44109
|
if (!item) return null;
|
|
43949
44110
|
if (now > (item.ttl || 0)) {
|
|
43950
44111
|
const ptHash = item.ptr_hash;
|
|
43951
44112
|
if (ptHash) {
|
|
43952
|
-
await this._client.send(new DeleteCommand({ TableName: this._tableName, Key: { token:
|
|
44113
|
+
await this._client.send(new DeleteCommand({ TableName: this._tableName, Key: { token: _vaultRevKey(ptHash) } }));
|
|
43953
44114
|
}
|
|
43954
|
-
await this._client.send(new DeleteCommand({ TableName: this._tableName, Key: { token:
|
|
44115
|
+
await this._client.send(new DeleteCommand({ TableName: this._tableName, Key: { token: _vaultKey(token) } }));
|
|
43955
44116
|
return null;
|
|
43956
44117
|
}
|
|
43957
44118
|
return item.ciphertext;
|
|
@@ -43965,7 +44126,7 @@ var init_vault = __esm({
|
|
|
43965
44126
|
const { GetCommand } = __require("@aws-sdk/lib-dynamodb");
|
|
43966
44127
|
const resp = await this._client.send(new GetCommand({
|
|
43967
44128
|
TableName: this._tableName,
|
|
43968
|
-
Key: { token:
|
|
44129
|
+
Key: { token: _vaultKey(token) }
|
|
43969
44130
|
}));
|
|
43970
44131
|
return resp.Item?.ptr_hash ?? null;
|
|
43971
44132
|
} catch {
|
|
@@ -43977,13 +44138,13 @@ var init_vault = __esm({
|
|
|
43977
44138
|
const { GetCommand, DeleteCommand } = __require("@aws-sdk/lib-dynamodb");
|
|
43978
44139
|
const resp = await this._client.send(new GetCommand({
|
|
43979
44140
|
TableName: this._tableName,
|
|
43980
|
-
Key: { token:
|
|
44141
|
+
Key: { token: _vaultKey(token) }
|
|
43981
44142
|
}));
|
|
43982
44143
|
const item = resp.Item;
|
|
43983
44144
|
if (item && item.ptr_hash) {
|
|
43984
|
-
await this._client.send(new DeleteCommand({ TableName: this._tableName, Key: { token:
|
|
44145
|
+
await this._client.send(new DeleteCommand({ TableName: this._tableName, Key: { token: _vaultRevKey(item.ptr_hash) } }));
|
|
43985
44146
|
}
|
|
43986
|
-
await this._client.send(new DeleteCommand({ TableName: this._tableName, Key: { token:
|
|
44147
|
+
await this._client.send(new DeleteCommand({ TableName: this._tableName, Key: { token: _vaultKey(token) } }));
|
|
43987
44148
|
} catch (e6) {
|
|
43988
44149
|
if (_getFailStrategy() === "closed") throw new exports.MaskVaultConnectionError(`DynamoDB delete failed: ${e6}`);
|
|
43989
44150
|
}
|
|
@@ -44005,10 +44166,10 @@ var init_vault = __esm({
|
|
|
44005
44166
|
async store(token, ciphertext, ttlSeconds, ptHash = null, metadata = null) {
|
|
44006
44167
|
try {
|
|
44007
44168
|
const payload = metadata ? JSON.stringify({ ct: ciphertext, meta: metadata }) : ciphertext;
|
|
44008
|
-
await this._client.set(
|
|
44169
|
+
await this._client.set(_vaultKey(token), Buffer.from(payload), { expires: ttlSeconds });
|
|
44009
44170
|
if (ptHash) {
|
|
44010
|
-
await this._client.set(
|
|
44011
|
-
await this._client.set(
|
|
44171
|
+
await this._client.set(_vaultRevKey(ptHash), Buffer.from(token), { expires: ttlSeconds });
|
|
44172
|
+
await this._client.set(_vaultHashKey(token), Buffer.from(ptHash), { expires: ttlSeconds });
|
|
44012
44173
|
}
|
|
44013
44174
|
} catch (e6) {
|
|
44014
44175
|
throw new exports.MaskVaultConnectionError(`Memcached error: ${e6}`);
|
|
@@ -44016,7 +44177,7 @@ var init_vault = __esm({
|
|
|
44016
44177
|
}
|
|
44017
44178
|
async getPtHashForToken(token) {
|
|
44018
44179
|
try {
|
|
44019
|
-
const { value } = await this._client.get(
|
|
44180
|
+
const { value } = await this._client.get(_vaultHashKey(token));
|
|
44020
44181
|
return value ? value.toString() : null;
|
|
44021
44182
|
} catch {
|
|
44022
44183
|
return null;
|
|
@@ -44024,7 +44185,7 @@ var init_vault = __esm({
|
|
|
44024
44185
|
}
|
|
44025
44186
|
async getTokenByPlaintextHash(ptHash) {
|
|
44026
44187
|
try {
|
|
44027
|
-
const { value } = await this._client.get(
|
|
44188
|
+
const { value } = await this._client.get(_vaultRevKey(ptHash));
|
|
44028
44189
|
if (!value) return null;
|
|
44029
44190
|
const token = value.toString();
|
|
44030
44191
|
return await this.retrieve(token) !== null ? token : null;
|
|
@@ -44035,8 +44196,9 @@ var init_vault = __esm({
|
|
|
44035
44196
|
}
|
|
44036
44197
|
async retrieve(token) {
|
|
44037
44198
|
try {
|
|
44038
|
-
const { value } = await this._client.get(
|
|
44039
|
-
|
|
44199
|
+
const { value } = await this._client.get(_vaultKey(token));
|
|
44200
|
+
if (!value) return null;
|
|
44201
|
+
return _unwrapPayload(value.toString());
|
|
44040
44202
|
} catch (e6) {
|
|
44041
44203
|
if (_getFailStrategy() === "closed") throw new exports.MaskVaultConnectionError(`Memcached read failed: ${e6}`);
|
|
44042
44204
|
return null;
|
|
@@ -44044,12 +44206,12 @@ var init_vault = __esm({
|
|
|
44044
44206
|
}
|
|
44045
44207
|
async delete(token) {
|
|
44046
44208
|
try {
|
|
44047
|
-
const { value } = await this._client.get(
|
|
44209
|
+
const { value } = await this._client.get(_vaultHashKey(token));
|
|
44048
44210
|
const ptHash = value ? value.toString() : null;
|
|
44049
|
-
await this._client.delete(
|
|
44050
|
-
await this._client.delete(
|
|
44211
|
+
await this._client.delete(_vaultKey(token));
|
|
44212
|
+
await this._client.delete(_vaultHashKey(token));
|
|
44051
44213
|
if (ptHash) {
|
|
44052
|
-
await this._client.delete(
|
|
44214
|
+
await this._client.delete(_vaultRevKey(ptHash));
|
|
44053
44215
|
}
|
|
44054
44216
|
} catch (e6) {
|
|
44055
44217
|
if (_getFailStrategy() === "closed") throw new exports.MaskVaultConnectionError(`Memcached delete failed: ${e6}`);
|
|
@@ -59534,7 +59696,7 @@ var init_transformers_scanner = __esm({
|
|
|
59534
59696
|
);
|
|
59535
59697
|
}
|
|
59536
59698
|
if (!this._pool) {
|
|
59537
|
-
const workerPath =
|
|
59699
|
+
const workerPath = path2__namespace.resolve(__dirname, "nlp_worker.js");
|
|
59538
59700
|
const maxThreads = Math.max(1, Math.min(os__namespace.cpus().length - 1, 4));
|
|
59539
59701
|
this._pool = new Piscina({
|
|
59540
59702
|
filename: workerPath,
|