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/delete-chats.js
CHANGED
|
@@ -3779,8 +3779,29 @@ function getStealthScript(profile) {
|
|
|
3779
3779
|
const _toBlob = HTMLCanvasElement.prototype.toBlob;
|
|
3780
3780
|
const _getImageData = CanvasRenderingContext2D.prototype.getImageData;
|
|
3781
3781
|
|
|
3782
|
+
function isCaptchaCanvas(canvas) {
|
|
3783
|
+
try {
|
|
3784
|
+
if (!canvas) return false;
|
|
3785
|
+
const id = (canvas.id || "").toLowerCase();
|
|
3786
|
+
const cls = (canvas.className || "").toLowerCase();
|
|
3787
|
+
return (
|
|
3788
|
+
id.includes("baxia") ||
|
|
3789
|
+
id.includes("nc_") ||
|
|
3790
|
+
id.includes("captcha") ||
|
|
3791
|
+
id.includes("punish") ||
|
|
3792
|
+
cls.includes("baxia") ||
|
|
3793
|
+
cls.includes("nc_") ||
|
|
3794
|
+
cls.includes("captcha") ||
|
|
3795
|
+
Boolean(canvas.closest?.("#baxia-dialog, #baxia-punish, [class*='baxia'], [class*='nc_'], .auth-layout"))
|
|
3796
|
+
);
|
|
3797
|
+
} catch(e) {
|
|
3798
|
+
return false;
|
|
3799
|
+
}
|
|
3800
|
+
}
|
|
3801
|
+
|
|
3782
3802
|
function addNoise(canvas) {
|
|
3783
3803
|
try {
|
|
3804
|
+
if (isCaptchaCanvas(canvas)) return;
|
|
3784
3805
|
const ctx = canvas.getContext('2d');
|
|
3785
3806
|
if (!ctx) return;
|
|
3786
3807
|
const style = ctx.fillStyle;
|
|
@@ -3804,6 +3825,9 @@ function getStealthScript(profile) {
|
|
|
3804
3825
|
|
|
3805
3826
|
CanvasRenderingContext2D.prototype.getImageData = function(x, y, w, h) {
|
|
3806
3827
|
const imageData = _getImageData.apply(this, arguments);
|
|
3828
|
+
if (isCaptchaCanvas(this.canvas)) {
|
|
3829
|
+
return imageData;
|
|
3830
|
+
}
|
|
3807
3831
|
const data = imageData.data;
|
|
3808
3832
|
const maxPixels = Math.min(data.length / 4, 2500);
|
|
3809
3833
|
for (let i = 0; i < maxPixels * 4; i += 4) {
|
|
@@ -4759,37 +4783,52 @@ async function loginToQwen(accountId, email, password) {
|
|
|
4759
4783
|
async function loginViaApi(page, email, password) {
|
|
4760
4784
|
try {
|
|
4761
4785
|
const hashedPassword = crypto3.createHash("sha256").update(password).digest("hex");
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
email,
|
|
4770
|
-
password: hashedPassword,
|
|
4771
|
-
login_type: "email"
|
|
4772
|
-
},
|
|
4773
|
-
headers: {
|
|
4774
|
-
"content-type": "application/json",
|
|
4775
|
-
accept: "application/json, text/plain, */*",
|
|
4776
|
-
referer: qwenUrl("/auth"),
|
|
4777
|
-
origin: qwenOrigin(),
|
|
4778
|
-
source: "web"
|
|
4779
|
-
},
|
|
4780
|
-
timeout: 1e4
|
|
4781
|
-
});
|
|
4782
|
-
data = await response.json().catch(() => null);
|
|
4783
|
-
signinSuccess = Boolean(data && (data.success === true || data.token));
|
|
4784
|
-
} catch {
|
|
4785
|
-
}
|
|
4786
|
+
if (!page.url().includes("/auth")) {
|
|
4787
|
+
await page.goto(qwenUrl("/auth"), {
|
|
4788
|
+
waitUntil: "domcontentloaded",
|
|
4789
|
+
timeout: config.timeouts.navigation
|
|
4790
|
+
}).catch(() => {
|
|
4791
|
+
});
|
|
4792
|
+
await sleep2(1e3);
|
|
4786
4793
|
}
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4794
|
+
const signinUrl = "https://auth.qwen.ai/api/v2/auths/signin";
|
|
4795
|
+
const requestId = crypto3.randomUUID();
|
|
4796
|
+
const evalRes = await page.evaluate(
|
|
4797
|
+
async ({ email: email2, password: password2, signinUrl: signinUrl2, requestId: requestId2 }) => {
|
|
4798
|
+
try {
|
|
4799
|
+
const response = await fetch(signinUrl2, {
|
|
4800
|
+
method: "POST",
|
|
4801
|
+
signal: AbortSignal.timeout(15e3),
|
|
4802
|
+
credentials: "include",
|
|
4803
|
+
headers: {
|
|
4804
|
+
accept: "application/json, text/plain, */*",
|
|
4805
|
+
"content-type": "application/json",
|
|
4806
|
+
source: "web",
|
|
4807
|
+
version: "0.3.11",
|
|
4808
|
+
"x-request-origin": "https://chat.qwen.ai",
|
|
4809
|
+
timezone: (/* @__PURE__ */ new Date()).toString().split(" (")[0],
|
|
4810
|
+
"x-request-id": requestId2
|
|
4811
|
+
},
|
|
4812
|
+
body: JSON.stringify({ email: email2, password: password2 })
|
|
4813
|
+
});
|
|
4814
|
+
const json = await response.json().catch(() => null);
|
|
4815
|
+
return { ok: response.ok, status: response.status, data: json };
|
|
4816
|
+
} catch (e) {
|
|
4817
|
+
return { ok: false, error: e.message };
|
|
4818
|
+
}
|
|
4819
|
+
},
|
|
4820
|
+
{ email, password: hashedPassword, signinUrl, requestId }
|
|
4821
|
+
).catch(() => null);
|
|
4822
|
+
let data = evalRes?.data;
|
|
4823
|
+
let signinSuccess = Boolean(
|
|
4824
|
+
data && (data.success === true || data.token || data.data?.access_token || data.data?.token)
|
|
4825
|
+
);
|
|
4826
|
+
if (!signinSuccess && !data?.data?.code) {
|
|
4827
|
+
const fallbackUrl = qwenUrl("/api/v2/auths/signin");
|
|
4828
|
+
const fallbackRes = await page.evaluate(
|
|
4829
|
+
async ({ email: email2, password: password2, fallbackUrl: fallbackUrl2, requestId: requestId2 }) => {
|
|
4791
4830
|
try {
|
|
4792
|
-
const response = await fetch(
|
|
4831
|
+
const response = await fetch(fallbackUrl2, {
|
|
4793
4832
|
method: "POST",
|
|
4794
4833
|
signal: AbortSignal.timeout(1e4),
|
|
4795
4834
|
credentials: "include",
|
|
@@ -4797,10 +4836,11 @@ async function loginViaApi(page, email, password) {
|
|
|
4797
4836
|
accept: "application/json, text/plain, */*",
|
|
4798
4837
|
"content-type": "application/json",
|
|
4799
4838
|
source: "web",
|
|
4839
|
+
version: "0.3.11",
|
|
4800
4840
|
timezone: (/* @__PURE__ */ new Date()).toString().split(" (")[0],
|
|
4801
4841
|
"x-request-id": requestId2
|
|
4802
4842
|
},
|
|
4803
|
-
body: JSON.stringify({ email: email2, password: password2
|
|
4843
|
+
body: JSON.stringify({ email: email2, password: password2 })
|
|
4804
4844
|
});
|
|
4805
4845
|
const json = await response.json().catch(() => null);
|
|
4806
4846
|
return { ok: response.ok, status: response.status, data: json };
|
|
@@ -4808,11 +4848,13 @@ async function loginViaApi(page, email, password) {
|
|
|
4808
4848
|
return { ok: false, error: e.message };
|
|
4809
4849
|
}
|
|
4810
4850
|
},
|
|
4811
|
-
{ email, password: hashedPassword,
|
|
4851
|
+
{ email, password: hashedPassword, fallbackUrl, requestId }
|
|
4812
4852
|
).catch(() => null);
|
|
4813
|
-
if (
|
|
4814
|
-
data =
|
|
4815
|
-
signinSuccess = Boolean(
|
|
4853
|
+
if (fallbackRes?.data) {
|
|
4854
|
+
data = fallbackRes.data;
|
|
4855
|
+
signinSuccess = Boolean(
|
|
4856
|
+
data && (data.success === true || data.token || data.data?.access_token || data.data?.token)
|
|
4857
|
+
);
|
|
4816
4858
|
}
|
|
4817
4859
|
}
|
|
4818
4860
|
if (data?.success === false) {
|
|
@@ -4826,7 +4868,8 @@ async function loginViaApi(page, email, password) {
|
|
|
4826
4868
|
};
|
|
4827
4869
|
}
|
|
4828
4870
|
if (signinSuccess) {
|
|
4829
|
-
const token = data?.data?.token || data?.token;
|
|
4871
|
+
const token = data?.data?.access_token || data?.data?.token || data?.access_token || data?.token;
|
|
4872
|
+
const refreshToken = data?.data?.refresh_token || data?.refresh_token;
|
|
4830
4873
|
if (token) {
|
|
4831
4874
|
try {
|
|
4832
4875
|
await page.context().addCookies([
|
|
@@ -4850,14 +4893,19 @@ async function loginViaApi(page, email, password) {
|
|
|
4850
4893
|
}).catch(() => {
|
|
4851
4894
|
});
|
|
4852
4895
|
if (token) {
|
|
4853
|
-
await page.evaluate(
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4896
|
+
await page.evaluate(
|
|
4897
|
+
({ tok, rTok }) => {
|
|
4898
|
+
try {
|
|
4899
|
+
localStorage.removeItem("qwen_token_logged_out_marker");
|
|
4900
|
+
localStorage.setItem("token", tok);
|
|
4901
|
+
localStorage.setItem("access_token", tok);
|
|
4902
|
+
if (rTok) localStorage.setItem("refresh_token", rTok);
|
|
4903
|
+
document.cookie = `token=${encodeURIComponent(tok)}; path=/; domain=.qwen.ai; max-age=31536000`;
|
|
4904
|
+
} catch {
|
|
4905
|
+
}
|
|
4906
|
+
},
|
|
4907
|
+
{ tok: token, rTok: refreshToken }
|
|
4908
|
+
).catch(() => {
|
|
4861
4909
|
});
|
|
4862
4910
|
await page.reload({ waitUntil: "domcontentloaded" }).catch(() => {
|
|
4863
4911
|
});
|
|
@@ -4885,11 +4933,23 @@ async function loginViaApi(page, email, password) {
|
|
|
4885
4933
|
}
|
|
4886
4934
|
async function loginViaUi(page, email, password) {
|
|
4887
4935
|
try {
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4936
|
+
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 2e3).catch(() => false)) {
|
|
4937
|
+
return { success: true };
|
|
4938
|
+
}
|
|
4939
|
+
try {
|
|
4940
|
+
await page.goto(qwenUrl("/auth"), {
|
|
4941
|
+
waitUntil: "domcontentloaded",
|
|
4942
|
+
timeout: Math.min(config.timeouts.navigation, 15e3)
|
|
4943
|
+
});
|
|
4944
|
+
await sleep2(1e3);
|
|
4945
|
+
} catch (gotoErr) {
|
|
4946
|
+
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 3e3).catch(() => false)) {
|
|
4947
|
+
return { success: true };
|
|
4948
|
+
}
|
|
4949
|
+
}
|
|
4950
|
+
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 3e3).catch(() => false)) {
|
|
4951
|
+
return { success: true };
|
|
4952
|
+
}
|
|
4893
4953
|
const emailSelector = [
|
|
4894
4954
|
'input[type="email"]',
|
|
4895
4955
|
'input[name="email"]',
|
|
@@ -4899,7 +4959,7 @@ async function loginViaUi(page, email, password) {
|
|
|
4899
4959
|
].join(", ");
|
|
4900
4960
|
try {
|
|
4901
4961
|
await page.waitForSelector(emailSelector, {
|
|
4902
|
-
timeout: Math.min(config.timeouts.page,
|
|
4962
|
+
timeout: Math.min(config.timeouts.page, 5e3)
|
|
4903
4963
|
});
|
|
4904
4964
|
} catch {
|
|
4905
4965
|
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 3e3)) {
|
|
@@ -4912,30 +4972,55 @@ async function loginViaUi(page, email, password) {
|
|
|
4912
4972
|
return { success: false, reason: "Campo de e-mail n\xE3o encontrado (poss\xEDvel captcha)" };
|
|
4913
4973
|
}
|
|
4914
4974
|
await clearVisibleChallenge(page);
|
|
4915
|
-
const
|
|
4916
|
-
return page.locator('
|
|
4917
|
-
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
|
|
4918
|
-
}).first();
|
|
4975
|
+
const isPasswordInputPresent = async () => {
|
|
4976
|
+
return await page.locator('input[type="password"], input[name="password"]').count().catch(() => 0) > 0;
|
|
4919
4977
|
};
|
|
4920
|
-
|
|
4921
|
-
|
|
4922
|
-
|
|
4923
|
-
await pwdModeBtn.click({ timeout: 2e3 }).catch(() => {
|
|
4978
|
+
const revealPasswordMode = async () => {
|
|
4979
|
+
if (page.url().includes("/forget")) {
|
|
4980
|
+
await page.goto(qwenUrl("/auth"), { waitUntil: "domcontentloaded", timeout: 1e4 }).catch(() => {
|
|
4924
4981
|
});
|
|
4925
|
-
await sleep2(
|
|
4982
|
+
await sleep2(1e3);
|
|
4926
4983
|
}
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
if (await
|
|
4934
|
-
await
|
|
4984
|
+
if (await isPasswordInputPresent()) return;
|
|
4985
|
+
const btn = page.locator("button").filter({
|
|
4986
|
+
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
|
|
4987
|
+
}).filter({
|
|
4988
|
+
hasNotText: /(?:esqueci|forgot|olvid|reset|recover)/i
|
|
4989
|
+
}).first();
|
|
4990
|
+
if (await btn.isVisible({ timeout: 1500 }).catch(() => false)) {
|
|
4991
|
+
await btn.click({ timeout: 2e3 }).catch(() => {
|
|
4935
4992
|
});
|
|
4936
4993
|
await sleep2(500);
|
|
4937
4994
|
}
|
|
4995
|
+
if (await isPasswordInputPresent()) return;
|
|
4996
|
+
await page.evaluate(() => {
|
|
4997
|
+
try {
|
|
4998
|
+
const buttons = Array.from(document.querySelectorAll("button, [role='button'], a"));
|
|
4999
|
+
for (const b of buttons) {
|
|
5000
|
+
const txt = (b.innerText || "").trim().toLowerCase();
|
|
5001
|
+
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")) {
|
|
5002
|
+
b.click();
|
|
5003
|
+
return true;
|
|
5004
|
+
}
|
|
5005
|
+
}
|
|
5006
|
+
} catch {
|
|
5007
|
+
}
|
|
5008
|
+
return false;
|
|
5009
|
+
}).catch(() => false);
|
|
5010
|
+
await sleep2(500);
|
|
5011
|
+
};
|
|
5012
|
+
await revealPasswordMode();
|
|
5013
|
+
try {
|
|
5014
|
+
await page.fill(emailSelector, email, { timeout: 8e3 });
|
|
5015
|
+
await sleep2(300);
|
|
4938
5016
|
} catch {
|
|
5017
|
+
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 3e3)) {
|
|
5018
|
+
return { success: true };
|
|
5019
|
+
}
|
|
5020
|
+
throw new Error(`Campo de e-mail n\xE3o encontrado na tela de autentica\xE7\xE3o`);
|
|
5021
|
+
}
|
|
5022
|
+
if (!await isPasswordInputPresent()) {
|
|
5023
|
+
await revealPasswordMode();
|
|
4939
5024
|
}
|
|
4940
5025
|
const passwordSelector = 'input[type="password"], input[name="password"]';
|
|
4941
5026
|
try {
|
|
@@ -4954,17 +5039,50 @@ async function loginViaUi(page, email, password) {
|
|
|
4954
5039
|
reason: "Campo de senha n\xE3o encontrado na tela de autentica\xE7\xE3o"
|
|
4955
5040
|
};
|
|
4956
5041
|
}
|
|
4957
|
-
|
|
4958
|
-
|
|
5042
|
+
try {
|
|
5043
|
+
await page.fill(passwordSelector, password, { timeout: 8e3 });
|
|
5044
|
+
await sleep2(500);
|
|
5045
|
+
} catch {
|
|
5046
|
+
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 3e3)) {
|
|
5047
|
+
return { success: true };
|
|
5048
|
+
}
|
|
5049
|
+
throw new Error(`Campo de senha n\xE3o encontrado na tela de autentica\xE7\xE3o`);
|
|
5050
|
+
}
|
|
5051
|
+
await page.evaluate(() => {
|
|
5052
|
+
try {
|
|
5053
|
+
const emailEl = document.querySelector('input[name="email"], input[type="email"], input[type="text"]');
|
|
5054
|
+
const passEl = document.querySelector('input[type="password"], input[name="password"]');
|
|
5055
|
+
if (emailEl) {
|
|
5056
|
+
emailEl.dispatchEvent(new Event("input", { bubbles: true }));
|
|
5057
|
+
emailEl.dispatchEvent(new Event("change", { bubbles: true }));
|
|
5058
|
+
emailEl.dispatchEvent(new Event("blur", { bubbles: true }));
|
|
5059
|
+
}
|
|
5060
|
+
if (passEl) {
|
|
5061
|
+
passEl.dispatchEvent(new Event("input", { bubbles: true }));
|
|
5062
|
+
passEl.dispatchEvent(new Event("change", { bubbles: true }));
|
|
5063
|
+
passEl.dispatchEvent(new Event("blur", { bubbles: true }));
|
|
5064
|
+
}
|
|
5065
|
+
} catch {
|
|
5066
|
+
}
|
|
5067
|
+
}).catch(() => {
|
|
5068
|
+
});
|
|
4959
5069
|
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")';
|
|
4960
5070
|
const submitButton = page.locator(submitSelector).first();
|
|
4961
5071
|
try {
|
|
4962
5072
|
await page.waitForSelector('button[type="submit"]:not([disabled])', {
|
|
4963
|
-
timeout:
|
|
5073
|
+
timeout: 4e3
|
|
4964
5074
|
});
|
|
4965
5075
|
await submitButton.click();
|
|
4966
5076
|
} catch {
|
|
4967
|
-
await
|
|
5077
|
+
const isDisabled = await submitButton.isDisabled().catch(() => true);
|
|
5078
|
+
if (!isDisabled) {
|
|
5079
|
+
await submitButton.click({ force: true }).catch(() => {
|
|
5080
|
+
});
|
|
5081
|
+
} else {
|
|
5082
|
+
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 2e3)) {
|
|
5083
|
+
return { success: true };
|
|
5084
|
+
}
|
|
5085
|
+
}
|
|
4968
5086
|
}
|
|
4969
5087
|
const postSubmitDeadline = Date.now() + 15e3;
|
|
4970
5088
|
while (Date.now() < postSubmitDeadline) {
|
|
@@ -5550,6 +5668,17 @@ async function refreshHeadersInternal(accountId, timeoutMs = config.timeouts.hea
|
|
|
5550
5668
|
}
|
|
5551
5669
|
};
|
|
5552
5670
|
if (forceReauth) {
|
|
5671
|
+
const alreadyIn = await isPageLoggedIn(page, 2e3).catch(() => false);
|
|
5672
|
+
if (alreadyIn) {
|
|
5673
|
+
const liveCookies = await page.context().cookies();
|
|
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
|
+
}
|
|
5681
|
+
}
|
|
5553
5682
|
await executeReauth();
|
|
5554
5683
|
} else {
|
|
5555
5684
|
try {
|
|
@@ -5984,19 +6113,50 @@ async function keepAlivePlaywrightAccount(accountId) {
|
|
|
5984
6113
|
const now = Date.now();
|
|
5985
6114
|
const currentUrl = page.url();
|
|
5986
6115
|
const cookie = await getCookies(accountId);
|
|
5987
|
-
if (cookie && isTokenExpiringSoon(cookie,
|
|
5988
|
-
console.log(
|
|
5989
|
-
`\u{1F493} [SessionKeeper] Account ${accountId} token expires within 45m; proactively renewing session...`
|
|
5990
|
-
);
|
|
6116
|
+
if (cookie && isTokenExpiringSoon(cookie, 2)) {
|
|
5991
6117
|
try {
|
|
5992
|
-
await
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
5998
|
-
|
|
6118
|
+
await page.evaluate(async () => {
|
|
6119
|
+
await fetch("https://auth.qwen.ai/api/v2/auths/refresh", {
|
|
6120
|
+
method: "GET",
|
|
6121
|
+
credentials: "include"
|
|
6122
|
+
}).catch(() => {
|
|
6123
|
+
});
|
|
6124
|
+
await fetch("/api/v1/auths/", {
|
|
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...`
|
|
5999
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
|
+
}
|
|
6000
6160
|
}
|
|
6001
6161
|
}
|
|
6002
6162
|
const lastNavigation = lastKeepAliveNavigation.get(accountId) ?? 0;
|