@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 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