@leeguoo/pwtk-network-debugger 1.0.0 → 1.1.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.esm.js CHANGED
@@ -6671,10 +6671,17 @@ function decrypt(encryptedData, keyStr) {
6671
6671
  return encryptedData;
6672
6672
  }
6673
6673
  class NetworkInterceptor {
6674
- constructor() {
6674
+ constructor(options = {}) {
6675
6675
  this.requests = /* @__PURE__ */ new Map();
6676
6676
  this.listeners = [];
6677
6677
  this.decryptConfig = { enabled: false };
6678
+ this.STORAGE_KEY = "network_debugger_requests";
6679
+ this.MAX_STORAGE_SIZE = 100;
6680
+ this.persistenceEnabled = true;
6681
+ this.persistenceEnabled = options.persistence !== false;
6682
+ if (this.persistenceEnabled) {
6683
+ this.loadFromStorage();
6684
+ }
6678
6685
  this.interceptXHR();
6679
6686
  this.interceptFetch();
6680
6687
  }
@@ -6686,6 +6693,12 @@ class NetworkInterceptor {
6686
6693
  if (config?.slkExtractor) {
6687
6694
  this.decryptConfig.slkExtractor = config.slkExtractor;
6688
6695
  }
6696
+ if (config?.autoFetchKeys !== void 0) {
6697
+ this.decryptConfig.autoFetchKeys = config.autoFetchKeys;
6698
+ }
6699
+ if (config?.keyApiUrl) {
6700
+ this.decryptConfig.keyApiUrl = config.keyApiUrl;
6701
+ }
6689
6702
  }
6690
6703
  addListener(listener) {
6691
6704
  this.listeners.push(listener);
@@ -6701,6 +6714,9 @@ class NetworkInterceptor {
6701
6714
  }
6702
6715
  clearRequests() {
6703
6716
  this.requests.clear();
6717
+ if (this.persistenceEnabled) {
6718
+ this.clearStorage();
6719
+ }
6704
6720
  }
6705
6721
  generateRequestId() {
6706
6722
  return Math.random().toString(36).substr(2, 9);
@@ -6714,18 +6730,39 @@ class NetworkInterceptor {
6714
6730
  }
6715
6731
  });
6716
6732
  }
6717
- tryDecrypt(data, headers) {
6733
+ async tryDecrypt(data, headers) {
6718
6734
  if (!this.decryptConfig.enabled || !data) {
6719
6735
  return null;
6720
6736
  }
6721
6737
  try {
6722
6738
  let key = "";
6723
- if (this.decryptConfig.keyExtractor) {
6739
+ let slk = "";
6740
+ if (headers.cid && this.decryptConfig.autoFetchKeys !== false) {
6741
+ try {
6742
+ const apiUrl = this.decryptConfig.keyApiUrl || "https://gw-card-pay.buyacard.cc/ip/getSK";
6743
+ const response = await fetch(apiUrl, {
6744
+ headers: {
6745
+ cid: headers.cid,
6746
+ client: headers.client || "S_WEB",
6747
+ device: headers.device || "Web",
6748
+ language: headers.language || "CN"
6749
+ }
6750
+ });
6751
+ const result = await response.json();
6752
+ if (result.success && result.data) {
6753
+ const num = result.data;
6754
+ key = num.slice(2, 3) + num.slice(5, 6) + num.slice(8, 9);
6755
+ console.log("NetworkDebugger: 自动获取密钥成功:", key, "原始值:", num);
6756
+ }
6757
+ } catch (e) {
6758
+ console.warn("NetworkDebugger: 自动获取密钥失败:", e);
6759
+ }
6760
+ }
6761
+ if (!key && this.decryptConfig.keyExtractor) {
6724
6762
  key = this.decryptConfig.keyExtractor(headers);
6725
- } else {
6763
+ } else if (!key) {
6726
6764
  key = headers.keys || headers.cid || "";
6727
6765
  }
6728
- let slk = "";
6729
6766
  if (this.decryptConfig.slkExtractor) {
6730
6767
  slk = this.decryptConfig.slkExtractor(headers);
6731
6768
  } else {
@@ -6733,13 +6770,48 @@ class NetworkInterceptor {
6733
6770
  }
6734
6771
  const fullKey = key + slk;
6735
6772
  if (fullKey) {
6736
- return decrypt(typeof data === "string" ? data : JSON.stringify(data), fullKey);
6773
+ const decrypted = decrypt(typeof data === "string" ? data : JSON.stringify(data), fullKey);
6774
+ if (decrypted !== data) {
6775
+ console.log("NetworkDebugger: 解密成功", { key, slk, fullKey });
6776
+ return decrypted;
6777
+ }
6737
6778
  }
6738
6779
  } catch (error) {
6739
6780
  console.warn("NetworkDebugger: Decryption failed:", error);
6740
6781
  }
6741
6782
  return null;
6742
6783
  }
6784
+ // 持久化存储方法
6785
+ saveToStorage() {
6786
+ if (!this.persistenceEnabled) return;
6787
+ try {
6788
+ const requests = Array.from(this.requests.values()).sort((a, b) => b.timestamp - a.timestamp).slice(0, this.MAX_STORAGE_SIZE);
6789
+ localStorage.setItem(this.STORAGE_KEY, JSON.stringify(requests));
6790
+ } catch (e) {
6791
+ console.warn("NetworkDebugger: Failed to save to localStorage:", e);
6792
+ }
6793
+ }
6794
+ loadFromStorage() {
6795
+ try {
6796
+ const stored = localStorage.getItem(this.STORAGE_KEY);
6797
+ if (stored) {
6798
+ const requests = JSON.parse(stored);
6799
+ requests.forEach((req) => {
6800
+ this.requests.set(req.id, req);
6801
+ });
6802
+ console.log(`NetworkDebugger: 从存储中恢复了 ${requests.length} 条请求记录`);
6803
+ }
6804
+ } catch (e) {
6805
+ console.warn("NetworkDebugger: Failed to load from localStorage:", e);
6806
+ }
6807
+ }
6808
+ clearStorage() {
6809
+ try {
6810
+ localStorage.removeItem(this.STORAGE_KEY);
6811
+ } catch (e) {
6812
+ console.warn("NetworkDebugger: Failed to clear storage:", e);
6813
+ }
6814
+ }
6743
6815
  interceptXHR() {
6744
6816
  const originalXHR = window.XMLHttpRequest;
6745
6817
  const self2 = this;
@@ -6772,9 +6844,17 @@ class NetworkInterceptor {
6772
6844
  timestamp: startTime
6773
6845
  };
6774
6846
  if (body) {
6775
- requestData.decryptedRequest = self2.tryDecrypt(body, requestHeaders);
6847
+ self2.tryDecrypt(body, requestHeaders).then((decrypted) => {
6848
+ if (decrypted !== null) {
6849
+ requestData.decryptedRequest = decrypted;
6850
+ self2.requests.set(requestId, requestData);
6851
+ self2.saveToStorage();
6852
+ self2.notifyListeners(requestData);
6853
+ }
6854
+ }).catch((e) => console.warn("解密请求失败:", e));
6776
6855
  }
6777
6856
  self2.requests.set(requestId, requestData);
6857
+ self2.saveToStorage();
6778
6858
  self2.notifyListeners(requestData);
6779
6859
  return originalSend.call(this, body);
6780
6860
  };
@@ -6803,9 +6883,17 @@ class NetworkInterceptor {
6803
6883
  requestData.responseBody = xhr.responseText;
6804
6884
  }
6805
6885
  if (requestData.responseBody) {
6806
- requestData.decryptedResponse = self2.tryDecrypt(requestData.responseBody, { ...requestHeaders, ...responseHeaders });
6886
+ self2.tryDecrypt(requestData.responseBody, { ...requestHeaders, ...responseHeaders }).then((decrypted) => {
6887
+ if (decrypted !== null) {
6888
+ requestData.decryptedResponse = decrypted;
6889
+ self2.requests.set(requestId, requestData);
6890
+ self2.saveToStorage();
6891
+ self2.notifyListeners(requestData);
6892
+ }
6893
+ }).catch((e) => console.warn("解密响应失败:", e));
6807
6894
  }
6808
6895
  self2.requests.set(requestId, requestData);
6896
+ self2.saveToStorage();
6809
6897
  self2.notifyListeners(requestData);
6810
6898
  }
6811
6899
  }
@@ -6859,9 +6947,17 @@ class NetworkInterceptor {
6859
6947
  timestamp: startTime
6860
6948
  };
6861
6949
  if (requestBody) {
6862
- requestData.decryptedRequest = self2.tryDecrypt(requestBody, requestHeaders);
6950
+ self2.tryDecrypt(requestBody, requestHeaders).then((decrypted) => {
6951
+ if (decrypted !== null) {
6952
+ requestData.decryptedRequest = decrypted;
6953
+ self2.requests.set(requestId, requestData);
6954
+ self2.saveToStorage();
6955
+ self2.notifyListeners(requestData);
6956
+ }
6957
+ }).catch((e) => console.warn("解密请求失败:", e));
6863
6958
  }
6864
6959
  self2.requests.set(requestId, requestData);
6960
+ self2.saveToStorage();
6865
6961
  self2.notifyListeners(requestData);
6866
6962
  try {
6867
6963
  const response = await originalFetch.call(this, input, init);
@@ -6885,15 +6981,23 @@ class NetworkInterceptor {
6885
6981
  updatedRequestData.responseBody = responseText;
6886
6982
  }
6887
6983
  if (updatedRequestData.responseBody) {
6888
- updatedRequestData.decryptedResponse = self2.tryDecrypt(
6984
+ self2.tryDecrypt(
6889
6985
  updatedRequestData.responseBody,
6890
6986
  { ...requestHeaders, ...responseHeaders }
6891
- );
6987
+ ).then((decrypted) => {
6988
+ if (decrypted !== null) {
6989
+ updatedRequestData.decryptedResponse = decrypted;
6990
+ self2.requests.set(requestId, updatedRequestData);
6991
+ self2.saveToStorage();
6992
+ self2.notifyListeners(updatedRequestData);
6993
+ }
6994
+ }).catch((e) => console.warn("解密响应失败:", e));
6892
6995
  }
6893
6996
  } catch (error) {
6894
6997
  updatedRequestData.error = `Failed to read response: ${error}`;
6895
6998
  }
6896
6999
  self2.requests.set(requestId, updatedRequestData);
7000
+ self2.saveToStorage();
6897
7001
  self2.notifyListeners(updatedRequestData);
6898
7002
  }
6899
7003
  return response;
@@ -6904,6 +7008,7 @@ class NetworkInterceptor {
6904
7008
  updatedRequestData.error = error instanceof Error ? error.message : String(error);
6905
7009
  updatedRequestData.duration = endTime - startTime;
6906
7010
  self2.requests.set(requestId, updatedRequestData);
7011
+ self2.saveToStorage();
6907
7012
  self2.notifyListeners(updatedRequestData);
6908
7013
  }
6909
7014
  throw error;
@@ -6932,28 +7037,72 @@ class WasmLoader {
6932
7037
  }
6933
7038
  this.loading = true;
6934
7039
  try {
6935
- const defaultWasmUrl = wasmUrl || "/mimlib.wasm";
6936
- const defaultJsUrl = jsUrl || "/wasm_exec.js";
6937
- await this.loadScript(defaultJsUrl);
7040
+ const wasmPaths = [
7041
+ wasmUrl,
7042
+ "/mimlib.wasm",
7043
+ "/dist/mimlib.wasm",
7044
+ "/assets/mimlib.wasm",
7045
+ "https://gw-card-pay.buyacard.cc/mimlib.wasm"
7046
+ ].filter(Boolean);
7047
+ const jsPaths = [
7048
+ jsUrl,
7049
+ "/wasm_exec.js",
7050
+ "/dist/wasm_exec.js",
7051
+ "/assets/wasm_exec.js",
7052
+ "https://gw-card-pay.buyacard.cc/wasm_exec.js"
7053
+ ].filter(Boolean);
7054
+ let jsLoaded = false;
7055
+ for (const jsPath of jsPaths) {
7056
+ try {
7057
+ await this.loadScript(jsPath);
7058
+ if (typeof window.Go !== "undefined") {
7059
+ jsLoaded = true;
7060
+ console.log("NetworkDebugger: wasm_exec.js 加载成功:", jsPath);
7061
+ break;
7062
+ }
7063
+ } catch (e) {
7064
+ console.warn("NetworkDebugger: 尝试加载", jsPath, "失败:", e);
7065
+ continue;
7066
+ }
7067
+ }
7068
+ if (!jsLoaded) {
7069
+ throw new Error("Unable to load wasm_exec.js from any path");
7070
+ }
6938
7071
  if (typeof window.Go === "undefined") {
6939
7072
  throw new Error("Go WebAssembly runtime not available");
6940
7073
  }
6941
7074
  const go = new window.Go();
6942
- let wasmModule;
6943
- if (WebAssembly.instantiateStreaming) {
7075
+ let wasmModule = null;
7076
+ for (const wasmPath of wasmPaths) {
6944
7077
  try {
6945
- wasmModule = await WebAssembly.instantiateStreaming(
6946
- fetch(defaultWasmUrl),
6947
- go.importObject
6948
- );
6949
- } catch (streamError) {
6950
- console.warn("instantiateStreaming failed, falling back to instantiate:", streamError);
6951
- const wasmBuffer = await fetch(defaultWasmUrl).then((response) => response.arrayBuffer());
6952
- wasmModule = await WebAssembly.instantiate(wasmBuffer, go.importObject);
7078
+ if (WebAssembly.instantiateStreaming) {
7079
+ try {
7080
+ wasmModule = await WebAssembly.instantiateStreaming(
7081
+ fetch(wasmPath),
7082
+ go.importObject
7083
+ );
7084
+ console.log("NetworkDebugger: WebAssembly 加载成功:", wasmPath);
7085
+ break;
7086
+ } catch (streamError) {
7087
+ console.warn("instantiateStreaming 失败,尝试传统方式:", streamError);
7088
+ const wasmBuffer = await fetch(wasmPath).then((response) => response.arrayBuffer());
7089
+ wasmModule = await WebAssembly.instantiate(wasmBuffer, go.importObject);
7090
+ console.log("NetworkDebugger: WebAssembly 加载成功(传统方式):", wasmPath);
7091
+ break;
7092
+ }
7093
+ } else {
7094
+ const wasmBuffer = await fetch(wasmPath).then((response) => response.arrayBuffer());
7095
+ wasmModule = await WebAssembly.instantiate(wasmBuffer, go.importObject);
7096
+ console.log("NetworkDebugger: WebAssembly 加载成功(传统方式):", wasmPath);
7097
+ break;
7098
+ }
7099
+ } catch (error) {
7100
+ console.warn("NetworkDebugger: 尝试加载", wasmPath, "失败:", error);
7101
+ continue;
6953
7102
  }
6954
- } else {
6955
- const wasmBuffer = await fetch(defaultWasmUrl).then((response) => response.arrayBuffer());
6956
- wasmModule = await WebAssembly.instantiate(wasmBuffer, go.importObject);
7103
+ }
7104
+ if (!wasmModule) {
7105
+ throw new Error("Unable to load WebAssembly from any path");
6957
7106
  }
6958
7107
  go.run(wasmModule.instance);
6959
7108
  this.loaded = true;
@@ -8064,8 +8213,15 @@ class NetworkDebugger {
8064
8213
  },
8065
8214
  decrypt: {
8066
8215
  enabled: true,
8216
+ autoFetchKeys: true,
8217
+ keyApiUrl: "https://gw-card-pay.buyacard.cc/ip/getSK",
8067
8218
  ...config.decrypt
8068
8219
  },
8220
+ persistence: {
8221
+ enabled: true,
8222
+ maxRecords: 100,
8223
+ ...config.persistence
8224
+ },
8069
8225
  ...config
8070
8226
  };
8071
8227
  try {
@@ -8073,11 +8229,15 @@ class NetworkDebugger {
8073
8229
  this.wasmLoader = new WasmLoader();
8074
8230
  await this.wasmLoader.loadWasm(this.config.wasm.wasmUrl, this.config.wasm.jsUrl);
8075
8231
  }
8076
- this.interceptor = new NetworkInterceptor();
8232
+ this.interceptor = new NetworkInterceptor({
8233
+ persistence: this.config.persistence?.enabled
8234
+ });
8077
8235
  if (this.config.decrypt?.enabled) {
8078
8236
  this.interceptor.enableDecryption({
8079
8237
  keyExtractor: this.config.decrypt.keyExtractor || this.defaultKeyExtractor,
8080
- slkExtractor: this.config.decrypt.slkExtractor || this.defaultSlkExtractor
8238
+ slkExtractor: this.config.decrypt.slkExtractor || this.defaultSlkExtractor,
8239
+ autoFetchKeys: this.config.decrypt.autoFetchKeys,
8240
+ keyApiUrl: this.config.decrypt.keyApiUrl
8081
8241
  });
8082
8242
  }
8083
8243
  if (this.config.autoStart !== false) {