qwenproxy-cli 1.4.2 → 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 +242 -109
- package/dist/delete-chats.js +295 -120
- package/dist/index.js +296 -121
- package/dist/login.js +297 -121
- package/dist/reset-cooldowns.js +242 -109
- package/package.json +1 -1
- package/src/core/version.ts +1 -1
- package/src/login.ts +1 -1
- package/src/services/playwright.ts +352 -130
package/dist/clean-cache.js
CHANGED
|
@@ -3287,8 +3287,29 @@ function getStealthScript(profile) {
|
|
|
3287
3287
|
const _toBlob = HTMLCanvasElement.prototype.toBlob;
|
|
3288
3288
|
const _getImageData = CanvasRenderingContext2D.prototype.getImageData;
|
|
3289
3289
|
|
|
3290
|
+
function isCaptchaCanvas(canvas) {
|
|
3291
|
+
try {
|
|
3292
|
+
if (!canvas) return false;
|
|
3293
|
+
const id = (canvas.id || "").toLowerCase();
|
|
3294
|
+
const cls = (canvas.className || "").toLowerCase();
|
|
3295
|
+
return (
|
|
3296
|
+
id.includes("baxia") ||
|
|
3297
|
+
id.includes("nc_") ||
|
|
3298
|
+
id.includes("captcha") ||
|
|
3299
|
+
id.includes("punish") ||
|
|
3300
|
+
cls.includes("baxia") ||
|
|
3301
|
+
cls.includes("nc_") ||
|
|
3302
|
+
cls.includes("captcha") ||
|
|
3303
|
+
Boolean(canvas.closest?.("#baxia-dialog, #baxia-punish, [class*='baxia'], [class*='nc_'], .auth-layout"))
|
|
3304
|
+
);
|
|
3305
|
+
} catch(e) {
|
|
3306
|
+
return false;
|
|
3307
|
+
}
|
|
3308
|
+
}
|
|
3309
|
+
|
|
3290
3310
|
function addNoise(canvas) {
|
|
3291
3311
|
try {
|
|
3312
|
+
if (isCaptchaCanvas(canvas)) return;
|
|
3292
3313
|
const ctx = canvas.getContext('2d');
|
|
3293
3314
|
if (!ctx) return;
|
|
3294
3315
|
const style = ctx.fillStyle;
|
|
@@ -3312,6 +3333,9 @@ function getStealthScript(profile) {
|
|
|
3312
3333
|
|
|
3313
3334
|
CanvasRenderingContext2D.prototype.getImageData = function(x, y, w, h) {
|
|
3314
3335
|
const imageData = _getImageData.apply(this, arguments);
|
|
3336
|
+
if (isCaptchaCanvas(this.canvas)) {
|
|
3337
|
+
return imageData;
|
|
3338
|
+
}
|
|
3315
3339
|
const data = imageData.data;
|
|
3316
3340
|
const maxPixels = Math.min(data.length / 4, 2500);
|
|
3317
3341
|
for (let i = 0; i < maxPixels * 4; i += 4) {
|
|
@@ -3852,8 +3876,9 @@ async function loginToQwen(accountId, email, password) {
|
|
|
3852
3876
|
}
|
|
3853
3877
|
if (attempt < maxAttempts) {
|
|
3854
3878
|
const backoffMs = attempt * 5e3;
|
|
3879
|
+
const failReason = uiResult.reason || apiResult.reason || "falha tempor\xE1ria";
|
|
3855
3880
|
console.warn(
|
|
3856
|
-
`\u26A0\uFE0F [Playwright] Login attempt ${attempt}/${maxAttempts} failed for ${maskEmail(email)} (${
|
|
3881
|
+
`\u26A0\uFE0F [Playwright] Login attempt ${attempt}/${maxAttempts} failed for ${maskEmail(email)} (${failReason}), retrying in ${backoffMs / 1e3}s`
|
|
3857
3882
|
);
|
|
3858
3883
|
await sleep2(backoffMs);
|
|
3859
3884
|
}
|
|
@@ -3883,37 +3908,52 @@ async function loginToQwen(accountId, email, password) {
|
|
|
3883
3908
|
async function loginViaApi(page, email, password) {
|
|
3884
3909
|
try {
|
|
3885
3910
|
const hashedPassword = crypto3.createHash("sha256").update(password).digest("hex");
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
email,
|
|
3894
|
-
password: hashedPassword,
|
|
3895
|
-
login_type: "email"
|
|
3896
|
-
},
|
|
3897
|
-
headers: {
|
|
3898
|
-
"content-type": "application/json",
|
|
3899
|
-
accept: "application/json, text/plain, */*",
|
|
3900
|
-
referer: qwenUrl("/auth"),
|
|
3901
|
-
origin: qwenOrigin(),
|
|
3902
|
-
source: "web"
|
|
3903
|
-
},
|
|
3904
|
-
timeout: 1e4
|
|
3905
|
-
});
|
|
3906
|
-
data = await response.json().catch(() => null);
|
|
3907
|
-
signinSuccess = Boolean(data && (data.success === true || data.token));
|
|
3908
|
-
} catch {
|
|
3909
|
-
}
|
|
3911
|
+
if (!page.url().includes("/auth")) {
|
|
3912
|
+
await page.goto(qwenUrl("/auth"), {
|
|
3913
|
+
waitUntil: "domcontentloaded",
|
|
3914
|
+
timeout: config.timeouts.navigation
|
|
3915
|
+
}).catch(() => {
|
|
3916
|
+
});
|
|
3917
|
+
await sleep2(1e3);
|
|
3910
3918
|
}
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3919
|
+
const signinUrl = "https://auth.qwen.ai/api/v2/auths/signin";
|
|
3920
|
+
const requestId = crypto3.randomUUID();
|
|
3921
|
+
const evalRes = await page.evaluate(
|
|
3922
|
+
async ({ email: email2, password: password2, signinUrl: signinUrl2, requestId: requestId2 }) => {
|
|
3923
|
+
try {
|
|
3924
|
+
const response = await fetch(signinUrl2, {
|
|
3925
|
+
method: "POST",
|
|
3926
|
+
signal: AbortSignal.timeout(15e3),
|
|
3927
|
+
credentials: "include",
|
|
3928
|
+
headers: {
|
|
3929
|
+
accept: "application/json, text/plain, */*",
|
|
3930
|
+
"content-type": "application/json",
|
|
3931
|
+
source: "web",
|
|
3932
|
+
version: "0.3.11",
|
|
3933
|
+
"x-request-origin": "https://chat.qwen.ai",
|
|
3934
|
+
timezone: (/* @__PURE__ */ new Date()).toString().split(" (")[0],
|
|
3935
|
+
"x-request-id": requestId2
|
|
3936
|
+
},
|
|
3937
|
+
body: JSON.stringify({ email: email2, password: password2 })
|
|
3938
|
+
});
|
|
3939
|
+
const json = await response.json().catch(() => null);
|
|
3940
|
+
return { ok: response.ok, status: response.status, data: json };
|
|
3941
|
+
} catch (e) {
|
|
3942
|
+
return { ok: false, error: e.message };
|
|
3943
|
+
}
|
|
3944
|
+
},
|
|
3945
|
+
{ email, password: hashedPassword, signinUrl, requestId }
|
|
3946
|
+
).catch(() => null);
|
|
3947
|
+
let data = evalRes?.data;
|
|
3948
|
+
let signinSuccess = Boolean(
|
|
3949
|
+
data && (data.success === true || data.token || data.data?.access_token || data.data?.token)
|
|
3950
|
+
);
|
|
3951
|
+
if (!signinSuccess && !data?.data?.code) {
|
|
3952
|
+
const fallbackUrl = qwenUrl("/api/v2/auths/signin");
|
|
3953
|
+
const fallbackRes = await page.evaluate(
|
|
3954
|
+
async ({ email: email2, password: password2, fallbackUrl: fallbackUrl2, requestId: requestId2 }) => {
|
|
3915
3955
|
try {
|
|
3916
|
-
const response = await fetch(
|
|
3956
|
+
const response = await fetch(fallbackUrl2, {
|
|
3917
3957
|
method: "POST",
|
|
3918
3958
|
signal: AbortSignal.timeout(1e4),
|
|
3919
3959
|
credentials: "include",
|
|
@@ -3921,10 +3961,11 @@ async function loginViaApi(page, email, password) {
|
|
|
3921
3961
|
accept: "application/json, text/plain, */*",
|
|
3922
3962
|
"content-type": "application/json",
|
|
3923
3963
|
source: "web",
|
|
3964
|
+
version: "0.3.11",
|
|
3924
3965
|
timezone: (/* @__PURE__ */ new Date()).toString().split(" (")[0],
|
|
3925
3966
|
"x-request-id": requestId2
|
|
3926
3967
|
},
|
|
3927
|
-
body: JSON.stringify({ email: email2, password: password2
|
|
3968
|
+
body: JSON.stringify({ email: email2, password: password2 })
|
|
3928
3969
|
});
|
|
3929
3970
|
const json = await response.json().catch(() => null);
|
|
3930
3971
|
return { ok: response.ok, status: response.status, data: json };
|
|
@@ -3932,11 +3973,13 @@ async function loginViaApi(page, email, password) {
|
|
|
3932
3973
|
return { ok: false, error: e.message };
|
|
3933
3974
|
}
|
|
3934
3975
|
},
|
|
3935
|
-
{ email, password: hashedPassword,
|
|
3976
|
+
{ email, password: hashedPassword, fallbackUrl, requestId }
|
|
3936
3977
|
).catch(() => null);
|
|
3937
|
-
if (
|
|
3938
|
-
data =
|
|
3939
|
-
signinSuccess = Boolean(
|
|
3978
|
+
if (fallbackRes?.data) {
|
|
3979
|
+
data = fallbackRes.data;
|
|
3980
|
+
signinSuccess = Boolean(
|
|
3981
|
+
data && (data.success === true || data.token || data.data?.access_token || data.data?.token)
|
|
3982
|
+
);
|
|
3940
3983
|
}
|
|
3941
3984
|
}
|
|
3942
3985
|
if (data?.success === false) {
|
|
@@ -3950,7 +3993,8 @@ async function loginViaApi(page, email, password) {
|
|
|
3950
3993
|
};
|
|
3951
3994
|
}
|
|
3952
3995
|
if (signinSuccess) {
|
|
3953
|
-
const token = data?.data?.token || data?.token;
|
|
3996
|
+
const token = data?.data?.access_token || data?.data?.token || data?.access_token || data?.token;
|
|
3997
|
+
const refreshToken = data?.data?.refresh_token || data?.refresh_token;
|
|
3954
3998
|
if (token) {
|
|
3955
3999
|
try {
|
|
3956
4000
|
await page.context().addCookies([
|
|
@@ -3974,14 +4018,19 @@ async function loginViaApi(page, email, password) {
|
|
|
3974
4018
|
}).catch(() => {
|
|
3975
4019
|
});
|
|
3976
4020
|
if (token) {
|
|
3977
|
-
await page.evaluate(
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
4021
|
+
await page.evaluate(
|
|
4022
|
+
({ tok, rTok }) => {
|
|
4023
|
+
try {
|
|
4024
|
+
localStorage.removeItem("qwen_token_logged_out_marker");
|
|
4025
|
+
localStorage.setItem("token", tok);
|
|
4026
|
+
localStorage.setItem("access_token", tok);
|
|
4027
|
+
if (rTok) localStorage.setItem("refresh_token", rTok);
|
|
4028
|
+
document.cookie = `token=${encodeURIComponent(tok)}; path=/; domain=.qwen.ai; max-age=31536000`;
|
|
4029
|
+
} catch {
|
|
4030
|
+
}
|
|
4031
|
+
},
|
|
4032
|
+
{ tok: token, rTok: refreshToken }
|
|
4033
|
+
).catch(() => {
|
|
3985
4034
|
});
|
|
3986
4035
|
await page.reload({ waitUntil: "domcontentloaded" }).catch(() => {
|
|
3987
4036
|
});
|
|
@@ -4009,11 +4058,23 @@ async function loginViaApi(page, email, password) {
|
|
|
4009
4058
|
}
|
|
4010
4059
|
async function loginViaUi(page, email, password) {
|
|
4011
4060
|
try {
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4061
|
+
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 2e3).catch(() => false)) {
|
|
4062
|
+
return { success: true };
|
|
4063
|
+
}
|
|
4064
|
+
try {
|
|
4065
|
+
await page.goto(qwenUrl("/auth"), {
|
|
4066
|
+
waitUntil: "domcontentloaded",
|
|
4067
|
+
timeout: Math.min(config.timeouts.navigation, 15e3)
|
|
4068
|
+
});
|
|
4069
|
+
await sleep2(1e3);
|
|
4070
|
+
} catch (gotoErr) {
|
|
4071
|
+
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 3e3).catch(() => false)) {
|
|
4072
|
+
return { success: true };
|
|
4073
|
+
}
|
|
4074
|
+
}
|
|
4075
|
+
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 3e3).catch(() => false)) {
|
|
4076
|
+
return { success: true };
|
|
4077
|
+
}
|
|
4017
4078
|
const emailSelector = [
|
|
4018
4079
|
'input[type="email"]',
|
|
4019
4080
|
'input[name="email"]',
|
|
@@ -4023,7 +4084,7 @@ async function loginViaUi(page, email, password) {
|
|
|
4023
4084
|
].join(", ");
|
|
4024
4085
|
try {
|
|
4025
4086
|
await page.waitForSelector(emailSelector, {
|
|
4026
|
-
timeout: Math.min(config.timeouts.page,
|
|
4087
|
+
timeout: Math.min(config.timeouts.page, 5e3)
|
|
4027
4088
|
});
|
|
4028
4089
|
} catch {
|
|
4029
4090
|
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 3e3)) {
|
|
@@ -4036,30 +4097,55 @@ async function loginViaUi(page, email, password) {
|
|
|
4036
4097
|
return { success: false, reason: "Campo de e-mail n\xE3o encontrado (poss\xEDvel captcha)" };
|
|
4037
4098
|
}
|
|
4038
4099
|
await clearVisibleChallenge(page);
|
|
4039
|
-
const
|
|
4040
|
-
return page.locator('
|
|
4041
|
-
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
|
|
4042
|
-
}).first();
|
|
4100
|
+
const isPasswordInputPresent = async () => {
|
|
4101
|
+
return await page.locator('input[type="password"], input[name="password"]').count().catch(() => 0) > 0;
|
|
4043
4102
|
};
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
await pwdModeBtn.click({ timeout: 2e3 }).catch(() => {
|
|
4103
|
+
const revealPasswordMode = async () => {
|
|
4104
|
+
if (page.url().includes("/forget")) {
|
|
4105
|
+
await page.goto(qwenUrl("/auth"), { waitUntil: "domcontentloaded", timeout: 1e4 }).catch(() => {
|
|
4048
4106
|
});
|
|
4049
|
-
await sleep2(
|
|
4107
|
+
await sleep2(1e3);
|
|
4050
4108
|
}
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
if (await
|
|
4058
|
-
await
|
|
4109
|
+
if (await isPasswordInputPresent()) return;
|
|
4110
|
+
const btn = page.locator("button").filter({
|
|
4111
|
+
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
|
|
4112
|
+
}).filter({
|
|
4113
|
+
hasNotText: /(?:esqueci|forgot|olvid|reset|recover)/i
|
|
4114
|
+
}).first();
|
|
4115
|
+
if (await btn.isVisible({ timeout: 1500 }).catch(() => false)) {
|
|
4116
|
+
await btn.click({ timeout: 2e3 }).catch(() => {
|
|
4059
4117
|
});
|
|
4060
4118
|
await sleep2(500);
|
|
4061
4119
|
}
|
|
4120
|
+
if (await isPasswordInputPresent()) return;
|
|
4121
|
+
await page.evaluate(() => {
|
|
4122
|
+
try {
|
|
4123
|
+
const buttons = Array.from(document.querySelectorAll("button, [role='button'], a"));
|
|
4124
|
+
for (const b of buttons) {
|
|
4125
|
+
const txt = (b.innerText || "").trim().toLowerCase();
|
|
4126
|
+
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")) {
|
|
4127
|
+
b.click();
|
|
4128
|
+
return true;
|
|
4129
|
+
}
|
|
4130
|
+
}
|
|
4131
|
+
} catch {
|
|
4132
|
+
}
|
|
4133
|
+
return false;
|
|
4134
|
+
}).catch(() => false);
|
|
4135
|
+
await sleep2(500);
|
|
4136
|
+
};
|
|
4137
|
+
await revealPasswordMode();
|
|
4138
|
+
try {
|
|
4139
|
+
await page.fill(emailSelector, email, { timeout: 8e3 });
|
|
4140
|
+
await sleep2(300);
|
|
4062
4141
|
} catch {
|
|
4142
|
+
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 3e3)) {
|
|
4143
|
+
return { success: true };
|
|
4144
|
+
}
|
|
4145
|
+
throw new Error(`Campo de e-mail n\xE3o encontrado na tela de autentica\xE7\xE3o`);
|
|
4146
|
+
}
|
|
4147
|
+
if (!await isPasswordInputPresent()) {
|
|
4148
|
+
await revealPasswordMode();
|
|
4063
4149
|
}
|
|
4064
4150
|
const passwordSelector = 'input[type="password"], input[name="password"]';
|
|
4065
4151
|
try {
|
|
@@ -4078,61 +4164,108 @@ async function loginViaUi(page, email, password) {
|
|
|
4078
4164
|
reason: "Campo de senha n\xE3o encontrado na tela de autentica\xE7\xE3o"
|
|
4079
4165
|
};
|
|
4080
4166
|
}
|
|
4081
|
-
|
|
4082
|
-
|
|
4167
|
+
try {
|
|
4168
|
+
await page.fill(passwordSelector, password, { timeout: 8e3 });
|
|
4169
|
+
await sleep2(500);
|
|
4170
|
+
} catch {
|
|
4171
|
+
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 3e3)) {
|
|
4172
|
+
return { success: true };
|
|
4173
|
+
}
|
|
4174
|
+
throw new Error(`Campo de senha n\xE3o encontrado na tela de autentica\xE7\xE3o`);
|
|
4175
|
+
}
|
|
4176
|
+
await page.evaluate(() => {
|
|
4177
|
+
try {
|
|
4178
|
+
const emailEl = document.querySelector('input[name="email"], input[type="email"], input[type="text"]');
|
|
4179
|
+
const passEl = document.querySelector('input[type="password"], input[name="password"]');
|
|
4180
|
+
if (emailEl) {
|
|
4181
|
+
emailEl.dispatchEvent(new Event("input", { bubbles: true }));
|
|
4182
|
+
emailEl.dispatchEvent(new Event("change", { bubbles: true }));
|
|
4183
|
+
emailEl.dispatchEvent(new Event("blur", { bubbles: true }));
|
|
4184
|
+
}
|
|
4185
|
+
if (passEl) {
|
|
4186
|
+
passEl.dispatchEvent(new Event("input", { bubbles: true }));
|
|
4187
|
+
passEl.dispatchEvent(new Event("change", { bubbles: true }));
|
|
4188
|
+
passEl.dispatchEvent(new Event("blur", { bubbles: true }));
|
|
4189
|
+
}
|
|
4190
|
+
} catch {
|
|
4191
|
+
}
|
|
4192
|
+
}).catch(() => {
|
|
4193
|
+
});
|
|
4083
4194
|
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")';
|
|
4084
4195
|
const submitButton = page.locator(submitSelector).first();
|
|
4085
4196
|
try {
|
|
4086
4197
|
await page.waitForSelector('button[type="submit"]:not([disabled])', {
|
|
4087
|
-
timeout:
|
|
4198
|
+
timeout: 4e3
|
|
4088
4199
|
});
|
|
4089
4200
|
await submitButton.click();
|
|
4090
4201
|
} catch {
|
|
4091
|
-
await
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
const codeSelector = 'input[placeholder*="code" i], input[placeholder*="c\xF3digo" i], input[name*="code" i]';
|
|
4101
|
-
const codeInput = page.locator(codeSelector).first();
|
|
4102
|
-
if (await codeInput.isVisible().catch(() => false)) {
|
|
4103
|
-
return {
|
|
4104
|
-
success: false,
|
|
4105
|
-
reason: "Conta requer c\xF3digo de verifica\xE7\xE3o enviado por e-mail (2FA/OTP)"
|
|
4106
|
-
};
|
|
4202
|
+
const isDisabled = await submitButton.isDisabled().catch(() => true);
|
|
4203
|
+
if (!isDisabled) {
|
|
4204
|
+
await submitButton.click({ force: true }).catch(() => {
|
|
4205
|
+
});
|
|
4206
|
+
} else {
|
|
4207
|
+
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 2e3)) {
|
|
4208
|
+
return { success: true };
|
|
4209
|
+
}
|
|
4210
|
+
}
|
|
4107
4211
|
}
|
|
4108
|
-
const
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4212
|
+
const postSubmitDeadline = Date.now() + 15e3;
|
|
4213
|
+
while (Date.now() < postSubmitDeadline) {
|
|
4214
|
+
if (page.isClosed()) break;
|
|
4215
|
+
if (config.captcha.enabled) {
|
|
4216
|
+
await solveBaxiaCaptcha(page, {
|
|
4217
|
+
waitForMs: 1500,
|
|
4218
|
+
maxAttempts: config.captcha.maxAttempts,
|
|
4219
|
+
retryDelayMs: config.captcha.retryDelayMs
|
|
4220
|
+
}).catch(() => {
|
|
4221
|
+
});
|
|
4222
|
+
}
|
|
4223
|
+
const errorSelector = [
|
|
4224
|
+
".qwen-chat-v2-toast-text",
|
|
4225
|
+
".qwen-chat-v2-toast-content",
|
|
4226
|
+
".ant-form-item-explain-error",
|
|
4227
|
+
".ant-message-error",
|
|
4228
|
+
".ant-message-notice",
|
|
4229
|
+
'[role="alert"]',
|
|
4230
|
+
".qwenchat-auth-error",
|
|
4231
|
+
".auth-error-message"
|
|
4232
|
+
].join(", ");
|
|
4233
|
+
const errorEl = page.locator(errorSelector).first();
|
|
4234
|
+
if (await errorEl.isVisible().catch(() => false)) {
|
|
4235
|
+
const errorText = (await errorEl.innerText().catch(() => "")).trim();
|
|
4236
|
+
if (errorText) {
|
|
4237
|
+
const classified = classifyQwenAuthError(void 0, errorText);
|
|
4238
|
+
return {
|
|
4239
|
+
success: false,
|
|
4240
|
+
permanentFailure: classified.isPermanent,
|
|
4241
|
+
reason: `Formul\xE1rio: ${classified.reason}`
|
|
4242
|
+
};
|
|
4243
|
+
}
|
|
4244
|
+
}
|
|
4245
|
+
const codeSelector = 'input[placeholder*="code" i], input[placeholder*="c\xF3digo" i], input[name*="code" i]';
|
|
4246
|
+
const codeInput = page.locator(codeSelector).first();
|
|
4247
|
+
if (await codeInput.isVisible().catch(() => false)) {
|
|
4123
4248
|
return {
|
|
4124
4249
|
success: false,
|
|
4125
|
-
|
|
4126
|
-
reason: `Formul\xE1rio: ${classified.reason}`
|
|
4250
|
+
reason: "Conta requer c\xF3digo de verifica\xE7\xE3o enviado por e-mail (2FA/OTP)"
|
|
4127
4251
|
};
|
|
4128
4252
|
}
|
|
4253
|
+
try {
|
|
4254
|
+
const liveCookies = await page.context().cookies();
|
|
4255
|
+
if (liveCookies.some((c) => c.name === "token")) {
|
|
4256
|
+
return { success: true };
|
|
4257
|
+
}
|
|
4258
|
+
} catch {
|
|
4259
|
+
}
|
|
4260
|
+
const currentUrl = page.url();
|
|
4261
|
+
if (!currentUrl.includes("/auth") && !currentUrl.includes("/login")) {
|
|
4262
|
+
if (await isPageLoggedIn(page, 3e3)) {
|
|
4263
|
+
return { success: true };
|
|
4264
|
+
}
|
|
4265
|
+
}
|
|
4266
|
+
await sleep2(1e3);
|
|
4129
4267
|
}
|
|
4130
|
-
|
|
4131
|
-
if (isLoggedIn) {
|
|
4132
|
-
await page.goto(qwenUrl("/"), {
|
|
4133
|
-
waitUntil: "domcontentloaded",
|
|
4134
|
-
timeout: config.timeouts.navigation
|
|
4135
|
-
});
|
|
4268
|
+
if (await isPageLoggedIn(page, 3e3)) {
|
|
4136
4269
|
return { success: true };
|
|
4137
4270
|
}
|
|
4138
4271
|
return {
|