@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/dist/index.d.ts CHANGED
@@ -26,7 +26,6 @@ export interface LogDropNetworkConfig {
26
26
 
27
27
  export interface LogDropConfig {
28
28
  appId: string;
29
- apiKey: string;
30
29
  webSecretKey?: string | null;
31
30
  baseUrl?: string;
32
31
  env?: string;
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-alpha2" : "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
- * apiKey?: string,
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.apiKey = cfg.apiKey ?? null;
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
- apiKey: this.apiKey,
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
- * apiKey: string,
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._apiKey = cfg.apiKey ?? "";
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._apiKey,
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?.apiKey === config.apiKey ? this._lastSentUserUpdate : null;
4304
+ const last = this._lastSentUserUpdate?.appId === config.appId ? this._lastSentUserUpdate : null;
4035
4305
  const runtime = {
4036
- apiKey: config.apiKey,
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.apiKey
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._enqueue(LogLevel.NETWORK_ACTIVITY, payload, new LogFlow("NetworkActivity", payload.uuid));
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
- if (!config || !config.appId) throw new Error("LogDrop.init requires config.appId");
4618
- const apiKey = String(config.apiKey || "").trim();
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: String(config.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
- apiKey: this._config.apiKey,
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
- apiKey: this._config.apiKey,
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: log.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.apiKey,
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.apiKey,
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 allLogs = await this._readAllLogs();
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.apiKey
6065
+ "x-api-key": this._config.appId
5755
6066
  };
5756
6067
  const sessionToken = this._getAccessToken();
5757
6068
  const refreshToken = this._getRefreshToken();