qwenproxy-cli 1.6.4 → 1.6.6

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);
@@ -3544,6 +3588,13 @@ async function initPlaywrightForAccount(rawAccount, headless = config.playwright
3544
3588
  await existingInit;
3545
3589
  return;
3546
3590
  }
3591
+ let resolveInit;
3592
+ let rejectInit;
3593
+ const inFlightDeferred = new Promise((res, rej) => {
3594
+ resolveInit = res;
3595
+ rejectInit = rej;
3596
+ });
3597
+ inFlightAccountInits.set(account.id, inFlightDeferred);
3547
3598
  const initPromise = (async () => {
3548
3599
  const release = await acquireAccountMutex(
3549
3600
  account.id,
@@ -3758,6 +3809,22 @@ async function initPlaywrightForAccount(rawAccount, headless = config.playwright
3758
3809
  }
3759
3810
  }
3760
3811
  }
3812
+ const currentCache = getHeaderCache(account.id);
3813
+ const currentCookie = currentCache?.headers?.cookie || "";
3814
+ if (currentCookie && isTokenExpiringSoon(currentCookie, 5)) {
3815
+ try {
3816
+ const refreshRes = await refreshAccountToken(account.id);
3817
+ if (refreshRes.success) {
3818
+ console.log(
3819
+ `\u26A1 [Playwright] Silently refreshed expired token restored from DB for ${maskEmail(account.email)}`
3820
+ );
3821
+ }
3822
+ } catch (err) {
3823
+ console.warn(
3824
+ `\u26A0\uFE0F [Playwright] Failed to proactively refresh expired token from DB for ${maskEmail(account.email)}: ${err?.message || err}`
3825
+ );
3826
+ }
3827
+ }
3761
3828
  return;
3762
3829
  }
3763
3830
  const cookies = await acctContext.cookies();
@@ -3812,9 +3879,12 @@ async function initPlaywrightForAccount(rawAccount, headless = config.playwright
3812
3879
  release();
3813
3880
  }
3814
3881
  })();
3815
- inFlightAccountInits.set(account.id, initPromise);
3816
3882
  try {
3817
3883
  await initPromise;
3884
+ resolveInit();
3885
+ } catch (error) {
3886
+ rejectInit(error);
3887
+ throw error;
3818
3888
  } finally {
3819
3889
  inFlightAccountInits.delete(account.id);
3820
3890
  }
