@dx-do/client 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 +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.cjs.js
CHANGED
|
@@ -2036,7 +2036,7 @@ utils$3.reduceDescriptors(AxiosHeaders$1.prototype, ({ value }, key) => {
|
|
|
2036
2036
|
|
|
2037
2037
|
utils$3.freezeMethods(AxiosHeaders$1);
|
|
2038
2038
|
|
|
2039
|
-
const REDACTED = '[REDACTED ****]';
|
|
2039
|
+
const REDACTED$1 = '[REDACTED ****]';
|
|
2040
2040
|
|
|
2041
2041
|
function hasOwnOrPrototypeToJSON(source) {
|
|
2042
2042
|
if (utils$3.hasOwnProp(source, 'toJSON')) {
|
|
@@ -2091,7 +2091,7 @@ function redactConfig(config, redactKeys) {
|
|
|
2091
2091
|
|
|
2092
2092
|
result = Object.create(null);
|
|
2093
2093
|
for (const [key, value] of Object.entries(source)) {
|
|
2094
|
-
const reducedValue = lowerKeys.has(key.toLowerCase()) ? REDACTED : visit(value);
|
|
2094
|
+
const reducedValue = lowerKeys.has(key.toLowerCase()) ? REDACTED$1 : visit(value);
|
|
2095
2095
|
if (!utils$3.isUndefined(reducedValue)) {
|
|
2096
2096
|
result[key] = reducedValue;
|
|
2097
2097
|
}
|
|
@@ -14712,6 +14712,18 @@ var setToStringTag = esSetTostringtag;
|
|
|
14712
14712
|
var hasOwn$1 = hasown;
|
|
14713
14713
|
var populate = populate$1;
|
|
14714
14714
|
|
|
14715
|
+
/**
|
|
14716
|
+
* Escape CR, LF, and `"` in a multipart `name`/`filename` parameter, so a field
|
|
14717
|
+
* name or filename can not break out of its header line to inject headers or
|
|
14718
|
+
* smuggle additional parts. Matches the WHATWG HTML multipart/form-data encoding.
|
|
14719
|
+
*
|
|
14720
|
+
* @param {string} str - the parameter value to escape
|
|
14721
|
+
* @returns {string} the escaped value
|
|
14722
|
+
*/
|
|
14723
|
+
function escapeHeaderParam(str) {
|
|
14724
|
+
return String(str).replace(/\r/g, '%0D').replace(/\n/g, '%0A').replace(/"/g, '%22');
|
|
14725
|
+
}
|
|
14726
|
+
|
|
14715
14727
|
/**
|
|
14716
14728
|
* Create readable "multipart/form-data" streams.
|
|
14717
14729
|
* Can be used to submit forms
|
|
@@ -14877,7 +14889,7 @@ FormData$1.prototype._multiPartHeader = function (field, value, options) {
|
|
|
14877
14889
|
var contents = '';
|
|
14878
14890
|
var headers = {
|
|
14879
14891
|
// add custom disposition as third element or keep it two elements if not
|
|
14880
|
-
'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []),
|
|
14892
|
+
'Content-Disposition': ['form-data', 'name="' + escapeHeaderParam(field) + '"'].concat(contentDisposition || []),
|
|
14881
14893
|
// if no content type. allow it to be empty array
|
|
14882
14894
|
'Content-Type': [].concat(contentType || [])
|
|
14883
14895
|
};
|
|
@@ -14931,7 +14943,7 @@ FormData$1.prototype._getContentDisposition = function (value, options) { // esl
|
|
|
14931
14943
|
}
|
|
14932
14944
|
|
|
14933
14945
|
if (filename) {
|
|
14934
|
-
return 'filename="' + filename + '"';
|
|
14946
|
+
return 'filename="' + escapeHeaderParam(filename) + '"';
|
|
14935
14947
|
}
|
|
14936
14948
|
};
|
|
14937
14949
|
|
|
@@ -61955,6 +61967,99 @@ class StrictMap extends Map {
|
|
|
61955
61967
|
}
|
|
61956
61968
|
}
|
|
61957
61969
|
|
|
61970
|
+
/**
|
|
61971
|
+
* Redaction helpers for keeping auth tokens and other secrets out of logs.
|
|
61972
|
+
*
|
|
61973
|
+
* Auth tokens live in axios `error.config.headers` — e.g. `Authorization: Bearer
|
|
61974
|
+
* <userToken>` and `X-Asm-Auth: <dxASMToken>`. Anything that serializes a whole
|
|
61975
|
+
* error / config / headers object (`JSON.stringify`, an AxiosError's `.toJSON()`,
|
|
61976
|
+
* `console.log(err)`, or a logger that deep-prints its argument) will spill them.
|
|
61977
|
+
* These helpers strip the secrets before anything is logged or re-thrown.
|
|
61978
|
+
*/
|
|
61979
|
+
const REDACTED = '[REDACTED]';
|
|
61980
|
+
/** Lowercased object-key names whose values must never be logged. */
|
|
61981
|
+
const SENSITIVE_KEYS = new Set([
|
|
61982
|
+
'authorization',
|
|
61983
|
+
'x-asm-auth',
|
|
61984
|
+
'cookie',
|
|
61985
|
+
'set-cookie',
|
|
61986
|
+
'proxy-authorization',
|
|
61987
|
+
'usertoken',
|
|
61988
|
+
'dxasmtoken',
|
|
61989
|
+
'tenanttoken',
|
|
61990
|
+
'agenttoken',
|
|
61991
|
+
'accesstoken',
|
|
61992
|
+
'refreshtoken',
|
|
61993
|
+
'password',
|
|
61994
|
+
'apikey',
|
|
61995
|
+
'x-api-key',
|
|
61996
|
+
]);
|
|
61997
|
+
/** Matches `Bearer <token>` anywhere in a string. */
|
|
61998
|
+
const BEARER = /Bearer\s+\S+/gi;
|
|
61999
|
+
function redactString(value) {
|
|
62000
|
+
return value.replace(BEARER, `Bearer ${REDACTED}`);
|
|
62001
|
+
}
|
|
62002
|
+
/**
|
|
62003
|
+
* Returns a deep copy of `value` with sensitive object keys masked and any
|
|
62004
|
+
* `Bearer <token>` substrings scrubbed. Safe to pass anything: it is
|
|
62005
|
+
* circular-reference safe (axios errors are circular), and `Error` instances are
|
|
62006
|
+
* reduced to `{ name, message, stack }` (all scrubbed) so their token-bearing
|
|
62007
|
+
* `config`/`request`/`response` are dropped entirely.
|
|
62008
|
+
*/
|
|
62009
|
+
function redactValue(value, seen = new WeakSet()) {
|
|
62010
|
+
if (typeof value === 'string')
|
|
62011
|
+
return redactString(value);
|
|
62012
|
+
if (value === null || typeof value !== 'object')
|
|
62013
|
+
return value;
|
|
62014
|
+
if (seen.has(value))
|
|
62015
|
+
return '[Circular]';
|
|
62016
|
+
seen.add(value);
|
|
62017
|
+
if (Array.isArray(value)) {
|
|
62018
|
+
return value.map((entry) => redactValue(entry, seen));
|
|
62019
|
+
}
|
|
62020
|
+
if (value instanceof Error) {
|
|
62021
|
+
return {
|
|
62022
|
+
name: value.name,
|
|
62023
|
+
message: redactString(value.message),
|
|
62024
|
+
stack: value.stack ? redactString(value.stack) : undefined,
|
|
62025
|
+
};
|
|
62026
|
+
}
|
|
62027
|
+
const out = {};
|
|
62028
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
62029
|
+
out[key] = SENSITIVE_KEYS.has(key.toLowerCase())
|
|
62030
|
+
? REDACTED
|
|
62031
|
+
: redactValue(entry, seen);
|
|
62032
|
+
}
|
|
62033
|
+
return out;
|
|
62034
|
+
}
|
|
62035
|
+
/**
|
|
62036
|
+
* Strips auth tokens from an (possibly Axios) error IN PLACE and returns it, so it
|
|
62037
|
+
* stays a throwable `Error` with its stack intact but no longer carries the token
|
|
62038
|
+
* in `config.headers`, `response.config.headers`, or the raw request header string.
|
|
62039
|
+
* Non-error / non-axios values are returned unchanged.
|
|
62040
|
+
*
|
|
62041
|
+
* Use this at the axios boundary (a response error interceptor) so every catch,
|
|
62042
|
+
* re-throw, and top-level handler downstream sees a token-free error.
|
|
62043
|
+
*/
|
|
62044
|
+
function sanitizeAxiosError(err) {
|
|
62045
|
+
if (!err || typeof err !== 'object')
|
|
62046
|
+
return err;
|
|
62047
|
+
const e = err;
|
|
62048
|
+
// Only touch things that look like axios errors.
|
|
62049
|
+
if (!e.isAxiosError && !e.config && !e.response)
|
|
62050
|
+
return err;
|
|
62051
|
+
if (e.config?.headers)
|
|
62052
|
+
e.config.headers = redactValue(e.config.headers);
|
|
62053
|
+
if (e.response?.config?.headers) {
|
|
62054
|
+
e.response.config.headers = redactValue(e.response.config.headers);
|
|
62055
|
+
}
|
|
62056
|
+
// Node's ClientRequest keeps the raw request (incl. the Authorization line) in `_header`.
|
|
62057
|
+
if (e.request && typeof e.request._header === 'string') {
|
|
62058
|
+
e.request._header = redactString(e.request._header);
|
|
62059
|
+
}
|
|
62060
|
+
return err;
|
|
62061
|
+
}
|
|
62062
|
+
|
|
61958
62063
|
/**
|
|
61959
62064
|
* Service for APM agents: query by name/regex, list names/statuses, traces,
|
|
61960
62065
|
* thread dumps, and license/device reporting.
|
|
@@ -64597,12 +64702,15 @@ class AsmService {
|
|
|
64597
64702
|
baseURL =
|
|
64598
64703
|
this.dxSaaSService.dxdoConfiguration.dxConfiguration.dxASMbaseAPIURL;
|
|
64599
64704
|
}
|
|
64600
|
-
|
|
64705
|
+
const client = createClient({
|
|
64601
64706
|
baseURL,
|
|
64602
64707
|
headers: {
|
|
64603
64708
|
'X-Asm-Auth': this.dxSaaSService.dxdoConfiguration.dxConfiguration.dxASMToken,
|
|
64604
64709
|
},
|
|
64605
64710
|
});
|
|
64711
|
+
// Strip the X-Asm-Auth token from any error before it can be logged/propagated.
|
|
64712
|
+
client.instance.interceptors.response.use((response) => response, (error) => Promise.reject(sanitizeAxiosError(error)));
|
|
64713
|
+
this.localClient = client;
|
|
64606
64714
|
}
|
|
64607
64715
|
return this.localClient;
|
|
64608
64716
|
}
|
|
@@ -64615,7 +64723,7 @@ class AsmService {
|
|
|
64615
64723
|
return foldersList.data;
|
|
64616
64724
|
})
|
|
64617
64725
|
.catch((error) => {
|
|
64618
|
-
this.log.error(error);
|
|
64726
|
+
this.log.error('ASM foldersList failed', error instanceof Error ? error.message : String(error));
|
|
64619
64727
|
throw error;
|
|
64620
64728
|
});
|
|
64621
64729
|
}
|
|
@@ -67352,56 +67460,47 @@ const coerce$1 = (version, options) => {
|
|
|
67352
67460
|
};
|
|
67353
67461
|
var coerce_1 = coerce$1;
|
|
67354
67462
|
|
|
67355
|
-
|
|
67356
|
-
|
|
67357
|
-
|
|
67358
|
-
|
|
67359
|
-
|
|
67360
|
-
hasRequiredLrucache = 1;
|
|
67361
|
-
|
|
67362
|
-
class LRUCache {
|
|
67363
|
-
constructor () {
|
|
67364
|
-
this.max = 1000;
|
|
67365
|
-
this.map = new Map();
|
|
67366
|
-
}
|
|
67367
|
-
|
|
67368
|
-
get (key) {
|
|
67369
|
-
const value = this.map.get(key);
|
|
67370
|
-
if (value === undefined) {
|
|
67371
|
-
return undefined
|
|
67372
|
-
} else {
|
|
67373
|
-
// Remove the key from the map and add it to the end
|
|
67374
|
-
this.map.delete(key);
|
|
67375
|
-
this.map.set(key, value);
|
|
67376
|
-
return value
|
|
67377
|
-
}
|
|
67378
|
-
}
|
|
67463
|
+
class LRUCache {
|
|
67464
|
+
constructor () {
|
|
67465
|
+
this.max = 1000;
|
|
67466
|
+
this.map = new Map();
|
|
67467
|
+
}
|
|
67379
67468
|
|
|
67380
|
-
|
|
67381
|
-
|
|
67382
|
-
|
|
67469
|
+
get (key) {
|
|
67470
|
+
const value = this.map.get(key);
|
|
67471
|
+
if (value === undefined) {
|
|
67472
|
+
return undefined
|
|
67473
|
+
} else {
|
|
67474
|
+
// Remove the key from the map and add it to the end
|
|
67475
|
+
this.map.delete(key);
|
|
67476
|
+
this.map.set(key, value);
|
|
67477
|
+
return value
|
|
67478
|
+
}
|
|
67479
|
+
}
|
|
67383
67480
|
|
|
67384
|
-
|
|
67385
|
-
|
|
67481
|
+
delete (key) {
|
|
67482
|
+
return this.map.delete(key)
|
|
67483
|
+
}
|
|
67386
67484
|
|
|
67387
|
-
|
|
67388
|
-
|
|
67389
|
-
if (this.map.size >= this.max) {
|
|
67390
|
-
const firstKey = this.map.keys().next().value;
|
|
67391
|
-
this.delete(firstKey);
|
|
67392
|
-
}
|
|
67485
|
+
set (key, value) {
|
|
67486
|
+
const deleted = this.delete(key);
|
|
67393
67487
|
|
|
67394
|
-
|
|
67395
|
-
|
|
67488
|
+
if (!deleted && value !== undefined) {
|
|
67489
|
+
// If cache is full, delete the least recently used item
|
|
67490
|
+
if (this.map.size >= this.max) {
|
|
67491
|
+
const firstKey = this.map.keys().next().value;
|
|
67492
|
+
this.delete(firstKey);
|
|
67493
|
+
}
|
|
67396
67494
|
|
|
67397
|
-
|
|
67398
|
-
|
|
67399
|
-
}
|
|
67495
|
+
this.map.set(key, value);
|
|
67496
|
+
}
|
|
67400
67497
|
|
|
67401
|
-
|
|
67402
|
-
|
|
67498
|
+
return this
|
|
67499
|
+
}
|
|
67403
67500
|
}
|
|
67404
67501
|
|
|
67502
|
+
var lrucache = LRUCache;
|
|
67503
|
+
|
|
67405
67504
|
var range;
|
|
67406
67505
|
var hasRequiredRange;
|
|
67407
67506
|
|
|
@@ -67623,7 +67722,7 @@ function requireRange () {
|
|
|
67623
67722
|
|
|
67624
67723
|
range = Range;
|
|
67625
67724
|
|
|
67626
|
-
const LRU =
|
|
67725
|
+
const LRU = lrucache;
|
|
67627
67726
|
const cache = new LRU();
|
|
67628
67727
|
|
|
67629
67728
|
const parseOptions = parseOptions_1;
|
|
@@ -70251,6 +70350,9 @@ class DxSaasService {
|
|
|
70251
70350
|
.replace(/-/g, '')
|
|
70252
70351
|
.toLowerCase();
|
|
70253
70352
|
this.initializeProxyIfNecessary();
|
|
70353
|
+
// Strip auth tokens from any error this client surfaces, so nothing downstream
|
|
70354
|
+
// (handleAxiosError, re-throws, top-level catches) can log the Authorization header.
|
|
70355
|
+
this._httpClient.interceptors.response.use((response) => response, (error) => Promise.reject(sanitizeAxiosError(error)));
|
|
70254
70356
|
if (process__namespace.env.DXDO_LOG_REQUESTS) {
|
|
70255
70357
|
log.info('Logging requests');
|
|
70256
70358
|
const requestLogFile = process__namespace.env.DXDO_REQUEST_LOG_FILE ??
|
|
@@ -71210,20 +71312,21 @@ class DxSaasService {
|
|
|
71210
71312
|
}
|
|
71211
71313
|
static handleAxiosError(reason, isStream = false) {
|
|
71212
71314
|
if (reason.isAxiosError && reason.response) {
|
|
71213
|
-
|
|
71214
|
-
|
|
71215
|
-
DxSaasService.staticLog.
|
|
71216
|
-
DxSaasService.staticLog.error('[Axios Error
|
|
71315
|
+
// NB: request headers are already token-scrubbed by the response interceptor;
|
|
71316
|
+
// redactValue is belt-and-suspenders in case this is ever called off-path.
|
|
71317
|
+
DxSaasService.staticLog.debug('[Axios Error DEBUG]', redactValue(reason.toJSON()));
|
|
71318
|
+
DxSaasService.staticLog.error('[Axios Error BASIC]', `${reason.request.method} ${reason.config?.url} ${JSON.stringify(redactValue(reason.config?.params ?? {}))}`);
|
|
71319
|
+
DxSaasService.staticLog.error('[Axios Error BODY]', redactValue(reason.config?.data ?? {}));
|
|
71217
71320
|
if (isStream) {
|
|
71218
71321
|
DxSaasService.staticLog.error(`[Axios Error STATUS] ${reason.response.status} / ${reason.message} `);
|
|
71219
71322
|
}
|
|
71220
71323
|
else {
|
|
71221
|
-
DxSaasService.staticLog.error(`[Axios Error STATUS] ${reason.response.status} / ${reason.message} / ${JSON.stringify(reason.response.data)}`);
|
|
71324
|
+
DxSaasService.staticLog.error(`[Axios Error STATUS] ${reason.response.status} / ${reason.message} / ${JSON.stringify(redactValue(reason.response.data))}`);
|
|
71222
71325
|
}
|
|
71223
71326
|
return new SimpleHTTPError(reason.response.status, reason.message);
|
|
71224
71327
|
}
|
|
71225
71328
|
else
|
|
71226
|
-
return reason; //
|
|
71329
|
+
return sanitizeAxiosError(reason); // scrub before propagating
|
|
71227
71330
|
}
|
|
71228
71331
|
static async legacyAuth(v3Configuration) {
|
|
71229
71332
|
return this.legacyAxaRequest(v3Configuration, 'GET', 'ess/security/v1/me', false, false);
|