qwenproxy-cli 1.4.2 → 1.4.3
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 +54 -39
- package/dist/delete-chats.js +54 -39
- package/dist/index.js +55 -40
- package/dist/login.js +56 -40
- package/dist/reset-cooldowns.js +54 -39
- package/package.json +1 -1
- package/src/core/version.ts +1 -1
- package/src/login.ts +1 -1
- package/src/services/playwright.ts +64 -45
package/dist/clean-cache.js
CHANGED
|
@@ -3852,8 +3852,9 @@ async function loginToQwen(accountId, email, password) {
|
|
|
3852
3852
|
}
|
|
3853
3853
|
if (attempt < maxAttempts) {
|
|
3854
3854
|
const backoffMs = attempt * 5e3;
|
|
3855
|
+
const failReason = uiResult.reason || apiResult.reason || "falha tempor\xE1ria";
|
|
3855
3856
|
console.warn(
|
|
3856
|
-
`\u26A0\uFE0F [Playwright] Login attempt ${attempt}/${maxAttempts} failed for ${maskEmail(email)} (${
|
|
3857
|
+
`\u26A0\uFE0F [Playwright] Login attempt ${attempt}/${maxAttempts} failed for ${maskEmail(email)} (${failReason}), retrying in ${backoffMs / 1e3}s`
|
|
3857
3858
|
);
|
|
3858
3859
|
await sleep2(backoffMs);
|
|
3859
3860
|
}
|
|
@@ -4090,49 +4091,63 @@ async function loginViaUi(page, email, password) {
|
|
|
4090
4091
|
} catch {
|
|
4091
4092
|
await page.keyboard.press("Enter");
|
|
4092
4093
|
}
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4094
|
+
const postSubmitDeadline = Date.now() + 15e3;
|
|
4095
|
+
while (Date.now() < postSubmitDeadline) {
|
|
4096
|
+
if (page.isClosed()) break;
|
|
4097
|
+
if (config.captcha.enabled) {
|
|
4098
|
+
await solveBaxiaCaptcha(page, {
|
|
4099
|
+
waitForMs: 1500,
|
|
4100
|
+
maxAttempts: config.captcha.maxAttempts,
|
|
4101
|
+
retryDelayMs: config.captcha.retryDelayMs
|
|
4102
|
+
}).catch(() => {
|
|
4103
|
+
});
|
|
4104
|
+
}
|
|
4105
|
+
const errorSelector = [
|
|
4106
|
+
".qwen-chat-v2-toast-text",
|
|
4107
|
+
".qwen-chat-v2-toast-content",
|
|
4108
|
+
".ant-form-item-explain-error",
|
|
4109
|
+
".ant-message-error",
|
|
4110
|
+
".ant-message-notice",
|
|
4111
|
+
'[role="alert"]',
|
|
4112
|
+
".qwenchat-auth-error",
|
|
4113
|
+
".auth-error-message"
|
|
4114
|
+
].join(", ");
|
|
4115
|
+
const errorEl = page.locator(errorSelector).first();
|
|
4116
|
+
if (await errorEl.isVisible().catch(() => false)) {
|
|
4117
|
+
const errorText = (await errorEl.innerText().catch(() => "")).trim();
|
|
4118
|
+
if (errorText) {
|
|
4119
|
+
const classified = classifyQwenAuthError(void 0, errorText);
|
|
4120
|
+
return {
|
|
4121
|
+
success: false,
|
|
4122
|
+
permanentFailure: classified.isPermanent,
|
|
4123
|
+
reason: `Formul\xE1rio: ${classified.reason}`
|
|
4124
|
+
};
|
|
4125
|
+
}
|
|
4126
|
+
}
|
|
4127
|
+
const codeSelector = 'input[placeholder*="code" i], input[placeholder*="c\xF3digo" i], input[name*="code" i]';
|
|
4128
|
+
const codeInput = page.locator(codeSelector).first();
|
|
4129
|
+
if (await codeInput.isVisible().catch(() => false)) {
|
|
4123
4130
|
return {
|
|
4124
4131
|
success: false,
|
|
4125
|
-
|
|
4126
|
-
reason: `Formul\xE1rio: ${classified.reason}`
|
|
4132
|
+
reason: "Conta requer c\xF3digo de verifica\xE7\xE3o enviado por e-mail (2FA/OTP)"
|
|
4127
4133
|
};
|
|
4128
4134
|
}
|
|
4135
|
+
try {
|
|
4136
|
+
const liveCookies = await page.context().cookies();
|
|
4137
|
+
if (liveCookies.some((c) => c.name === "token")) {
|
|
4138
|
+
return { success: true };
|
|
4139
|
+
}
|
|
4140
|
+
} catch {
|
|
4141
|
+
}
|
|
4142
|
+
const currentUrl = page.url();
|
|
4143
|
+
if (!currentUrl.includes("/auth") && !currentUrl.includes("/login")) {
|
|
4144
|
+
if (await isPageLoggedIn(page, 3e3)) {
|
|
4145
|
+
return { success: true };
|
|
4146
|
+
}
|
|
4147
|
+
}
|
|
4148
|
+
await sleep2(1e3);
|
|
4129
4149
|
}
|
|
4130
|
-
|
|
4131
|
-
if (isLoggedIn) {
|
|
4132
|
-
await page.goto(qwenUrl("/"), {
|
|
4133
|
-
waitUntil: "domcontentloaded",
|
|
4134
|
-
timeout: config.timeouts.navigation
|
|
4135
|
-
});
|
|
4150
|
+
if (await isPageLoggedIn(page, 3e3)) {
|
|
4136
4151
|
return { success: true };
|
|
4137
4152
|
}
|
|
4138
4153
|
return {
|
package/dist/delete-chats.js
CHANGED
|
@@ -4727,8 +4727,9 @@ async function loginToQwen(accountId, email, password) {
|
|
|
4727
4727
|
}
|
|
4728
4728
|
if (attempt < maxAttempts) {
|
|
4729
4729
|
const backoffMs = attempt * 5e3;
|
|
4730
|
+
const failReason = uiResult.reason || apiResult.reason || "falha tempor\xE1ria";
|
|
4730
4731
|
console.warn(
|
|
4731
|
-
`\u26A0\uFE0F [Playwright] Login attempt ${attempt}/${maxAttempts} failed for ${maskEmail(email)} (${
|
|
4732
|
+
`\u26A0\uFE0F [Playwright] Login attempt ${attempt}/${maxAttempts} failed for ${maskEmail(email)} (${failReason}), retrying in ${backoffMs / 1e3}s`
|
|
4732
4733
|
);
|
|
4733
4734
|
await sleep2(backoffMs);
|
|
4734
4735
|
}
|
|
@@ -4965,49 +4966,63 @@ async function loginViaUi(page, email, password) {
|
|
|
4965
4966
|
} catch {
|
|
4966
4967
|
await page.keyboard.press("Enter");
|
|
4967
4968
|
}
|
|
4968
|
-
|
|
4969
|
-
|
|
4970
|
-
|
|
4971
|
-
|
|
4972
|
-
|
|
4973
|
-
|
|
4974
|
-
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
|
|
4983
|
-
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
|
|
4997
|
-
|
|
4969
|
+
const postSubmitDeadline = Date.now() + 15e3;
|
|
4970
|
+
while (Date.now() < postSubmitDeadline) {
|
|
4971
|
+
if (page.isClosed()) break;
|
|
4972
|
+
if (config.captcha.enabled) {
|
|
4973
|
+
await solveBaxiaCaptcha(page, {
|
|
4974
|
+
waitForMs: 1500,
|
|
4975
|
+
maxAttempts: config.captcha.maxAttempts,
|
|
4976
|
+
retryDelayMs: config.captcha.retryDelayMs
|
|
4977
|
+
}).catch(() => {
|
|
4978
|
+
});
|
|
4979
|
+
}
|
|
4980
|
+
const errorSelector = [
|
|
4981
|
+
".qwen-chat-v2-toast-text",
|
|
4982
|
+
".qwen-chat-v2-toast-content",
|
|
4983
|
+
".ant-form-item-explain-error",
|
|
4984
|
+
".ant-message-error",
|
|
4985
|
+
".ant-message-notice",
|
|
4986
|
+
'[role="alert"]',
|
|
4987
|
+
".qwenchat-auth-error",
|
|
4988
|
+
".auth-error-message"
|
|
4989
|
+
].join(", ");
|
|
4990
|
+
const errorEl = page.locator(errorSelector).first();
|
|
4991
|
+
if (await errorEl.isVisible().catch(() => false)) {
|
|
4992
|
+
const errorText = (await errorEl.innerText().catch(() => "")).trim();
|
|
4993
|
+
if (errorText) {
|
|
4994
|
+
const classified = classifyQwenAuthError(void 0, errorText);
|
|
4995
|
+
return {
|
|
4996
|
+
success: false,
|
|
4997
|
+
permanentFailure: classified.isPermanent,
|
|
4998
|
+
reason: `Formul\xE1rio: ${classified.reason}`
|
|
4999
|
+
};
|
|
5000
|
+
}
|
|
5001
|
+
}
|
|
5002
|
+
const codeSelector = 'input[placeholder*="code" i], input[placeholder*="c\xF3digo" i], input[name*="code" i]';
|
|
5003
|
+
const codeInput = page.locator(codeSelector).first();
|
|
5004
|
+
if (await codeInput.isVisible().catch(() => false)) {
|
|
4998
5005
|
return {
|
|
4999
5006
|
success: false,
|
|
5000
|
-
|
|
5001
|
-
reason: `Formul\xE1rio: ${classified.reason}`
|
|
5007
|
+
reason: "Conta requer c\xF3digo de verifica\xE7\xE3o enviado por e-mail (2FA/OTP)"
|
|
5002
5008
|
};
|
|
5003
5009
|
}
|
|
5010
|
+
try {
|
|
5011
|
+
const liveCookies = await page.context().cookies();
|
|
5012
|
+
if (liveCookies.some((c) => c.name === "token")) {
|
|
5013
|
+
return { success: true };
|
|
5014
|
+
}
|
|
5015
|
+
} catch {
|
|
5016
|
+
}
|
|
5017
|
+
const currentUrl = page.url();
|
|
5018
|
+
if (!currentUrl.includes("/auth") && !currentUrl.includes("/login")) {
|
|
5019
|
+
if (await isPageLoggedIn(page, 3e3)) {
|
|
5020
|
+
return { success: true };
|
|
5021
|
+
}
|
|
5022
|
+
}
|
|
5023
|
+
await sleep2(1e3);
|
|
5004
5024
|
}
|
|
5005
|
-
|
|
5006
|
-
if (isLoggedIn) {
|
|
5007
|
-
await page.goto(qwenUrl("/"), {
|
|
5008
|
-
waitUntil: "domcontentloaded",
|
|
5009
|
-
timeout: config.timeouts.navigation
|
|
5010
|
-
});
|
|
5025
|
+
if (await isPageLoggedIn(page, 3e3)) {
|
|
5011
5026
|
return { success: true };
|
|
5012
5027
|
}
|
|
5013
5028
|
return {
|
package/dist/index.js
CHANGED
|
@@ -5944,8 +5944,9 @@ async function loginToQwen(accountId, email, password) {
|
|
|
5944
5944
|
}
|
|
5945
5945
|
if (attempt < maxAttempts) {
|
|
5946
5946
|
const backoffMs = attempt * 5e3;
|
|
5947
|
+
const failReason = uiResult.reason || apiResult.reason || "falha tempor\xE1ria";
|
|
5947
5948
|
console.warn(
|
|
5948
|
-
`\u26A0\uFE0F [Playwright] Login attempt ${attempt}/${maxAttempts} failed for ${maskEmail(email)} (${
|
|
5949
|
+
`\u26A0\uFE0F [Playwright] Login attempt ${attempt}/${maxAttempts} failed for ${maskEmail(email)} (${failReason}), retrying in ${backoffMs / 1e3}s`
|
|
5949
5950
|
);
|
|
5950
5951
|
await sleep2(backoffMs);
|
|
5951
5952
|
}
|
|
@@ -6182,49 +6183,63 @@ async function loginViaUi(page, email, password) {
|
|
|
6182
6183
|
} catch {
|
|
6183
6184
|
await page.keyboard.press("Enter");
|
|
6184
6185
|
}
|
|
6185
|
-
|
|
6186
|
-
|
|
6187
|
-
|
|
6188
|
-
|
|
6189
|
-
|
|
6190
|
-
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
|
|
6195
|
-
|
|
6196
|
-
|
|
6197
|
-
|
|
6198
|
-
|
|
6199
|
-
|
|
6200
|
-
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
|
|
6211
|
-
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
|
|
6186
|
+
const postSubmitDeadline = Date.now() + 15e3;
|
|
6187
|
+
while (Date.now() < postSubmitDeadline) {
|
|
6188
|
+
if (page.isClosed()) break;
|
|
6189
|
+
if (config.captcha.enabled) {
|
|
6190
|
+
await solveBaxiaCaptcha(page, {
|
|
6191
|
+
waitForMs: 1500,
|
|
6192
|
+
maxAttempts: config.captcha.maxAttempts,
|
|
6193
|
+
retryDelayMs: config.captcha.retryDelayMs
|
|
6194
|
+
}).catch(() => {
|
|
6195
|
+
});
|
|
6196
|
+
}
|
|
6197
|
+
const errorSelector = [
|
|
6198
|
+
".qwen-chat-v2-toast-text",
|
|
6199
|
+
".qwen-chat-v2-toast-content",
|
|
6200
|
+
".ant-form-item-explain-error",
|
|
6201
|
+
".ant-message-error",
|
|
6202
|
+
".ant-message-notice",
|
|
6203
|
+
'[role="alert"]',
|
|
6204
|
+
".qwenchat-auth-error",
|
|
6205
|
+
".auth-error-message"
|
|
6206
|
+
].join(", ");
|
|
6207
|
+
const errorEl = page.locator(errorSelector).first();
|
|
6208
|
+
if (await errorEl.isVisible().catch(() => false)) {
|
|
6209
|
+
const errorText = (await errorEl.innerText().catch(() => "")).trim();
|
|
6210
|
+
if (errorText) {
|
|
6211
|
+
const classified = classifyQwenAuthError(void 0, errorText);
|
|
6212
|
+
return {
|
|
6213
|
+
success: false,
|
|
6214
|
+
permanentFailure: classified.isPermanent,
|
|
6215
|
+
reason: `Formul\xE1rio: ${classified.reason}`
|
|
6216
|
+
};
|
|
6217
|
+
}
|
|
6218
|
+
}
|
|
6219
|
+
const codeSelector = 'input[placeholder*="code" i], input[placeholder*="c\xF3digo" i], input[name*="code" i]';
|
|
6220
|
+
const codeInput = page.locator(codeSelector).first();
|
|
6221
|
+
if (await codeInput.isVisible().catch(() => false)) {
|
|
6215
6222
|
return {
|
|
6216
6223
|
success: false,
|
|
6217
|
-
|
|
6218
|
-
reason: `Formul\xE1rio: ${classified.reason}`
|
|
6224
|
+
reason: "Conta requer c\xF3digo de verifica\xE7\xE3o enviado por e-mail (2FA/OTP)"
|
|
6219
6225
|
};
|
|
6220
6226
|
}
|
|
6227
|
+
try {
|
|
6228
|
+
const liveCookies = await page.context().cookies();
|
|
6229
|
+
if (liveCookies.some((c) => c.name === "token")) {
|
|
6230
|
+
return { success: true };
|
|
6231
|
+
}
|
|
6232
|
+
} catch {
|
|
6233
|
+
}
|
|
6234
|
+
const currentUrl = page.url();
|
|
6235
|
+
if (!currentUrl.includes("/auth") && !currentUrl.includes("/login")) {
|
|
6236
|
+
if (await isPageLoggedIn(page, 3e3)) {
|
|
6237
|
+
return { success: true };
|
|
6238
|
+
}
|
|
6239
|
+
}
|
|
6240
|
+
await sleep2(1e3);
|
|
6221
6241
|
}
|
|
6222
|
-
|
|
6223
|
-
if (isLoggedIn) {
|
|
6224
|
-
await page.goto(qwenUrl("/"), {
|
|
6225
|
-
waitUntil: "domcontentloaded",
|
|
6226
|
-
timeout: config.timeouts.navigation
|
|
6227
|
-
});
|
|
6242
|
+
if (await isPageLoggedIn(page, 3e3)) {
|
|
6228
6243
|
return { success: true };
|
|
6229
6244
|
}
|
|
6230
6245
|
return {
|
|
@@ -25498,7 +25513,7 @@ function getAppVersion() {
|
|
|
25498
25513
|
}
|
|
25499
25514
|
} catch {
|
|
25500
25515
|
}
|
|
25501
|
-
cachedVersion = "v1.4.
|
|
25516
|
+
cachedVersion = "v1.4.3";
|
|
25502
25517
|
return cachedVersion;
|
|
25503
25518
|
}
|
|
25504
25519
|
var cachedVersion;
|
package/dist/login.js
CHANGED
|
@@ -4812,8 +4812,9 @@ async function loginToQwen(accountId, email, password) {
|
|
|
4812
4812
|
}
|
|
4813
4813
|
if (attempt < maxAttempts) {
|
|
4814
4814
|
const backoffMs = attempt * 5e3;
|
|
4815
|
+
const failReason = uiResult.reason || apiResult.reason || "falha tempor\xE1ria";
|
|
4815
4816
|
console.warn(
|
|
4816
|
-
`\u26A0\uFE0F [Playwright] Login attempt ${attempt}/${maxAttempts} failed for ${maskEmail(email)} (${
|
|
4817
|
+
`\u26A0\uFE0F [Playwright] Login attempt ${attempt}/${maxAttempts} failed for ${maskEmail(email)} (${failReason}), retrying in ${backoffMs / 1e3}s`
|
|
4817
4818
|
);
|
|
4818
4819
|
await sleep2(backoffMs);
|
|
4819
4820
|
}
|
|
@@ -5050,49 +5051,63 @@ async function loginViaUi(page, email, password) {
|
|
|
5050
5051
|
} catch {
|
|
5051
5052
|
await page.keyboard.press("Enter");
|
|
5052
5053
|
}
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
|
|
5054
|
+
const postSubmitDeadline = Date.now() + 15e3;
|
|
5055
|
+
while (Date.now() < postSubmitDeadline) {
|
|
5056
|
+
if (page.isClosed()) break;
|
|
5057
|
+
if (config.captcha.enabled) {
|
|
5058
|
+
await solveBaxiaCaptcha(page, {
|
|
5059
|
+
waitForMs: 1500,
|
|
5060
|
+
maxAttempts: config.captcha.maxAttempts,
|
|
5061
|
+
retryDelayMs: config.captcha.retryDelayMs
|
|
5062
|
+
}).catch(() => {
|
|
5063
|
+
});
|
|
5064
|
+
}
|
|
5065
|
+
const errorSelector = [
|
|
5066
|
+
".qwen-chat-v2-toast-text",
|
|
5067
|
+
".qwen-chat-v2-toast-content",
|
|
5068
|
+
".ant-form-item-explain-error",
|
|
5069
|
+
".ant-message-error",
|
|
5070
|
+
".ant-message-notice",
|
|
5071
|
+
'[role="alert"]',
|
|
5072
|
+
".qwenchat-auth-error",
|
|
5073
|
+
".auth-error-message"
|
|
5074
|
+
].join(", ");
|
|
5075
|
+
const errorEl = page.locator(errorSelector).first();
|
|
5076
|
+
if (await errorEl.isVisible().catch(() => false)) {
|
|
5077
|
+
const errorText = (await errorEl.innerText().catch(() => "")).trim();
|
|
5078
|
+
if (errorText) {
|
|
5079
|
+
const classified = classifyQwenAuthError(void 0, errorText);
|
|
5080
|
+
return {
|
|
5081
|
+
success: false,
|
|
5082
|
+
permanentFailure: classified.isPermanent,
|
|
5083
|
+
reason: `Formul\xE1rio: ${classified.reason}`
|
|
5084
|
+
};
|
|
5085
|
+
}
|
|
5086
|
+
}
|
|
5087
|
+
const codeSelector = 'input[placeholder*="code" i], input[placeholder*="c\xF3digo" i], input[name*="code" i]';
|
|
5088
|
+
const codeInput = page.locator(codeSelector).first();
|
|
5089
|
+
if (await codeInput.isVisible().catch(() => false)) {
|
|
5083
5090
|
return {
|
|
5084
5091
|
success: false,
|
|
5085
|
-
|
|
5086
|
-
reason: `Formul\xE1rio: ${classified.reason}`
|
|
5092
|
+
reason: "Conta requer c\xF3digo de verifica\xE7\xE3o enviado por e-mail (2FA/OTP)"
|
|
5087
5093
|
};
|
|
5088
5094
|
}
|
|
5095
|
+
try {
|
|
5096
|
+
const liveCookies = await page.context().cookies();
|
|
5097
|
+
if (liveCookies.some((c) => c.name === "token")) {
|
|
5098
|
+
return { success: true };
|
|
5099
|
+
}
|
|
5100
|
+
} catch {
|
|
5101
|
+
}
|
|
5102
|
+
const currentUrl = page.url();
|
|
5103
|
+
if (!currentUrl.includes("/auth") && !currentUrl.includes("/login")) {
|
|
5104
|
+
if (await isPageLoggedIn(page, 3e3)) {
|
|
5105
|
+
return { success: true };
|
|
5106
|
+
}
|
|
5107
|
+
}
|
|
5108
|
+
await sleep2(1e3);
|
|
5089
5109
|
}
|
|
5090
|
-
|
|
5091
|
-
if (isLoggedIn) {
|
|
5092
|
-
await page.goto(qwenUrl("/"), {
|
|
5093
|
-
waitUntil: "domcontentloaded",
|
|
5094
|
-
timeout: config.timeouts.navigation
|
|
5095
|
-
});
|
|
5110
|
+
if (await isPageLoggedIn(page, 3e3)) {
|
|
5096
5111
|
return { success: true };
|
|
5097
5112
|
}
|
|
5098
5113
|
return {
|
|
@@ -6446,7 +6461,8 @@ async function addAccountFlow() {
|
|
|
6446
6461
|
const { config: config3 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
6447
6462
|
const ok = await validateAccountLogin2(
|
|
6448
6463
|
{ id: tempId, email: trimmedEmail, password: trimmedPassword },
|
|
6449
|
-
|
|
6464
|
+
false,
|
|
6465
|
+
// Visible browser so user can see and complete challenges if needed
|
|
6450
6466
|
config3.playwright.browser
|
|
6451
6467
|
);
|
|
6452
6468
|
if (ok) {
|
package/dist/reset-cooldowns.js
CHANGED
|
@@ -4088,8 +4088,9 @@ async function loginToQwen(accountId, email, password) {
|
|
|
4088
4088
|
}
|
|
4089
4089
|
if (attempt < maxAttempts) {
|
|
4090
4090
|
const backoffMs = attempt * 5e3;
|
|
4091
|
+
const failReason = uiResult.reason || apiResult.reason || "falha tempor\xE1ria";
|
|
4091
4092
|
console.warn(
|
|
4092
|
-
`\u26A0\uFE0F [Playwright] Login attempt ${attempt}/${maxAttempts} failed for ${maskEmail(email)} (${
|
|
4093
|
+
`\u26A0\uFE0F [Playwright] Login attempt ${attempt}/${maxAttempts} failed for ${maskEmail(email)} (${failReason}), retrying in ${backoffMs / 1e3}s`
|
|
4093
4094
|
);
|
|
4094
4095
|
await sleep2(backoffMs);
|
|
4095
4096
|
}
|
|
@@ -4326,49 +4327,63 @@ async function loginViaUi(page, email, password) {
|
|
|
4326
4327
|
} catch {
|
|
4327
4328
|
await page.keyboard.press("Enter");
|
|
4328
4329
|
}
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4330
|
+
const postSubmitDeadline = Date.now() + 15e3;
|
|
4331
|
+
while (Date.now() < postSubmitDeadline) {
|
|
4332
|
+
if (page.isClosed()) break;
|
|
4333
|
+
if (config.captcha.enabled) {
|
|
4334
|
+
await solveBaxiaCaptcha(page, {
|
|
4335
|
+
waitForMs: 1500,
|
|
4336
|
+
maxAttempts: config.captcha.maxAttempts,
|
|
4337
|
+
retryDelayMs: config.captcha.retryDelayMs
|
|
4338
|
+
}).catch(() => {
|
|
4339
|
+
});
|
|
4340
|
+
}
|
|
4341
|
+
const errorSelector = [
|
|
4342
|
+
".qwen-chat-v2-toast-text",
|
|
4343
|
+
".qwen-chat-v2-toast-content",
|
|
4344
|
+
".ant-form-item-explain-error",
|
|
4345
|
+
".ant-message-error",
|
|
4346
|
+
".ant-message-notice",
|
|
4347
|
+
'[role="alert"]',
|
|
4348
|
+
".qwenchat-auth-error",
|
|
4349
|
+
".auth-error-message"
|
|
4350
|
+
].join(", ");
|
|
4351
|
+
const errorEl = page.locator(errorSelector).first();
|
|
4352
|
+
if (await errorEl.isVisible().catch(() => false)) {
|
|
4353
|
+
const errorText = (await errorEl.innerText().catch(() => "")).trim();
|
|
4354
|
+
if (errorText) {
|
|
4355
|
+
const classified = classifyQwenAuthError(void 0, errorText);
|
|
4356
|
+
return {
|
|
4357
|
+
success: false,
|
|
4358
|
+
permanentFailure: classified.isPermanent,
|
|
4359
|
+
reason: `Formul\xE1rio: ${classified.reason}`
|
|
4360
|
+
};
|
|
4361
|
+
}
|
|
4362
|
+
}
|
|
4363
|
+
const codeSelector = 'input[placeholder*="code" i], input[placeholder*="c\xF3digo" i], input[name*="code" i]';
|
|
4364
|
+
const codeInput = page.locator(codeSelector).first();
|
|
4365
|
+
if (await codeInput.isVisible().catch(() => false)) {
|
|
4359
4366
|
return {
|
|
4360
4367
|
success: false,
|
|
4361
|
-
|
|
4362
|
-
reason: `Formul\xE1rio: ${classified.reason}`
|
|
4368
|
+
reason: "Conta requer c\xF3digo de verifica\xE7\xE3o enviado por e-mail (2FA/OTP)"
|
|
4363
4369
|
};
|
|
4364
4370
|
}
|
|
4371
|
+
try {
|
|
4372
|
+
const liveCookies = await page.context().cookies();
|
|
4373
|
+
if (liveCookies.some((c) => c.name === "token")) {
|
|
4374
|
+
return { success: true };
|
|
4375
|
+
}
|
|
4376
|
+
} catch {
|
|
4377
|
+
}
|
|
4378
|
+
const currentUrl = page.url();
|
|
4379
|
+
if (!currentUrl.includes("/auth") && !currentUrl.includes("/login")) {
|
|
4380
|
+
if (await isPageLoggedIn(page, 3e3)) {
|
|
4381
|
+
return { success: true };
|
|
4382
|
+
}
|
|
4383
|
+
}
|
|
4384
|
+
await sleep2(1e3);
|
|
4365
4385
|
}
|
|
4366
|
-
|
|
4367
|
-
if (isLoggedIn) {
|
|
4368
|
-
await page.goto(qwenUrl("/"), {
|
|
4369
|
-
waitUntil: "domcontentloaded",
|
|
4370
|
-
timeout: config.timeouts.navigation
|
|
4371
|
-
});
|
|
4386
|
+
if (await isPageLoggedIn(page, 3e3)) {
|
|
4372
4387
|
return { success: true };
|
|
4373
4388
|
}
|
|
4374
4389
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qwenproxy-cli",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.3",
|
|
4
4
|
"description": "High-performance OpenAI & Anthropic compatible API gateway for Qwen with multi-account rotation, interactive TUI, and resilient tool calling.",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"bin": {
|
package/src/core/version.ts
CHANGED
package/src/login.ts
CHANGED
|
@@ -120,7 +120,7 @@ async function addAccountFlow() {
|
|
|
120
120
|
|
|
121
121
|
const ok = await validateAccountLogin(
|
|
122
122
|
{ id: tempId, email: trimmedEmail, password: trimmedPassword },
|
|
123
|
-
|
|
123
|
+
false, // Visible browser so user can see and complete challenges if needed
|
|
124
124
|
config.playwright.browser,
|
|
125
125
|
);
|
|
126
126
|
|
|
@@ -2163,8 +2163,9 @@ async function loginToQwen(
|
|
|
2163
2163
|
|
|
2164
2164
|
if (attempt < maxAttempts) {
|
|
2165
2165
|
const backoffMs = attempt * 5_000;
|
|
2166
|
+
const failReason = uiResult.reason || apiResult.reason || "falha temporária";
|
|
2166
2167
|
console.warn(
|
|
2167
|
-
`⚠️ [Playwright] Login attempt ${attempt}/${maxAttempts} failed for ${maskEmail(email)} (${
|
|
2168
|
+
`⚠️ [Playwright] Login attempt ${attempt}/${maxAttempts} failed for ${maskEmail(email)} (${failReason}), retrying in ${backoffMs / 1000}s`,
|
|
2168
2169
|
);
|
|
2169
2170
|
await sleep(backoffMs);
|
|
2170
2171
|
}
|
|
@@ -2447,58 +2448,76 @@ async function loginViaUi(
|
|
|
2447
2448
|
} catch {
|
|
2448
2449
|
await page.keyboard.press("Enter");
|
|
2449
2450
|
}
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2451
|
+
// Post-submit verification loop: wait up to 15s for captcha, redirect, cookies, or errors
|
|
2452
|
+
const postSubmitDeadline = Date.now() + 15_000;
|
|
2453
|
+
while (Date.now() < postSubmitDeadline) {
|
|
2454
|
+
if (page.isClosed()) break;
|
|
2455
|
+
|
|
2456
|
+
// If a slider puzzle captcha appeared after submit, solve it automatically
|
|
2457
|
+
if (config.captcha.enabled) {
|
|
2458
|
+
await solveBaxiaCaptcha(page, {
|
|
2459
|
+
waitForMs: 1500,
|
|
2460
|
+
maxAttempts: config.captcha.maxAttempts,
|
|
2461
|
+
retryDelayMs: config.captcha.retryDelayMs,
|
|
2462
|
+
}).catch(() => {});
|
|
2463
|
+
}
|
|
2458
2464
|
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2465
|
+
// Check for UI error elements in DOM (Ant Design errors, alerts, toasts)
|
|
2466
|
+
const errorSelector = [
|
|
2467
|
+
".qwen-chat-v2-toast-text",
|
|
2468
|
+
".qwen-chat-v2-toast-content",
|
|
2469
|
+
".ant-form-item-explain-error",
|
|
2470
|
+
".ant-message-error",
|
|
2471
|
+
".ant-message-notice",
|
|
2472
|
+
'[role="alert"]',
|
|
2473
|
+
".qwenchat-auth-error",
|
|
2474
|
+
".auth-error-message",
|
|
2475
|
+
].join(", ");
|
|
2476
|
+
const errorEl = page.locator(errorSelector).first();
|
|
2477
|
+
if (await errorEl.isVisible().catch(() => false)) {
|
|
2478
|
+
const errorText = (await errorEl.innerText().catch(() => "")).trim();
|
|
2479
|
+
if (errorText) {
|
|
2480
|
+
const classified = classifyQwenAuthError(undefined, errorText);
|
|
2481
|
+
return {
|
|
2482
|
+
success: false,
|
|
2483
|
+
permanentFailure: classified.isPermanent,
|
|
2484
|
+
reason: `Formulário: ${classified.reason}`,
|
|
2485
|
+
};
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2469
2488
|
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
".ant-message-error",
|
|
2476
|
-
".ant-message-notice",
|
|
2477
|
-
'[role="alert"]',
|
|
2478
|
-
".qwenchat-auth-error",
|
|
2479
|
-
".auth-error-message",
|
|
2480
|
-
].join(", ");
|
|
2481
|
-
const errorEl = page.locator(errorSelector).first();
|
|
2482
|
-
if (await errorEl.isVisible().catch(() => false)) {
|
|
2483
|
-
const errorText = (await errorEl.innerText().catch(() => "")).trim();
|
|
2484
|
-
if (errorText) {
|
|
2485
|
-
const classified = classifyQwenAuthError(undefined, errorText);
|
|
2489
|
+
// Check if an OTP code verification screen appeared (e.g. 2FA / email verification code)
|
|
2490
|
+
const codeSelector =
|
|
2491
|
+
'input[placeholder*="code" i], input[placeholder*="código" i], input[name*="code" i]';
|
|
2492
|
+
const codeInput = page.locator(codeSelector).first();
|
|
2493
|
+
if (await codeInput.isVisible().catch(() => false)) {
|
|
2486
2494
|
return {
|
|
2487
2495
|
success: false,
|
|
2488
|
-
|
|
2489
|
-
reason: `Formulário: ${classified.reason}`,
|
|
2496
|
+
reason: "Conta requer código de verificação enviado por e-mail (2FA/OTP)",
|
|
2490
2497
|
};
|
|
2491
2498
|
}
|
|
2492
|
-
}
|
|
2493
2499
|
|
|
2494
|
-
|
|
2495
|
-
|
|
2500
|
+
// Check if auth cookie 'token' appeared
|
|
2501
|
+
try {
|
|
2502
|
+
const liveCookies = await page.context().cookies();
|
|
2503
|
+
if (liveCookies.some((c) => c.name === "token")) {
|
|
2504
|
+
return { success: true };
|
|
2505
|
+
}
|
|
2506
|
+
} catch {}
|
|
2496
2507
|
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2508
|
+
// Check if page redirected away from /auth and is logged in
|
|
2509
|
+
const currentUrl = page.url();
|
|
2510
|
+
if (!currentUrl.includes("/auth") && !currentUrl.includes("/login")) {
|
|
2511
|
+
if (await isPageLoggedIn(page, 3000)) {
|
|
2512
|
+
return { success: true };
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
|
|
2516
|
+
await sleep(1000);
|
|
2517
|
+
}
|
|
2518
|
+
|
|
2519
|
+
// Final check
|
|
2520
|
+
if (await isPageLoggedIn(page, 3000)) {
|
|
2502
2521
|
return { success: true };
|
|
2503
2522
|
}
|
|
2504
2523
|
|