qwenproxy-cli 1.4.7 → 1.4.8
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/clean-cache.js +17 -5
- package/dist/delete-chats.js +213 -69
- package/dist/index.js +215 -71
- package/dist/login.js +161 -59
- package/dist/reset-cooldowns.js +17 -5
- package/package.json +1 -1
- package/src/core/database.ts +10 -5
- package/src/core/version.ts +1 -1
- package/src/routes/chat/retry-policy.ts +4 -3
- package/src/services/playwright.ts +180 -58
- package/src/services/qwen-chat-pool.ts +9 -0
- package/src/services/qwen.ts +43 -10
package/dist/clean-cache.js
CHANGED
|
@@ -314,6 +314,7 @@ function runMigrations(db2) {
|
|
|
314
314
|
"sec_ch_ua_mobile TEXT",
|
|
315
315
|
"sec_ch_ua_platform TEXT",
|
|
316
316
|
"version TEXT",
|
|
317
|
+
"refresh_token TEXT",
|
|
317
318
|
"captured_at INTEGER DEFAULT 0"
|
|
318
319
|
];
|
|
319
320
|
for (const col of authSessionCols) {
|
|
@@ -392,11 +393,11 @@ function saveAuthSession(accountId, session) {
|
|
|
392
393
|
INSERT OR REPLACE INTO qwen_auth_sessions (
|
|
393
394
|
account_id, cookie, user_agent, bx_v, bx_ua, bx_umidtoken,
|
|
394
395
|
sec_ch_ua, sec_ch_ua_mobile, sec_ch_ua_platform, version,
|
|
395
|
-
user_id, token_expires_at, captured_at, updated_at
|
|
396
|
+
user_id, token_expires_at, refresh_token, captured_at, updated_at
|
|
396
397
|
) VALUES (
|
|
397
398
|
?, ?, ?, ?, ?, ?,
|
|
398
399
|
?, ?, ?, ?,
|
|
399
|
-
?, ?, ?, datetime('now')
|
|
400
|
+
?, ?, ?, ?, datetime('now')
|
|
400
401
|
)
|
|
401
402
|
`);
|
|
402
403
|
stmt.run(
|
|
@@ -412,6 +413,7 @@ function saveAuthSession(accountId, session) {
|
|
|
412
413
|
session.version || null,
|
|
413
414
|
session.userId || null,
|
|
414
415
|
session.tokenExpiresAt || null,
|
|
416
|
+
session.refreshToken || null,
|
|
415
417
|
session.capturedAt ?? Date.now()
|
|
416
418
|
);
|
|
417
419
|
}
|
|
@@ -420,7 +422,7 @@ function getValidAuthSession(accountId, maxAgeMs = 30 * 24 * 60 * 60 * 1e3) {
|
|
|
420
422
|
const row = database.prepare(
|
|
421
423
|
`SELECT account_id, cookie, user_agent, bx_v, bx_ua, bx_umidtoken,
|
|
422
424
|
sec_ch_ua, sec_ch_ua_mobile, sec_ch_ua_platform, version,
|
|
423
|
-
user_id, token_expires_at, captured_at
|
|
425
|
+
user_id, token_expires_at, refresh_token, captured_at
|
|
424
426
|
FROM qwen_auth_sessions WHERE account_id = ?`
|
|
425
427
|
).get(accountId);
|
|
426
428
|
if (!row) return null;
|
|
@@ -428,7 +430,7 @@ function getValidAuthSession(accountId, maxAgeMs = 30 * 24 * 60 * 60 * 1e3) {
|
|
|
428
430
|
if (capturedAt <= 0 || Date.now() - capturedAt > maxAgeMs) {
|
|
429
431
|
return null;
|
|
430
432
|
}
|
|
431
|
-
if (row.token_expires_at) {
|
|
433
|
+
if (!row.refresh_token && row.token_expires_at) {
|
|
432
434
|
const tokenExpMs = Number(row.token_expires_at) * 1e3;
|
|
433
435
|
if (tokenExpMs <= Date.now() + 5 * 60 * 1e3) {
|
|
434
436
|
return null;
|
|
@@ -450,6 +452,7 @@ function getValidAuthSession(accountId, maxAgeMs = 30 * 24 * 60 * 60 * 1e3) {
|
|
|
450
452
|
version: row.version || void 0,
|
|
451
453
|
userId: row.user_id || void 0,
|
|
452
454
|
tokenExpiresAt: row.token_expires_at ? Number(row.token_expires_at) : void 0,
|
|
455
|
+
refreshToken: row.refresh_token || void 0,
|
|
453
456
|
capturedAt
|
|
454
457
|
};
|
|
455
458
|
}
|
|
@@ -3812,6 +3815,7 @@ async function loginToQwen(accountId, email, password) {
|
|
|
3812
3815
|
secChUaPlatform: cache.headers["sec-ch-ua-platform"] || void 0,
|
|
3813
3816
|
version: cache.headers["version"] || void 0,
|
|
3814
3817
|
tokenExpiresAt: exp || void 0,
|
|
3818
|
+
refreshToken: apiResult.refreshToken,
|
|
3815
3819
|
capturedAt: Date.now()
|
|
3816
3820
|
});
|
|
3817
3821
|
}
|
|
@@ -3845,6 +3849,13 @@ async function loginToQwen(accountId, email, password) {
|
|
|
3845
3849
|
markAccountHeadersReady(accountId);
|
|
3846
3850
|
const { saveAuthSession: saveAuthSession2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
3847
3851
|
const exp = parseJwtExpiry(tokenCookie.value);
|
|
3852
|
+
let rTok = uiResult.refreshToken;
|
|
3853
|
+
if (!rTok) {
|
|
3854
|
+
try {
|
|
3855
|
+
rTok = await page.evaluate(() => localStorage.getItem("refresh_token") || "") || void 0;
|
|
3856
|
+
} catch {
|
|
3857
|
+
}
|
|
3858
|
+
}
|
|
3848
3859
|
saveAuthSession2(accountId, {
|
|
3849
3860
|
cookie: cookieStr,
|
|
3850
3861
|
userAgent: cache.headers["user-agent"] || "",
|
|
@@ -3856,6 +3867,7 @@ async function loginToQwen(accountId, email, password) {
|
|
|
3856
3867
|
secChUaPlatform: cache.headers["sec-ch-ua-platform"] || void 0,
|
|
3857
3868
|
version: cache.headers["version"] || void 0,
|
|
3858
3869
|
tokenExpiresAt: exp || void 0,
|
|
3870
|
+
refreshToken: rTok,
|
|
3859
3871
|
capturedAt: Date.now()
|
|
3860
3872
|
});
|
|
3861
3873
|
}
|
|
@@ -4034,7 +4046,7 @@ async function loginViaApi(page, email, password) {
|
|
|
4034
4046
|
});
|
|
4035
4047
|
await page.reload({ waitUntil: "domcontentloaded" }).catch(() => {
|
|
4036
4048
|
});
|
|
4037
|
-
return { success: true };
|
|
4049
|
+
return { success: true, token, refreshToken };
|
|
4038
4050
|
}
|
|
4039
4051
|
}
|
|
4040
4052
|
return {
|
package/dist/delete-chats.js
CHANGED
|
@@ -314,6 +314,7 @@ function runMigrations(db2) {
|
|
|
314
314
|
"sec_ch_ua_mobile TEXT",
|
|
315
315
|
"sec_ch_ua_platform TEXT",
|
|
316
316
|
"version TEXT",
|
|
317
|
+
"refresh_token TEXT",
|
|
317
318
|
"captured_at INTEGER DEFAULT 0"
|
|
318
319
|
];
|
|
319
320
|
for (const col of authSessionCols) {
|
|
@@ -392,11 +393,11 @@ function saveAuthSession(accountId, session) {
|
|
|
392
393
|
INSERT OR REPLACE INTO qwen_auth_sessions (
|
|
393
394
|
account_id, cookie, user_agent, bx_v, bx_ua, bx_umidtoken,
|
|
394
395
|
sec_ch_ua, sec_ch_ua_mobile, sec_ch_ua_platform, version,
|
|
395
|
-
user_id, token_expires_at, captured_at, updated_at
|
|
396
|
+
user_id, token_expires_at, refresh_token, captured_at, updated_at
|
|
396
397
|
) VALUES (
|
|
397
398
|
?, ?, ?, ?, ?, ?,
|
|
398
399
|
?, ?, ?, ?,
|
|
399
|
-
?, ?, ?, datetime('now')
|
|
400
|
+
?, ?, ?, ?, datetime('now')
|
|
400
401
|
)
|
|
401
402
|
`);
|
|
402
403
|
stmt.run(
|
|
@@ -412,6 +413,7 @@ function saveAuthSession(accountId, session) {
|
|
|
412
413
|
session.version || null,
|
|
413
414
|
session.userId || null,
|
|
414
415
|
session.tokenExpiresAt || null,
|
|
416
|
+
session.refreshToken || null,
|
|
415
417
|
session.capturedAt ?? Date.now()
|
|
416
418
|
);
|
|
417
419
|
}
|
|
@@ -420,7 +422,7 @@ function getValidAuthSession(accountId, maxAgeMs = 30 * 24 * 60 * 60 * 1e3) {
|
|
|
420
422
|
const row = database.prepare(
|
|
421
423
|
`SELECT account_id, cookie, user_agent, bx_v, bx_ua, bx_umidtoken,
|
|
422
424
|
sec_ch_ua, sec_ch_ua_mobile, sec_ch_ua_platform, version,
|
|
423
|
-
user_id, token_expires_at, captured_at
|
|
425
|
+
user_id, token_expires_at, refresh_token, captured_at
|
|
424
426
|
FROM qwen_auth_sessions WHERE account_id = ?`
|
|
425
427
|
).get(accountId);
|
|
426
428
|
if (!row) return null;
|
|
@@ -428,7 +430,7 @@ function getValidAuthSession(accountId, maxAgeMs = 30 * 24 * 60 * 60 * 1e3) {
|
|
|
428
430
|
if (capturedAt <= 0 || Date.now() - capturedAt > maxAgeMs) {
|
|
429
431
|
return null;
|
|
430
432
|
}
|
|
431
|
-
if (row.token_expires_at) {
|
|
433
|
+
if (!row.refresh_token && row.token_expires_at) {
|
|
432
434
|
const tokenExpMs = Number(row.token_expires_at) * 1e3;
|
|
433
435
|
if (tokenExpMs <= Date.now() + 5 * 60 * 1e3) {
|
|
434
436
|
return null;
|
|
@@ -450,6 +452,7 @@ function getValidAuthSession(accountId, maxAgeMs = 30 * 24 * 60 * 60 * 1e3) {
|
|
|
450
452
|
version: row.version || void 0,
|
|
451
453
|
userId: row.user_id || void 0,
|
|
452
454
|
tokenExpiresAt: row.token_expires_at ? Number(row.token_expires_at) : void 0,
|
|
455
|
+
refreshToken: row.refresh_token || void 0,
|
|
453
456
|
capturedAt
|
|
454
457
|
};
|
|
455
458
|
}
|
|
@@ -3052,6 +3055,7 @@ __export(playwright_exports, {
|
|
|
3052
3055
|
parseCookiesForBrowser: () => parseCookiesForBrowser,
|
|
3053
3056
|
pruneAllPlaywrightProfiles: () => pruneAllPlaywrightProfiles,
|
|
3054
3057
|
prunePlaywrightProfileCaches: () => prunePlaywrightProfileCaches,
|
|
3058
|
+
refreshAccountToken: () => refreshAccountToken,
|
|
3055
3059
|
refreshHeaders: () => refreshHeaders,
|
|
3056
3060
|
refreshHeadersWithProfileReset: () => refreshHeadersWithProfileReset,
|
|
3057
3061
|
registerPlaywrightAccountForTests: () => registerPlaywrightAccountForTests,
|
|
@@ -4687,6 +4691,7 @@ async function loginToQwen(accountId, email, password) {
|
|
|
4687
4691
|
secChUaPlatform: cache.headers["sec-ch-ua-platform"] || void 0,
|
|
4688
4692
|
version: cache.headers["version"] || void 0,
|
|
4689
4693
|
tokenExpiresAt: exp || void 0,
|
|
4694
|
+
refreshToken: apiResult.refreshToken,
|
|
4690
4695
|
capturedAt: Date.now()
|
|
4691
4696
|
});
|
|
4692
4697
|
}
|
|
@@ -4720,6 +4725,13 @@ async function loginToQwen(accountId, email, password) {
|
|
|
4720
4725
|
markAccountHeadersReady(accountId);
|
|
4721
4726
|
const { saveAuthSession: saveAuthSession2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
4722
4727
|
const exp = parseJwtExpiry(tokenCookie.value);
|
|
4728
|
+
let rTok = uiResult.refreshToken;
|
|
4729
|
+
if (!rTok) {
|
|
4730
|
+
try {
|
|
4731
|
+
rTok = await page.evaluate(() => localStorage.getItem("refresh_token") || "") || void 0;
|
|
4732
|
+
} catch {
|
|
4733
|
+
}
|
|
4734
|
+
}
|
|
4723
4735
|
saveAuthSession2(accountId, {
|
|
4724
4736
|
cookie: cookieStr,
|
|
4725
4737
|
userAgent: cache.headers["user-agent"] || "",
|
|
@@ -4731,6 +4743,7 @@ async function loginToQwen(accountId, email, password) {
|
|
|
4731
4743
|
secChUaPlatform: cache.headers["sec-ch-ua-platform"] || void 0,
|
|
4732
4744
|
version: cache.headers["version"] || void 0,
|
|
4733
4745
|
tokenExpiresAt: exp || void 0,
|
|
4746
|
+
refreshToken: rTok,
|
|
4734
4747
|
capturedAt: Date.now()
|
|
4735
4748
|
});
|
|
4736
4749
|
}
|
|
@@ -4909,7 +4922,7 @@ async function loginViaApi(page, email, password) {
|
|
|
4909
4922
|
});
|
|
4910
4923
|
await page.reload({ waitUntil: "domcontentloaded" }).catch(() => {
|
|
4911
4924
|
});
|
|
4912
|
-
return { success: true };
|
|
4925
|
+
return { success: true, token, refreshToken };
|
|
4913
4926
|
}
|
|
4914
4927
|
}
|
|
4915
4928
|
return {
|
|
@@ -5152,6 +5165,137 @@ async function loginViaUi(page, email, password) {
|
|
|
5152
5165
|
return { success: false, reason: err?.message || String(err) };
|
|
5153
5166
|
}
|
|
5154
5167
|
}
|
|
5168
|
+
async function refreshAccountToken(accountId) {
|
|
5169
|
+
const page = accountPages.get(accountId);
|
|
5170
|
+
if (!page || page.isClosed()) {
|
|
5171
|
+
return { success: false, error: "Account page not active" };
|
|
5172
|
+
}
|
|
5173
|
+
const { getValidAuthSession: getValidAuthSession2, saveAuthSession: saveAuthSession2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
5174
|
+
const session = getValidAuthSession2(accountId);
|
|
5175
|
+
let refreshToken = session?.refreshToken;
|
|
5176
|
+
if (!refreshToken) {
|
|
5177
|
+
try {
|
|
5178
|
+
refreshToken = await page.evaluate(() => localStorage.getItem("refresh_token") || "") || void 0;
|
|
5179
|
+
} catch {
|
|
5180
|
+
}
|
|
5181
|
+
}
|
|
5182
|
+
if (refreshToken) {
|
|
5183
|
+
try {
|
|
5184
|
+
const refreshResult = await page.evaluate(
|
|
5185
|
+
async ({ rTok }) => {
|
|
5186
|
+
try {
|
|
5187
|
+
const response = await fetch("https://auth.qwen.ai/api/v2/auths/refresh", {
|
|
5188
|
+
method: "GET",
|
|
5189
|
+
credentials: "include",
|
|
5190
|
+
headers: {
|
|
5191
|
+
accept: "application/json, text/plain, */*",
|
|
5192
|
+
source: "web",
|
|
5193
|
+
version: "0.3.11",
|
|
5194
|
+
"x-request-origin": "https://chat.qwen.ai",
|
|
5195
|
+
timezone: (/* @__PURE__ */ new Date()).toString().split(" (")[0],
|
|
5196
|
+
authorization: `Bearer ${rTok}`
|
|
5197
|
+
}
|
|
5198
|
+
});
|
|
5199
|
+
const json2 = await response.json().catch(() => null);
|
|
5200
|
+
return { ok: response.ok, status: response.status, data: json2 };
|
|
5201
|
+
} catch (e) {
|
|
5202
|
+
return { ok: false, error: e.message };
|
|
5203
|
+
}
|
|
5204
|
+
},
|
|
5205
|
+
{ rTok: refreshToken }
|
|
5206
|
+
);
|
|
5207
|
+
const json = refreshResult?.data;
|
|
5208
|
+
if (json && json.success === true && json.data) {
|
|
5209
|
+
const newAccessToken = json.data.access_token || json.data.token;
|
|
5210
|
+
const newRefreshToken = json.data.refresh_token || refreshToken;
|
|
5211
|
+
if (newAccessToken) {
|
|
5212
|
+
await page.context().addCookies([
|
|
5213
|
+
{
|
|
5214
|
+
name: "token",
|
|
5215
|
+
value: newAccessToken,
|
|
5216
|
+
domain: ".qwen.ai",
|
|
5217
|
+
path: "/",
|
|
5218
|
+
expires: Math.floor(Date.now() / 1e3) + 31536e3,
|
|
5219
|
+
httpOnly: false,
|
|
5220
|
+
secure: true,
|
|
5221
|
+
sameSite: "Lax"
|
|
5222
|
+
}
|
|
5223
|
+
]);
|
|
5224
|
+
await page.evaluate(
|
|
5225
|
+
({ tok, rTok }) => {
|
|
5226
|
+
try {
|
|
5227
|
+
localStorage.removeItem("qwen_token_logged_out_marker");
|
|
5228
|
+
localStorage.setItem("token", tok);
|
|
5229
|
+
localStorage.setItem("access_token", tok);
|
|
5230
|
+
if (rTok) localStorage.setItem("refresh_token", rTok);
|
|
5231
|
+
document.cookie = `token=${encodeURIComponent(tok)}; path=/; domain=.qwen.ai; max-age=31536000`;
|
|
5232
|
+
} catch {
|
|
5233
|
+
}
|
|
5234
|
+
},
|
|
5235
|
+
{ tok: newAccessToken, rTok: newRefreshToken }
|
|
5236
|
+
).catch(() => {
|
|
5237
|
+
});
|
|
5238
|
+
const liveCookies = await page.context().cookies();
|
|
5239
|
+
const cookieStr = liveCookies.map((c) => `${c.name}=${c.value}`).join("; ");
|
|
5240
|
+
const cache = getHeaderCache(accountId);
|
|
5241
|
+
cache.headers.cookie = cookieStr;
|
|
5242
|
+
cache.lastRefresh = Date.now();
|
|
5243
|
+
markAccountHeadersReady(accountId);
|
|
5244
|
+
saveAuthSession2(accountId, {
|
|
5245
|
+
cookie: cookieStr,
|
|
5246
|
+
userAgent: cache.headers["user-agent"] || session?.userAgent || "",
|
|
5247
|
+
bxV: cache.headers["bx-v"] || session?.bxV || "2.5.37",
|
|
5248
|
+
bxUa: cache.headers["bx-ua"] || session?.bxUa || "",
|
|
5249
|
+
bxUmidtoken: cache.headers["bx-umidtoken"] || session?.bxUmidtoken || "",
|
|
5250
|
+
secChUa: cache.headers["sec-ch-ua"] || session?.secChUa,
|
|
5251
|
+
secChUaMobile: cache.headers["sec-ch-ua-mobile"] || session?.secChUaMobile,
|
|
5252
|
+
secChUaPlatform: cache.headers["sec-ch-ua-platform"] || session?.secChUaPlatform,
|
|
5253
|
+
version: cache.headers["version"] || session?.version,
|
|
5254
|
+
userId: session?.userId,
|
|
5255
|
+
tokenExpiresAt: parseJwtExpiry(newAccessToken) || void 0,
|
|
5256
|
+
refreshToken: newRefreshToken,
|
|
5257
|
+
capturedAt: Date.now()
|
|
5258
|
+
});
|
|
5259
|
+
return { success: true, token: newAccessToken };
|
|
5260
|
+
}
|
|
5261
|
+
}
|
|
5262
|
+
} catch {
|
|
5263
|
+
}
|
|
5264
|
+
}
|
|
5265
|
+
const { getAccountCredentials: getAccountCredentials2 } = await Promise.resolve().then(() => (init_accounts(), accounts_exports));
|
|
5266
|
+
const creds = getAccountCredentials2(accountId);
|
|
5267
|
+
if (creds && creds.email && creds.password) {
|
|
5268
|
+
const apiResult = await loginViaApi(page, creds.email, creds.password);
|
|
5269
|
+
if (apiResult.success) {
|
|
5270
|
+
const liveCookies = await page.context().cookies();
|
|
5271
|
+
const tokenCookie = liveCookies.find((c) => c.name === "token");
|
|
5272
|
+
if (tokenCookie) {
|
|
5273
|
+
const cookieStr = liveCookies.map((c) => `${c.name}=${c.value}`).join("; ");
|
|
5274
|
+
const cache = getHeaderCache(accountId);
|
|
5275
|
+
cache.headers.cookie = cookieStr;
|
|
5276
|
+
cache.lastRefresh = Date.now();
|
|
5277
|
+
markAccountHeadersReady(accountId);
|
|
5278
|
+
saveAuthSession2(accountId, {
|
|
5279
|
+
cookie: cookieStr,
|
|
5280
|
+
userAgent: cache.headers["user-agent"] || session?.userAgent || "",
|
|
5281
|
+
bxV: cache.headers["bx-v"] || session?.bxV || "2.5.37",
|
|
5282
|
+
bxUa: cache.headers["bx-ua"] || session?.bxUa || "",
|
|
5283
|
+
bxUmidtoken: cache.headers["bx-umidtoken"] || session?.bxUmidtoken || "",
|
|
5284
|
+
secChUa: cache.headers["sec-ch-ua"] || session?.secChUa,
|
|
5285
|
+
secChUaMobile: cache.headers["sec-ch-ua-mobile"] || session?.secChUaMobile,
|
|
5286
|
+
secChUaPlatform: cache.headers["sec-ch-ua-platform"] || session?.secChUaPlatform,
|
|
5287
|
+
version: cache.headers["version"] || session?.version,
|
|
5288
|
+
userId: session?.userId,
|
|
5289
|
+
tokenExpiresAt: parseJwtExpiry(tokenCookie.value) || void 0,
|
|
5290
|
+
refreshToken: apiResult.refreshToken,
|
|
5291
|
+
capturedAt: Date.now()
|
|
5292
|
+
});
|
|
5293
|
+
return { success: true, token: tokenCookie.value };
|
|
5294
|
+
}
|
|
5295
|
+
}
|
|
5296
|
+
}
|
|
5297
|
+
return { success: false, error: "Could not refresh or re-authenticate token" };
|
|
5298
|
+
}
|
|
5155
5299
|
async function captureQwenHeaders(accountId, pageOverride, timeoutMs = config.timeouts.headers, triggerGraceMs = HEADER_CAPTURE_TRIGGER_GRACE_MS) {
|
|
5156
5300
|
const page = pageOverride ?? accountPages.get(accountId);
|
|
5157
5301
|
if (!page || page.isClosed()) {
|
|
@@ -5668,16 +5812,9 @@ async function refreshHeadersInternal(accountId, timeoutMs = config.timeouts.hea
|
|
|
5668
5812
|
}
|
|
5669
5813
|
};
|
|
5670
5814
|
if (forceReauth) {
|
|
5671
|
-
const
|
|
5672
|
-
if (
|
|
5673
|
-
|
|
5674
|
-
if (liveCookies.some((c) => c.name === "token")) {
|
|
5675
|
-
const cookieStr = liveCookies.map((c) => `${c.name}=${c.value}`).join("; ");
|
|
5676
|
-
cache.headers.cookie = cookieStr;
|
|
5677
|
-
cache.lastRefresh = Date.now();
|
|
5678
|
-
markAccountHeadersReady(accountId);
|
|
5679
|
-
return;
|
|
5680
|
-
}
|
|
5815
|
+
const refreshed = await refreshAccountToken(accountId);
|
|
5816
|
+
if (refreshed.success) {
|
|
5817
|
+
return;
|
|
5681
5818
|
}
|
|
5682
5819
|
await executeReauth();
|
|
5683
5820
|
} else {
|
|
@@ -6113,50 +6250,15 @@ async function keepAlivePlaywrightAccount(accountId) {
|
|
|
6113
6250
|
const now = Date.now();
|
|
6114
6251
|
const currentUrl = page.url();
|
|
6115
6252
|
const cookie = await getCookies(accountId);
|
|
6116
|
-
if (cookie && isTokenExpiringSoon(cookie,
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
|
|
6122
|
-
|
|
6123
|
-
|
|
6124
|
-
|
|
6125
|
-
method: "GET",
|
|
6126
|
-
credentials: "include"
|
|
6127
|
-
}).catch(() => {
|
|
6128
|
-
});
|
|
6129
|
-
}).catch(() => {
|
|
6130
|
-
});
|
|
6131
|
-
const liveCookies = await page.context().cookies();
|
|
6132
|
-
const tokenCookie = liveCookies.find((c) => c.name === "token");
|
|
6133
|
-
if (tokenCookie) {
|
|
6134
|
-
const cookieStr = liveCookies.map((c) => `${c.name}=${c.value}`).join("; ");
|
|
6135
|
-
const cache = getHeaderCache(accountId);
|
|
6136
|
-
cache.headers.cookie = cookieStr;
|
|
6137
|
-
cache.lastRefresh = Date.now();
|
|
6138
|
-
markAccountHeadersReady(accountId);
|
|
6139
|
-
lastKeepAliveNavigation.set(accountId, now);
|
|
6140
|
-
touchAccountActivity(accountId);
|
|
6141
|
-
return true;
|
|
6142
|
-
}
|
|
6143
|
-
} catch {
|
|
6144
|
-
}
|
|
6145
|
-
const loggedIn = await isPageLoggedIn(page, 2e3).catch(() => false);
|
|
6146
|
-
if (!loggedIn) {
|
|
6147
|
-
console.log(
|
|
6148
|
-
`\u{1F493} [SessionKeeper] Account ${accountId} session expired; renewing session...`
|
|
6149
|
-
);
|
|
6150
|
-
try {
|
|
6151
|
-
await refreshHeadersInternal(accountId, config.timeouts.headers, true);
|
|
6152
|
-
lastKeepAliveNavigation.set(accountId, now);
|
|
6153
|
-
touchAccountActivity(accountId);
|
|
6154
|
-
return true;
|
|
6155
|
-
} catch (err) {
|
|
6156
|
-
console.warn(
|
|
6157
|
-
`[SessionKeeper] Proactive session renewal failed for ${accountId}: ${getErrorMessage(err)}`
|
|
6158
|
-
);
|
|
6159
|
-
}
|
|
6253
|
+
if (cookie && isTokenExpiringSoon(cookie, 5)) {
|
|
6254
|
+
console.log(
|
|
6255
|
+
`\u{1F493} [SessionKeeper] Account ${accountId} access token expiring soon (<5m); silently refreshing...`
|
|
6256
|
+
);
|
|
6257
|
+
const res = await refreshAccountToken(accountId);
|
|
6258
|
+
if (res.success) {
|
|
6259
|
+
lastKeepAliveNavigation.set(accountId, now);
|
|
6260
|
+
touchAccountActivity(accountId);
|
|
6261
|
+
return true;
|
|
6160
6262
|
}
|
|
6161
6263
|
}
|
|
6162
6264
|
const lastNavigation = lastKeepAliveNavigation.get(accountId) ?? 0;
|
|
@@ -7522,6 +7624,16 @@ async function createQwenChatSession(headers, model, accountId, chatMode = "thre
|
|
|
7522
7624
|
}
|
|
7523
7625
|
}
|
|
7524
7626
|
if (json?.data?.code === "Unauthorized" || json?.code === "Unauthorized" || rawLower.includes("unauthorized") || rawLower.includes("permission to access")) {
|
|
7627
|
+
if (accountId) {
|
|
7628
|
+
try {
|
|
7629
|
+
const { refreshAccountToken: refreshAccountToken2 } = await Promise.resolve().then(() => (init_playwright(), playwright_exports));
|
|
7630
|
+
const refreshed = await refreshAccountToken2(accountId);
|
|
7631
|
+
if (refreshed.success) {
|
|
7632
|
+
return createQwenChatSession(headers, model, accountId, chatMode);
|
|
7633
|
+
}
|
|
7634
|
+
} catch {
|
|
7635
|
+
}
|
|
7636
|
+
}
|
|
7525
7637
|
throw new QwenUpstreamError(
|
|
7526
7638
|
`Qwen create chat unauthorized: ${raw.substring(0, 300)}`,
|
|
7527
7639
|
"Unauthorized",
|
|
@@ -8217,16 +8329,28 @@ async function requestQwenTextInBrowser(accountId, method, path6, headers, body,
|
|
|
8217
8329
|
});
|
|
8218
8330
|
if (response2.status === 401) {
|
|
8219
8331
|
try {
|
|
8220
|
-
const
|
|
8221
|
-
|
|
8222
|
-
|
|
8223
|
-
|
|
8224
|
-
|
|
8225
|
-
|
|
8332
|
+
const rTok = localStorage.getItem("refresh_token");
|
|
8333
|
+
if (rTok) {
|
|
8334
|
+
const refreshRes = await fetch("https://auth.qwen.ai/api/v2/auths/refresh", {
|
|
8335
|
+
method: "GET",
|
|
8336
|
+
credentials: "include",
|
|
8337
|
+
headers: {
|
|
8338
|
+
accept: "application/json, text/plain, */*",
|
|
8339
|
+
source: "web",
|
|
8340
|
+
version: "0.3.11",
|
|
8341
|
+
"x-request-origin": "https://chat.qwen.ai",
|
|
8342
|
+
timezone: (/* @__PURE__ */ new Date()).toString().split(" (")[0],
|
|
8343
|
+
authorization: `Bearer ${rTok}`
|
|
8344
|
+
},
|
|
8345
|
+
signal: AbortSignal.timeout(5e3)
|
|
8346
|
+
});
|
|
8226
8347
|
const refreshJson = await refreshRes.json().catch(() => null);
|
|
8227
|
-
|
|
8228
|
-
|
|
8348
|
+
const freshTok = refreshJson?.data?.access_token || refreshJson?.data?.token;
|
|
8349
|
+
const nextRTok = refreshJson?.data?.refresh_token;
|
|
8350
|
+
if (refreshJson?.success === true && freshTok) {
|
|
8229
8351
|
localStorage.setItem("token", freshTok);
|
|
8352
|
+
localStorage.setItem("access_token", freshTok);
|
|
8353
|
+
if (nextRTok) localStorage.setItem("refresh_token", nextRTok);
|
|
8230
8354
|
document.cookie = `token=${encodeURIComponent(freshTok)}; path=/; domain=.qwen.ai; max-age=31536000`;
|
|
8231
8355
|
if (headers2["authorization"] || headers2["Authorization"]) {
|
|
8232
8356
|
headers2["authorization"] = `Bearer ${freshTok}`;
|
|
@@ -8264,13 +8388,29 @@ async function requestQwenTextInBrowser(accountId, method, path6, headers, body,
|
|
|
8264
8388
|
}
|
|
8265
8389
|
);
|
|
8266
8390
|
const recoverOnTimeout = !options.noMutexRecovery;
|
|
8267
|
-
|
|
8391
|
+
let response = await withQwenBrowserPage(
|
|
8268
8392
|
accountId,
|
|
8269
8393
|
evaluateRequest,
|
|
8270
8394
|
void 0,
|
|
8271
8395
|
options.timeoutMs,
|
|
8272
8396
|
recoverOnTimeout
|
|
8273
8397
|
);
|
|
8398
|
+
if (response.status === 401 && accountId) {
|
|
8399
|
+
try {
|
|
8400
|
+
const { refreshAccountToken: refreshAccountToken2 } = await Promise.resolve().then(() => (init_playwright(), playwright_exports));
|
|
8401
|
+
const refreshed = await refreshAccountToken2(accountId);
|
|
8402
|
+
if (refreshed.success) {
|
|
8403
|
+
response = await withQwenBrowserPage(
|
|
8404
|
+
accountId,
|
|
8405
|
+
evaluateRequest,
|
|
8406
|
+
void 0,
|
|
8407
|
+
options.timeoutMs,
|
|
8408
|
+
recoverOnTimeout
|
|
8409
|
+
);
|
|
8410
|
+
}
|
|
8411
|
+
} catch {
|
|
8412
|
+
}
|
|
8413
|
+
}
|
|
8274
8414
|
return new Response(response.raw, {
|
|
8275
8415
|
status: response.status,
|
|
8276
8416
|
headers: response.contentType ? { "content-type": response.contentType } : void 0
|
|
@@ -8793,7 +8933,11 @@ async function syncQwenRequestPersonalization(instruction, accountId, metadata =
|
|
|
8793
8933
|
);
|
|
8794
8934
|
try {
|
|
8795
8935
|
currentSettings = null;
|
|
8796
|
-
const {
|
|
8936
|
+
const { refreshAccountToken: refreshAccountToken2 } = await Promise.resolve().then(() => (init_playwright(), playwright_exports));
|
|
8937
|
+
if (accountId) {
|
|
8938
|
+
await refreshAccountToken2(accountId);
|
|
8939
|
+
}
|
|
8940
|
+
const { headers: freshHeaders } = await getQwenHeaders(false, accountId);
|
|
8797
8941
|
requestHeaders = buildCapturedQwenHeaders(freshHeaders, {
|
|
8798
8942
|
referer: qwenUrl("/settings/personalization")
|
|
8799
8943
|
});
|