noibu-react-native 0.2.35-rc.6 → 0.2.35
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/constants.js +1 -1
- package/dist/monitors/RequestMonitor.js +16 -31
- package/dist/utils/piiRedactor.js +4 -24
- package/package.json +1 -1
package/dist/constants.js
CHANGED
|
@@ -24,7 +24,7 @@ const CONTENT_TYPE = 'content-type';
|
|
|
24
24
|
* Gets the script id from the cookie object, returns default if cannot be found
|
|
25
25
|
*/
|
|
26
26
|
function GET_SCRIPT_ID() {
|
|
27
|
-
return "1.0.104-rn-sdk-0.2.35
|
|
27
|
+
return "1.0.104-rn-sdk-0.2.35" ;
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
30
|
* Gets the max metro recon number
|
|
@@ -10,7 +10,6 @@ import { HTTPDataBundler } from './http-tools/HTTPDataBundler.js';
|
|
|
10
10
|
import GqlErrorValidator from './http-tools/GqlErrorValidator.js';
|
|
11
11
|
import { Singleton } from './BaseMonitor.js';
|
|
12
12
|
import { Severity, PageVisitErrorSource } from 'noibu-metroplex-ts-bindings';
|
|
13
|
-
import { removePII } from '../utils/piiRedactor.js';
|
|
14
13
|
|
|
15
14
|
/** request monitor */
|
|
16
15
|
const BODY_USED_ERROR = 'Response data unavailable due to an improperly wrapped fetch call';
|
|
@@ -163,15 +162,7 @@ class RequestMonitor extends Singleton {
|
|
|
163
162
|
? yield GqlErrorValidator.fromFetchResponseText(url, options, request, status, responseText)
|
|
164
163
|
: null;
|
|
165
164
|
const isHttpError = isHttpCodeFailure(status);
|
|
166
|
-
|
|
167
|
-
if (shouldCaptureBody) {
|
|
168
|
-
try {
|
|
169
|
-
maybeRequestText = yield ((_a = request === null || request === void 0 ? void 0 : request.text) === null || _a === void 0 ? void 0 : _a.call(request));
|
|
170
|
-
}
|
|
171
|
-
catch (_b) {
|
|
172
|
-
// request body unavailable (e.g. whatwg-fetch polyfill "Already read") — proceed without it
|
|
173
|
-
}
|
|
174
|
-
}
|
|
165
|
+
const maybeRequestText = shouldCaptureBody ? yield Promise.resolve((_a = request === null || request === void 0 ? void 0 : request.text) === null || _a === void 0 ? void 0 : _a.call(request)) : undefined;
|
|
175
166
|
const responseTextForHttp = shouldCaptureBody
|
|
176
167
|
? responseText !== null && responseText !== void 0 ? responseText : BODY_USED_ERROR
|
|
177
168
|
: undefined;
|
|
@@ -182,7 +173,7 @@ class RequestMonitor extends Singleton {
|
|
|
182
173
|
const seq = saveHTTPEvent(httpEvent, httpData, !!gqlError);
|
|
183
174
|
if (isHttpError) {
|
|
184
175
|
// this does not consume response body so no need to clone it
|
|
185
|
-
saveErrorToPagevisit(
|
|
176
|
+
saveErrorToPagevisit(Object.assign(Object.assign({}, ogResponse), { type: PageVisitErrorSource.Response }), seq);
|
|
186
177
|
}
|
|
187
178
|
if (gqlError) {
|
|
188
179
|
gqlError.forEach(error => saveErrorToPagevisit({
|
|
@@ -253,28 +244,22 @@ class RequestMonitor extends Singleton {
|
|
|
253
244
|
* once and rebuild a fresh Response to avoid mutating the customer's bodyUsed.
|
|
254
245
|
*/
|
|
255
246
|
const customerPromise = promiseFromOriginalFetch.then((ogResponse) => __awaiter(this, void 0, void 0, function* () {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
customerResponse = RequestMonitor.buildCustomerResponse(ogResponse, buffered.body);
|
|
267
|
-
}
|
|
247
|
+
const shouldCheckGql = GqlErrorValidator.shouldCheckRequest(url, options, request);
|
|
248
|
+
const shouldCaptureBody = HTTPDataBundler.getInstance().shouldContinueForURL(url);
|
|
249
|
+
const shouldReadBody = shouldCaptureBody || shouldCheckGql;
|
|
250
|
+
let customerResponse = ogResponse;
|
|
251
|
+
let responseText;
|
|
252
|
+
if (shouldReadBody) {
|
|
253
|
+
const buffered = yield RequestMonitor.readResponseBody(ogResponse);
|
|
254
|
+
if (buffered) {
|
|
255
|
+
responseText = buffered.text;
|
|
256
|
+
customerResponse = RequestMonitor.buildCustomerResponse(ogResponse, buffered.body);
|
|
268
257
|
}
|
|
269
|
-
RequestMonitor.handleFetchResponse(startTime, url, method, options, request, ogResponse, responseText, shouldCaptureBody, shouldCheckGql).catch(() => {
|
|
270
|
-
// errors are handled inside handleFetchResponse
|
|
271
|
-
});
|
|
272
|
-
return customerResponse;
|
|
273
|
-
}
|
|
274
|
-
catch (_a) {
|
|
275
|
-
// SDK processing failed — return original response so the customer is never affected
|
|
276
|
-
return ogResponse;
|
|
277
258
|
}
|
|
259
|
+
RequestMonitor.handleFetchResponse(startTime, url, method, options, request, ogResponse, responseText, shouldCaptureBody, shouldCheckGql).catch(() => {
|
|
260
|
+
// errors are handled inside handleFetchResponse
|
|
261
|
+
});
|
|
262
|
+
return customerResponse;
|
|
278
263
|
}));
|
|
279
264
|
customerPromise.catch(err => {
|
|
280
265
|
RequestMonitor.handleFetchFailure(err, url);
|
|
@@ -60,7 +60,6 @@ const exactFieldsToRedact = [
|
|
|
60
60
|
'cardnumber',
|
|
61
61
|
'email',
|
|
62
62
|
];
|
|
63
|
-
const MAX_NESTED_JSON_REDACTION_DEPTH = 5;
|
|
64
63
|
/**
|
|
65
64
|
* Redacts one string, returns redacted value or false if nothing to redact
|
|
66
65
|
*/
|
|
@@ -71,12 +70,10 @@ function shouldRedact(field) {
|
|
|
71
70
|
/**
|
|
72
71
|
* Try to parse content as a JSON object and
|
|
73
72
|
* iterate it recursively removing PII.
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* @param {String} content - The string to parse and redact PII from
|
|
77
|
-
* @param {Number} maxDepth - Maximum recursion depth for nested JSON strings (default: MAX_NESTED_JSON_REDACTION_DEPTH)
|
|
73
|
+
* Returns original content if nothing was changes or error is thrown.
|
|
74
|
+
* @param {String} content
|
|
78
75
|
*/
|
|
79
|
-
function tryParseObjectAndRemovePII(content
|
|
76
|
+
function tryParseObjectAndRemovePII(content) {
|
|
80
77
|
const first = content[0];
|
|
81
78
|
const isParsable = first === '{' || first === '[';
|
|
82
79
|
if (!isParsable) {
|
|
@@ -85,7 +82,7 @@ function tryParseObjectAndRemovePII(content, maxDepth = MAX_NESTED_JSON_REDACTIO
|
|
|
85
82
|
let redacted = false;
|
|
86
83
|
try {
|
|
87
84
|
const instance = JSON.parse(content);
|
|
88
|
-
iterateObjectRecursively(instance, (current, property
|
|
85
|
+
iterateObjectRecursively(instance, (current, property) => {
|
|
89
86
|
if (typeof property !== 'string') {
|
|
90
87
|
return undefined;
|
|
91
88
|
}
|
|
@@ -95,23 +92,6 @@ function tryParseObjectAndRemovePII(content, maxDepth = MAX_NESTED_JSON_REDACTIO
|
|
|
95
92
|
redacted = true;
|
|
96
93
|
return PII_REDACTION_REPLACEMENT_STRING;
|
|
97
94
|
}
|
|
98
|
-
// If the value is a JSON string, parse it and redact recursively
|
|
99
|
-
// maxDepth guards against deeply nested structures affecting performance
|
|
100
|
-
if (typeof value === 'string' && maxDepth > 1) {
|
|
101
|
-
try {
|
|
102
|
-
const parsed = JSON.parse(value);
|
|
103
|
-
if (typeof parsed === 'object' && parsed !== null) {
|
|
104
|
-
const redactedString = tryParseObjectAndRemovePII(value, maxDepth - 1);
|
|
105
|
-
if (redactedString !== value) {
|
|
106
|
-
redacted = true;
|
|
107
|
-
return redactedString;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
catch (_a) {
|
|
112
|
-
// not valid JSON, leave as is
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
95
|
return undefined;
|
|
116
96
|
});
|
|
117
97
|
return redacted ? stringifyJSON(instance) : content;
|
package/package.json
CHANGED