@dx-do/client 6.3.5 → 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 +158 -55
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +158 -55
- package/dist/index.esm.js.map +1 -1
- package/dist/src/lib/model/datastore/datastore-schemas.d.ts.map +1 -1
- package/dist/src/lib/services/asm.service.d.ts.map +1 -1
- package/dist/src/lib/services/dx-saas.service.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -2014,7 +2014,7 @@ utils$3.reduceDescriptors(AxiosHeaders$1.prototype, ({ value }, key) => {
|
|
|
2014
2014
|
|
|
2015
2015
|
utils$3.freezeMethods(AxiosHeaders$1);
|
|
2016
2016
|
|
|
2017
|
-
const REDACTED = '[REDACTED ****]';
|
|
2017
|
+
const REDACTED$1 = '[REDACTED ****]';
|
|
2018
2018
|
|
|
2019
2019
|
function hasOwnOrPrototypeToJSON(source) {
|
|
2020
2020
|
if (utils$3.hasOwnProp(source, 'toJSON')) {
|
|
@@ -2069,7 +2069,7 @@ function redactConfig(config, redactKeys) {
|
|
|
2069
2069
|
|
|
2070
2070
|
result = Object.create(null);
|
|
2071
2071
|
for (const [key, value] of Object.entries(source)) {
|
|
2072
|
-
const reducedValue = lowerKeys.has(key.toLowerCase()) ? REDACTED : visit(value);
|
|
2072
|
+
const reducedValue = lowerKeys.has(key.toLowerCase()) ? REDACTED$1 : visit(value);
|
|
2073
2073
|
if (!utils$3.isUndefined(reducedValue)) {
|
|
2074
2074
|
result[key] = reducedValue;
|
|
2075
2075
|
}
|
|
@@ -14690,6 +14690,18 @@ var setToStringTag = esSetTostringtag;
|
|
|
14690
14690
|
var hasOwn$1 = hasown;
|
|
14691
14691
|
var populate = populate$1;
|
|
14692
14692
|
|
|
14693
|
+
/**
|
|
14694
|
+
* Escape CR, LF, and `"` in a multipart `name`/`filename` parameter, so a field
|
|
14695
|
+
* name or filename can not break out of its header line to inject headers or
|
|
14696
|
+
* smuggle additional parts. Matches the WHATWG HTML multipart/form-data encoding.
|
|
14697
|
+
*
|
|
14698
|
+
* @param {string} str - the parameter value to escape
|
|
14699
|
+
* @returns {string} the escaped value
|
|
14700
|
+
*/
|
|
14701
|
+
function escapeHeaderParam(str) {
|
|
14702
|
+
return String(str).replace(/\r/g, '%0D').replace(/\n/g, '%0A').replace(/"/g, '%22');
|
|
14703
|
+
}
|
|
14704
|
+
|
|
14693
14705
|
/**
|
|
14694
14706
|
* Create readable "multipart/form-data" streams.
|
|
14695
14707
|
* Can be used to submit forms
|
|
@@ -14855,7 +14867,7 @@ FormData$2.prototype._multiPartHeader = function (field, value, options) {
|
|
|
14855
14867
|
var contents = '';
|
|
14856
14868
|
var headers = {
|
|
14857
14869
|
// add custom disposition as third element or keep it two elements if not
|
|
14858
|
-
'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []),
|
|
14870
|
+
'Content-Disposition': ['form-data', 'name="' + escapeHeaderParam(field) + '"'].concat(contentDisposition || []),
|
|
14859
14871
|
// if no content type. allow it to be empty array
|
|
14860
14872
|
'Content-Type': [].concat(contentType || [])
|
|
14861
14873
|
};
|
|
@@ -14909,7 +14921,7 @@ FormData$2.prototype._getContentDisposition = function (value, options) { // esl
|
|
|
14909
14921
|
}
|
|
14910
14922
|
|
|
14911
14923
|
if (filename) {
|
|
14912
|
-
return 'filename="' + filename + '"';
|
|
14924
|
+
return 'filename="' + escapeHeaderParam(filename) + '"';
|
|
14913
14925
|
}
|
|
14914
14926
|
};
|
|
14915
14927
|
|
|
@@ -61933,6 +61945,99 @@ class StrictMap extends Map {
|
|
|
61933
61945
|
}
|
|
61934
61946
|
}
|
|
61935
61947
|
|
|
61948
|
+
/**
|
|
61949
|
+
* Redaction helpers for keeping auth tokens and other secrets out of logs.
|
|
61950
|
+
*
|
|
61951
|
+
* Auth tokens live in axios `error.config.headers` — e.g. `Authorization: Bearer
|
|
61952
|
+
* <userToken>` and `X-Asm-Auth: <dxASMToken>`. Anything that serializes a whole
|
|
61953
|
+
* error / config / headers object (`JSON.stringify`, an AxiosError's `.toJSON()`,
|
|
61954
|
+
* `console.log(err)`, or a logger that deep-prints its argument) will spill them.
|
|
61955
|
+
* These helpers strip the secrets before anything is logged or re-thrown.
|
|
61956
|
+
*/
|
|
61957
|
+
const REDACTED = '[REDACTED]';
|
|
61958
|
+
/** Lowercased object-key names whose values must never be logged. */
|
|
61959
|
+
const SENSITIVE_KEYS = new Set([
|
|
61960
|
+
'authorization',
|
|
61961
|
+
'x-asm-auth',
|
|
61962
|
+
'cookie',
|
|
61963
|
+
'set-cookie',
|
|
61964
|
+
'proxy-authorization',
|
|
61965
|
+
'usertoken',
|
|
61966
|
+
'dxasmtoken',
|
|
61967
|
+
'tenanttoken',
|
|
61968
|
+
'agenttoken',
|
|
61969
|
+
'accesstoken',
|
|
61970
|
+
'refreshtoken',
|
|
61971
|
+
'password',
|
|
61972
|
+
'apikey',
|
|
61973
|
+
'x-api-key',
|
|
61974
|
+
]);
|
|
61975
|
+
/** Matches `Bearer <token>` anywhere in a string. */
|
|
61976
|
+
const BEARER = /Bearer\s+\S+/gi;
|
|
61977
|
+
function redactString(value) {
|
|
61978
|
+
return value.replace(BEARER, `Bearer ${REDACTED}`);
|
|
61979
|
+
}
|
|
61980
|
+
/**
|
|
61981
|
+
* Returns a deep copy of `value` with sensitive object keys masked and any
|
|
61982
|
+
* `Bearer <token>` substrings scrubbed. Safe to pass anything: it is
|
|
61983
|
+
* circular-reference safe (axios errors are circular), and `Error` instances are
|
|
61984
|
+
* reduced to `{ name, message, stack }` (all scrubbed) so their token-bearing
|
|
61985
|
+
* `config`/`request`/`response` are dropped entirely.
|
|
61986
|
+
*/
|
|
61987
|
+
function redactValue(value, seen = new WeakSet()) {
|
|
61988
|
+
if (typeof value === 'string')
|
|
61989
|
+
return redactString(value);
|
|
61990
|
+
if (value === null || typeof value !== 'object')
|
|
61991
|
+
return value;
|
|
61992
|
+
if (seen.has(value))
|
|
61993
|
+
return '[Circular]';
|
|
61994
|
+
seen.add(value);
|
|
61995
|
+
if (Array.isArray(value)) {
|
|
61996
|
+
return value.map((entry) => redactValue(entry, seen));
|
|
61997
|
+
}
|
|
61998
|
+
if (value instanceof Error) {
|
|
61999
|
+
return {
|
|
62000
|
+
name: value.name,
|
|
62001
|
+
message: redactString(value.message),
|
|
62002
|
+
stack: value.stack ? redactString(value.stack) : undefined,
|
|
62003
|
+
};
|
|
62004
|
+
}
|
|
62005
|
+
const out = {};
|
|
62006
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
62007
|
+
out[key] = SENSITIVE_KEYS.has(key.toLowerCase())
|
|
62008
|
+
? REDACTED
|
|
62009
|
+
: redactValue(entry, seen);
|
|
62010
|
+
}
|
|
62011
|
+
return out;
|
|
62012
|
+
}
|
|
62013
|
+
/**
|
|
62014
|
+
* Strips auth tokens from an (possibly Axios) error IN PLACE and returns it, so it
|
|
62015
|
+
* stays a throwable `Error` with its stack intact but no longer carries the token
|
|
62016
|
+
* in `config.headers`, `response.config.headers`, or the raw request header string.
|
|
62017
|
+
* Non-error / non-axios values are returned unchanged.
|
|
62018
|
+
*
|
|
62019
|
+
* Use this at the axios boundary (a response error interceptor) so every catch,
|
|
62020
|
+
* re-throw, and top-level handler downstream sees a token-free error.
|
|
62021
|
+
*/
|
|
62022
|
+
function sanitizeAxiosError(err) {
|
|
62023
|
+
if (!err || typeof err !== 'object')
|
|
62024
|
+
return err;
|
|
62025
|
+
const e = err;
|
|
62026
|
+
// Only touch things that look like axios errors.
|
|
62027
|
+
if (!e.isAxiosError && !e.config && !e.response)
|
|
62028
|
+
return err;
|
|
62029
|
+
if (e.config?.headers)
|
|
62030
|
+
e.config.headers = redactValue(e.config.headers);
|
|
62031
|
+
if (e.response?.config?.headers) {
|
|
62032
|
+
e.response.config.headers = redactValue(e.response.config.headers);
|
|
62033
|
+
}
|
|
62034
|
+
// Node's ClientRequest keeps the raw request (incl. the Authorization line) in `_header`.
|
|
62035
|
+
if (e.request && typeof e.request._header === 'string') {
|
|
62036
|
+
e.request._header = redactString(e.request._header);
|
|
62037
|
+
}
|
|
62038
|
+
return err;
|
|
62039
|
+
}
|
|
62040
|
+
|
|
61936
62041
|
/**
|
|
61937
62042
|
* Service for APM agents: query by name/regex, list names/statuses, traces,
|
|
61938
62043
|
* thread dumps, and license/device reporting.
|
|
@@ -64575,12 +64680,15 @@ class AsmService {
|
|
|
64575
64680
|
baseURL =
|
|
64576
64681
|
this.dxSaaSService.dxdoConfiguration.dxConfiguration.dxASMbaseAPIURL;
|
|
64577
64682
|
}
|
|
64578
|
-
|
|
64683
|
+
const client = createClient({
|
|
64579
64684
|
baseURL,
|
|
64580
64685
|
headers: {
|
|
64581
64686
|
'X-Asm-Auth': this.dxSaaSService.dxdoConfiguration.dxConfiguration.dxASMToken,
|
|
64582
64687
|
},
|
|
64583
64688
|
});
|
|
64689
|
+
// Strip the X-Asm-Auth token from any error before it can be logged/propagated.
|
|
64690
|
+
client.instance.interceptors.response.use((response) => response, (error) => Promise.reject(sanitizeAxiosError(error)));
|
|
64691
|
+
this.localClient = client;
|
|
64584
64692
|
}
|
|
64585
64693
|
return this.localClient;
|
|
64586
64694
|
}
|
|
@@ -64593,7 +64701,7 @@ class AsmService {
|
|
|
64593
64701
|
return foldersList.data;
|
|
64594
64702
|
})
|
|
64595
64703
|
.catch((error) => {
|
|
64596
|
-
this.log.error(error);
|
|
64704
|
+
this.log.error('ASM foldersList failed', error instanceof Error ? error.message : String(error));
|
|
64597
64705
|
throw error;
|
|
64598
64706
|
});
|
|
64599
64707
|
}
|
|
@@ -67330,56 +67438,47 @@ const coerce$1 = (version, options) => {
|
|
|
67330
67438
|
};
|
|
67331
67439
|
var coerce_1 = coerce$1;
|
|
67332
67440
|
|
|
67333
|
-
|
|
67334
|
-
|
|
67335
|
-
|
|
67336
|
-
|
|
67337
|
-
|
|
67338
|
-
hasRequiredLrucache = 1;
|
|
67339
|
-
|
|
67340
|
-
class LRUCache {
|
|
67341
|
-
constructor () {
|
|
67342
|
-
this.max = 1000;
|
|
67343
|
-
this.map = new Map();
|
|
67344
|
-
}
|
|
67345
|
-
|
|
67346
|
-
get (key) {
|
|
67347
|
-
const value = this.map.get(key);
|
|
67348
|
-
if (value === undefined) {
|
|
67349
|
-
return undefined
|
|
67350
|
-
} else {
|
|
67351
|
-
// Remove the key from the map and add it to the end
|
|
67352
|
-
this.map.delete(key);
|
|
67353
|
-
this.map.set(key, value);
|
|
67354
|
-
return value
|
|
67355
|
-
}
|
|
67356
|
-
}
|
|
67441
|
+
class LRUCache {
|
|
67442
|
+
constructor () {
|
|
67443
|
+
this.max = 1000;
|
|
67444
|
+
this.map = new Map();
|
|
67445
|
+
}
|
|
67357
67446
|
|
|
67358
|
-
|
|
67359
|
-
|
|
67360
|
-
|
|
67447
|
+
get (key) {
|
|
67448
|
+
const value = this.map.get(key);
|
|
67449
|
+
if (value === undefined) {
|
|
67450
|
+
return undefined
|
|
67451
|
+
} else {
|
|
67452
|
+
// Remove the key from the map and add it to the end
|
|
67453
|
+
this.map.delete(key);
|
|
67454
|
+
this.map.set(key, value);
|
|
67455
|
+
return value
|
|
67456
|
+
}
|
|
67457
|
+
}
|
|
67361
67458
|
|
|
67362
|
-
|
|
67363
|
-
|
|
67459
|
+
delete (key) {
|
|
67460
|
+
return this.map.delete(key)
|
|
67461
|
+
}
|
|
67364
67462
|
|
|
67365
|
-
|
|
67366
|
-
|
|
67367
|
-
if (this.map.size >= this.max) {
|
|
67368
|
-
const firstKey = this.map.keys().next().value;
|
|
67369
|
-
this.delete(firstKey);
|
|
67370
|
-
}
|
|
67463
|
+
set (key, value) {
|
|
67464
|
+
const deleted = this.delete(key);
|
|
67371
67465
|
|
|
67372
|
-
|
|
67373
|
-
|
|
67466
|
+
if (!deleted && value !== undefined) {
|
|
67467
|
+
// If cache is full, delete the least recently used item
|
|
67468
|
+
if (this.map.size >= this.max) {
|
|
67469
|
+
const firstKey = this.map.keys().next().value;
|
|
67470
|
+
this.delete(firstKey);
|
|
67471
|
+
}
|
|
67374
67472
|
|
|
67375
|
-
|
|
67376
|
-
|
|
67377
|
-
}
|
|
67473
|
+
this.map.set(key, value);
|
|
67474
|
+
}
|
|
67378
67475
|
|
|
67379
|
-
|
|
67380
|
-
|
|
67476
|
+
return this
|
|
67477
|
+
}
|
|
67381
67478
|
}
|
|
67382
67479
|
|
|
67480
|
+
var lrucache = LRUCache;
|
|
67481
|
+
|
|
67383
67482
|
var range;
|
|
67384
67483
|
var hasRequiredRange;
|
|
67385
67484
|
|
|
@@ -67601,7 +67700,7 @@ function requireRange () {
|
|
|
67601
67700
|
|
|
67602
67701
|
range = Range;
|
|
67603
67702
|
|
|
67604
|
-
const LRU =
|
|
67703
|
+
const LRU = lrucache;
|
|
67605
67704
|
const cache = new LRU();
|
|
67606
67705
|
|
|
67607
67706
|
const parseOptions = parseOptions_1;
|
|
@@ -70229,6 +70328,9 @@ class DxSaasService {
|
|
|
70229
70328
|
.replace(/-/g, '')
|
|
70230
70329
|
.toLowerCase();
|
|
70231
70330
|
this.initializeProxyIfNecessary();
|
|
70331
|
+
// Strip auth tokens from any error this client surfaces, so nothing downstream
|
|
70332
|
+
// (handleAxiosError, re-throws, top-level catches) can log the Authorization header.
|
|
70333
|
+
this._httpClient.interceptors.response.use((response) => response, (error) => Promise.reject(sanitizeAxiosError(error)));
|
|
70232
70334
|
if (process$1.env.DXDO_LOG_REQUESTS) {
|
|
70233
70335
|
log.info('Logging requests');
|
|
70234
70336
|
const requestLogFile = process$1.env.DXDO_REQUEST_LOG_FILE ??
|
|
@@ -71188,20 +71290,21 @@ class DxSaasService {
|
|
|
71188
71290
|
}
|
|
71189
71291
|
static handleAxiosError(reason, isStream = false) {
|
|
71190
71292
|
if (reason.isAxiosError && reason.response) {
|
|
71191
|
-
|
|
71192
|
-
|
|
71193
|
-
DxSaasService.staticLog.
|
|
71194
|
-
DxSaasService.staticLog.error('[Axios Error
|
|
71293
|
+
// NB: request headers are already token-scrubbed by the response interceptor;
|
|
71294
|
+
// redactValue is belt-and-suspenders in case this is ever called off-path.
|
|
71295
|
+
DxSaasService.staticLog.debug('[Axios Error DEBUG]', redactValue(reason.toJSON()));
|
|
71296
|
+
DxSaasService.staticLog.error('[Axios Error BASIC]', `${reason.request.method} ${reason.config?.url} ${JSON.stringify(redactValue(reason.config?.params ?? {}))}`);
|
|
71297
|
+
DxSaasService.staticLog.error('[Axios Error BODY]', redactValue(reason.config?.data ?? {}));
|
|
71195
71298
|
if (isStream) {
|
|
71196
71299
|
DxSaasService.staticLog.error(`[Axios Error STATUS] ${reason.response.status} / ${reason.message} `);
|
|
71197
71300
|
}
|
|
71198
71301
|
else {
|
|
71199
|
-
DxSaasService.staticLog.error(`[Axios Error STATUS] ${reason.response.status} / ${reason.message} / ${JSON.stringify(reason.response.data)}`);
|
|
71302
|
+
DxSaasService.staticLog.error(`[Axios Error STATUS] ${reason.response.status} / ${reason.message} / ${JSON.stringify(redactValue(reason.response.data))}`);
|
|
71200
71303
|
}
|
|
71201
71304
|
return new SimpleHTTPError(reason.response.status, reason.message);
|
|
71202
71305
|
}
|
|
71203
71306
|
else
|
|
71204
|
-
return reason; //
|
|
71307
|
+
return sanitizeAxiosError(reason); // scrub before propagating
|
|
71205
71308
|
}
|
|
71206
71309
|
static async legacyAuth(v3Configuration) {
|
|
71207
71310
|
return this.legacyAxaRequest(v3Configuration, 'GET', 'ess/security/v1/me', false, false);
|