qwenproxy-cli 1.6.9 → 1.6.10

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.js CHANGED
@@ -4629,7 +4629,19 @@ async function isPageLoggedIn(page, timeoutMs = SESSION_PROBE_NAVIGATION_TIMEOUT
4629
4629
  if (localStorage.getItem("qwen_token_logged_out_marker")) {
4630
4630
  return false;
4631
4631
  }
4632
- const res = await fetch("/api/v1/auths/", { method: "GET" });
4632
+ const lsToken = (localStorage.getItem("token") || "").trim();
4633
+ if (lsToken && !/(?:^|;\s*)token=/.test(document.cookie || "")) {
4634
+ try {
4635
+ document.cookie = `token=${encodeURIComponent(lsToken)}; path=/; domain=.qwen.ai; max-age=31536000`;
4636
+ } catch {
4637
+ }
4638
+ }
4639
+ const authHeaders = lsToken ? { Authorization: `Bearer ${lsToken}` } : {};
4640
+ const res = await fetch("/api/v1/auths/", {
4641
+ method: "GET",
4642
+ headers: authHeaders,
4643
+ credentials: "include"
4644
+ });
4633
4645
  if (res.status !== 200) return false;
4634
4646
  const json = await res.json().catch(() => null);
4635
4647
  if (!json) return false;
@@ -4647,6 +4659,7 @@ async function isPageLoggedIn(page, timeoutMs = SESSION_PROBE_NAVIGATION_TIMEOUT
4647
4659
  try {
4648
4660
  const settingsRes = await fetch("/api/v2/users/user/settings", {
4649
4661
  method: "GET",
4662
+ headers: authHeaders,
4650
4663
  credentials: "include",
4651
4664
  signal: AbortSignal.timeout(3e3)
4652
4665
  });
@@ -5805,8 +5818,15 @@ async function initPlaywrightForAccount(rawAccount, headless = config.playwright
5805
5818
  const hasAuthCookie = cookies.some(
5806
5819
  (c) => c.name.toLowerCase().includes("token") || c.name.toLowerCase().includes("session")
5807
5820
  );
5821
+ let initialLoginAttempted = false;
5808
5822
  if (!hasAuthCookie && account.email && account.password) {
5809
- await loginToQwen(account.id, account.email, account.password);
5823
+ initialLoginAttempted = true;
5824
+ const loggedIn = await loginToQwen(account.id, account.email, account.password);
5825
+ if (!loggedIn) {
5826
+ throw new Error(
5827
+ `Authentication failed for account ${maskEmail(account.email)}`
5828
+ );
5829
+ }
5810
5830
  }
5811
5831
  try {
5812
5832
  await acctPage.goto(qwenUrl("/"), {
@@ -5816,13 +5836,21 @@ async function initPlaywrightForAccount(rawAccount, headless = config.playwright
5816
5836
  await sleep2(1500);
5817
5837
  const currentUrl = acctPage.url();
5818
5838
  const isAuthUrl = currentUrl.includes("/auth") || currentUrl.includes("/login");
5819
- if (isAuthUrl && account.email && account.password) {
5839
+ if (isAuthUrl && !initialLoginAttempted && account.email && account.password) {
5820
5840
  console.log(
5821
5841
  `[Playwright] Initial login needed for ${maskEmail(account.email)}, authenticating...`
5822
5842
  );
5823
- await loginToQwen(account.id, account.email, account.password);
5843
+ const loggedIn = await loginToQwen(account.id, account.email, account.password);
5844
+ if (!loggedIn) {
5845
+ throw new Error(
5846
+ `Authentication failed for account ${maskEmail(account.email)}`
5847
+ );
5848
+ }
5824
5849
  }
5825
5850
  } catch (err) {
5851
+ if (err?.message?.includes("Authentication failed for account")) {
5852
+ throw err;
5853
+ }
5826
5854
  console.warn(
5827
5855
  `\u26A0\uFE0F [Playwright] Initial navigation check for ${maskEmail(account.email)}: ${err.message}`
5828
5856
  );
@@ -6371,10 +6399,30 @@ async function loginToQwen(accountId, email, password) {
6371
6399
  const uiResult = await loginViaUi(page, email, password);
6372
6400
  if (uiResult.success) {
6373
6401
  cookieCaches.delete(accountId);
6374
- await saveStorageState(page.context(), accountId);
6375
6402
  try {
6376
- const liveCookies = await page.context().cookies();
6377
- const tokenCookie = liveCookies.find((c) => c.name === "token");
6403
+ let liveCookies = await page.context().cookies();
6404
+ let tokenCookie = liveCookies.find((c) => c.name === "token");
6405
+ if (!tokenCookie) {
6406
+ const lsTok = uiResult.token || await page.evaluate(() => (localStorage.getItem("token") || "").trim()).catch(() => "");
6407
+ if (lsTok) {
6408
+ await page.context().addCookies([
6409
+ {
6410
+ name: "token",
6411
+ value: lsTok,
6412
+ domain: ".qwen.ai",
6413
+ path: "/",
6414
+ expires: Math.floor(Date.now() / 1e3) + 31536e3,
6415
+ httpOnly: false,
6416
+ secure: true,
6417
+ sameSite: "Lax"
6418
+ }
6419
+ ]).catch(() => {
6420
+ });
6421
+ liveCookies = await page.context().cookies();
6422
+ tokenCookie = liveCookies.find((c) => c.name === "token");
6423
+ }
6424
+ }
6425
+ await saveStorageState(page.context(), accountId);
6378
6426
  if (tokenCookie) {
6379
6427
  const cookieStr = liveCookies.map((c) => `${c.name}=${c.value}`).join("; ");
6380
6428
  const cache3 = getHeaderCache(accountId);
@@ -6383,7 +6431,7 @@ async function loginToQwen(accountId, email, password) {
6383
6431
  markAccountHeadersReady(accountId);
6384
6432
  const { saveAuthSession: saveAuthSession2 } = await Promise.resolve().then(() => (init_database(), database_exports));
6385
6433
  const exp = parseJwtExpiry(tokenCookie.value);
6386
- let rTok = uiResult.refreshToken;
6434
+ let rTok = uiResult.refreshToken || liveCookies.find((c) => c.name === "refresh_token")?.value;
6387
6435
  if (!rTok) {
6388
6436
  try {
6389
6437
  rTok = await page.evaluate(() => localStorage.getItem("refresh_token") || "") || void 0;
@@ -6464,8 +6512,9 @@ async function loginViaApi(page, email, password) {
6464
6512
  }
6465
6513
  const signinUrl = "https://auth.qwen.ai/api/v2/auths/signin";
6466
6514
  const requestId = crypto5.randomUUID();
6515
+ const webVersion = getQwenWebVersion() || "0.3.26";
6467
6516
  const evalRes = await page.evaluate(
6468
- async ({ email: email2, password: password2, signinUrl: signinUrl2, requestId: requestId2, tz }) => {
6517
+ async ({ email: email2, password: password2, signinUrl: signinUrl2, requestId: requestId2, tz, version }) => {
6469
6518
  try {
6470
6519
  const response = await fetch(signinUrl2, {
6471
6520
  method: "POST",
@@ -6475,7 +6524,7 @@ async function loginViaApi(page, email, password) {
6475
6524
  accept: "application/json, text/plain, */*",
6476
6525
  "content-type": "application/json",
6477
6526
  source: "web",
6478
- version: getQwenWebVersion() || "0.3.26",
6527
+ version,
6479
6528
  "x-request-origin": "https://chat.qwen.ai",
6480
6529
  timezone: tz,
6481
6530
  "x-request-id": requestId2
@@ -6488,7 +6537,14 @@ async function loginViaApi(page, email, password) {
6488
6537
  return { ok: false, error: e.message };
6489
6538
  }
6490
6539
  },
6491
- { email, password: hashedPassword, signinUrl, requestId, tz: formatAsciiTimezone() }
6540
+ {
6541
+ email,
6542
+ password: hashedPassword,
6543
+ signinUrl,
6544
+ requestId,
6545
+ tz: formatAsciiTimezone(),
6546
+ version: webVersion
6547
+ }
6492
6548
  ).catch(() => null);
6493
6549
  let data = evalRes?.data;
6494
6550
  let signinSuccess = Boolean(
@@ -6497,7 +6553,7 @@ async function loginViaApi(page, email, password) {
6497
6553
  if (!signinSuccess && !data?.data?.code) {
6498
6554
  const fallbackUrl = qwenUrl("/api/v2/auths/signin");
6499
6555
  const fallbackRes = await page.evaluate(
6500
- async ({ email: email2, password: password2, fallbackUrl: fallbackUrl2, requestId: requestId2, tz }) => {
6556
+ async ({ email: email2, password: password2, fallbackUrl: fallbackUrl2, requestId: requestId2, tz, version }) => {
6501
6557
  try {
6502
6558
  const response = await fetch(fallbackUrl2, {
6503
6559
  method: "POST",
@@ -6507,7 +6563,7 @@ async function loginViaApi(page, email, password) {
6507
6563
  accept: "application/json, text/plain, */*",
6508
6564
  "content-type": "application/json",
6509
6565
  source: "web",
6510
- version: getQwenWebVersion() || "0.3.26",
6566
+ version,
6511
6567
  timezone: tz,
6512
6568
  "x-request-id": requestId2
6513
6569
  },
@@ -6519,7 +6575,14 @@ async function loginViaApi(page, email, password) {
6519
6575
  return { ok: false, error: e.message };
6520
6576
  }
6521
6577
  },
6522
- { email, password: hashedPassword, fallbackUrl, requestId, tz: formatAsciiTimezone() }
6578
+ {
6579
+ email,
6580
+ password: hashedPassword,
6581
+ fallbackUrl,
6582
+ requestId,
6583
+ tz: formatAsciiTimezone(),
6584
+ version: webVersion
6585
+ }
6523
6586
  ).catch(() => null);
6524
6587
  if (fallbackRes?.data) {
6525
6588
  data = fallbackRes.data;
@@ -6744,28 +6807,34 @@ async function loginViaUi(page, email, password) {
6744
6807
  await sleep2(500);
6745
6808
  const submitSelector = 'button.qwenchat-auth-pc-submit-button, button[type="submit"], button:has-text("Log in"), button:has-text("Sign in"), button:has-text("Fazer login"), button:has-text("Entrar"), button:has-text("Iniciar sesi\xF3n"), button:has-text("\u767B\u5F55")';
6746
6809
  const submitButton = page.locator(submitSelector).first();
6747
- await page.evaluate((sel) => {
6748
- try {
6749
- const btn = document.querySelector(sel);
6750
- if (btn) {
6751
- btn.removeAttribute("disabled");
6752
- btn.classList.remove("ant-btn-disabled");
6753
- btn.click();
6754
- }
6755
- } catch {
6756
- }
6757
- }, submitSelector).catch(() => {
6758
- });
6810
+ let submitted = false;
6759
6811
  try {
6760
6812
  if (await submitButton.isVisible({ timeout: 2e3 }).catch(() => false)) {
6761
- await submitButton.click({ force: true, timeout: 2e3 }).catch(() => {
6813
+ await submitButton.click({ timeout: 2e3 }).catch(() => {
6762
6814
  });
6815
+ submitted = true;
6763
6816
  }
6764
6817
  } catch {
6765
6818
  }
6766
- const passInput = page.locator(passwordSelector).first();
6767
- await passInput.press("Enter", { timeout: 2e3 }).catch(() => {
6768
- });
6819
+ if (!submitted) {
6820
+ await page.evaluate(() => {
6821
+ try {
6822
+ const btn = document.querySelector(
6823
+ 'button.qwenchat-auth-pc-submit-button, button[type="submit"]'
6824
+ );
6825
+ if (btn) {
6826
+ btn.removeAttribute("disabled");
6827
+ btn.classList.remove("ant-btn-disabled");
6828
+ btn.click();
6829
+ }
6830
+ } catch {
6831
+ }
6832
+ }).catch(() => {
6833
+ });
6834
+ const passInput = page.locator(passwordSelector).first();
6835
+ await passInput.press("Enter", { timeout: 2e3 }).catch(() => {
6836
+ });
6837
+ }
6769
6838
  const postSubmitDeadline = Date.now() + 15e3;
6770
6839
  while (Date.now() < postSubmitDeadline) {
6771
6840
  if (page.isClosed()) break;
@@ -6783,9 +6852,12 @@ async function loginViaUi(page, email, password) {
6783
6852
  ".ant-form-item-explain-error",
6784
6853
  ".ant-message-error",
6785
6854
  ".ant-message-notice",
6855
+ ".ant-message-custom-content",
6856
+ ".ant-notification-notice",
6786
6857
  '[role="alert"]',
6787
6858
  ".qwenchat-auth-error",
6788
- ".auth-error-message"
6859
+ ".auth-error-message",
6860
+ ".qwenchat-toast"
6789
6861
  ].join(", ");
6790
6862
  const errorEl = page.locator(errorSelector).first();
6791
6863
  if (await errorEl.isVisible().catch(() => false)) {
@@ -6799,7 +6871,15 @@ async function loginViaUi(page, email, password) {
6799
6871
  };
6800
6872
  }
6801
6873
  }
6802
- const codeSelector = 'input[placeholder*="code" i], input[placeholder*="c\xF3digo" i], input[name*="code" i]';
6874
+ const codeSelector = [
6875
+ 'input[placeholder*="code" i]',
6876
+ 'input[placeholder*="c\xF3digo" i]',
6877
+ 'input[name*="code" i]',
6878
+ ".qwenchat-verification-code-input",
6879
+ ".qwenchat-verification-code-input-cell",
6880
+ '[aria-label*="Verification code" i]',
6881
+ '[aria-label*="c\xF3digo de verifica\xE7\xE3o" i]'
6882
+ ].join(", ");
6803
6883
  const codeInput = page.locator(codeSelector).first();
6804
6884
  if (await codeInput.isVisible().catch(() => false)) {
6805
6885
  return {
@@ -6809,17 +6889,45 @@ async function loginViaUi(page, email, password) {
6809
6889
  }
6810
6890
  try {
6811
6891
  const liveCookies = await page.context().cookies();
6812
- if (liveCookies.some((c) => c.name === "token")) {
6813
- return { success: true };
6892
+ const rTokCookie = liveCookies.find((c) => c.name === "refresh_token")?.value;
6893
+ const tokCookie = liveCookies.find((c) => c.name === "token")?.value;
6894
+ if (tokCookie) {
6895
+ return { success: true, token: tokCookie, refreshToken: rTokCookie };
6896
+ }
6897
+ const currentUrl = page.url();
6898
+ if (!currentUrl.includes("/auth") && !currentUrl.includes("/login")) {
6899
+ const lsTok = await page.evaluate(() => {
6900
+ const t = (localStorage.getItem("token") || "").trim();
6901
+ if (t) {
6902
+ try {
6903
+ document.cookie = `token=${encodeURIComponent(t)}; path=/; domain=.qwen.ai; max-age=31536000`;
6904
+ } catch {
6905
+ }
6906
+ }
6907
+ return t;
6908
+ }).catch(() => "");
6909
+ if (lsTok) {
6910
+ await page.context().addCookies([
6911
+ {
6912
+ name: "token",
6913
+ value: lsTok,
6914
+ domain: ".qwen.ai",
6915
+ path: "/",
6916
+ expires: Math.floor(Date.now() / 1e3) + 31536e3,
6917
+ httpOnly: false,
6918
+ secure: true,
6919
+ sameSite: "Lax"
6920
+ }
6921
+ ]).catch(() => {
6922
+ });
6923
+ return { success: true, token: lsTok, refreshToken: rTokCookie };
6924
+ }
6925
+ if (await isPageLoggedIn(page, 3e3)) {
6926
+ return { success: true, refreshToken: rTokCookie };
6927
+ }
6814
6928
  }
6815
6929
  } catch {
6816
6930
  }
6817
- const currentUrl = page.url();
6818
- if (!currentUrl.includes("/auth") && !currentUrl.includes("/login")) {
6819
- if (await isPageLoggedIn(page, 3e3)) {
6820
- return { success: true };
6821
- }
6822
- }
6823
6931
  await sleep2(1e3);
6824
6932
  }
6825
6933
  if (await isPageLoggedIn(page, 3e3)) {
@@ -6848,10 +6956,18 @@ async function refreshAccountToken(accountId) {
6848
6956
  } catch {
6849
6957
  }
6850
6958
  }
6959
+ if (!refreshToken) {
6960
+ try {
6961
+ const liveCookies = await page.context().cookies();
6962
+ refreshToken = liveCookies.find((c) => c.name === "refresh_token")?.value;
6963
+ } catch {
6964
+ }
6965
+ }
6851
6966
  if (refreshToken) {
6852
6967
  try {
6968
+ const webVersion = getQwenWebVersion() || "0.3.26";
6853
6969
  const refreshResult = await page.evaluate(
6854
- async ({ rTok, tz }) => {
6970
+ async ({ rTok, tz, version }) => {
6855
6971
  try {
6856
6972
  const response = await fetch("https://auth.qwen.ai/api/v2/auths/refresh", {
6857
6973
  method: "GET",
@@ -6859,7 +6975,7 @@ async function refreshAccountToken(accountId) {
6859
6975
  headers: {
6860
6976
  accept: "application/json, text/plain, */*",
6861
6977
  source: "web",
6862
- version: getQwenWebVersion() || "0.3.26",
6978
+ version,
6863
6979
  "x-request-origin": "https://chat.qwen.ai",
6864
6980
  timezone: tz,
6865
6981
  authorization: `Bearer ${rTok}`
@@ -6871,7 +6987,7 @@ async function refreshAccountToken(accountId) {
6871
6987
  return { ok: false, error: e.message };
6872
6988
  }
6873
6989
  },
6874
- { rTok: refreshToken, tz: formatAsciiTimezone() }
6990
+ { rTok: refreshToken, tz: formatAsciiTimezone(), version: webVersion }
6875
6991
  );
6876
6992
  const json = refreshResult?.data;
6877
6993
  if (json && json.success === true && json.data) {
@@ -27095,7 +27211,7 @@ function getAppVersion() {
27095
27211
  }
27096
27212
  } catch {
27097
27213
  }
27098
- cachedVersion = "v1.6.9";
27214
+ cachedVersion = "v1.6.10";
27099
27215
  return cachedVersion;
27100
27216
  }
27101
27217
  var cachedVersion;