qwenproxy-cli 1.6.4 → 1.6.5

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.
@@ -1814,6 +1814,7 @@ var init_mutex = __esm({
1814
1814
  locked = false;
1815
1815
  lockedAt = 0;
1816
1816
  lockedByKey = "";
1817
+ epoch = 0;
1817
1818
  async acquire(timeoutMs = 3e5, key = "") {
1818
1819
  const holdLimitMs = this.maxHoldMs;
1819
1820
  if (this.locked && Date.now() - this.lockedAt > holdLimitMs) {
@@ -1824,6 +1825,7 @@ var init_mutex = __esm({
1824
1825
  this.locked = false;
1825
1826
  this.lockedAt = 0;
1826
1827
  this.lockedByKey = "";
1828
+ this.epoch++;
1827
1829
  }
1828
1830
  if (!this.locked) {
1829
1831
  this.locked = true;
@@ -1862,10 +1864,12 @@ var init_mutex = __esm({
1862
1864
  }
1863
1865
  }
1864
1866
  createRelease() {
1867
+ const epoch = this.epoch;
1865
1868
  let released = false;
1866
1869
  return () => {
1867
1870
  if (released) return;
1868
1871
  released = true;
1872
+ if (epoch !== this.epoch) return;
1869
1873
  this.release();
1870
1874
  };
1871
1875
  }
@@ -2673,6 +2677,45 @@ var init_waf_isolation = __esm({
2673
2677
  }
2674
2678
  });
2675
2679
 
2680
+ // src/utils/timezone.ts
2681
+ function formatAsciiTimezone(date = /* @__PURE__ */ new Date()) {
2682
+ const dayName = DAYS[date.getDay()];
2683
+ const monthName = MONTHS[date.getMonth()];
2684
+ const day = String(date.getDate()).padStart(2, "0");
2685
+ const year = date.getFullYear();
2686
+ const hours = String(date.getHours()).padStart(2, "0");
2687
+ const minutes = String(date.getMinutes()).padStart(2, "0");
2688
+ const seconds = String(date.getSeconds()).padStart(2, "0");
2689
+ const offsetMinutes = -date.getTimezoneOffset();
2690
+ const sign = offsetMinutes >= 0 ? "+" : "-";
2691
+ const absOffset = Math.abs(offsetMinutes);
2692
+ const offsetHours = String(Math.floor(absOffset / 60)).padStart(2, "0");
2693
+ const offsetMins = String(absOffset % 60).padStart(2, "0");
2694
+ const tzOffset = `GMT${sign}${offsetHours}${offsetMins}`;
2695
+ return `${dayName} ${monthName} ${day} ${year} ${hours}:${minutes}:${seconds} ${tzOffset}`;
2696
+ }
2697
+ var DAYS, MONTHS;
2698
+ var init_timezone = __esm({
2699
+ "src/utils/timezone.ts"() {
2700
+ "use strict";
2701
+ DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
2702
+ MONTHS = [
2703
+ "Jan",
2704
+ "Feb",
2705
+ "Mar",
2706
+ "Apr",
2707
+ "May",
2708
+ "Jun",
2709
+ "Jul",
2710
+ "Aug",
2711
+ "Sep",
2712
+ "Oct",
2713
+ "Nov",
2714
+ "Dec"
2715
+ ];
2716
+ }
2717
+ });
2718
+
2676
2719
  // src/services/qwen-headers.ts
2677
2720
  import { v4 as uuidv4 } from "uuid";
2678
2721
  function getDefaultQwenUserAgent(major = getChromeMajor()) {
@@ -2690,6 +2733,7 @@ var init_qwen_headers = __esm({
2690
2733
  init_qwen_url();
2691
2734
  init_config();
2692
2735
  init_fingerprint();
2736
+ init_timezone();
2693
2737
  dynamicWebVersion = null;
2694
2738
  QWEN_WEB_VERSION = config.qwen.webVersion;
2695
2739
  DEFAULT_QWEN_USER_AGENT = getDefaultQwenUserAgent(151);
@@ -3758,6 +3802,22 @@ async function initPlaywrightForAccount(rawAccount, headless = config.playwright
3758
3802
  }
3759
3803
  }
3760
3804
  }
3805
+ const currentCache = getHeaderCache(account.id);
3806
+ const currentCookie = currentCache?.headers?.cookie || "";
3807
+ if (currentCookie && isTokenExpiringSoon(currentCookie, 5)) {
3808
+ try {
3809
+ const refreshRes = await refreshAccountToken(account.id);
3810
+ if (refreshRes.success) {
3811
+ console.log(
3812
+ `\u26A1 [Playwright] Silently refreshed expired token restored from DB for ${maskEmail(account.email)}`
3813
+ );
3814
+ }
3815
+ } catch (err) {
3816
+ console.warn(
3817
+ `\u26A0\uFE0F [Playwright] Failed to proactively refresh expired token from DB for ${maskEmail(account.email)}: ${err?.message || err}`
3818
+ );
3819
+ }
3820
+ }
3761
3821
  return;
3762
3822
  }
3763
3823
  const cookies = await acctContext.cookies();
@@ -4015,7 +4075,7 @@ async function loginViaApi(page, email, password) {
4015
4075
  const signinUrl = "https://auth.qwen.ai/api/v2/auths/signin";
4016
4076
  const requestId = crypto3.randomUUID();
4017
4077
  const evalRes = await page.evaluate(
4018
- async ({ email: email2, password: password2, signinUrl: signinUrl2, requestId: requestId2 }) => {
4078
+ async ({ email: email2, password: password2, signinUrl: signinUrl2, requestId: requestId2, tz }) => {
4019
4079
  try {
4020
4080
  const response = await fetch(signinUrl2, {
4021
4081
  method: "POST",
@@ -4027,7 +4087,7 @@ async function loginViaApi(page, email, password) {
4027
4087
  source: "web",
4028
4088
  version: "0.3.11",
4029
4089
  "x-request-origin": "https://chat.qwen.ai",
4030
- timezone: (/* @__PURE__ */ new Date()).toString().split(" (")[0],
4090
+ timezone: tz,
4031
4091
  "x-request-id": requestId2
4032
4092
  },
4033
4093
  body: JSON.stringify({ email: email2, password: password2 })
@@ -4038,7 +4098,7 @@ async function loginViaApi(page, email, password) {
4038
4098
  return { ok: false, error: e.message };
4039
4099
  }
4040
4100
  },
4041
- { email, password: hashedPassword, signinUrl, requestId }
4101
+ { email, password: hashedPassword, signinUrl, requestId, tz: formatAsciiTimezone() }
4042
4102
  ).catch(() => null);
4043
4103
  let data = evalRes?.data;
4044
4104
  let signinSuccess = Boolean(
@@ -4047,7 +4107,7 @@ async function loginViaApi(page, email, password) {
4047
4107
  if (!signinSuccess && !data?.data?.code) {
4048
4108
  const fallbackUrl = qwenUrl("/api/v2/auths/signin");
4049
4109
  const fallbackRes = await page.evaluate(
4050
- async ({ email: email2, password: password2, fallbackUrl: fallbackUrl2, requestId: requestId2 }) => {
4110
+ async ({ email: email2, password: password2, fallbackUrl: fallbackUrl2, requestId: requestId2, tz }) => {
4051
4111
  try {
4052
4112
  const response = await fetch(fallbackUrl2, {
4053
4113
  method: "POST",
@@ -4058,7 +4118,7 @@ async function loginViaApi(page, email, password) {
4058
4118
  "content-type": "application/json",
4059
4119
  source: "web",
4060
4120
  version: "0.3.11",
4061
- timezone: (/* @__PURE__ */ new Date()).toString().split(" (")[0],
4121
+ timezone: tz,
4062
4122
  "x-request-id": requestId2
4063
4123
  },
4064
4124
  body: JSON.stringify({ email: email2, password: password2 })
@@ -4069,7 +4129,7 @@ async function loginViaApi(page, email, password) {
4069
4129
  return { ok: false, error: e.message };
4070
4130
  }
4071
4131
  },
4072
- { email, password: hashedPassword, fallbackUrl, requestId }
4132
+ { email, password: hashedPassword, fallbackUrl, requestId, tz: formatAsciiTimezone() }
4073
4133
  ).catch(() => null);
4074
4134
  if (fallbackRes?.data) {
4075
4135
  data = fallbackRes.data;
@@ -4401,7 +4461,7 @@ async function refreshAccountToken(accountId) {
4401
4461
  if (refreshToken) {
4402
4462
  try {
4403
4463
  const refreshResult = await page.evaluate(
4404
- async ({ rTok }) => {
4464
+ async ({ rTok, tz }) => {
4405
4465
  try {
4406
4466
  const response = await fetch("https://auth.qwen.ai/api/v2/auths/refresh", {
4407
4467
  method: "GET",
@@ -4411,7 +4471,7 @@ async function refreshAccountToken(accountId) {
4411
4471
  source: "web",
4412
4472
  version: "0.3.11",
4413
4473
  "x-request-origin": "https://chat.qwen.ai",
4414
- timezone: (/* @__PURE__ */ new Date()).toString().split(" (")[0],
4474
+ timezone: tz,
4415
4475
  authorization: `Bearer ${rTok}`
4416
4476
  }
4417
4477
  });
@@ -4421,7 +4481,7 @@ async function refreshAccountToken(accountId) {
4421
4481
  return { ok: false, error: e.message };
4422
4482
  }
4423
4483
  },
4424
- { rTok: refreshToken }
4484
+ { rTok: refreshToken, tz: formatAsciiTimezone() }
4425
4485
  );
4426
4486
  const json = refreshResult?.data;
4427
4487
  if (json && json.success === true && json.data) {
@@ -4459,6 +4519,7 @@ async function refreshAccountToken(accountId) {
4459
4519
  const cache = getHeaderCache(accountId);
4460
4520
  cache.headers.cookie = cookieStr;
4461
4521
  cache.lastRefresh = Date.now();
4522
+ cookieCaches.set(accountId, { cookie: cookieStr, timestamp: Date.now() });
4462
4523
  markAccountHeadersReady(accountId);
4463
4524
  saveAuthSession2(accountId, {
4464
4525
  cookie: cookieStr,
@@ -4493,6 +4554,7 @@ async function refreshAccountToken(accountId) {
4493
4554
  const cache = getHeaderCache(accountId);
4494
4555
  cache.headers.cookie = cookieStr;
4495
4556
  cache.lastRefresh = Date.now();
4557
+ cookieCaches.set(accountId, { cookie: cookieStr, timestamp: Date.now() });
4496
4558
  markAccountHeadersReady(accountId);
4497
4559
  saveAuthSession2(accountId, {
4498
4560
  cookie: cookieStr,
@@ -5373,6 +5435,7 @@ var init_playwright = __esm({
5373
5435
  init_qwen_headers();
5374
5436
  init_paths();
5375
5437
  init_jwt();
5438
+ init_timezone();
5376
5439
  requireLocal = createRequire(import.meta.url);
5377
5440
  contextInitHooks = [];
5378
5441
  ACCOUNT_MUTEX_MAX_HOLD_MS = 18e4;
@@ -5382,7 +5445,7 @@ var init_playwright = __esm({
5382
5445
  inFlightAccountInits = /* @__PURE__ */ new Map();
5383
5446
  headerCaches = /* @__PURE__ */ new Map();
5384
5447
  HEADER_CACHE_TTL = 24 * 60 * 60 * 1e3;
5385
- COOKIE_CACHE_TTL = 15 * 60 * 1e3;
5448
+ COOKIE_CACHE_TTL = 60 * 1e3;
5386
5449
  cookieCaches = /* @__PURE__ */ new Map();
5387
5450
  lastAccountActivity = /* @__PURE__ */ new Map();
5388
5451
  lastKeepAliveNavigation = /* @__PURE__ */ new Map();