@log-drop/web 1.0.0-alpha2 → 1.0.0-alpha4
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/README.md +1 -3
- package/dist/index.cjs +334 -23
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +0 -1
- package/dist/index.js +334 -23
- package/dist/index.js.map +3 -3
- package/dist/logdrop-sw.js +2 -2
- package/dist/logdrop.min.js +2 -2
- package/dist/logdrop.min.js.map +4 -4
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ LogDropConstants.DEFAULT_BASE_URL = "https://server.logdrop.io";
|
|
|
9
9
|
LogDropConstants.DEFAULT_WEB_SECRET_KEY = "xuM9w0BAQEFx";
|
|
10
10
|
LogDropConstants.FILE_EXPORT_INTERVAL_MS = 3e5;
|
|
11
11
|
LogDropConstants.DEVICE_INFO_INTERVAL_MS = 1e4;
|
|
12
|
-
LogDropConstants.SDK_VERSION = true ? "1.0.0-
|
|
12
|
+
LogDropConstants.SDK_VERSION = true ? "1.0.0-alpha4" : "1.0.0";
|
|
13
13
|
LogDropConstants.STORAGE_CHECK_INTERVAL_MS = 12e4;
|
|
14
14
|
LogDropConstants.MAX_LOCAL_STORAGE_SIZE = 5242880;
|
|
15
15
|
LogDropConstants.DATABASE_MAX_STORAGE_LIMIT = 16e6;
|
|
@@ -511,6 +511,168 @@ var NetworkInstrumentation = class {
|
|
|
511
511
|
}
|
|
512
512
|
};
|
|
513
513
|
|
|
514
|
+
// src/instrumentation/httpCapturePolicy.js
|
|
515
|
+
var ALWAYS_MASKED_HEADERS = /* @__PURE__ */ new Set([
|
|
516
|
+
"authorization",
|
|
517
|
+
"proxy-authorization",
|
|
518
|
+
"x-auth-token",
|
|
519
|
+
"x-api-key",
|
|
520
|
+
"x-session-token",
|
|
521
|
+
"cookie",
|
|
522
|
+
"set-cookie"
|
|
523
|
+
]);
|
|
524
|
+
var MASK = "***";
|
|
525
|
+
var MAX_PATTERN_LENGTH = 500;
|
|
526
|
+
var DANGEROUS_PATTERN = /(a\+)\+|\(\.\*\)\+|\(\.\+\)\+/;
|
|
527
|
+
function normalizeHost(value) {
|
|
528
|
+
const host = String(value ?? "").trim().replace(/\.+$/, "").toLowerCase();
|
|
529
|
+
if (!host || /[/:?#@]/.test(host) || host.length > 253) return null;
|
|
530
|
+
return host;
|
|
531
|
+
}
|
|
532
|
+
function normalizePath(value) {
|
|
533
|
+
const trimmed = String(value ?? "").trim();
|
|
534
|
+
if (!trimmed) return "/";
|
|
535
|
+
const withSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
536
|
+
return withSlash.length > 1 ? withSlash.replace(/\/+$/, "") : withSlash;
|
|
537
|
+
}
|
|
538
|
+
function domainMatches(host, ruleHost) {
|
|
539
|
+
return host === ruleHost || host.endsWith(`.${ruleHost}`);
|
|
540
|
+
}
|
|
541
|
+
function pathMatches(path, rulePath, matchType) {
|
|
542
|
+
if (matchType === "EXACT") return path === rulePath;
|
|
543
|
+
if (matchType === "PREFIX") return rulePath === "/" || path === rulePath || path.startsWith(`${rulePath}/`);
|
|
544
|
+
return false;
|
|
545
|
+
}
|
|
546
|
+
function parseUrl(url) {
|
|
547
|
+
try {
|
|
548
|
+
const parsed = new URL(String(url ?? ""));
|
|
549
|
+
const host = normalizeHost(parsed.hostname);
|
|
550
|
+
return host ? { host, path: normalizePath(parsed.pathname) } : null;
|
|
551
|
+
} catch {
|
|
552
|
+
return null;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
function compileSensitivePatterns(filters) {
|
|
556
|
+
const patterns = [];
|
|
557
|
+
for (const filter of Array.isArray(filters) ? filters : []) {
|
|
558
|
+
const source = String(filter ?? "");
|
|
559
|
+
if (!source || source.length > MAX_PATTERN_LENGTH) continue;
|
|
560
|
+
const parts = source.match(/^\/(.+)\/([gimsuy]*)$/);
|
|
561
|
+
const body = parts ? parts[1] : source;
|
|
562
|
+
if (DANGEROUS_PATTERN.test(body)) continue;
|
|
563
|
+
let flags = parts ? parts[2] : "";
|
|
564
|
+
if (!flags.includes("g")) flags += "g";
|
|
565
|
+
if (!flags.includes("i")) flags += "i";
|
|
566
|
+
try {
|
|
567
|
+
patterns.push(new RegExp(body, flags));
|
|
568
|
+
} catch {
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
return patterns;
|
|
572
|
+
}
|
|
573
|
+
function hashString(text) {
|
|
574
|
+
let hash = 2166136261;
|
|
575
|
+
for (let i = 0; i < text.length; i++) {
|
|
576
|
+
hash ^= text.charCodeAt(i);
|
|
577
|
+
hash = Math.imul(hash, 16777619);
|
|
578
|
+
}
|
|
579
|
+
return (hash >>> 0).toString(16);
|
|
580
|
+
}
|
|
581
|
+
function buildHttpCapturePolicy(config) {
|
|
582
|
+
const policy = {
|
|
583
|
+
domainBlacklist: (config?.httpDomainBlackList ?? []).map(normalizeHost).filter(Boolean),
|
|
584
|
+
pathBlacklist: Array.isArray(config?.httpPathBlackList) ? config.httpPathBlackList : [],
|
|
585
|
+
captureConfig: config?.httpPayloadCaptureConfig ?? null,
|
|
586
|
+
sensitivePatterns: compileSensitivePatterns(config?.sensitiveInfoFilter)
|
|
587
|
+
};
|
|
588
|
+
policy.fingerprint = hashString(JSON.stringify([
|
|
589
|
+
policy.domainBlacklist,
|
|
590
|
+
policy.pathBlacklist,
|
|
591
|
+
policy.captureConfig,
|
|
592
|
+
policy.sensitivePatterns.map((pattern) => `${pattern.source}/${pattern.flags}`)
|
|
593
|
+
]));
|
|
594
|
+
return policy;
|
|
595
|
+
}
|
|
596
|
+
function shouldIgnoreHttpUrl(url, policy) {
|
|
597
|
+
const target = parseUrl(url);
|
|
598
|
+
if (!target || !policy) return false;
|
|
599
|
+
if (policy.domainBlacklist.some((domain) => domainMatches(target.host, domain))) return true;
|
|
600
|
+
return policy.pathBlacklist.some((rule) => {
|
|
601
|
+
const ruleHost = normalizeHost(rule?.host);
|
|
602
|
+
if (!ruleHost || !domainMatches(target.host, ruleHost)) return false;
|
|
603
|
+
return pathMatches(target.path, normalizePath(rule.path), rule.matchType);
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
function resolveDisabledPayloadFields(url, captureConfig) {
|
|
607
|
+
const disabled = {
|
|
608
|
+
requestHeaders: captureConfig?.disableRequestHeaders === true,
|
|
609
|
+
requestBody: captureConfig?.disableRequestBody === true,
|
|
610
|
+
responseHeaders: captureConfig?.disableResponseHeaders === true,
|
|
611
|
+
responseBody: captureConfig?.disableResponseBody === true
|
|
612
|
+
};
|
|
613
|
+
const target = parseUrl(url);
|
|
614
|
+
if (!captureConfig || !target) return disabled;
|
|
615
|
+
for (const rule of captureConfig.rules ?? []) {
|
|
616
|
+
const ruleHost = normalizeHost(rule?.host);
|
|
617
|
+
if (!ruleHost || !domainMatches(target.host, ruleHost)) continue;
|
|
618
|
+
if (rule.path && String(rule.path).trim() && !pathMatches(target.path, normalizePath(rule.path), rule.matchType)) {
|
|
619
|
+
continue;
|
|
620
|
+
}
|
|
621
|
+
disabled.requestHeaders || (disabled.requestHeaders = rule.disableRequestHeaders === true);
|
|
622
|
+
disabled.requestBody || (disabled.requestBody = rule.disableRequestBody === true);
|
|
623
|
+
disabled.responseHeaders || (disabled.responseHeaders = rule.disableResponseHeaders === true);
|
|
624
|
+
disabled.responseBody || (disabled.responseBody = rule.disableResponseBody === true);
|
|
625
|
+
}
|
|
626
|
+
return disabled;
|
|
627
|
+
}
|
|
628
|
+
function maskSensitive(text, patterns) {
|
|
629
|
+
if (typeof text !== "string" || !patterns?.length) return text;
|
|
630
|
+
let output = text;
|
|
631
|
+
for (const regex of patterns) {
|
|
632
|
+
regex.lastIndex = 0;
|
|
633
|
+
output = output.replace(regex, (...args) => {
|
|
634
|
+
const groups = args.slice(1, -2).filter((group) => typeof group === "string" || group === void 0);
|
|
635
|
+
const present = groups.filter((group) => group !== void 0 && group !== "");
|
|
636
|
+
if (present.length === 3) return `${groups[0]}${MASK}${groups[2]}`;
|
|
637
|
+
if (present.length === 2) return `${groups[0]}${MASK}`;
|
|
638
|
+
return MASK;
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
return output;
|
|
642
|
+
}
|
|
643
|
+
function maskStructured(value, patterns) {
|
|
644
|
+
if (value == null || !patterns.length) return value;
|
|
645
|
+
if (typeof value === "string") return maskSensitive(value, patterns);
|
|
646
|
+
try {
|
|
647
|
+
return JSON.parse(maskSensitive(JSON.stringify(value), patterns));
|
|
648
|
+
} catch {
|
|
649
|
+
return value;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
function maskCredentialHeaders(headers) {
|
|
653
|
+
if (!headers || typeof headers !== "object") return {};
|
|
654
|
+
const out = {};
|
|
655
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
656
|
+
out[key] = ALWAYS_MASKED_HEADERS.has(String(key).toLowerCase()) ? MASK : value;
|
|
657
|
+
}
|
|
658
|
+
return out;
|
|
659
|
+
}
|
|
660
|
+
function applyHttpCapturePolicy(payload, policy) {
|
|
661
|
+
if (!payload) return null;
|
|
662
|
+
const effective = policy ?? buildHttpCapturePolicy(null);
|
|
663
|
+
if (shouldIgnoreHttpUrl(payload.url, effective)) return null;
|
|
664
|
+
const disabled = resolveDisabledPayloadFields(payload.url, effective.captureConfig);
|
|
665
|
+
const patterns = effective.sensitivePatterns;
|
|
666
|
+
return {
|
|
667
|
+
...payload,
|
|
668
|
+
url: maskSensitive(String(payload.url ?? ""), patterns),
|
|
669
|
+
requestHeaders: disabled.requestHeaders ? {} : maskStructured(maskCredentialHeaders(payload.requestHeaders), patterns),
|
|
670
|
+
requestBody: disabled.requestBody ? null : maskStructured(payload.requestBody ?? null, patterns),
|
|
671
|
+
responseHeaders: disabled.responseHeaders ? {} : maskStructured(maskCredentialHeaders(payload.responseHeaders), patterns),
|
|
672
|
+
responseBody: disabled.responseBody ? null : maskStructured(payload.responseBody ?? null, patterns)
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
|
|
514
676
|
// src/push/pushModule.js
|
|
515
677
|
function hasWindow2() {
|
|
516
678
|
return typeof window !== "undefined";
|
|
@@ -540,7 +702,7 @@ var PushModule = class {
|
|
|
540
702
|
* serviceWorkerRegistration?: ServiceWorkerRegistration | null,
|
|
541
703
|
* isPushEnabled?: boolean,
|
|
542
704
|
* onRemoteMessageReceived?: ((payload: any) => void) | null,
|
|
543
|
-
*
|
|
705
|
+
* appId?: string,
|
|
544
706
|
* apiBase?: string,
|
|
545
707
|
* deviceId?: string,
|
|
546
708
|
* getSessionToken?: (() => string | null) | null,
|
|
@@ -558,7 +720,7 @@ var PushModule = class {
|
|
|
558
720
|
this.serviceWorkerRegistration = cfg.serviceWorkerRegistration ?? null;
|
|
559
721
|
this.isPushEnabled = cfg.isPushEnabled !== false;
|
|
560
722
|
this.onRemoteMessageReceived = typeof cfg.onRemoteMessageReceived === "function" ? cfg.onRemoteMessageReceived : null;
|
|
561
|
-
this.
|
|
723
|
+
this.appId = cfg.appId ?? null;
|
|
562
724
|
this.apiBase = cfg.apiBase ?? "";
|
|
563
725
|
this.deviceId = cfg.deviceId ?? null;
|
|
564
726
|
this.getSessionToken = typeof cfg.getSessionToken === "function" ? cfg.getSessionToken : null;
|
|
@@ -880,7 +1042,7 @@ var PushModule = class {
|
|
|
880
1042
|
config: {
|
|
881
1043
|
vapidPublicKey: this.vapidPublicKey,
|
|
882
1044
|
apiBase: this.apiBase,
|
|
883
|
-
|
|
1045
|
+
appId: this.appId,
|
|
884
1046
|
sessionToken: this.getSessionToken ? this.getSessionToken() : null,
|
|
885
1047
|
deviceUuid: this.deviceId
|
|
886
1048
|
}
|
|
@@ -1696,6 +1858,105 @@ function decodeWebPushConfig(buf) {
|
|
|
1696
1858
|
}
|
|
1697
1859
|
return result;
|
|
1698
1860
|
}
|
|
1861
|
+
var HTTP_PATH_MATCH_TYPES = ["EXACT", "PREFIX"];
|
|
1862
|
+
function decodeHttpPathMatchType(value) {
|
|
1863
|
+
return HTTP_PATH_MATCH_TYPES[value] ?? null;
|
|
1864
|
+
}
|
|
1865
|
+
function decodeHttpPathBlacklistRule(buf) {
|
|
1866
|
+
const r = new ProtoReader(buf);
|
|
1867
|
+
const result = { host: "", path: "", matchType: "EXACT" };
|
|
1868
|
+
while (r.hasMore()) {
|
|
1869
|
+
const tag = r.readTag();
|
|
1870
|
+
switch (tag.fieldNumber) {
|
|
1871
|
+
case 1:
|
|
1872
|
+
result.host = r.readString();
|
|
1873
|
+
break;
|
|
1874
|
+
case 2:
|
|
1875
|
+
result.path = r.readString();
|
|
1876
|
+
break;
|
|
1877
|
+
case 3:
|
|
1878
|
+
result.matchType = decodeHttpPathMatchType(r.readVarint());
|
|
1879
|
+
break;
|
|
1880
|
+
default:
|
|
1881
|
+
r.skip(tag.wireType);
|
|
1882
|
+
}
|
|
1883
|
+
}
|
|
1884
|
+
return result;
|
|
1885
|
+
}
|
|
1886
|
+
function decodeHttpPayloadCaptureRule(buf) {
|
|
1887
|
+
const r = new ProtoReader(buf);
|
|
1888
|
+
const result = {
|
|
1889
|
+
host: "",
|
|
1890
|
+
path: null,
|
|
1891
|
+
matchType: "EXACT",
|
|
1892
|
+
disableRequestHeaders: false,
|
|
1893
|
+
disableRequestBody: false,
|
|
1894
|
+
disableResponseHeaders: false,
|
|
1895
|
+
disableResponseBody: false
|
|
1896
|
+
};
|
|
1897
|
+
while (r.hasMore()) {
|
|
1898
|
+
const tag = r.readTag();
|
|
1899
|
+
switch (tag.fieldNumber) {
|
|
1900
|
+
case 1:
|
|
1901
|
+
result.host = r.readString();
|
|
1902
|
+
break;
|
|
1903
|
+
case 2:
|
|
1904
|
+
result.path = r.readString();
|
|
1905
|
+
break;
|
|
1906
|
+
case 3:
|
|
1907
|
+
result.matchType = decodeHttpPathMatchType(r.readVarint());
|
|
1908
|
+
break;
|
|
1909
|
+
case 4:
|
|
1910
|
+
result.disableRequestHeaders = r.readBool();
|
|
1911
|
+
break;
|
|
1912
|
+
case 5:
|
|
1913
|
+
result.disableRequestBody = r.readBool();
|
|
1914
|
+
break;
|
|
1915
|
+
case 6:
|
|
1916
|
+
result.disableResponseHeaders = r.readBool();
|
|
1917
|
+
break;
|
|
1918
|
+
case 7:
|
|
1919
|
+
result.disableResponseBody = r.readBool();
|
|
1920
|
+
break;
|
|
1921
|
+
default:
|
|
1922
|
+
r.skip(tag.wireType);
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
return result;
|
|
1926
|
+
}
|
|
1927
|
+
function decodeHttpPayloadCaptureConfig(buf) {
|
|
1928
|
+
const r = new ProtoReader(buf);
|
|
1929
|
+
const result = {
|
|
1930
|
+
disableRequestHeaders: false,
|
|
1931
|
+
disableRequestBody: false,
|
|
1932
|
+
disableResponseHeaders: false,
|
|
1933
|
+
disableResponseBody: false,
|
|
1934
|
+
rules: []
|
|
1935
|
+
};
|
|
1936
|
+
while (r.hasMore()) {
|
|
1937
|
+
const tag = r.readTag();
|
|
1938
|
+
switch (tag.fieldNumber) {
|
|
1939
|
+
case 1:
|
|
1940
|
+
result.disableRequestHeaders = r.readBool();
|
|
1941
|
+
break;
|
|
1942
|
+
case 2:
|
|
1943
|
+
result.disableRequestBody = r.readBool();
|
|
1944
|
+
break;
|
|
1945
|
+
case 3:
|
|
1946
|
+
result.disableResponseHeaders = r.readBool();
|
|
1947
|
+
break;
|
|
1948
|
+
case 4:
|
|
1949
|
+
result.disableResponseBody = r.readBool();
|
|
1950
|
+
break;
|
|
1951
|
+
case 5:
|
|
1952
|
+
result.rules.push(decodeHttpPayloadCaptureRule(r.readBytes()));
|
|
1953
|
+
break;
|
|
1954
|
+
default:
|
|
1955
|
+
r.skip(tag.wireType);
|
|
1956
|
+
}
|
|
1957
|
+
}
|
|
1958
|
+
return result;
|
|
1959
|
+
}
|
|
1699
1960
|
function decodeSdkRiskConfig(buf) {
|
|
1700
1961
|
const r = new ProtoReader(buf);
|
|
1701
1962
|
const result = {
|
|
@@ -1732,6 +1993,8 @@ function decodeConfigResponse(buf) {
|
|
|
1732
1993
|
isCrashTrackingEnabled: false,
|
|
1733
1994
|
isEventTrackingEnabled: false,
|
|
1734
1995
|
httpDomainBlackList: [],
|
|
1996
|
+
httpPathBlackList: [],
|
|
1997
|
+
httpPayloadCaptureConfig: null,
|
|
1735
1998
|
sensitiveInfoFilter: [],
|
|
1736
1999
|
sslPinning: null,
|
|
1737
2000
|
accessToken: "",
|
|
@@ -1792,6 +2055,12 @@ function decodeConfigResponse(buf) {
|
|
|
1792
2055
|
case 15:
|
|
1793
2056
|
result.isEventTrackingEnabled = r.readBool();
|
|
1794
2057
|
break;
|
|
2058
|
+
case 16:
|
|
2059
|
+
result.httpPathBlackList.push(decodeHttpPathBlacklistRule(r.readBytes()));
|
|
2060
|
+
break;
|
|
2061
|
+
case 17:
|
|
2062
|
+
result.httpPayloadCaptureConfig = decodeHttpPayloadCaptureConfig(r.readBytes());
|
|
2063
|
+
break;
|
|
1795
2064
|
case 18:
|
|
1796
2065
|
result.webPushConfig = decodeWebPushConfig(r.readBytes());
|
|
1797
2066
|
break;
|
|
@@ -1961,7 +2230,7 @@ var EventModule = class {
|
|
|
1961
2230
|
* getSessionId: () => string,
|
|
1962
2231
|
* getUserUuid: () => string|null,
|
|
1963
2232
|
* release: string|undefined,
|
|
1964
|
-
*
|
|
2233
|
+
* appId: string,
|
|
1965
2234
|
* apiBase: string,
|
|
1966
2235
|
* isEventTrackingEnabled: boolean,
|
|
1967
2236
|
* isFirstVisit: boolean,
|
|
@@ -1978,7 +2247,7 @@ var EventModule = class {
|
|
|
1978
2247
|
this._logEvent = typeof cfg.logEvent === "function" ? cfg.logEvent : null;
|
|
1979
2248
|
this._getSessionToken = typeof cfg.getSessionToken === "function" ? cfg.getSessionToken : null;
|
|
1980
2249
|
this._release = cfg.release ?? void 0;
|
|
1981
|
-
this.
|
|
2250
|
+
this._appId = cfg.appId ?? "";
|
|
1982
2251
|
this._apiBase = cfg.apiBase ?? "";
|
|
1983
2252
|
this._isEventTrackingEnabled = cfg.isEventTrackingEnabled === true;
|
|
1984
2253
|
this._isFirstVisit = cfg.isFirstVisit === true;
|
|
@@ -2282,7 +2551,7 @@ var EventModule = class {
|
|
|
2282
2551
|
headers: {
|
|
2283
2552
|
"Content-Type": "application/x-protobuf",
|
|
2284
2553
|
"Accept": "application/x-protobuf",
|
|
2285
|
-
"x-api-key": this.
|
|
2554
|
+
"x-api-key": this._appId,
|
|
2286
2555
|
"x-session-token": sessionToken
|
|
2287
2556
|
},
|
|
2288
2557
|
body: new Blob([protoBytes], { type: "application/x-protobuf" })
|
|
@@ -3475,6 +3744,7 @@ var LogDropClient = class {
|
|
|
3475
3744
|
};
|
|
3476
3745
|
this._activeIpReputationAction = this._loadStoredIpReputationAction();
|
|
3477
3746
|
this._ipReputationExpiryTimer = null;
|
|
3747
|
+
this._httpCapturePolicy = null;
|
|
3478
3748
|
this._loadCachedServerConfig();
|
|
3479
3749
|
this._user = this._loadPersistedExternalUser();
|
|
3480
3750
|
this._errorHandlersInstalled = false;
|
|
@@ -4031,9 +4301,9 @@ var LogDropClient = class {
|
|
|
4031
4301
|
const fetchFn = hasWindow5() ? window.fetch : typeof fetch !== "undefined" ? fetch : null;
|
|
4032
4302
|
if (typeof fetchFn !== "function") return false;
|
|
4033
4303
|
const osInfo = this._getOsInfo();
|
|
4034
|
-
const last = this._lastSentUserUpdate?.
|
|
4304
|
+
const last = this._lastSentUserUpdate?.appId === config.appId ? this._lastSentUserUpdate : null;
|
|
4035
4305
|
const runtime = {
|
|
4036
|
-
|
|
4306
|
+
appId: config.appId,
|
|
4037
4307
|
userUuid: task.userUuid,
|
|
4038
4308
|
osName: osInfo.osName,
|
|
4039
4309
|
osVersion: osInfo.osVersion,
|
|
@@ -4063,7 +4333,7 @@ var LogDropClient = class {
|
|
|
4063
4333
|
const headers = {
|
|
4064
4334
|
"content-type": "application/x-protobuf",
|
|
4065
4335
|
"accept": "application/x-protobuf",
|
|
4066
|
-
"x-api-key": config.
|
|
4336
|
+
"x-api-key": config.appId
|
|
4067
4337
|
};
|
|
4068
4338
|
let usedSignatureAuth = false;
|
|
4069
4339
|
if (sessionToken) {
|
|
@@ -4301,6 +4571,7 @@ var LogDropClient = class {
|
|
|
4301
4571
|
if (typeof parsed.data.isSDKDisabled === "boolean") {
|
|
4302
4572
|
this._serverConfig.isSDKDisabled = parsed.data.isSDKDisabled;
|
|
4303
4573
|
}
|
|
4574
|
+
this._httpCapturePolicy = buildHttpCapturePolicy(parsed.data);
|
|
4304
4575
|
}
|
|
4305
4576
|
}
|
|
4306
4577
|
} catch {
|
|
@@ -4322,6 +4593,9 @@ var LogDropClient = class {
|
|
|
4322
4593
|
if (typeof data.isHttpLoggingEnabled === "boolean") {
|
|
4323
4594
|
this._serverConfig.isHttpLoggingEnabled = data.isHttpLoggingEnabled;
|
|
4324
4595
|
}
|
|
4596
|
+
if ("httpDomainBlackList" in data || "httpPayloadCaptureConfig" in data || "sensitiveInfoFilter" in data) {
|
|
4597
|
+
this._httpCapturePolicy = buildHttpCapturePolicy(data);
|
|
4598
|
+
}
|
|
4325
4599
|
if (typeof data.isCrashTrackingEnabled === "boolean" && this._crashTrackingOverride === null) {
|
|
4326
4600
|
this._serverConfig.isCrashTrackingEnabled = data.isCrashTrackingEnabled;
|
|
4327
4601
|
}
|
|
@@ -4381,7 +4655,7 @@ var LogDropClient = class {
|
|
|
4381
4655
|
onEvent: (eventName, payload) => {
|
|
4382
4656
|
if (eventName !== "network_activity") return;
|
|
4383
4657
|
if (!this._serverConfig.isHttpLoggingEnabled || !this._config?.network?.enabled) return;
|
|
4384
|
-
this.
|
|
4658
|
+
this._recordNetworkActivity(payload);
|
|
4385
4659
|
},
|
|
4386
4660
|
getBaseHref,
|
|
4387
4661
|
excludeUrls: this._config.network.excludeUrls,
|
|
@@ -4400,6 +4674,31 @@ var LogDropClient = class {
|
|
|
4400
4674
|
});
|
|
4401
4675
|
this._net.install();
|
|
4402
4676
|
}
|
|
4677
|
+
_recordNetworkActivity(payload) {
|
|
4678
|
+
const recorded = applyHttpCapturePolicy(payload, this._httpCapturePolicy);
|
|
4679
|
+
if (!recorded) return;
|
|
4680
|
+
this._enqueue(LogLevel.NETWORK_ACTIVITY, recorded, new LogFlow("NetworkActivity", recorded.uuid));
|
|
4681
|
+
}
|
|
4682
|
+
// Logs captured before the init response, or under rules that have changed
|
|
4683
|
+
// since, are filtered again with the current policy before upload; logs
|
|
4684
|
+
// stored under the same rules are sent as they are. Returns null when the
|
|
4685
|
+
// log must be dropped.
|
|
4686
|
+
_applyHttpCapturePolicyToStoredLog(log) {
|
|
4687
|
+
const policy = this._httpCapturePolicy;
|
|
4688
|
+
if (!policy || log.level === LogLevel.DEVICEINFO) return log.message;
|
|
4689
|
+
if (log.httpPolicyFingerprint === policy.fingerprint) return log.message;
|
|
4690
|
+
if (log.level !== LogLevel.NETWORK_ACTIVITY) {
|
|
4691
|
+
return maskSensitive(log.message, policy.sensitivePatterns);
|
|
4692
|
+
}
|
|
4693
|
+
let parsed;
|
|
4694
|
+
try {
|
|
4695
|
+
parsed = JSON.parse(log.message);
|
|
4696
|
+
} catch {
|
|
4697
|
+
return maskSensitive(log.message, policy.sensitivePatterns);
|
|
4698
|
+
}
|
|
4699
|
+
const recorded = applyHttpCapturePolicy(parsed, policy);
|
|
4700
|
+
return recorded ? safeStringify(recorded) : null;
|
|
4701
|
+
}
|
|
4403
4702
|
_uninstallNetworkInstrumentation() {
|
|
4404
4703
|
if (this._net) {
|
|
4405
4704
|
this._net.uninstall();
|
|
@@ -4614,9 +4913,8 @@ var LogDropClient = class {
|
|
|
4614
4913
|
this._warnInternal("[LogDrop] SDK is disabled by server configuration");
|
|
4615
4914
|
return;
|
|
4616
4915
|
}
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
if (!apiKey) throw new Error("LogDrop.init requires config.apiKey");
|
|
4916
|
+
const appId = String(config?.appId || "").trim();
|
|
4917
|
+
if (!appId) throw new Error("LogDrop.init requires config.appId");
|
|
4620
4918
|
const defaultWebSecretKey = config.webSecretKey == null ? LogDropConstants.DEFAULT_WEB_SECRET_KEY : config.webSecretKey;
|
|
4621
4919
|
const webSecretKey = String(defaultWebSecretKey || "").trim() || null;
|
|
4622
4920
|
const baseUrl = normalizeBaseUrl(config.baseUrl);
|
|
@@ -4643,8 +4941,7 @@ var LogDropClient = class {
|
|
|
4643
4941
|
]
|
|
4644
4942
|
};
|
|
4645
4943
|
this._config = {
|
|
4646
|
-
appId
|
|
4647
|
-
apiKey,
|
|
4944
|
+
appId,
|
|
4648
4945
|
webSecretKey,
|
|
4649
4946
|
baseUrl,
|
|
4650
4947
|
endpoint,
|
|
@@ -4687,7 +4984,7 @@ var LogDropClient = class {
|
|
|
4687
4984
|
isPushEnabled: true,
|
|
4688
4985
|
// default; overridden by server config in _applyServerConfig
|
|
4689
4986
|
onRemoteMessageReceived: this._config.onRemoteMessageReceived,
|
|
4690
|
-
|
|
4987
|
+
appId: this._config.appId,
|
|
4691
4988
|
apiBase: this._config.baseUrl,
|
|
4692
4989
|
deviceId: this._deviceId,
|
|
4693
4990
|
getSessionToken: () => this._getAccessToken(),
|
|
@@ -4721,7 +5018,7 @@ var LogDropClient = class {
|
|
|
4721
5018
|
// Mirror every successfully sent event into the log stream at EVENT level.
|
|
4722
5019
|
logEvent: (eventLog) => this._enqueue(LogLevel.EVENT, eventLog),
|
|
4723
5020
|
release: this._config.release,
|
|
4724
|
-
|
|
5021
|
+
appId: this._config.appId,
|
|
4725
5022
|
apiBase: this._config.baseUrl,
|
|
4726
5023
|
isEventTrackingEnabled: this._serverConfig.isEventTrackingEnabled,
|
|
4727
5024
|
isFirstVisit: this._isNewDevice,
|
|
@@ -5017,6 +5314,13 @@ var LogDropClient = class {
|
|
|
5017
5314
|
// IMPORTANT: if message object convert => JSON string
|
|
5018
5315
|
message: typeof message === "string" ? message : safeStringify(message)
|
|
5019
5316
|
};
|
|
5317
|
+
const policy = this._httpCapturePolicy;
|
|
5318
|
+
if (policy && level !== LogLevel.DEVICEINFO) {
|
|
5319
|
+
if (level !== LogLevel.NETWORK_ACTIVITY) {
|
|
5320
|
+
entry.message = maskSensitive(entry.message, policy.sensitivePatterns);
|
|
5321
|
+
}
|
|
5322
|
+
entry.httpPolicyFingerprint = policy.fingerprint;
|
|
5323
|
+
}
|
|
5020
5324
|
if (tag) {
|
|
5021
5325
|
entry.tag = tag;
|
|
5022
5326
|
}
|
|
@@ -5102,6 +5406,7 @@ var LogDropClient = class {
|
|
|
5102
5406
|
message: entry.message
|
|
5103
5407
|
};
|
|
5104
5408
|
if (entry.tag) logRecord.tag = entry.tag;
|
|
5409
|
+
if (entry.httpPolicyFingerprint) logRecord.httpPolicyFingerprint = entry.httpPolicyFingerprint;
|
|
5105
5410
|
if (logFlow && logFlow instanceof LogFlow) {
|
|
5106
5411
|
logRecord.flowId = logFlow.id;
|
|
5107
5412
|
logRecord.flowName = logFlow.name;
|
|
@@ -5403,11 +5708,16 @@ var LogDropClient = class {
|
|
|
5403
5708
|
for (const [sessionId, logs] of Object.entries(sessionGroups)) {
|
|
5404
5709
|
const sessionLogs = [];
|
|
5405
5710
|
for (const log of logs) {
|
|
5711
|
+
const message = this._applyHttpCapturePolicyToStoredLog(log);
|
|
5712
|
+
if (message === null) {
|
|
5713
|
+
chunk.droppedLogIds.push(log.id);
|
|
5714
|
+
continue;
|
|
5715
|
+
}
|
|
5406
5716
|
const logEntry = {
|
|
5407
5717
|
id: log.id,
|
|
5408
5718
|
ts: log.ts,
|
|
5409
5719
|
level: log.level,
|
|
5410
|
-
message
|
|
5720
|
+
message,
|
|
5411
5721
|
flowId: log.flowId,
|
|
5412
5722
|
flowName: log.flowName,
|
|
5413
5723
|
flowAttributes: log.flowAttributes
|
|
@@ -5480,7 +5790,7 @@ var LogDropClient = class {
|
|
|
5480
5790
|
headers: {
|
|
5481
5791
|
"content-type": "application/x-protobuf",
|
|
5482
5792
|
"accept": "application/x-protobuf",
|
|
5483
|
-
"x-api-key": this._config.
|
|
5793
|
+
"x-api-key": this._config.appId,
|
|
5484
5794
|
"x-session-token": sessionToken
|
|
5485
5795
|
},
|
|
5486
5796
|
body: new Blob([protoBytes], { type: "application/x-protobuf" })
|
|
@@ -5526,7 +5836,7 @@ var LogDropClient = class {
|
|
|
5526
5836
|
headers: {
|
|
5527
5837
|
"content-type": "application/x-protobuf",
|
|
5528
5838
|
"accept": "application/x-protobuf",
|
|
5529
|
-
"x-api-key": this._config.
|
|
5839
|
+
"x-api-key": this._config.appId,
|
|
5530
5840
|
"x-session-token": sessionToken
|
|
5531
5841
|
},
|
|
5532
5842
|
body: new Blob([protoBytes], { type: "application/x-protobuf" })
|
|
@@ -5625,7 +5935,8 @@ var LogDropClient = class {
|
|
|
5625
5935
|
if (!this._dbPromise) return false;
|
|
5626
5936
|
this._fileFlushInProgress = true;
|
|
5627
5937
|
try {
|
|
5628
|
-
const
|
|
5938
|
+
const storedLogs = await this._readAllLogs();
|
|
5939
|
+
const allLogs = this._httpCapturePolicy ? storedLogs : storedLogs.filter((log) => log.level !== LogLevel.NETWORK_ACTIVITY);
|
|
5629
5940
|
if (this._isInternalLoggingEnabled()) {
|
|
5630
5941
|
this._logInternal(`[LogDrop DEBUG] _flushLogs called. DB log count: ${allLogs.length}`);
|
|
5631
5942
|
}
|
|
@@ -5751,7 +6062,7 @@ var LogDropClient = class {
|
|
|
5751
6062
|
const headers = {
|
|
5752
6063
|
"content-type": "application/x-protobuf",
|
|
5753
6064
|
"accept": "application/x-protobuf",
|
|
5754
|
-
"x-api-key": this._config.
|
|
6065
|
+
"x-api-key": this._config.appId
|
|
5755
6066
|
};
|
|
5756
6067
|
const sessionToken = this._getAccessToken();
|
|
5757
6068
|
const refreshToken = this._getRefreshToken();
|