@simplr-ai/react-native 1.1.0 → 1.2.1
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/{chunk-FCBLJE3T.js → chunk-JDFZXUFN.js} +231 -12
- package/dist/chunk-JDFZXUFN.js.map +1 -0
- package/dist/{flags-CwhHmaHQ.d.cts → flags-DFkb45Q8.d.cts} +51 -1
- package/dist/{flags-CwhHmaHQ.d.ts → flags-DFkb45Q8.d.ts} +51 -1
- package/dist/hooks/index.cjs +228 -9
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.d.cts +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/index.cjs +229 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -3
- package/dist/index.d.ts +24 -3
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-FCBLJE3T.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -20,6 +20,98 @@ var SimplrError = class _SimplrError extends Error {
|
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
+
// src/network-log.ts
|
|
24
|
+
var SENSITIVE_HEADERS = /* @__PURE__ */ new Set([
|
|
25
|
+
"authorization",
|
|
26
|
+
"cookie",
|
|
27
|
+
"set-cookie",
|
|
28
|
+
"x-api-key",
|
|
29
|
+
"x-auth-token",
|
|
30
|
+
"x-csrf-token",
|
|
31
|
+
"x-xsrf-token"
|
|
32
|
+
]);
|
|
33
|
+
var SENSITIVE_KEY_PARTS = [
|
|
34
|
+
"password",
|
|
35
|
+
"passwd",
|
|
36
|
+
"secret",
|
|
37
|
+
"token",
|
|
38
|
+
"api_key",
|
|
39
|
+
"apikey",
|
|
40
|
+
"authorization",
|
|
41
|
+
"auth",
|
|
42
|
+
"credential",
|
|
43
|
+
"private_key",
|
|
44
|
+
"card",
|
|
45
|
+
"cardnumber",
|
|
46
|
+
"pan",
|
|
47
|
+
"cvv",
|
|
48
|
+
"cvc",
|
|
49
|
+
"ssn",
|
|
50
|
+
"pin",
|
|
51
|
+
"otp"
|
|
52
|
+
];
|
|
53
|
+
var MAX_REDACT_DEPTH = 8;
|
|
54
|
+
var MAX_BODY_CHARS = 1e4;
|
|
55
|
+
function isSensitiveKey(key, extraKeys) {
|
|
56
|
+
const lower = key.toLowerCase();
|
|
57
|
+
if (extraKeys.some((k) => lower === k.toLowerCase())) return true;
|
|
58
|
+
return SENSITIVE_KEY_PARTS.some((part) => lower.includes(part));
|
|
59
|
+
}
|
|
60
|
+
function redactDeep(value, extraKeys, depth = 0) {
|
|
61
|
+
if (depth >= MAX_REDACT_DEPTH) return "[truncated]";
|
|
62
|
+
if (Array.isArray(value)) return value.map((v) => redactDeep(v, extraKeys, depth + 1));
|
|
63
|
+
if (value && typeof value === "object") {
|
|
64
|
+
const out = {};
|
|
65
|
+
for (const [key, val] of Object.entries(value)) {
|
|
66
|
+
out[key] = isSensitiveKey(key, extraKeys) ? "[REDACTED]" : redactDeep(val, extraKeys, depth + 1);
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
return value;
|
|
71
|
+
}
|
|
72
|
+
function redactHeaders(headers) {
|
|
73
|
+
if (!headers) return void 0;
|
|
74
|
+
const out = {};
|
|
75
|
+
const set = (key, value) => {
|
|
76
|
+
out[key] = SENSITIVE_HEADERS.has(key.toLowerCase()) ? "[REDACTED]" : value;
|
|
77
|
+
};
|
|
78
|
+
if (typeof headers.forEach === "function" && !Array.isArray(headers)) {
|
|
79
|
+
headers.forEach((value, key) => set(key, value));
|
|
80
|
+
} else {
|
|
81
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
82
|
+
set(key, String(value));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return out;
|
|
86
|
+
}
|
|
87
|
+
function previewBody(raw, redactFields = []) {
|
|
88
|
+
if (raw === void 0 || raw === null) return void 0;
|
|
89
|
+
let value = raw;
|
|
90
|
+
if (typeof raw === "string") {
|
|
91
|
+
try {
|
|
92
|
+
value = JSON.parse(raw);
|
|
93
|
+
} catch {
|
|
94
|
+
return raw.length > MAX_BODY_CHARS ? raw.slice(0, MAX_BODY_CHARS) + "\u2026[truncated]" : raw;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const redacted = redactDeep(value, redactFields);
|
|
98
|
+
let text;
|
|
99
|
+
try {
|
|
100
|
+
text = JSON.stringify(redacted);
|
|
101
|
+
} catch {
|
|
102
|
+
return "[unserializable]";
|
|
103
|
+
}
|
|
104
|
+
if (text.length > MAX_BODY_CHARS) {
|
|
105
|
+
return text.slice(0, MAX_BODY_CHARS) + "\u2026[truncated]";
|
|
106
|
+
}
|
|
107
|
+
return redacted;
|
|
108
|
+
}
|
|
109
|
+
function newLogId() {
|
|
110
|
+
const uuid = globalThis?.crypto?.randomUUID;
|
|
111
|
+
if (typeof uuid === "function") return uuid.call(globalThis.crypto);
|
|
112
|
+
return `req_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`;
|
|
113
|
+
}
|
|
114
|
+
|
|
23
115
|
// src/http.ts
|
|
24
116
|
async function apiRequest(cfg, method, path, body) {
|
|
25
117
|
const fetchImpl = cfg.fetchImpl ?? globalThis.fetch;
|
|
@@ -28,13 +120,32 @@ async function apiRequest(cfg, method, path, body) {
|
|
|
28
120
|
}
|
|
29
121
|
const controller = new AbortController();
|
|
30
122
|
const timer = setTimeout(() => controller.abort(), cfg.timeoutMs);
|
|
123
|
+
const url = `${cfg.baseUrl}${path}`;
|
|
124
|
+
const requestHeaders = {
|
|
125
|
+
"Content-Type": "application/json",
|
|
126
|
+
...cfg.authHeaders
|
|
127
|
+
};
|
|
128
|
+
const startedAt = Date.now();
|
|
129
|
+
const log = cfg.onNetworkLog ? {
|
|
130
|
+
id: newLogId(),
|
|
131
|
+
source: "frontend",
|
|
132
|
+
timestamp: new Date(startedAt).toISOString(),
|
|
133
|
+
method,
|
|
134
|
+
url,
|
|
135
|
+
requestHeaders: redactHeaders(requestHeaders),
|
|
136
|
+
requestBody: cfg.logBodies ? previewBody(body, cfg.redactFields) : void 0
|
|
137
|
+
} : null;
|
|
138
|
+
const emit = (extra) => {
|
|
139
|
+
if (!log || !cfg.onNetworkLog) return;
|
|
140
|
+
try {
|
|
141
|
+
cfg.onNetworkLog({ ...log, durationMs: Date.now() - startedAt, ...extra });
|
|
142
|
+
} catch {
|
|
143
|
+
}
|
|
144
|
+
};
|
|
31
145
|
try {
|
|
32
|
-
const res = await fetchImpl(
|
|
146
|
+
const res = await fetchImpl(url, {
|
|
33
147
|
method,
|
|
34
|
-
headers:
|
|
35
|
-
"Content-Type": "application/json",
|
|
36
|
-
...cfg.authHeaders
|
|
37
|
-
},
|
|
148
|
+
headers: requestHeaders,
|
|
38
149
|
body: body !== void 0 ? JSON.stringify(body) : void 0,
|
|
39
150
|
signal: controller.signal
|
|
40
151
|
});
|
|
@@ -45,6 +156,13 @@ async function apiRequest(cfg, method, path, body) {
|
|
|
45
156
|
} catch {
|
|
46
157
|
parsed = text;
|
|
47
158
|
}
|
|
159
|
+
emit({
|
|
160
|
+
status: res.status,
|
|
161
|
+
statusText: res.statusText,
|
|
162
|
+
ok: res.ok,
|
|
163
|
+
responseHeaders: redactHeaders(res.headers),
|
|
164
|
+
responseBody: cfg.logBodies ? previewBody(parsed ?? text, cfg.redactFields) : void 0
|
|
165
|
+
});
|
|
48
166
|
if (!res.ok) {
|
|
49
167
|
const message = parsed && (parsed.message || parsed.error) || `Simplr API error ${res.status}`;
|
|
50
168
|
throw new SimplrError(message, res.status, parsed);
|
|
@@ -53,8 +171,10 @@ async function apiRequest(cfg, method, path, body) {
|
|
|
53
171
|
} catch (err) {
|
|
54
172
|
if (err instanceof SimplrError) throw err;
|
|
55
173
|
if (err instanceof Error && err.name === "AbortError") {
|
|
174
|
+
emit({ ok: false, error: `timed out after ${cfg.timeoutMs}ms` });
|
|
56
175
|
throw new SimplrError(`Request to ${path} timed out after ${cfg.timeoutMs}ms`, 0, null);
|
|
57
176
|
}
|
|
177
|
+
emit({ ok: false, error: err instanceof Error ? err.message : "Network error" });
|
|
58
178
|
throw new SimplrError(err instanceof Error ? err.message : "Network error", 0, null);
|
|
59
179
|
} finally {
|
|
60
180
|
clearTimeout(timer);
|
|
@@ -64,6 +184,57 @@ function normalizeBaseUrl(url) {
|
|
|
64
184
|
return url.replace(/\/+$/, "");
|
|
65
185
|
}
|
|
66
186
|
|
|
187
|
+
// src/network-shipper.ts
|
|
188
|
+
var DEFAULT_BATCH = 25;
|
|
189
|
+
var DEFAULT_FLUSH_MS = 5e3;
|
|
190
|
+
var NetworkLogShipper = class {
|
|
191
|
+
constructor(cfg) {
|
|
192
|
+
this.queue = [];
|
|
193
|
+
this.timer = null;
|
|
194
|
+
this.cfg = cfg;
|
|
195
|
+
}
|
|
196
|
+
start() {
|
|
197
|
+
if (this.timer) return;
|
|
198
|
+
const interval = this.cfg.flushIntervalMs ?? DEFAULT_FLUSH_MS;
|
|
199
|
+
this.timer = setInterval(() => {
|
|
200
|
+
void this.flush();
|
|
201
|
+
}, interval);
|
|
202
|
+
this.timer?.unref?.();
|
|
203
|
+
}
|
|
204
|
+
add(entry) {
|
|
205
|
+
this.queue.push({
|
|
206
|
+
...entry,
|
|
207
|
+
sdk: this.cfg.sdk,
|
|
208
|
+
applicationId: entry.applicationId ?? this.cfg.applicationId,
|
|
209
|
+
environment: entry.environment ?? this.cfg.environment
|
|
210
|
+
});
|
|
211
|
+
if (this.queue.length >= (this.cfg.batchSize ?? DEFAULT_BATCH)) {
|
|
212
|
+
void this.flush();
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
async flush() {
|
|
216
|
+
if (this.queue.length === 0) return;
|
|
217
|
+
const logs = this.queue;
|
|
218
|
+
this.queue = [];
|
|
219
|
+
try {
|
|
220
|
+
await this.cfg.fetchImpl(`${this.cfg.baseUrl}/v1/network-logs`, {
|
|
221
|
+
method: "POST",
|
|
222
|
+
headers: {
|
|
223
|
+
"Content-Type": "application/json",
|
|
224
|
+
"X-API-Key": this.cfg.apiKey
|
|
225
|
+
},
|
|
226
|
+
body: JSON.stringify({ logs })
|
|
227
|
+
});
|
|
228
|
+
} catch {
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
stop() {
|
|
232
|
+
if (this.timer) clearInterval(this.timer);
|
|
233
|
+
this.timer = null;
|
|
234
|
+
void this.flush();
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
|
|
67
238
|
// src/hash.ts
|
|
68
239
|
function murmurHash3(input, seed = 0) {
|
|
69
240
|
let h1 = seed;
|
|
@@ -391,6 +562,9 @@ var SimplrProfiles = class {
|
|
|
391
562
|
this.baseUrl = config.baseUrl ? normalizeBaseUrl(config.baseUrl) : DEFAULT_BASE_URL;
|
|
392
563
|
if (config.timeoutMs !== void 0) this.timeoutMs = config.timeoutMs;
|
|
393
564
|
this.fetchImpl = config.fetchImpl;
|
|
565
|
+
this.onNetworkLog = config.onNetworkLog;
|
|
566
|
+
this.logBodies = config.logBodies;
|
|
567
|
+
this.redactFields = config.redactFields;
|
|
394
568
|
this.configured = true;
|
|
395
569
|
return this;
|
|
396
570
|
}
|
|
@@ -411,7 +585,10 @@ var SimplrProfiles = class {
|
|
|
411
585
|
authHeaders: { "X-API-Key": this.apiKey },
|
|
412
586
|
baseUrl: this.baseUrl,
|
|
413
587
|
timeoutMs: this.timeoutMs,
|
|
414
|
-
fetchImpl: this.fetchImpl
|
|
588
|
+
fetchImpl: this.fetchImpl,
|
|
589
|
+
onNetworkLog: this.onNetworkLog,
|
|
590
|
+
logBodies: this.logBodies,
|
|
591
|
+
redactFields: this.redactFields
|
|
415
592
|
};
|
|
416
593
|
}
|
|
417
594
|
/** Create or update an anonymous profile and link the current device. */
|
|
@@ -639,6 +816,9 @@ var SimplrAI = class {
|
|
|
639
816
|
this.baseUrl = config.baseUrl ? normalizeBaseUrl(config.baseUrl) : DEFAULT_BASE_URL3;
|
|
640
817
|
if (config.timeoutMs !== void 0) this.timeoutMs = config.timeoutMs;
|
|
641
818
|
this.fetchImpl = config.fetchImpl;
|
|
819
|
+
this.onNetworkLog = config.onNetworkLog;
|
|
820
|
+
this.logBodies = config.logBodies;
|
|
821
|
+
this.redactFields = config.redactFields;
|
|
642
822
|
this.configured = true;
|
|
643
823
|
return this;
|
|
644
824
|
}
|
|
@@ -652,7 +832,10 @@ var SimplrAI = class {
|
|
|
652
832
|
authHeaders: { "X-API-Key": this.apiKey },
|
|
653
833
|
baseUrl: this.baseUrl,
|
|
654
834
|
timeoutMs: this.timeoutMs,
|
|
655
|
-
fetchImpl: this.fetchImpl
|
|
835
|
+
fetchImpl: this.fetchImpl,
|
|
836
|
+
onNetworkLog: this.onNetworkLog,
|
|
837
|
+
logBodies: this.logBodies,
|
|
838
|
+
redactFields: this.redactFields
|
|
656
839
|
};
|
|
657
840
|
}
|
|
658
841
|
/** Create a new AI delegation token for a user. POST /v1/ai/delegations. */
|
|
@@ -775,12 +958,37 @@ var SimplrFraud = class {
|
|
|
775
958
|
this.baseUrl = config.baseUrl ? normalizeBaseUrl(config.baseUrl) : DEFAULT_BASE_URL4;
|
|
776
959
|
if (config.timeoutMs !== void 0) this.timeoutMs = config.timeoutMs;
|
|
777
960
|
this.fetchImpl = config.fetchImpl;
|
|
961
|
+
const logSelf = !!config.logSelfCalls;
|
|
962
|
+
this.logBodies = config.logBodies ?? (config.shipNetworkLogs && logSelf);
|
|
963
|
+
this.redactFields = config.redactFields;
|
|
778
964
|
this.configured = true;
|
|
965
|
+
this.shipper?.stop();
|
|
966
|
+
this.shipper = void 0;
|
|
967
|
+
if (config.shipNetworkLogs && logSelf) {
|
|
968
|
+
this.shipper = new NetworkLogShipper({
|
|
969
|
+
baseUrl: this.baseUrl,
|
|
970
|
+
apiKey: this.apiKey,
|
|
971
|
+
fetchImpl: this.fetchImpl ?? globalThis.fetch,
|
|
972
|
+
sdk: "react-native",
|
|
973
|
+
applicationId: config.applicationId,
|
|
974
|
+
environment: config.environment
|
|
975
|
+
});
|
|
976
|
+
this.shipper.start();
|
|
977
|
+
}
|
|
978
|
+
const shipper = this.shipper;
|
|
979
|
+
const userLog = config.onNetworkLog;
|
|
980
|
+
this.onNetworkLog = shipper || userLog ? (entry) => {
|
|
981
|
+
shipper?.add(entry);
|
|
982
|
+
userLog?.(entry);
|
|
983
|
+
} : void 0;
|
|
779
984
|
const sub = {
|
|
780
985
|
apiKey: this.apiKey,
|
|
781
986
|
baseUrl: this.baseUrl,
|
|
782
987
|
timeoutMs: this.timeoutMs,
|
|
783
|
-
fetchImpl: this.fetchImpl
|
|
988
|
+
fetchImpl: this.fetchImpl,
|
|
989
|
+
onNetworkLog: this.onNetworkLog,
|
|
990
|
+
logBodies: this.logBodies,
|
|
991
|
+
redactFields: this.redactFields
|
|
784
992
|
};
|
|
785
993
|
this.profiles.configure(sub);
|
|
786
994
|
this.ai.configure(sub);
|
|
@@ -799,9 +1007,20 @@ var SimplrFraud = class {
|
|
|
799
1007
|
authHeaders: { "X-API-Key": this.apiKey },
|
|
800
1008
|
baseUrl: this.baseUrl,
|
|
801
1009
|
timeoutMs: this.timeoutMs,
|
|
802
|
-
fetchImpl: this.fetchImpl
|
|
1010
|
+
fetchImpl: this.fetchImpl,
|
|
1011
|
+
onNetworkLog: this.onNetworkLog,
|
|
1012
|
+
logBodies: this.logBodies,
|
|
1013
|
+
redactFields: this.redactFields
|
|
803
1014
|
};
|
|
804
1015
|
}
|
|
1016
|
+
/** Flush any queued network logs to /v1/network-logs. */
|
|
1017
|
+
flushNetworkLogs() {
|
|
1018
|
+
return this.shipper?.flush() ?? Promise.resolve();
|
|
1019
|
+
}
|
|
1020
|
+
/** Stop the network-log shipper and flush remaining logs. */
|
|
1021
|
+
close() {
|
|
1022
|
+
this.shipper?.stop();
|
|
1023
|
+
}
|
|
805
1024
|
// --- Biometrics ---------------------------------------------------------
|
|
806
1025
|
/** Start collecting touch biometrics and reset the form timer. */
|
|
807
1026
|
startTracking() {
|
|
@@ -987,6 +1206,7 @@ var simplrFlags = new SimplrFlags();
|
|
|
987
1206
|
// src/index.ts
|
|
988
1207
|
var src_default = SimplrFraud;
|
|
989
1208
|
|
|
1209
|
+
exports.NetworkLogShipper = NetworkLogShipper;
|
|
990
1210
|
exports.SimplrAI = SimplrAI;
|
|
991
1211
|
exports.SimplrError = SimplrError;
|
|
992
1212
|
exports.SimplrFlags = SimplrFlags;
|