qwenproxy-cli 1.4.3 → 1.4.7
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 +188 -70
- package/dist/delete-chats.js +241 -81
- package/dist/index.js +242 -82
- package/dist/login.js +241 -81
- package/dist/reset-cooldowns.js +188 -70
- package/package.json +1 -1
- package/src/core/version.ts +1 -1
- package/src/services/playwright.ts +288 -85
package/dist/login.js
CHANGED
|
@@ -3864,8 +3864,29 @@ function getStealthScript(profile) {
|
|
|
3864
3864
|
const _toBlob = HTMLCanvasElement.prototype.toBlob;
|
|
3865
3865
|
const _getImageData = CanvasRenderingContext2D.prototype.getImageData;
|
|
3866
3866
|
|
|
3867
|
+
function isCaptchaCanvas(canvas) {
|
|
3868
|
+
try {
|
|
3869
|
+
if (!canvas) return false;
|
|
3870
|
+
const id = (canvas.id || "").toLowerCase();
|
|
3871
|
+
const cls = (canvas.className || "").toLowerCase();
|
|
3872
|
+
return (
|
|
3873
|
+
id.includes("baxia") ||
|
|
3874
|
+
id.includes("nc_") ||
|
|
3875
|
+
id.includes("captcha") ||
|
|
3876
|
+
id.includes("punish") ||
|
|
3877
|
+
cls.includes("baxia") ||
|
|
3878
|
+
cls.includes("nc_") ||
|
|
3879
|
+
cls.includes("captcha") ||
|
|
3880
|
+
Boolean(canvas.closest?.("#baxia-dialog, #baxia-punish, [class*='baxia'], [class*='nc_'], .auth-layout"))
|
|
3881
|
+
);
|
|
3882
|
+
} catch(e) {
|
|
3883
|
+
return false;
|
|
3884
|
+
}
|
|
3885
|
+
}
|
|
3886
|
+
|
|
3867
3887
|
function addNoise(canvas) {
|
|
3868
3888
|
try {
|
|
3889
|
+
if (isCaptchaCanvas(canvas)) return;
|
|
3869
3890
|
const ctx = canvas.getContext('2d');
|
|
3870
3891
|
if (!ctx) return;
|
|
3871
3892
|
const style = ctx.fillStyle;
|
|
@@ -3889,6 +3910,9 @@ function getStealthScript(profile) {
|
|
|
3889
3910
|
|
|
3890
3911
|
CanvasRenderingContext2D.prototype.getImageData = function(x, y, w, h) {
|
|
3891
3912
|
const imageData = _getImageData.apply(this, arguments);
|
|
3913
|
+
if (isCaptchaCanvas(this.canvas)) {
|
|
3914
|
+
return imageData;
|
|
3915
|
+
}
|
|
3892
3916
|
const data = imageData.data;
|
|
3893
3917
|
const maxPixels = Math.min(data.length / 4, 2500);
|
|
3894
3918
|
for (let i = 0; i < maxPixels * 4; i += 4) {
|
|
@@ -4844,37 +4868,52 @@ async function loginToQwen(accountId, email, password) {
|
|
|
4844
4868
|
async function loginViaApi(page, email, password) {
|
|
4845
4869
|
try {
|
|
4846
4870
|
const hashedPassword = crypto3.createHash("sha256").update(password).digest("hex");
|
|
4847
|
-
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
email,
|
|
4855
|
-
password: hashedPassword,
|
|
4856
|
-
login_type: "email"
|
|
4857
|
-
},
|
|
4858
|
-
headers: {
|
|
4859
|
-
"content-type": "application/json",
|
|
4860
|
-
accept: "application/json, text/plain, */*",
|
|
4861
|
-
referer: qwenUrl("/auth"),
|
|
4862
|
-
origin: qwenOrigin(),
|
|
4863
|
-
source: "web"
|
|
4864
|
-
},
|
|
4865
|
-
timeout: 1e4
|
|
4866
|
-
});
|
|
4867
|
-
data = await response.json().catch(() => null);
|
|
4868
|
-
signinSuccess = Boolean(data && (data.success === true || data.token));
|
|
4869
|
-
} catch {
|
|
4870
|
-
}
|
|
4871
|
+
if (!page.url().includes("/auth")) {
|
|
4872
|
+
await page.goto(qwenUrl("/auth"), {
|
|
4873
|
+
waitUntil: "domcontentloaded",
|
|
4874
|
+
timeout: config.timeouts.navigation
|
|
4875
|
+
}).catch(() => {
|
|
4876
|
+
});
|
|
4877
|
+
await sleep2(1e3);
|
|
4871
4878
|
}
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4879
|
+
const signinUrl = "https://auth.qwen.ai/api/v2/auths/signin";
|
|
4880
|
+
const requestId = crypto3.randomUUID();
|
|
4881
|
+
const evalRes = await page.evaluate(
|
|
4882
|
+
async ({ email: email2, password: password2, signinUrl: signinUrl2, requestId: requestId2 }) => {
|
|
4883
|
+
try {
|
|
4884
|
+
const response = await fetch(signinUrl2, {
|
|
4885
|
+
method: "POST",
|
|
4886
|
+
signal: AbortSignal.timeout(15e3),
|
|
4887
|
+
credentials: "include",
|
|
4888
|
+
headers: {
|
|
4889
|
+
accept: "application/json, text/plain, */*",
|
|
4890
|
+
"content-type": "application/json",
|
|
4891
|
+
source: "web",
|
|
4892
|
+
version: "0.3.11",
|
|
4893
|
+
"x-request-origin": "https://chat.qwen.ai",
|
|
4894
|
+
timezone: (/* @__PURE__ */ new Date()).toString().split(" (")[0],
|
|
4895
|
+
"x-request-id": requestId2
|
|
4896
|
+
},
|
|
4897
|
+
body: JSON.stringify({ email: email2, password: password2 })
|
|
4898
|
+
});
|
|
4899
|
+
const json = await response.json().catch(() => null);
|
|
4900
|
+
return { ok: response.ok, status: response.status, data: json };
|
|
4901
|
+
} catch (e) {
|
|
4902
|
+
return { ok: false, error: e.message };
|
|
4903
|
+
}
|
|
4904
|
+
},
|
|
4905
|
+
{ email, password: hashedPassword, signinUrl, requestId }
|
|
4906
|
+
).catch(() => null);
|
|
4907
|
+
let data = evalRes?.data;
|
|
4908
|
+
let signinSuccess = Boolean(
|
|
4909
|
+
data && (data.success === true || data.token || data.data?.access_token || data.data?.token)
|
|
4910
|
+
);
|
|
4911
|
+
if (!signinSuccess && !data?.data?.code) {
|
|
4912
|
+
const fallbackUrl = qwenUrl("/api/v2/auths/signin");
|
|
4913
|
+
const fallbackRes = await page.evaluate(
|
|
4914
|
+
async ({ email: email2, password: password2, fallbackUrl: fallbackUrl2, requestId: requestId2 }) => {
|
|
4876
4915
|
try {
|
|
4877
|
-
const response = await fetch(
|
|
4916
|
+
const response = await fetch(fallbackUrl2, {
|
|
4878
4917
|
method: "POST",
|
|
4879
4918
|
signal: AbortSignal.timeout(1e4),
|
|
4880
4919
|
credentials: "include",
|
|
@@ -4882,10 +4921,11 @@ async function loginViaApi(page, email, password) {
|
|
|
4882
4921
|
accept: "application/json, text/plain, */*",
|
|
4883
4922
|
"content-type": "application/json",
|
|
4884
4923
|
source: "web",
|
|
4924
|
+
version: "0.3.11",
|
|
4885
4925
|
timezone: (/* @__PURE__ */ new Date()).toString().split(" (")[0],
|
|
4886
4926
|
"x-request-id": requestId2
|
|
4887
4927
|
},
|
|
4888
|
-
body: JSON.stringify({ email: email2, password: password2
|
|
4928
|
+
body: JSON.stringify({ email: email2, password: password2 })
|
|
4889
4929
|
});
|
|
4890
4930
|
const json = await response.json().catch(() => null);
|
|
4891
4931
|
return { ok: response.ok, status: response.status, data: json };
|
|
@@ -4893,11 +4933,13 @@ async function loginViaApi(page, email, password) {
|
|
|
4893
4933
|
return { ok: false, error: e.message };
|
|
4894
4934
|
}
|
|
4895
4935
|
},
|
|
4896
|
-
{ email, password: hashedPassword,
|
|
4936
|
+
{ email, password: hashedPassword, fallbackUrl, requestId }
|
|
4897
4937
|
).catch(() => null);
|
|
4898
|
-
if (
|
|
4899
|
-
data =
|
|
4900
|
-
signinSuccess = Boolean(
|
|
4938
|
+
if (fallbackRes?.data) {
|
|
4939
|
+
data = fallbackRes.data;
|
|
4940
|
+
signinSuccess = Boolean(
|
|
4941
|
+
data && (data.success === true || data.token || data.data?.access_token || data.data?.token)
|
|
4942
|
+
);
|
|
4901
4943
|
}
|
|
4902
4944
|
}
|
|
4903
4945
|
if (data?.success === false) {
|
|
@@ -4911,7 +4953,8 @@ async function loginViaApi(page, email, password) {
|
|
|
4911
4953
|
};
|
|
4912
4954
|
}
|
|
4913
4955
|
if (signinSuccess) {
|
|
4914
|
-
const token = data?.data?.token || data?.token;
|
|
4956
|
+
const token = data?.data?.access_token || data?.data?.token || data?.access_token || data?.token;
|
|
4957
|
+
const refreshToken = data?.data?.refresh_token || data?.refresh_token;
|
|
4915
4958
|
if (token) {
|
|
4916
4959
|
try {
|
|
4917
4960
|
await page.context().addCookies([
|
|
@@ -4935,14 +4978,19 @@ async function loginViaApi(page, email, password) {
|
|
|
4935
4978
|
}).catch(() => {
|
|
4936
4979
|
});
|
|
4937
4980
|
if (token) {
|
|
4938
|
-
await page.evaluate(
|
|
4939
|
-
|
|
4940
|
-
|
|
4941
|
-
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
|
|
4981
|
+
await page.evaluate(
|
|
4982
|
+
({ tok, rTok }) => {
|
|
4983
|
+
try {
|
|
4984
|
+
localStorage.removeItem("qwen_token_logged_out_marker");
|
|
4985
|
+
localStorage.setItem("token", tok);
|
|
4986
|
+
localStorage.setItem("access_token", tok);
|
|
4987
|
+
if (rTok) localStorage.setItem("refresh_token", rTok);
|
|
4988
|
+
document.cookie = `token=${encodeURIComponent(tok)}; path=/; domain=.qwen.ai; max-age=31536000`;
|
|
4989
|
+
} catch {
|
|
4990
|
+
}
|
|
4991
|
+
},
|
|
4992
|
+
{ tok: token, rTok: refreshToken }
|
|
4993
|
+
).catch(() => {
|
|
4946
4994
|
});
|
|
4947
4995
|
await page.reload({ waitUntil: "domcontentloaded" }).catch(() => {
|
|
4948
4996
|
});
|
|
@@ -4970,11 +5018,23 @@ async function loginViaApi(page, email, password) {
|
|
|
4970
5018
|
}
|
|
4971
5019
|
async function loginViaUi(page, email, password) {
|
|
4972
5020
|
try {
|
|
4973
|
-
|
|
4974
|
-
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
5021
|
+
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 2e3).catch(() => false)) {
|
|
5022
|
+
return { success: true };
|
|
5023
|
+
}
|
|
5024
|
+
try {
|
|
5025
|
+
await page.goto(qwenUrl("/auth"), {
|
|
5026
|
+
waitUntil: "domcontentloaded",
|
|
5027
|
+
timeout: Math.min(config.timeouts.navigation, 15e3)
|
|
5028
|
+
});
|
|
5029
|
+
await sleep2(1e3);
|
|
5030
|
+
} catch (gotoErr) {
|
|
5031
|
+
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 3e3).catch(() => false)) {
|
|
5032
|
+
return { success: true };
|
|
5033
|
+
}
|
|
5034
|
+
}
|
|
5035
|
+
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 3e3).catch(() => false)) {
|
|
5036
|
+
return { success: true };
|
|
5037
|
+
}
|
|
4978
5038
|
const emailSelector = [
|
|
4979
5039
|
'input[type="email"]',
|
|
4980
5040
|
'input[name="email"]',
|
|
@@ -4984,7 +5044,7 @@ async function loginViaUi(page, email, password) {
|
|
|
4984
5044
|
].join(", ");
|
|
4985
5045
|
try {
|
|
4986
5046
|
await page.waitForSelector(emailSelector, {
|
|
4987
|
-
timeout: Math.min(config.timeouts.page,
|
|
5047
|
+
timeout: Math.min(config.timeouts.page, 5e3)
|
|
4988
5048
|
});
|
|
4989
5049
|
} catch {
|
|
4990
5050
|
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 3e3)) {
|
|
@@ -4997,30 +5057,55 @@ async function loginViaUi(page, email, password) {
|
|
|
4997
5057
|
return { success: false, reason: "Campo de e-mail n\xE3o encontrado (poss\xEDvel captcha)" };
|
|
4998
5058
|
}
|
|
4999
5059
|
await clearVisibleChallenge(page);
|
|
5000
|
-
const
|
|
5001
|
-
return page.locator('
|
|
5002
|
-
hasText: /(?:log\s*in\s*with\s*(?:a\s*)?password|fazer\s*login\s*com\s*senha|entrar\s*com\s*(?:uma\s*)?senha|iniciar\s*sesi[oó]n\s*con\s*contrase[nñ]a|密码登录)/i
|
|
5003
|
-
}).first();
|
|
5060
|
+
const isPasswordInputPresent = async () => {
|
|
5061
|
+
return await page.locator('input[type="password"], input[name="password"]').count().catch(() => 0) > 0;
|
|
5004
5062
|
};
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
await pwdModeBtn.click({ timeout: 2e3 }).catch(() => {
|
|
5063
|
+
const revealPasswordMode = async () => {
|
|
5064
|
+
if (page.url().includes("/forget")) {
|
|
5065
|
+
await page.goto(qwenUrl("/auth"), { waitUntil: "domcontentloaded", timeout: 1e4 }).catch(() => {
|
|
5009
5066
|
});
|
|
5010
|
-
await sleep2(
|
|
5067
|
+
await sleep2(1e3);
|
|
5011
5068
|
}
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
if (await
|
|
5019
|
-
await
|
|
5069
|
+
if (await isPasswordInputPresent()) return;
|
|
5070
|
+
const btn = page.locator("button").filter({
|
|
5071
|
+
hasText: /(?:log\s*in\s*with\s*(?:a\s*)?password|fazer\s*login\s*com\s*senha|entrar\s*com\s*(?:uma\s*)?senha|iniciar\s*sesi[oó]n\s*con\s*contrase[nñ]a|密码登录)/i
|
|
5072
|
+
}).filter({
|
|
5073
|
+
hasNotText: /(?:esqueci|forgot|olvid|reset|recover)/i
|
|
5074
|
+
}).first();
|
|
5075
|
+
if (await btn.isVisible({ timeout: 1500 }).catch(() => false)) {
|
|
5076
|
+
await btn.click({ timeout: 2e3 }).catch(() => {
|
|
5020
5077
|
});
|
|
5021
5078
|
await sleep2(500);
|
|
5022
5079
|
}
|
|
5080
|
+
if (await isPasswordInputPresent()) return;
|
|
5081
|
+
await page.evaluate(() => {
|
|
5082
|
+
try {
|
|
5083
|
+
const buttons = Array.from(document.querySelectorAll("button, [role='button'], a"));
|
|
5084
|
+
for (const b of buttons) {
|
|
5085
|
+
const txt = (b.innerText || "").trim().toLowerCase();
|
|
5086
|
+
if (/(?:log\s*in\s*with\s*(?:a\s*)?password|fazer\s*login\s*com\s*senha|entrar\s*com\s*(?:uma\s*)?senha|iniciar\s*sesi[oó]n\s*con\s*contrase[nñ]a|密码登录)/i.test(txt) && !txt.includes("esqueci") && !txt.includes("forgot") && !txt.includes("olvid") && !txt.includes("reset")) {
|
|
5087
|
+
b.click();
|
|
5088
|
+
return true;
|
|
5089
|
+
}
|
|
5090
|
+
}
|
|
5091
|
+
} catch {
|
|
5092
|
+
}
|
|
5093
|
+
return false;
|
|
5094
|
+
}).catch(() => false);
|
|
5095
|
+
await sleep2(500);
|
|
5096
|
+
};
|
|
5097
|
+
await revealPasswordMode();
|
|
5098
|
+
try {
|
|
5099
|
+
await page.fill(emailSelector, email, { timeout: 8e3 });
|
|
5100
|
+
await sleep2(300);
|
|
5023
5101
|
} catch {
|
|
5102
|
+
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 3e3)) {
|
|
5103
|
+
return { success: true };
|
|
5104
|
+
}
|
|
5105
|
+
throw new Error(`Campo de e-mail n\xE3o encontrado na tela de autentica\xE7\xE3o`);
|
|
5106
|
+
}
|
|
5107
|
+
if (!await isPasswordInputPresent()) {
|
|
5108
|
+
await revealPasswordMode();
|
|
5024
5109
|
}
|
|
5025
5110
|
const passwordSelector = 'input[type="password"], input[name="password"]';
|
|
5026
5111
|
try {
|
|
@@ -5039,17 +5124,50 @@ async function loginViaUi(page, email, password) {
|
|
|
5039
5124
|
reason: "Campo de senha n\xE3o encontrado na tela de autentica\xE7\xE3o"
|
|
5040
5125
|
};
|
|
5041
5126
|
}
|
|
5042
|
-
|
|
5043
|
-
|
|
5127
|
+
try {
|
|
5128
|
+
await page.fill(passwordSelector, password, { timeout: 8e3 });
|
|
5129
|
+
await sleep2(500);
|
|
5130
|
+
} catch {
|
|
5131
|
+
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 3e3)) {
|
|
5132
|
+
return { success: true };
|
|
5133
|
+
}
|
|
5134
|
+
throw new Error(`Campo de senha n\xE3o encontrado na tela de autentica\xE7\xE3o`);
|
|
5135
|
+
}
|
|
5136
|
+
await page.evaluate(() => {
|
|
5137
|
+
try {
|
|
5138
|
+
const emailEl = document.querySelector('input[name="email"], input[type="email"], input[type="text"]');
|
|
5139
|
+
const passEl = document.querySelector('input[type="password"], input[name="password"]');
|
|
5140
|
+
if (emailEl) {
|
|
5141
|
+
emailEl.dispatchEvent(new Event("input", { bubbles: true }));
|
|
5142
|
+
emailEl.dispatchEvent(new Event("change", { bubbles: true }));
|
|
5143
|
+
emailEl.dispatchEvent(new Event("blur", { bubbles: true }));
|
|
5144
|
+
}
|
|
5145
|
+
if (passEl) {
|
|
5146
|
+
passEl.dispatchEvent(new Event("input", { bubbles: true }));
|
|
5147
|
+
passEl.dispatchEvent(new Event("change", { bubbles: true }));
|
|
5148
|
+
passEl.dispatchEvent(new Event("blur", { bubbles: true }));
|
|
5149
|
+
}
|
|
5150
|
+
} catch {
|
|
5151
|
+
}
|
|
5152
|
+
}).catch(() => {
|
|
5153
|
+
});
|
|
5044
5154
|
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")';
|
|
5045
5155
|
const submitButton = page.locator(submitSelector).first();
|
|
5046
5156
|
try {
|
|
5047
5157
|
await page.waitForSelector('button[type="submit"]:not([disabled])', {
|
|
5048
|
-
timeout:
|
|
5158
|
+
timeout: 4e3
|
|
5049
5159
|
});
|
|
5050
5160
|
await submitButton.click();
|
|
5051
5161
|
} catch {
|
|
5052
|
-
await
|
|
5162
|
+
const isDisabled = await submitButton.isDisabled().catch(() => true);
|
|
5163
|
+
if (!isDisabled) {
|
|
5164
|
+
await submitButton.click({ force: true }).catch(() => {
|
|
5165
|
+
});
|
|
5166
|
+
} else {
|
|
5167
|
+
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 2e3)) {
|
|
5168
|
+
return { success: true };
|
|
5169
|
+
}
|
|
5170
|
+
}
|
|
5053
5171
|
}
|
|
5054
5172
|
const postSubmitDeadline = Date.now() + 15e3;
|
|
5055
5173
|
while (Date.now() < postSubmitDeadline) {
|
|
@@ -5635,6 +5753,17 @@ async function refreshHeadersInternal(accountId, timeoutMs = config.timeouts.hea
|
|
|
5635
5753
|
}
|
|
5636
5754
|
};
|
|
5637
5755
|
if (forceReauth) {
|
|
5756
|
+
const alreadyIn = await isPageLoggedIn(page, 2e3).catch(() => false);
|
|
5757
|
+
if (alreadyIn) {
|
|
5758
|
+
const liveCookies = await page.context().cookies();
|
|
5759
|
+
if (liveCookies.some((c) => c.name === "token")) {
|
|
5760
|
+
const cookieStr = liveCookies.map((c) => `${c.name}=${c.value}`).join("; ");
|
|
5761
|
+
cache.headers.cookie = cookieStr;
|
|
5762
|
+
cache.lastRefresh = Date.now();
|
|
5763
|
+
markAccountHeadersReady(accountId);
|
|
5764
|
+
return;
|
|
5765
|
+
}
|
|
5766
|
+
}
|
|
5638
5767
|
await executeReauth();
|
|
5639
5768
|
} else {
|
|
5640
5769
|
try {
|
|
@@ -6069,19 +6198,50 @@ async function keepAlivePlaywrightAccount(accountId) {
|
|
|
6069
6198
|
const now = Date.now();
|
|
6070
6199
|
const currentUrl = page.url();
|
|
6071
6200
|
const cookie = await getCookies(accountId);
|
|
6072
|
-
if (cookie && isTokenExpiringSoon(cookie,
|
|
6073
|
-
console.log(
|
|
6074
|
-
`\u{1F493} [SessionKeeper] Account ${accountId} token expires within 45m; proactively renewing session...`
|
|
6075
|
-
);
|
|
6201
|
+
if (cookie && isTokenExpiringSoon(cookie, 2)) {
|
|
6076
6202
|
try {
|
|
6077
|
-
await
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
|
|
6203
|
+
await page.evaluate(async () => {
|
|
6204
|
+
await fetch("https://auth.qwen.ai/api/v2/auths/refresh", {
|
|
6205
|
+
method: "GET",
|
|
6206
|
+
credentials: "include"
|
|
6207
|
+
}).catch(() => {
|
|
6208
|
+
});
|
|
6209
|
+
await fetch("/api/v1/auths/", {
|
|
6210
|
+
method: "GET",
|
|
6211
|
+
credentials: "include"
|
|
6212
|
+
}).catch(() => {
|
|
6213
|
+
});
|
|
6214
|
+
}).catch(() => {
|
|
6215
|
+
});
|
|
6216
|
+
const liveCookies = await page.context().cookies();
|
|
6217
|
+
const tokenCookie = liveCookies.find((c) => c.name === "token");
|
|
6218
|
+
if (tokenCookie) {
|
|
6219
|
+
const cookieStr = liveCookies.map((c) => `${c.name}=${c.value}`).join("; ");
|
|
6220
|
+
const cache = getHeaderCache(accountId);
|
|
6221
|
+
cache.headers.cookie = cookieStr;
|
|
6222
|
+
cache.lastRefresh = Date.now();
|
|
6223
|
+
markAccountHeadersReady(accountId);
|
|
6224
|
+
lastKeepAliveNavigation.set(accountId, now);
|
|
6225
|
+
touchAccountActivity(accountId);
|
|
6226
|
+
return true;
|
|
6227
|
+
}
|
|
6228
|
+
} catch {
|
|
6229
|
+
}
|
|
6230
|
+
const loggedIn = await isPageLoggedIn(page, 2e3).catch(() => false);
|
|
6231
|
+
if (!loggedIn) {
|
|
6232
|
+
console.log(
|
|
6233
|
+
`\u{1F493} [SessionKeeper] Account ${accountId} session expired; renewing session...`
|
|
6084
6234
|
);
|
|
6235
|
+
try {
|
|
6236
|
+
await refreshHeadersInternal(accountId, config.timeouts.headers, true);
|
|
6237
|
+
lastKeepAliveNavigation.set(accountId, now);
|
|
6238
|
+
touchAccountActivity(accountId);
|
|
6239
|
+
return true;
|
|
6240
|
+
} catch (err) {
|
|
6241
|
+
console.warn(
|
|
6242
|
+
`[SessionKeeper] Proactive session renewal failed for ${accountId}: ${getErrorMessage(err)}`
|
|
6243
|
+
);
|
|
6244
|
+
}
|
|
6085
6245
|
}
|
|
6086
6246
|
}
|
|
6087
6247
|
const lastNavigation = lastKeepAliveNavigation.get(accountId) ?? 0;
|