@leeguoo/pwtk-network-debugger 1.0.0 → 1.2.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
@@ -6686,6 +6686,12 @@ class NetworkInterceptor {
6686
6686
  if (config?.slkExtractor) {
6687
6687
  this.decryptConfig.slkExtractor = config.slkExtractor;
6688
6688
  }
6689
+ if (config?.autoFetchKeys !== void 0) {
6690
+ this.decryptConfig.autoFetchKeys = config.autoFetchKeys;
6691
+ }
6692
+ if (config?.keyApiUrl) {
6693
+ this.decryptConfig.keyApiUrl = config.keyApiUrl;
6694
+ }
6689
6695
  }
6690
6696
  addListener(listener) {
6691
6697
  this.listeners.push(listener);
@@ -6714,18 +6720,39 @@ class NetworkInterceptor {
6714
6720
  }
6715
6721
  });
6716
6722
  }
6717
- tryDecrypt(data, headers) {
6723
+ async tryDecrypt(data, headers) {
6718
6724
  if (!this.decryptConfig.enabled || !data) {
6719
6725
  return null;
6720
6726
  }
6721
6727
  try {
6722
6728
  let key = "";
6723
- if (this.decryptConfig.keyExtractor) {
6729
+ let slk = "";
6730
+ if (headers.cid && this.decryptConfig.autoFetchKeys !== false) {
6731
+ try {
6732
+ const apiUrl = this.decryptConfig.keyApiUrl || "https://gw-card-pay.buyacard.cc/ip/getSK";
6733
+ const response = await fetch(apiUrl, {
6734
+ headers: {
6735
+ cid: headers.cid,
6736
+ client: headers.client || "S_WEB",
6737
+ device: headers.device || "Web",
6738
+ language: headers.language || "CN"
6739
+ }
6740
+ });
6741
+ const result = await response.json();
6742
+ if (result.success && result.data) {
6743
+ const num = result.data;
6744
+ key = num.slice(2, 3) + num.slice(5, 6) + num.slice(8, 9);
6745
+ console.log("NetworkDebugger: 自动获取密钥成功:", key, "原始值:", num);
6746
+ }
6747
+ } catch (e) {
6748
+ console.warn("NetworkDebugger: 自动获取密钥失败:", e);
6749
+ }
6750
+ }
6751
+ if (!key && this.decryptConfig.keyExtractor) {
6724
6752
  key = this.decryptConfig.keyExtractor(headers);
6725
- } else {
6753
+ } else if (!key) {
6726
6754
  key = headers.keys || headers.cid || "";
6727
6755
  }
6728
- let slk = "";
6729
6756
  if (this.decryptConfig.slkExtractor) {
6730
6757
  slk = this.decryptConfig.slkExtractor(headers);
6731
6758
  } else {
@@ -6733,7 +6760,11 @@ class NetworkInterceptor {
6733
6760
  }
6734
6761
  const fullKey = key + slk;
6735
6762
  if (fullKey) {
6736
- return decrypt(typeof data === "string" ? data : JSON.stringify(data), fullKey);
6763
+ const decrypted = decrypt(typeof data === "string" ? data : JSON.stringify(data), fullKey);
6764
+ if (decrypted !== data) {
6765
+ console.log("NetworkDebugger: 解密成功", { key, slk, fullKey });
6766
+ return decrypted;
6767
+ }
6737
6768
  }
6738
6769
  } catch (error) {
6739
6770
  console.warn("NetworkDebugger: Decryption failed:", error);
@@ -6772,7 +6803,13 @@ class NetworkInterceptor {
6772
6803
  timestamp: startTime
6773
6804
  };
6774
6805
  if (body) {
6775
- requestData.decryptedRequest = self2.tryDecrypt(body, requestHeaders);
6806
+ self2.tryDecrypt(body, requestHeaders).then((decrypted) => {
6807
+ if (decrypted !== null) {
6808
+ requestData.decryptedRequest = decrypted;
6809
+ self2.requests.set(requestId, requestData);
6810
+ self2.notifyListeners(requestData);
6811
+ }
6812
+ }).catch((e) => console.warn("解密请求失败:", e));
6776
6813
  }
6777
6814
  self2.requests.set(requestId, requestData);
6778
6815
  self2.notifyListeners(requestData);
@@ -6803,7 +6840,13 @@ class NetworkInterceptor {
6803
6840
  requestData.responseBody = xhr.responseText;
6804
6841
  }
6805
6842
  if (requestData.responseBody) {
6806
- requestData.decryptedResponse = self2.tryDecrypt(requestData.responseBody, { ...requestHeaders, ...responseHeaders });
6843
+ self2.tryDecrypt(requestData.responseBody, { ...requestHeaders, ...responseHeaders }).then((decrypted) => {
6844
+ if (decrypted !== null) {
6845
+ requestData.decryptedResponse = decrypted;
6846
+ self2.requests.set(requestId, requestData);
6847
+ self2.notifyListeners(requestData);
6848
+ }
6849
+ }).catch((e) => console.warn("解密响应失败:", e));
6807
6850
  }
6808
6851
  self2.requests.set(requestId, requestData);
6809
6852
  self2.notifyListeners(requestData);
@@ -6859,7 +6902,13 @@ class NetworkInterceptor {
6859
6902
  timestamp: startTime
6860
6903
  };
6861
6904
  if (requestBody) {
6862
- requestData.decryptedRequest = self2.tryDecrypt(requestBody, requestHeaders);
6905
+ self2.tryDecrypt(requestBody, requestHeaders).then((decrypted) => {
6906
+ if (decrypted !== null) {
6907
+ requestData.decryptedRequest = decrypted;
6908
+ self2.requests.set(requestId, requestData);
6909
+ self2.notifyListeners(requestData);
6910
+ }
6911
+ }).catch((e) => console.warn("解密请求失败:", e));
6863
6912
  }
6864
6913
  self2.requests.set(requestId, requestData);
6865
6914
  self2.notifyListeners(requestData);
@@ -6885,10 +6934,16 @@ class NetworkInterceptor {
6885
6934
  updatedRequestData.responseBody = responseText;
6886
6935
  }
6887
6936
  if (updatedRequestData.responseBody) {
6888
- updatedRequestData.decryptedResponse = self2.tryDecrypt(
6937
+ self2.tryDecrypt(
6889
6938
  updatedRequestData.responseBody,
6890
6939
  { ...requestHeaders, ...responseHeaders }
6891
- );
6940
+ ).then((decrypted) => {
6941
+ if (decrypted !== null) {
6942
+ updatedRequestData.decryptedResponse = decrypted;
6943
+ self2.requests.set(requestId, updatedRequestData);
6944
+ self2.notifyListeners(updatedRequestData);
6945
+ }
6946
+ }).catch((e) => console.warn("解密响应失败:", e));
6892
6947
  }
6893
6948
  } catch (error) {
6894
6949
  updatedRequestData.error = `Failed to read response: ${error}`;
@@ -6932,28 +6987,72 @@ class WasmLoader {
6932
6987
  }
6933
6988
  this.loading = true;
6934
6989
  try {
6935
- const defaultWasmUrl = wasmUrl || "/mimlib.wasm";
6936
- const defaultJsUrl = jsUrl || "/wasm_exec.js";
6937
- await this.loadScript(defaultJsUrl);
6990
+ const wasmPaths = [
6991
+ wasmUrl,
6992
+ "/mimlib.wasm",
6993
+ "/dist/mimlib.wasm",
6994
+ "/assets/mimlib.wasm",
6995
+ "https://gw-card-pay.buyacard.cc/mimlib.wasm"
6996
+ ].filter(Boolean);
6997
+ const jsPaths = [
6998
+ jsUrl,
6999
+ "/wasm_exec.js",
7000
+ "/dist/wasm_exec.js",
7001
+ "/assets/wasm_exec.js",
7002
+ "https://gw-card-pay.buyacard.cc/wasm_exec.js"
7003
+ ].filter(Boolean);
7004
+ let jsLoaded = false;
7005
+ for (const jsPath of jsPaths) {
7006
+ try {
7007
+ await this.loadScript(jsPath);
7008
+ if (typeof window.Go !== "undefined") {
7009
+ jsLoaded = true;
7010
+ console.log("NetworkDebugger: wasm_exec.js 加载成功:", jsPath);
7011
+ break;
7012
+ }
7013
+ } catch (e) {
7014
+ console.warn("NetworkDebugger: 尝试加载", jsPath, "失败:", e);
7015
+ continue;
7016
+ }
7017
+ }
7018
+ if (!jsLoaded) {
7019
+ throw new Error("Unable to load wasm_exec.js from any path");
7020
+ }
6938
7021
  if (typeof window.Go === "undefined") {
6939
7022
  throw new Error("Go WebAssembly runtime not available");
6940
7023
  }
6941
7024
  const go = new window.Go();
6942
- let wasmModule;
6943
- if (WebAssembly.instantiateStreaming) {
7025
+ let wasmModule = null;
7026
+ for (const wasmPath of wasmPaths) {
6944
7027
  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);
7028
+ if (WebAssembly.instantiateStreaming) {
7029
+ try {
7030
+ wasmModule = await WebAssembly.instantiateStreaming(
7031
+ fetch(wasmPath),
7032
+ go.importObject
7033
+ );
7034
+ console.log("NetworkDebugger: WebAssembly 加载成功:", wasmPath);
7035
+ break;
7036
+ } catch (streamError) {
7037
+ console.warn("instantiateStreaming 失败,尝试传统方式:", streamError);
7038
+ const wasmBuffer = await fetch(wasmPath).then((response) => response.arrayBuffer());
7039
+ wasmModule = await WebAssembly.instantiate(wasmBuffer, go.importObject);
7040
+ console.log("NetworkDebugger: WebAssembly 加载成功(传统方式):", wasmPath);
7041
+ break;
7042
+ }
7043
+ } else {
7044
+ const wasmBuffer = await fetch(wasmPath).then((response) => response.arrayBuffer());
7045
+ wasmModule = await WebAssembly.instantiate(wasmBuffer, go.importObject);
7046
+ console.log("NetworkDebugger: WebAssembly 加载成功(传统方式):", wasmPath);
7047
+ break;
7048
+ }
7049
+ } catch (error) {
7050
+ console.warn("NetworkDebugger: 尝试加载", wasmPath, "失败:", error);
7051
+ continue;
6953
7052
  }
6954
- } else {
6955
- const wasmBuffer = await fetch(defaultWasmUrl).then((response) => response.arrayBuffer());
6956
- wasmModule = await WebAssembly.instantiate(wasmBuffer, go.importObject);
7053
+ }
7054
+ if (!wasmModule) {
7055
+ throw new Error("Unable to load WebAssembly from any path");
6957
7056
  }
6958
7057
  go.run(wasmModule.instance);
6959
7058
  this.loaded = true;
@@ -7181,6 +7280,7 @@ const styles = `
7181
7280
  padding: 10px;
7182
7281
  cursor: pointer;
7183
7282
  transition: all 0.2s;
7283
+ position: relative;
7184
7284
  }
7185
7285
 
7186
7286
  .request-item:hover {
@@ -7330,6 +7430,27 @@ const styles = `
7330
7430
  font-weight: bold;
7331
7431
  }
7332
7432
 
7433
+ .share-btn {
7434
+ background: #2196F3;
7435
+ color: #fff;
7436
+ border: none;
7437
+ padding: 4px 8px;
7438
+ border-radius: 3px;
7439
+ font-size: 10px;
7440
+ margin-left: 8px;
7441
+ cursor: pointer;
7442
+ transition: all 0.2s;
7443
+ }
7444
+
7445
+ .share-btn:hover {
7446
+ background: #1976D2;
7447
+ transform: scale(1.1);
7448
+ }
7449
+
7450
+ .share-btn:active {
7451
+ transform: scale(0.95);
7452
+ }
7453
+
7333
7454
  .console-content {
7334
7455
  background: #000;
7335
7456
  color: #0f0;
@@ -7497,6 +7618,77 @@ const styles = `
7497
7618
  cursor: sw-resize;
7498
7619
  }
7499
7620
  `;
7621
+ async function createShareLink(requestData) {
7622
+ try {
7623
+ const shareData = {
7624
+ // 基础信息
7625
+ url: requestData.url,
7626
+ method: requestData.method,
7627
+ headers: requestData.headers,
7628
+ status: requestData.status,
7629
+ statusText: requestData.statusText,
7630
+ timestamp: requestData.timestamp,
7631
+ duration: requestData.duration,
7632
+ // 请求和响应数据
7633
+ requestBody: requestData.requestBody,
7634
+ responseBody: requestData.responseBody,
7635
+ responseHeaders: requestData.responseHeaders,
7636
+ // 解密后的数据(如果有)
7637
+ decryptedRequest: requestData.decryptedRequest,
7638
+ decryptedResponse: requestData.decryptedResponse,
7639
+ // 错误信息(如果有)
7640
+ error: requestData.error,
7641
+ // 元数据
7642
+ creator: "PWTK Network Debugger by Leo (@leeguoo)",
7643
+ createdAt: Date.now(),
7644
+ version: "1.2.0"
7645
+ };
7646
+ const response = await fetch("https://gw-card-pay.buyacard.cc/api/dokv/storage", {
7647
+ method: "POST",
7648
+ headers: {
7649
+ "Content-Type": "application/json"
7650
+ },
7651
+ body: JSON.stringify({
7652
+ data: shareData,
7653
+ type: "network-request",
7654
+ expireIn: 7 * 24 * 60 * 60 * 1e3
7655
+ // 7天过期
7656
+ })
7657
+ });
7658
+ const result = await response.json();
7659
+ if (result.success && result.id) {
7660
+ const shareUrl = `https://curl.bwg.leeguoo.com/share/${result.id}`;
7661
+ console.log(`🔗 分享链接创建成功 (by Leo): ${shareUrl}`);
7662
+ return shareUrl;
7663
+ } else {
7664
+ throw new Error(result.message || "创建分享失败");
7665
+ }
7666
+ } catch (error) {
7667
+ console.error("NetworkDebugger: 创建分享链接失败:", error);
7668
+ throw error;
7669
+ }
7670
+ }
7671
+ async function copyToClipboard(text) {
7672
+ try {
7673
+ if (navigator.clipboard && navigator.clipboard.writeText) {
7674
+ await navigator.clipboard.writeText(text);
7675
+ return true;
7676
+ } else {
7677
+ const textArea = document.createElement("textarea");
7678
+ textArea.value = text;
7679
+ textArea.style.position = "fixed";
7680
+ textArea.style.opacity = "0";
7681
+ document.body.appendChild(textArea);
7682
+ textArea.select();
7683
+ const success = document.execCommand("copy");
7684
+ document.body.removeChild(textArea);
7685
+ return success;
7686
+ }
7687
+ } catch (error) {
7688
+ console.error("复制到剪贴板失败:", error);
7689
+ return false;
7690
+ }
7691
+ }
7500
7692
  class DebugPanel {
7501
7693
  constructor(interceptor, config = {}) {
7502
7694
  this.isDragging = false;
@@ -7529,7 +7721,7 @@ class DebugPanel {
7529
7721
  this.container.className = `${this.config.position} ${this.config.minimized ? "minimized" : ""}`;
7530
7722
  this.container.innerHTML = `
7531
7723
  <div class="debugger-header">
7532
- <div class="debugger-title">🔍 Network Debugger</div>
7724
+ <div class="debugger-title">🔍 Network Debugger <span style="font-size: 10px; opacity: 0.7;">by Leo</span></div>
7533
7725
  <div class="debugger-controls">
7534
7726
  <button class="debugger-btn" data-action="clear" title="清空">🗑️</button>
7535
7727
  <button class="debugger-btn" data-action="export" title="导出">💾</button>
@@ -7543,6 +7735,7 @@ class DebugPanel {
7543
7735
  <button class="debugger-tab active" data-tab="network">网络</button>
7544
7736
  ${this.config.showConsole ? '<button class="debugger-tab" data-tab="console">控制台</button>' : ""}
7545
7737
  <button class="debugger-tab" data-tab="tools">工具</button>
7738
+ <button class="debugger-tab" data-tab="about">关于</button>
7546
7739
  </div>
7547
7740
  <div class="debugger-panel-content">
7548
7741
  <div class="network-panel" data-panel="network">
@@ -7570,6 +7763,19 @@ class DebugPanel {
7570
7763
  <textarea placeholder="在这里粘贴 cURL 命令或输入要测试的数据..." style="width: 100%; height: 200px; background: #222; color: #fff; border: 1px solid #444; padding: 8px; font-family: monospace;"></textarea>
7571
7764
  </div>
7572
7765
  </div>
7766
+ <div class="about-panel" data-panel="about" style="display: none;">
7767
+ <div style="padding: 20px; color: #fff; text-align: center;">
7768
+ <h2 style="margin: 0 0 20px 0;">🔍 PWTK Network Debugger</h2>
7769
+ <p style="margin: 10px 0;">Version: 1.2.0</p>
7770
+ <p style="margin: 10px 0;">👨‍💻 Created by <strong>Leo (@leeguoo)</strong></p>
7771
+ <p style="margin: 10px 0;">📧 技术支持:请联系 Leo</p>
7772
+ <p style="margin: 10px 0;">🌐 分享服务:curl.bwg.leeguoo.com</p>
7773
+ <div style="margin-top: 20px; padding: 15px; background: #333; border-radius: 8px;">
7774
+ <p style="margin: 5px 0; font-size: 12px;">本工具专为 PWTK 项目开发</p>
7775
+ <p style="margin: 5px 0; font-size: 12px;">提供网络请求拦截、解密、分享等功能</p>
7776
+ </div>
7777
+ </div>
7778
+ </div>
7573
7779
  </div>
7574
7780
  </div>
7575
7781
  `;
@@ -7689,6 +7895,7 @@ class DebugPanel {
7689
7895
  <span class="request-status ${statusClass}">${request.status || "ERR"}</span>
7690
7896
  ${hasDecryptedData ? '<span class="decrypted-badge">🔓</span>' : ""}
7691
7897
  ${hasError ? '<span class="error-badge">⚠️</span>' : ""}
7898
+ <button class="share-btn" title="分享此请求 (by Leo)" onclick="event.stopPropagation()">📤</button>
7692
7899
  </div>
7693
7900
  <div class="request-info">
7694
7901
  <span>${new Date(request.timestamp).toLocaleTimeString()}</span>
@@ -7701,6 +7908,13 @@ class DebugPanel {
7701
7908
  item.addEventListener("click", () => {
7702
7909
  item.classList.toggle("expanded");
7703
7910
  });
7911
+ const shareBtn = item.querySelector(".share-btn");
7912
+ if (shareBtn) {
7913
+ shareBtn.addEventListener("click", async (e) => {
7914
+ e.stopPropagation();
7915
+ await this.shareRequest(request);
7916
+ });
7917
+ }
7704
7918
  return item;
7705
7919
  }
7706
7920
  renderRequestDetails(request) {
@@ -7833,7 +8047,8 @@ class DebugPanel {
7833
8047
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7834
8048
  requests: this.requestsCache,
7835
8049
  userAgent: navigator.userAgent,
7836
- url: window.location.href
8050
+ url: window.location.href,
8051
+ creator: "PWTK Network Debugger by Leo (@leeguoo)"
7837
8052
  };
7838
8053
  const blob = new Blob([JSON.stringify(data, null, 2)], { type: "application/json" });
7839
8054
  const url = URL.createObjectURL(blob);
@@ -7842,7 +8057,32 @@ class DebugPanel {
7842
8057
  a.download = `network-debug-${Date.now()}.json`;
7843
8058
  a.click();
7844
8059
  URL.revokeObjectURL(url);
7845
- this.logToConsole("💾 网络数据已导出");
8060
+ this.logToConsole("💾 网络数据已导出 (by Leo)");
8061
+ }
8062
+ async shareRequest(request) {
8063
+ try {
8064
+ this.logToConsole("📤 正在创建分享链接...");
8065
+ const shareUrl = await createShareLink(request);
8066
+ if (shareUrl) {
8067
+ const copied = await copyToClipboard(shareUrl);
8068
+ if (copied) {
8069
+ this.logToConsole(`✅ 分享链接已复制到剪贴板: ${shareUrl}`);
8070
+ alert(`分享链接已复制到剪贴板!
8071
+ ${shareUrl}
8072
+
8073
+ Created by Leo (@leeguoo)`);
8074
+ } else {
8075
+ this.logToConsole(`✅ 分享链接: ${shareUrl}`);
8076
+ prompt("分享链接已创建,请手动复制:\n\nCreated by Leo (@leeguoo)", shareUrl);
8077
+ }
8078
+ } else {
8079
+ throw new Error("无法创建分享链接");
8080
+ }
8081
+ } catch (error) {
8082
+ console.error("分享失败:", error);
8083
+ this.logToConsole(`❌ 分享失败: ${error}`);
8084
+ alert("分享失败,请稍后重试");
8085
+ }
7846
8086
  }
7847
8087
  toggleMinimize() {
7848
8088
  this.config.minimized = !this.config.minimized;
@@ -8064,6 +8304,8 @@ class NetworkDebugger {
8064
8304
  },
8065
8305
  decrypt: {
8066
8306
  enabled: true,
8307
+ autoFetchKeys: true,
8308
+ keyApiUrl: "https://gw-card-pay.buyacard.cc/ip/getSK",
8067
8309
  ...config.decrypt
8068
8310
  },
8069
8311
  ...config
@@ -8077,14 +8319,24 @@ class NetworkDebugger {
8077
8319
  if (this.config.decrypt?.enabled) {
8078
8320
  this.interceptor.enableDecryption({
8079
8321
  keyExtractor: this.config.decrypt.keyExtractor || this.defaultKeyExtractor,
8080
- slkExtractor: this.config.decrypt.slkExtractor || this.defaultSlkExtractor
8322
+ slkExtractor: this.config.decrypt.slkExtractor || this.defaultSlkExtractor,
8323
+ autoFetchKeys: this.config.decrypt.autoFetchKeys,
8324
+ keyApiUrl: this.config.decrypt.keyApiUrl
8081
8325
  });
8082
8326
  }
8083
8327
  if (this.config.autoStart !== false) {
8084
8328
  this.createPanel();
8085
8329
  }
8086
8330
  this.initialized = true;
8087
- console.log("🔍 NetworkDebugger initialized successfully by Leo (@leeguoo)");
8331
+ console.log(`
8332
+ ╔════════════════════════════════════════╗
8333
+ ║ PWTK Network Debugger v1.2.0 ║
8334
+ ║ Created by Leo (@leeguoo) ║
8335
+ ║ 技术支持: 请联系 Leo ║
8336
+ ║ 分享服务: curl.bwg.leeguoo.com ║
8337
+ ╚════════════════════════════════════════╝
8338
+ `);
8339
+ console.log("🔍 NetworkDebugger initialized successfully");
8088
8340
  } catch (error) {
8089
8341
  console.error("NetworkDebugger initialization failed:", error);
8090
8342
  throw error;