@dx-do/util 6.3.4 → 6.4.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.cjs.js +95 -0
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +94 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/lib/security/redact.d.ts +28 -0
- package/dist/src/lib/security/redact.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -29886,6 +29886,99 @@ function mapSupportReviver(key, value) {
|
|
|
29886
29886
|
return value;
|
|
29887
29887
|
}
|
|
29888
29888
|
|
|
29889
|
+
/**
|
|
29890
|
+
* Redaction helpers for keeping auth tokens and other secrets out of logs.
|
|
29891
|
+
*
|
|
29892
|
+
* Auth tokens live in axios `error.config.headers` — e.g. `Authorization: Bearer
|
|
29893
|
+
* <userToken>` and `X-Asm-Auth: <dxASMToken>`. Anything that serializes a whole
|
|
29894
|
+
* error / config / headers object (`JSON.stringify`, an AxiosError's `.toJSON()`,
|
|
29895
|
+
* `console.log(err)`, or a logger that deep-prints its argument) will spill them.
|
|
29896
|
+
* These helpers strip the secrets before anything is logged or re-thrown.
|
|
29897
|
+
*/
|
|
29898
|
+
const REDACTED = '[REDACTED]';
|
|
29899
|
+
/** Lowercased object-key names whose values must never be logged. */
|
|
29900
|
+
const SENSITIVE_KEYS = new Set([
|
|
29901
|
+
'authorization',
|
|
29902
|
+
'x-asm-auth',
|
|
29903
|
+
'cookie',
|
|
29904
|
+
'set-cookie',
|
|
29905
|
+
'proxy-authorization',
|
|
29906
|
+
'usertoken',
|
|
29907
|
+
'dxasmtoken',
|
|
29908
|
+
'tenanttoken',
|
|
29909
|
+
'agenttoken',
|
|
29910
|
+
'accesstoken',
|
|
29911
|
+
'refreshtoken',
|
|
29912
|
+
'password',
|
|
29913
|
+
'apikey',
|
|
29914
|
+
'x-api-key',
|
|
29915
|
+
]);
|
|
29916
|
+
/** Matches `Bearer <token>` anywhere in a string. */
|
|
29917
|
+
const BEARER = /Bearer\s+\S+/gi;
|
|
29918
|
+
function redactString(value) {
|
|
29919
|
+
return value.replace(BEARER, `Bearer ${REDACTED}`);
|
|
29920
|
+
}
|
|
29921
|
+
/**
|
|
29922
|
+
* Returns a deep copy of `value` with sensitive object keys masked and any
|
|
29923
|
+
* `Bearer <token>` substrings scrubbed. Safe to pass anything: it is
|
|
29924
|
+
* circular-reference safe (axios errors are circular), and `Error` instances are
|
|
29925
|
+
* reduced to `{ name, message, stack }` (all scrubbed) so their token-bearing
|
|
29926
|
+
* `config`/`request`/`response` are dropped entirely.
|
|
29927
|
+
*/
|
|
29928
|
+
function redactValue(value, seen = new WeakSet()) {
|
|
29929
|
+
if (typeof value === 'string')
|
|
29930
|
+
return redactString(value);
|
|
29931
|
+
if (value === null || typeof value !== 'object')
|
|
29932
|
+
return value;
|
|
29933
|
+
if (seen.has(value))
|
|
29934
|
+
return '[Circular]';
|
|
29935
|
+
seen.add(value);
|
|
29936
|
+
if (Array.isArray(value)) {
|
|
29937
|
+
return value.map((entry) => redactValue(entry, seen));
|
|
29938
|
+
}
|
|
29939
|
+
if (value instanceof Error) {
|
|
29940
|
+
return {
|
|
29941
|
+
name: value.name,
|
|
29942
|
+
message: redactString(value.message),
|
|
29943
|
+
stack: value.stack ? redactString(value.stack) : undefined,
|
|
29944
|
+
};
|
|
29945
|
+
}
|
|
29946
|
+
const out = {};
|
|
29947
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
29948
|
+
out[key] = SENSITIVE_KEYS.has(key.toLowerCase())
|
|
29949
|
+
? REDACTED
|
|
29950
|
+
: redactValue(entry, seen);
|
|
29951
|
+
}
|
|
29952
|
+
return out;
|
|
29953
|
+
}
|
|
29954
|
+
/**
|
|
29955
|
+
* Strips auth tokens from an (possibly Axios) error IN PLACE and returns it, so it
|
|
29956
|
+
* stays a throwable `Error` with its stack intact but no longer carries the token
|
|
29957
|
+
* in `config.headers`, `response.config.headers`, or the raw request header string.
|
|
29958
|
+
* Non-error / non-axios values are returned unchanged.
|
|
29959
|
+
*
|
|
29960
|
+
* Use this at the axios boundary (a response error interceptor) so every catch,
|
|
29961
|
+
* re-throw, and top-level handler downstream sees a token-free error.
|
|
29962
|
+
*/
|
|
29963
|
+
function sanitizeAxiosError(err) {
|
|
29964
|
+
if (!err || typeof err !== 'object')
|
|
29965
|
+
return err;
|
|
29966
|
+
const e = err;
|
|
29967
|
+
// Only touch things that look like axios errors.
|
|
29968
|
+
if (!e.isAxiosError && !e.config && !e.response)
|
|
29969
|
+
return err;
|
|
29970
|
+
if (e.config?.headers)
|
|
29971
|
+
e.config.headers = redactValue(e.config.headers);
|
|
29972
|
+
if (e.response?.config?.headers) {
|
|
29973
|
+
e.response.config.headers = redactValue(e.response.config.headers);
|
|
29974
|
+
}
|
|
29975
|
+
// Node's ClientRequest keeps the raw request (incl. the Authorization line) in `_header`.
|
|
29976
|
+
if (e.request && typeof e.request._header === 'string') {
|
|
29977
|
+
e.request._header = redactString(e.request._header);
|
|
29978
|
+
}
|
|
29979
|
+
return err;
|
|
29980
|
+
}
|
|
29981
|
+
|
|
29889
29982
|
class RemoveEmptyTransform extends node_stream.Transform {
|
|
29890
29983
|
_transform(chunk, encoding, callback) {
|
|
29891
29984
|
const possiblyEmptyChunk = chunk.toString().trim();
|
|
@@ -29908,4 +30001,6 @@ exports.enumFromValue = enumFromValue;
|
|
|
29908
30001
|
exports.enumToString = enumToString;
|
|
29909
30002
|
exports.mapSupportReplacer = mapSupportReplacer;
|
|
29910
30003
|
exports.mapSupportReviver = mapSupportReviver;
|
|
30004
|
+
exports.redactValue = redactValue;
|
|
30005
|
+
exports.sanitizeAxiosError = sanitizeAxiosError;
|
|
29911
30006
|
//# sourceMappingURL=index.cjs.js.map
|