@@ -4015,7 +4085,7 @@ async function loginViaApi(page, email, password) {
4015
4085
  const signinUrl = "https://auth.qwen.ai/api/v2/auths/signin";
4016
4086
  const requestId = crypto3.randomUUID();
4017
4087
  const evalRes = await page.evaluate(
4018
- async ({ email: email2, password: password2, signinUrl: signinUrl2, requestId: requestId2 }) => {
4088
+ async ({ email: email2, password: password2, signinUrl: signinUrl2, requestId: requestId2, tz }) => {
4019
4089
  try {
4020
4090
  const response = await fetch(signinUrl2, {
4021
4091
  method: "POST",
@@ -4027,7 +4097,7 @@ async function loginViaApi(page, email, password) {
4027
4097
  source: "web",
4028
4098
  version: "0.3.11",
4029
4099
  "x-request-origin": "https://chat.qwen.ai",
4030
- timezone: (/* @__PURE__ */ new Date()).toString().split(" (")[0],
4100
+ timezone: tz,
4031
4101
  "x-request-id": requestId2
4032
4102
  },
4033
4103
  body: JSON.stringify({ email: email2, password: password2 })
@@ -4038,7 +4108,7 @@ async function loginViaApi(page, email, password) {
4038
4108
  return { ok: false, error: e.message };
4039
4109
  }
4040
4110
  },
4041
- { email, password: hashedPassword, signinUrl, requestId }
4111
+ { email, password: hashedPassword, signinUrl, requestId, tz: formatAsciiTimezone() }
4042
4112
  ).catch(() => null);
4043
4113
  let data = evalRes?.data;
4044
4114
  let signinSuccess = Boolean(
@@ -4047,7 +4117,7 @@ async function loginViaApi(page, email, password) {
4047
4117
  if (!signinSuccess && !data?.data?.code) {
4048
4118
  const fallbackUrl = qwenUrl("/api/v2/auths/signin");
4049
4119
  const fallbackRes = await page.evaluate(
4050
- async ({ email: email2, password: password2, fallbackUrl: fallbackUrl2, requestId: requestId2 }) => {
4120
+ async ({ email: email2, password: password2, fallbackUrl: fallbackUrl2, requestId: requestId2, tz }) => {
4051
4121
  try {
4052
4122
  const response = await fetch(fallbackUrl2, {
4053
4123
  method: "POST",
@@ -4058,7 +4128,7 @@ async function loginViaApi(page, email, password) {
4058
4128
  "content-type": "application/json",
4059
4129
  source: "web",
4060
4130
  version: "0.3.11",
4061
- timezone: (/* @__PURE__ */ new Date()).toString().split(" (")[0],
4131
+ timezone: tz,
4062
4132
  "x-request-id": requestId2
4063
4133
  },
4064
4134
  body: JSON.stringify({ email: email2, password: password2 })
@@ -4069,7 +4139,7 @@ async function loginViaApi(page, email, password) {
4069
4139
  return { ok: false, error: e.message };
4070
4140
  }
4071
4141
  },
4072
- { email, password: hashedPassword, fallbackUrl, requestId }
4142
+ { email, password: hashedPassword, fallbackUrl, requestId, tz: formatAsciiTimezone() }
4073
4143
  ).catch(() => null);
4074
4144
  if (fallbackRes?.data) {
4075
4145
  data = fallbackRes.data;
@@ -4401,7 +4471,7 @@ async function refreshAccountToken(accountId) {
4401
4471
  if (refreshToken) {
4402
4472
  try {
4403
4473
  const refreshResult = await page.evaluate(
4404
- async ({ rTok }) => {
4474
+ async ({ rTok, tz }) => {
4405
4475
  try {
4406
4476
  const response = await fetch("https://auth.qwen.ai/api/v2/auths/refresh", {
4407
4477
  method: "GET",
@@ -4411,7 +4481,7 @@ async function refreshAccountToken(accountId) {
4411
4481
  source: "web",
4412
4482
  version: "0.3.11",
4413
4483
  "x-request-origin": "https://chat.qwen.ai",
4414
- timezone: (/* @__PURE__ */ new Date()).toString().split(" (")[0],
4484
+ timezone: tz,
4415
4485
  authorization: `Bearer ${rTok}`
4416
4486
  }
4417
4487
  });
@@ -4421,7 +4491,7 @@ async function refreshAccountToken(accountId) {
4421
4491
  return { ok: false, error: e.message };
4422
4492
  }
4423
4493
  },
4424
- { rTok: refreshToken }
4494
+ { rTok: refreshToken, tz: formatAsciiTimezone() }
4425
4495
  );
4426
4496
  const json = refreshResult?.data;
4427
4497
  if (json && json.success === true && json.data) {
@@ -4459,6 +4529,7 @@ async function refreshAccountToken(accountId) {
4459
4529
  const cache = getHeaderCache(accountId);
4460
4530
  cache.headers.cookie = cookieStr;
4461
4531
  cache.lastRefresh = Date.now();
4532
+ cookieCaches.set(accountId, { cookie: cookieStr, timestamp: Date.now() });
4462
4533
  markAccountHeadersReady(accountId);
4463
4534
  saveAuthSession2(accountId, {
4464
4535
  cookie: cookieStr,
@@ -4493,6 +4564,7 @@ async function refreshAccountToken(accountId) {
4493
4564
  const cache = getHeaderCache(accountId);
4494
4565
  cache.headers.cookie = cookieStr;
4495
4566
  cache.lastRefresh = Date.now();
4567
+ cookieCaches.set(accountId, { cookie: cookieStr, timestamp: Date.now() });
4496
4568
  markAccountHeadersReady(accountId);
4497
4569
  saveAuthSession2(accountId, {
4498
4570
  cookie: cookieStr,
@@ -5373,6 +5445,7 @@ var init_playwright = __esm({
5373
5445
  init_qwen_headers();
5374
5446
  init_paths();
5375
5447
  init_jwt();
5448
+ init_timezone();
5376
5449
  requireLocal = createRequire(import.meta.url);
5377
5450
  contextInitHooks = [];
5378
5451
  ACCOUNT_MUTEX_MAX_HOLD_MS = 18e4;
@@ -5382,7 +5455,7 @@ var init_playwright = __esm({
5382
5455
  inFlightAccountInits = /* @__PURE__ */ new Map();
5383
5456
  headerCaches = /* @__PURE__ */ new Map();
5384
5457
  HEADER_CACHE_TTL = 24 * 60 * 60 * 1e3;
5385
- COOKIE_CACHE_TTL = 15 * 60 * 1e3;
5458
+ COOKIE_CACHE_TTL = 60 * 1e3;
5386
5459
  cookieCaches = /* @__PURE__ */ new Map();
5387
5460
  lastAccountActivity = /* @__PURE__ */ new Map();
5388
5461
  lastKeepAliveNavigation = /* @__PURE__ */ new Map();