qwenproxy-cli 1.6.11 → 1.6.12
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 +350 -18
- package/dist/delete-chats.js +900 -474
- package/dist/index.js +484 -58
- package/dist/login.js +373 -27
- package/dist/reset-cooldowns.js +684 -350
- package/dist/sync-clients.js +4 -1
- package/package.json +1 -1
- package/src/core/config.ts +4 -1
- package/src/core/model-alias.ts +1 -0
- package/src/core/version.ts +1 -1
- package/src/services/auth-playwright.ts +3 -2
- package/src/services/captcha-coordinator.ts +6 -4
- package/src/services/captcha-solver.ts +400 -2
- package/src/services/playwright.ts +62 -22
- package/src/services/qwen-chat-pool.ts +52 -9
- package/src/services/qwen-headers.ts +18 -1
- package/src/services/qwen.ts +6 -4
- package/src/services/session-keeper.ts +70 -8
package/dist/reset-cooldowns.js
CHANGED
|
@@ -1354,7 +1354,7 @@ var init_config = __esm({
|
|
|
1354
1354
|
// Version header on Qwen API requests = the deployed web bundle version
|
|
1355
1355
|
// (fallback when dynamic DOM detection is not yet completed).
|
|
1356
1356
|
// Override via env when Qwen ships a new bundle.
|
|
1357
|
-
QWEN_WEB_VERSION: z.string().default("0.3.
|
|
1357
|
+
QWEN_WEB_VERSION: z.string().default("0.3.43"),
|
|
1358
1358
|
// Controls bx-ua/bx-umidtoken injection on the GENERAL API paths
|
|
1359
1359
|
// (chats/new, settings): those work without them (live-probed). The
|
|
1360
1360
|
// completions path is the exception — the 0.2.86 HAR shows the real
|
|
@@ -1397,6 +1397,7 @@ var init_config = __esm({
|
|
|
1397
1397
|
CAPTCHA_SOLVER_ENABLED: z.string().default("true"),
|
|
1398
1398
|
CAPTCHA_SOLVER_MAX_ATTEMPTS: z.string().default("3"),
|
|
1399
1399
|
CAPTCHA_SOLVER_TIMEOUT_MS: z.string().default("15000"),
|
|
1400
|
+
CAPTCHA_SLIDER_TIMEOUT_MS: z.string().default("8000"),
|
|
1400
1401
|
CAPTCHA_SOLVER_RETRY_DELAY_MS: z.string().default("1000"),
|
|
1401
1402
|
CAPTCHA_SOLVER_SETTLE_MS: z.string().default("2000"),
|
|
1402
1403
|
CAPTCHA_ACCOUNT_COOLDOWN_MS: z.string().default("120000"),
|
|
@@ -1548,6 +1549,8 @@ var init_config = __esm({
|
|
|
1548
1549
|
enabled: env.CAPTCHA_SOLVER_ENABLED === "true",
|
|
1549
1550
|
maxAttempts: Math.max(1, Math.min(5, parseInt(env.CAPTCHA_SOLVER_MAX_ATTEMPTS))),
|
|
1550
1551
|
timeoutMs: Math.max(0, parseInt(env.CAPTCHA_SOLVER_TIMEOUT_MS)),
|
|
1552
|
+
/** Max wait for a challenge slider to become visible (slow WAF renders). */
|
|
1553
|
+
sliderTimeoutMs: Math.max(500, parseInt(env.CAPTCHA_SLIDER_TIMEOUT_MS)),
|
|
1551
1554
|
retryDelayMs: Math.max(0, parseInt(env.CAPTCHA_SOLVER_RETRY_DELAY_MS)),
|
|
1552
1555
|
settleMs: Math.max(0, parseInt(env.CAPTCHA_SOLVER_SETTLE_MS)),
|
|
1553
1556
|
/** Rest an account whose challenge could not be cleared before reusing it. */
|
|
@@ -1707,6 +1710,306 @@ var init_config = __esm({
|
|
|
1707
1710
|
}
|
|
1708
1711
|
});
|
|
1709
1712
|
|
|
1713
|
+
// src/services/qwen-url.ts
|
|
1714
|
+
function qwenUrl(path6 = "") {
|
|
1715
|
+
const normalizedPath = path6.replace(/^\/+/, "");
|
|
1716
|
+
return normalizedPath ? `${QWEN_BASE_URL}/${normalizedPath}` : QWEN_BASE_URL;
|
|
1717
|
+
}
|
|
1718
|
+
function qwenOrigin() {
|
|
1719
|
+
return QWEN_ORIGIN;
|
|
1720
|
+
}
|
|
1721
|
+
var QWEN_BASE_URL, QWEN_ORIGIN;
|
|
1722
|
+
var init_qwen_url = __esm({
|
|
1723
|
+
"src/services/qwen-url.ts"() {
|
|
1724
|
+
"use strict";
|
|
1725
|
+
init_config();
|
|
1726
|
+
QWEN_BASE_URL = config.qwen.baseUrl.trim().replace(/\/+$/, "");
|
|
1727
|
+
QWEN_ORIGIN = new URL(QWEN_BASE_URL).origin;
|
|
1728
|
+
}
|
|
1729
|
+
});
|
|
1730
|
+
|
|
1731
|
+
// src/services/fingerprint.ts
|
|
1732
|
+
function mulberry32(seed) {
|
|
1733
|
+
return () => {
|
|
1734
|
+
seed |= 0;
|
|
1735
|
+
seed = seed + 1831565813 | 0;
|
|
1736
|
+
let t = Math.imul(seed ^ seed >>> 15, 1 | seed);
|
|
1737
|
+
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
|
1738
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
1739
|
+
};
|
|
1740
|
+
}
|
|
1741
|
+
function seedFromString(value) {
|
|
1742
|
+
let hash = 0;
|
|
1743
|
+
for (let i = 0; i < value.length; i++) {
|
|
1744
|
+
hash = (hash << 5) - hash + value.charCodeAt(i) | 0;
|
|
1745
|
+
}
|
|
1746
|
+
return hash >>> 0;
|
|
1747
|
+
}
|
|
1748
|
+
function pick(rng, values) {
|
|
1749
|
+
return values[Math.floor(rng() * values.length)];
|
|
1750
|
+
}
|
|
1751
|
+
function randInt(rng, min, max) {
|
|
1752
|
+
return Math.floor(rng() * (max - min + 1)) + min;
|
|
1753
|
+
}
|
|
1754
|
+
function updateChromeMajor(major) {
|
|
1755
|
+
if (typeof major === "number" && major >= 100) {
|
|
1756
|
+
dynamicChromeMajor = major;
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
function getChromeMajor() {
|
|
1760
|
+
return dynamicChromeMajor;
|
|
1761
|
+
}
|
|
1762
|
+
function getSystemLocale() {
|
|
1763
|
+
return process.env.QWEN_LOCALE || (typeof Intl !== "undefined" && Intl.DateTimeFormat ? Intl.DateTimeFormat().resolvedOptions().locale : "") || "pt-BR";
|
|
1764
|
+
}
|
|
1765
|
+
function getLanguageProfiles(locale = getSystemLocale()) {
|
|
1766
|
+
const primary = locale.split("-")[0];
|
|
1767
|
+
if (primary === "en") {
|
|
1768
|
+
return [
|
|
1769
|
+
["en-US", "en"],
|
|
1770
|
+
["en-US", "en", "es"],
|
|
1771
|
+
["en", "en-US"],
|
|
1772
|
+
["en-US", "en;q=0.9"]
|
|
1773
|
+
];
|
|
1774
|
+
}
|
|
1775
|
+
return [
|
|
1776
|
+
[locale, primary, "en-US", "en"],
|
|
1777
|
+
[locale, primary, "en-US", "en", "es"],
|
|
1778
|
+
[locale, "en-US", "en", primary],
|
|
1779
|
+
[locale, primary, "en"],
|
|
1780
|
+
[locale, `${primary};q=0.9`, "en-US;q=0.8", "en;q=0.7"]
|
|
1781
|
+
];
|
|
1782
|
+
}
|
|
1783
|
+
function getFingerprintProfile(accountId) {
|
|
1784
|
+
const cached = profileCache.get(accountId);
|
|
1785
|
+
if (cached) return cached;
|
|
1786
|
+
const salt = rotationSalts.get(accountId) ?? 0;
|
|
1787
|
+
const seed = seedFromString(salt === 0 ? accountId : `${accountId}#r${salt}`);
|
|
1788
|
+
const rng = mulberry32(seed);
|
|
1789
|
+
const viewport = pick(rng, VIEWPORTS);
|
|
1790
|
+
const webgl = pick(rng, WEBGL_PROFILES);
|
|
1791
|
+
const languages = [...pick(rng, getLanguageProfiles())];
|
|
1792
|
+
const hardwareConcurrency = pick(rng, HARDWARE_CONCURRENCIES);
|
|
1793
|
+
const deviceMemory = pick(rng, DEVICE_MEMORIES);
|
|
1794
|
+
const platformInfo = pick(rng, PLATFORM_VERSIONS);
|
|
1795
|
+
const notABrand = pick(rng, NOT_A_BRAND_VARIANTS);
|
|
1796
|
+
const major = dynamicChromeMajor;
|
|
1797
|
+
const build = randInt(rng, 7300, 7600);
|
|
1798
|
+
const patch = randInt(rng, 0, 160);
|
|
1799
|
+
const chromeVersion = `${major}.0.${build}.${patch}`;
|
|
1800
|
+
const brands = [
|
|
1801
|
+
{ brand: notABrand.brand, version: notABrand.version },
|
|
1802
|
+
{ brand: "Google Chrome", version: String(major) },
|
|
1803
|
+
{ brand: "Chromium", version: String(major) }
|
|
1804
|
+
];
|
|
1805
|
+
const fullVersionList = [
|
|
1806
|
+
{ brand: notABrand.brand, version: chromeVersion },
|
|
1807
|
+
{ brand: "Google Chrome", version: chromeVersion },
|
|
1808
|
+
{ brand: "Chromium", version: chromeVersion }
|
|
1809
|
+
];
|
|
1810
|
+
const secChUa = brands.map((brand) => `"${brand.brand}";v="${brand.version}"`).join(", ");
|
|
1811
|
+
const userAgent = `Mozilla/5.0 (Windows NT ${platformInfo.major}.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${chromeVersion} Safari/537.36`;
|
|
1812
|
+
const profile = {
|
|
1813
|
+
accountId,
|
|
1814
|
+
seed,
|
|
1815
|
+
userAgent,
|
|
1816
|
+
appVersion: userAgent.replace("Mozilla/", ""),
|
|
1817
|
+
chromeMajor: CHROME_MAJOR,
|
|
1818
|
+
chromeVersion,
|
|
1819
|
+
brands,
|
|
1820
|
+
fullVersionList,
|
|
1821
|
+
secChUa,
|
|
1822
|
+
platform: "Win32",
|
|
1823
|
+
platformVersion: platformInfo.platformVersion,
|
|
1824
|
+
architecture: "x86",
|
|
1825
|
+
bitness: "64",
|
|
1826
|
+
languages,
|
|
1827
|
+
locale: languages[0].split(";")[0],
|
|
1828
|
+
timezoneId: "America/Sao_Paulo",
|
|
1829
|
+
viewport,
|
|
1830
|
+
hardwareConcurrency,
|
|
1831
|
+
deviceMemory,
|
|
1832
|
+
webglVendor: webgl.vendor,
|
|
1833
|
+
webglRenderer: webgl.renderer,
|
|
1834
|
+
colorDepth: 24,
|
|
1835
|
+
pixelDepth: 24,
|
|
1836
|
+
canvasNoiseSeed: randInt(rng, 1, 2147483647),
|
|
1837
|
+
audioNoiseSeed: randInt(rng, 1, 2147483647),
|
|
1838
|
+
webglNoiseSeed: randInt(rng, 1, 2147483647),
|
|
1839
|
+
outerWidthOffset: randInt(rng, 0, 20),
|
|
1840
|
+
outerHeightOffset: randInt(rng, 75, 95)
|
|
1841
|
+
};
|
|
1842
|
+
profileCache.set(accountId, profile);
|
|
1843
|
+
return profile;
|
|
1844
|
+
}
|
|
1845
|
+
function clearFingerprintCache(accountId) {
|
|
1846
|
+
if (accountId) profileCache.delete(accountId);
|
|
1847
|
+
else profileCache.clear();
|
|
1848
|
+
}
|
|
1849
|
+
var dynamicChromeMajor, CHROME_MAJOR, VIEWPORTS, WEBGL_PROFILES, HARDWARE_CONCURRENCIES, DEVICE_MEMORIES, PLATFORM_VERSIONS, NOT_A_BRAND_VARIANTS, profileCache, rotationSalts;
|
|
1850
|
+
var init_fingerprint = __esm({
|
|
1851
|
+
"src/services/fingerprint.ts"() {
|
|
1852
|
+
"use strict";
|
|
1853
|
+
dynamicChromeMajor = 151;
|
|
1854
|
+
CHROME_MAJOR = 151;
|
|
1855
|
+
VIEWPORTS = [
|
|
1856
|
+
{ width: 1366, height: 768 },
|
|
1857
|
+
{ width: 1440, height: 900 },
|
|
1858
|
+
{ width: 1536, height: 864 },
|
|
1859
|
+
{ width: 1600, height: 900 },
|
|
1860
|
+
{ width: 1680, height: 1050 },
|
|
1861
|
+
{ width: 1920, height: 1080 },
|
|
1862
|
+
{ width: 1920, height: 1200 },
|
|
1863
|
+
{ width: 1280, height: 720 },
|
|
1864
|
+
{ width: 1280, height: 800 },
|
|
1865
|
+
{ width: 1536, height: 864 }
|
|
1866
|
+
];
|
|
1867
|
+
WEBGL_PROFILES = [
|
|
1868
|
+
{
|
|
1869
|
+
vendor: "Google Inc. (Intel)",
|
|
1870
|
+
renderer: "ANGLE (Intel, Intel(R) UHD Graphics 630 Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
1871
|
+
},
|
|
1872
|
+
{
|
|
1873
|
+
vendor: "Google Inc. (Intel)",
|
|
1874
|
+
renderer: "ANGLE (Intel, Intel(R) Iris(R) Xe Graphics Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
1875
|
+
},
|
|
1876
|
+
{
|
|
1877
|
+
vendor: "Google Inc. (Intel)",
|
|
1878
|
+
renderer: "ANGLE (Intel, Intel(R) UHD Graphics 770 Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
1879
|
+
},
|
|
1880
|
+
{
|
|
1881
|
+
vendor: "Google Inc. (NVIDIA)",
|
|
1882
|
+
renderer: "ANGLE (NVIDIA, NVIDIA GeForce RTX 3060 Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
1883
|
+
},
|
|
1884
|
+
{
|
|
1885
|
+
vendor: "Google Inc. (NVIDIA)",
|
|
1886
|
+
renderer: "ANGLE (NVIDIA, NVIDIA GeForce RTX 3070 Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
1887
|
+
},
|
|
1888
|
+
{
|
|
1889
|
+
vendor: "Google Inc. (NVIDIA)",
|
|
1890
|
+
renderer: "ANGLE (NVIDIA, NVIDIA GeForce RTX 3080 Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
1891
|
+
},
|
|
1892
|
+
{
|
|
1893
|
+
vendor: "Google Inc. (NVIDIA)",
|
|
1894
|
+
renderer: "ANGLE (NVIDIA, NVIDIA GeForce RTX 4060 Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
1895
|
+
},
|
|
1896
|
+
{
|
|
1897
|
+
vendor: "Google Inc. (NVIDIA)",
|
|
1898
|
+
renderer: "ANGLE (NVIDIA, NVIDIA GeForce RTX 4070 Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
1899
|
+
},
|
|
1900
|
+
{
|
|
1901
|
+
vendor: "Google Inc. (NVIDIA)",
|
|
1902
|
+
renderer: "ANGLE (NVIDIA, NVIDIA GeForce GTX 1660 SUPER Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
1903
|
+
},
|
|
1904
|
+
{
|
|
1905
|
+
vendor: "Google Inc. (AMD)",
|
|
1906
|
+
renderer: "ANGLE (AMD, AMD Radeon RX 6600 Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
1907
|
+
},
|
|
1908
|
+
{
|
|
1909
|
+
vendor: "Google Inc. (AMD)",
|
|
1910
|
+
renderer: "ANGLE (AMD, AMD Radeon RX 7600 Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
1911
|
+
},
|
|
1912
|
+
{
|
|
1913
|
+
vendor: "Google Inc. (AMD)",
|
|
1914
|
+
renderer: "ANGLE (AMD, AMD Radeon RX 580 Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
1915
|
+
}
|
|
1916
|
+
];
|
|
1917
|
+
HARDWARE_CONCURRENCIES = [4, 6, 8, 8, 8, 12, 16, 16, 24, 32];
|
|
1918
|
+
DEVICE_MEMORIES = [4, 8, 8, 8, 16, 16, 32];
|
|
1919
|
+
PLATFORM_VERSIONS = [
|
|
1920
|
+
{ platform: "Windows", platformVersion: "14.0.0", major: "10" },
|
|
1921
|
+
{ platform: "Windows", platformVersion: "15.0.0", major: "11" },
|
|
1922
|
+
{ platform: "Windows", platformVersion: "14.0.0", major: "10" },
|
|
1923
|
+
{ platform: "Windows", platformVersion: "15.0.0", major: "11" }
|
|
1924
|
+
];
|
|
1925
|
+
NOT_A_BRAND_VARIANTS = [
|
|
1926
|
+
{ brand: "Not/A)Brand", version: "99" },
|
|
1927
|
+
{ brand: "Not)A_Brand", version: "99" },
|
|
1928
|
+
{ brand: "Not/A)Brand", version: "8" },
|
|
1929
|
+
{ brand: "Not?A_Brand", version: "24" },
|
|
1930
|
+
{ brand: "Not/A)Brand", version: "99" }
|
|
1931
|
+
];
|
|
1932
|
+
profileCache = /* @__PURE__ */ new Map();
|
|
1933
|
+
rotationSalts = /* @__PURE__ */ new Map();
|
|
1934
|
+
}
|
|
1935
|
+
});
|
|
1936
|
+
|
|
1937
|
+
// src/utils/timezone.ts
|
|
1938
|
+
function formatAsciiTimezone(date = /* @__PURE__ */ new Date()) {
|
|
1939
|
+
const dayName = DAYS[date.getDay()];
|
|
1940
|
+
const monthName = MONTHS[date.getMonth()];
|
|
1941
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
1942
|
+
const year = date.getFullYear();
|
|
1943
|
+
const hours = String(date.getHours()).padStart(2, "0");
|
|
1944
|
+
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
1945
|
+
const seconds = String(date.getSeconds()).padStart(2, "0");
|
|
1946
|
+
const offsetMinutes = -date.getTimezoneOffset();
|
|
1947
|
+
const sign = offsetMinutes >= 0 ? "+" : "-";
|
|
1948
|
+
const absOffset = Math.abs(offsetMinutes);
|
|
1949
|
+
const offsetHours = String(Math.floor(absOffset / 60)).padStart(2, "0");
|
|
1950
|
+
const offsetMins = String(absOffset % 60).padStart(2, "0");
|
|
1951
|
+
const tzOffset = `GMT${sign}${offsetHours}${offsetMins}`;
|
|
1952
|
+
return `${dayName} ${monthName} ${day} ${year} ${hours}:${minutes}:${seconds} ${tzOffset}`;
|
|
1953
|
+
}
|
|
1954
|
+
var DAYS, MONTHS;
|
|
1955
|
+
var init_timezone = __esm({
|
|
1956
|
+
"src/utils/timezone.ts"() {
|
|
1957
|
+
"use strict";
|
|
1958
|
+
DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
1959
|
+
MONTHS = [
|
|
1960
|
+
"Jan",
|
|
1961
|
+
"Feb",
|
|
1962
|
+
"Mar",
|
|
1963
|
+
"Apr",
|
|
1964
|
+
"May",
|
|
1965
|
+
"Jun",
|
|
1966
|
+
"Jul",
|
|
1967
|
+
"Aug",
|
|
1968
|
+
"Sep",
|
|
1969
|
+
"Oct",
|
|
1970
|
+
"Nov",
|
|
1971
|
+
"Dec"
|
|
1972
|
+
];
|
|
1973
|
+
}
|
|
1974
|
+
});
|
|
1975
|
+
|
|
1976
|
+
// src/services/qwen-headers.ts
|
|
1977
|
+
import { v4 as uuidv4 } from "uuid";
|
|
1978
|
+
function getDefaultQwenUserAgent(major = getChromeMajor()) {
|
|
1979
|
+
return `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${major}.0.0.0 Safari/537.36`;
|
|
1980
|
+
}
|
|
1981
|
+
function updateQwenWebVersion(version) {
|
|
1982
|
+
if (version && typeof version === "string" && /^\d+\.\d+\.\d+/.test(version)) {
|
|
1983
|
+
dynamicWebVersion = version.trim();
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
function getQwenWebVersion() {
|
|
1987
|
+
return dynamicWebVersion || config.qwen.webVersion;
|
|
1988
|
+
}
|
|
1989
|
+
function updateQwenBxVersion(version) {
|
|
1990
|
+
if (version && typeof version === "string" && /^\d+\.\d+\.\d+/.test(version)) {
|
|
1991
|
+
dynamicBxVersion = version.trim();
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
function getQwenBxVersion() {
|
|
1995
|
+
return dynamicBxVersion || config.auth.bxV;
|
|
1996
|
+
}
|
|
1997
|
+
var dynamicWebVersion, dynamicBxVersion, QWEN_WEB_VERSION, DEFAULT_QWEN_USER_AGENT, QWEN_TIMEZONE_HEADER;
|
|
1998
|
+
var init_qwen_headers = __esm({
|
|
1999
|
+
"src/services/qwen-headers.ts"() {
|
|
2000
|
+
"use strict";
|
|
2001
|
+
init_qwen_url();
|
|
2002
|
+
init_config();
|
|
2003
|
+
init_fingerprint();
|
|
2004
|
+
init_timezone();
|
|
2005
|
+
dynamicWebVersion = null;
|
|
2006
|
+
dynamicBxVersion = null;
|
|
2007
|
+
QWEN_WEB_VERSION = config.qwen.webVersion;
|
|
2008
|
+
DEFAULT_QWEN_USER_AGENT = getDefaultQwenUserAgent(151);
|
|
2009
|
+
QWEN_TIMEZONE_HEADER = (/* @__PURE__ */ new Date()).toString().split(" (")[0];
|
|
2010
|
+
}
|
|
2011
|
+
});
|
|
2012
|
+
|
|
1710
2013
|
// src/core/memory-usage.ts
|
|
1711
2014
|
import v8 from "v8";
|
|
1712
2015
|
import os2 from "os";
|
|
@@ -2074,255 +2377,49 @@ var init_mutex = __esm({
|
|
|
2074
2377
|
const epoch = this.epoch;
|
|
2075
2378
|
let released = false;
|
|
2076
2379
|
return () => {
|
|
2077
|
-
if (released) return;
|
|
2078
|
-
released = true;
|
|
2079
|
-
if (epoch !== this.epoch) return;
|
|
2080
|
-
this.release();
|
|
2081
|
-
};
|
|
2082
|
-
}
|
|
2083
|
-
release() {
|
|
2084
|
-
const next = this.queue.shift();
|
|
2085
|
-
if (next) {
|
|
2086
|
-
const waitTime = Date.now() - next.enqueuedAt;
|
|
2087
|
-
if (waitTime > 1e3 && logger.isLevelEnabled("debug")) {
|
|
2088
|
-
logger.debug(`[Mutex:${this.name}] dequeued key=${next.key} waited=${waitTime}ms`);
|
|
2089
|
-
}
|
|
2090
|
-
next.waiter();
|
|
2091
|
-
return;
|
|
2092
|
-
}
|
|
2093
|
-
this.locked = false;
|
|
2094
|
-
this.lockedAt = 0;
|
|
2095
|
-
this.lockedByKey = "";
|
|
2096
|
-
}
|
|
2097
|
-
/**
|
|
2098
|
-
* Heartbeat the lock: extend lockedAt while the holder is actively making progress.
|
|
2099
|
-
* Prevents premature force-release during long-running streaming generations.
|
|
2100
|
-
*/
|
|
2101
|
-
touch(key) {
|
|
2102
|
-
if (this.locked && (!key || this.lockedByKey === key)) {
|
|
2103
|
-
this.lockedAt = Date.now();
|
|
2104
|
-
}
|
|
2105
|
-
}
|
|
2106
|
-
/** Returns true if the mutex is not locked and has no waiting queue. */
|
|
2107
|
-
isIdle() {
|
|
2108
|
-
return !this.locked && this.queue.length === 0;
|
|
2109
|
-
}
|
|
2110
|
-
/** Returns diagnostic info about the current lock state. */
|
|
2111
|
-
state() {
|
|
2112
|
-
return {
|
|
2113
|
-
locked: this.locked,
|
|
2114
|
-
heldBy: this.lockedByKey,
|
|
2115
|
-
heldForMs: this.locked ? Date.now() - this.lockedAt : 0,
|
|
2116
|
-
queueLength: this.queue.length
|
|
2117
|
-
};
|
|
2118
|
-
}
|
|
2119
|
-
};
|
|
2120
|
-
}
|
|
2121
|
-
});
|
|
2122
|
-
|
|
2123
|
-
// src/services/fingerprint.ts
|
|
2124
|
-
function mulberry32(seed) {
|
|
2125
|
-
return () => {
|
|
2126
|
-
seed |= 0;
|
|
2127
|
-
seed = seed + 1831565813 | 0;
|
|
2128
|
-
let t = Math.imul(seed ^ seed >>> 15, 1 | seed);
|
|
2129
|
-
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
|
2130
|
-
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
2131
|
-
};
|
|
2132
|
-
}
|
|
2133
|
-
function seedFromString(value) {
|
|
2134
|
-
let hash = 0;
|
|
2135
|
-
for (let i = 0; i < value.length; i++) {
|
|
2136
|
-
hash = (hash << 5) - hash + value.charCodeAt(i) | 0;
|
|
2137
|
-
}
|
|
2138
|
-
return hash >>> 0;
|
|
2139
|
-
}
|
|
2140
|
-
function pick(rng, values) {
|
|
2141
|
-
return values[Math.floor(rng() * values.length)];
|
|
2142
|
-
}
|
|
2143
|
-
function randInt(rng, min, max) {
|
|
2144
|
-
return Math.floor(rng() * (max - min + 1)) + min;
|
|
2145
|
-
}
|
|
2146
|
-
function updateChromeMajor(major) {
|
|
2147
|
-
if (typeof major === "number" && major >= 100) {
|
|
2148
|
-
dynamicChromeMajor = major;
|
|
2149
|
-
}
|
|
2150
|
-
}
|
|
2151
|
-
function getChromeMajor() {
|
|
2152
|
-
return dynamicChromeMajor;
|
|
2153
|
-
}
|
|
2154
|
-
function getSystemLocale() {
|
|
2155
|
-
return process.env.QWEN_LOCALE || (typeof Intl !== "undefined" && Intl.DateTimeFormat ? Intl.DateTimeFormat().resolvedOptions().locale : "") || "pt-BR";
|
|
2156
|
-
}
|
|
2157
|
-
function getLanguageProfiles(locale = getSystemLocale()) {
|
|
2158
|
-
const primary = locale.split("-")[0];
|
|
2159
|
-
if (primary === "en") {
|
|
2160
|
-
return [
|
|
2161
|
-
["en-US", "en"],
|
|
2162
|
-
["en-US", "en", "es"],
|
|
2163
|
-
["en", "en-US"],
|
|
2164
|
-
["en-US", "en;q=0.9"]
|
|
2165
|
-
];
|
|
2166
|
-
}
|
|
2167
|
-
return [
|
|
2168
|
-
[locale, primary, "en-US", "en"],
|
|
2169
|
-
[locale, primary, "en-US", "en", "es"],
|
|
2170
|
-
[locale, "en-US", "en", primary],
|
|
2171
|
-
[locale, primary, "en"],
|
|
2172
|
-
[locale, `${primary};q=0.9`, "en-US;q=0.8", "en;q=0.7"]
|
|
2173
|
-
];
|
|
2174
|
-
}
|
|
2175
|
-
function getFingerprintProfile(accountId) {
|
|
2176
|
-
const cached = profileCache.get(accountId);
|
|
2177
|
-
if (cached) return cached;
|
|
2178
|
-
const salt = rotationSalts.get(accountId) ?? 0;
|
|
2179
|
-
const seed = seedFromString(salt === 0 ? accountId : `${accountId}#r${salt}`);
|
|
2180
|
-
const rng = mulberry32(seed);
|
|
2181
|
-
const viewport = pick(rng, VIEWPORTS);
|
|
2182
|
-
const webgl = pick(rng, WEBGL_PROFILES);
|
|
2183
|
-
const languages = [...pick(rng, getLanguageProfiles())];
|
|
2184
|
-
const hardwareConcurrency = pick(rng, HARDWARE_CONCURRENCIES);
|
|
2185
|
-
const deviceMemory = pick(rng, DEVICE_MEMORIES);
|
|
2186
|
-
const platformInfo = pick(rng, PLATFORM_VERSIONS);
|
|
2187
|
-
const notABrand = pick(rng, NOT_A_BRAND_VARIANTS);
|
|
2188
|
-
const major = dynamicChromeMajor;
|
|
2189
|
-
const build = randInt(rng, 7300, 7600);
|
|
2190
|
-
const patch = randInt(rng, 0, 160);
|
|
2191
|
-
const chromeVersion = `${major}.0.${build}.${patch}`;
|
|
2192
|
-
const brands = [
|
|
2193
|
-
{ brand: notABrand.brand, version: notABrand.version },
|
|
2194
|
-
{ brand: "Google Chrome", version: String(major) },
|
|
2195
|
-
{ brand: "Chromium", version: String(major) }
|
|
2196
|
-
];
|
|
2197
|
-
const fullVersionList = [
|
|
2198
|
-
{ brand: notABrand.brand, version: chromeVersion },
|
|
2199
|
-
{ brand: "Google Chrome", version: chromeVersion },
|
|
2200
|
-
{ brand: "Chromium", version: chromeVersion }
|
|
2201
|
-
];
|
|
2202
|
-
const secChUa = brands.map((brand) => `"${brand.brand}";v="${brand.version}"`).join(", ");
|
|
2203
|
-
const userAgent = `Mozilla/5.0 (Windows NT ${platformInfo.major}.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${chromeVersion} Safari/537.36`;
|
|
2204
|
-
const profile = {
|
|
2205
|
-
accountId,
|
|
2206
|
-
seed,
|
|
2207
|
-
userAgent,
|
|
2208
|
-
appVersion: userAgent.replace("Mozilla/", ""),
|
|
2209
|
-
chromeMajor: CHROME_MAJOR,
|
|
2210
|
-
chromeVersion,
|
|
2211
|
-
brands,
|
|
2212
|
-
fullVersionList,
|
|
2213
|
-
secChUa,
|
|
2214
|
-
platform: "Win32",
|
|
2215
|
-
platformVersion: platformInfo.platformVersion,
|
|
2216
|
-
architecture: "x86",
|
|
2217
|
-
bitness: "64",
|
|
2218
|
-
languages,
|
|
2219
|
-
locale: languages[0].split(";")[0],
|
|
2220
|
-
timezoneId: "America/Sao_Paulo",
|
|
2221
|
-
viewport,
|
|
2222
|
-
hardwareConcurrency,
|
|
2223
|
-
deviceMemory,
|
|
2224
|
-
webglVendor: webgl.vendor,
|
|
2225
|
-
webglRenderer: webgl.renderer,
|
|
2226
|
-
colorDepth: 24,
|
|
2227
|
-
pixelDepth: 24,
|
|
2228
|
-
canvasNoiseSeed: randInt(rng, 1, 2147483647),
|
|
2229
|
-
audioNoiseSeed: randInt(rng, 1, 2147483647),
|
|
2230
|
-
webglNoiseSeed: randInt(rng, 1, 2147483647),
|
|
2231
|
-
outerWidthOffset: randInt(rng, 0, 20),
|
|
2232
|
-
outerHeightOffset: randInt(rng, 75, 95)
|
|
2233
|
-
};
|
|
2234
|
-
profileCache.set(accountId, profile);
|
|
2235
|
-
return profile;
|
|
2236
|
-
}
|
|
2237
|
-
function clearFingerprintCache(accountId) {
|
|
2238
|
-
if (accountId) profileCache.delete(accountId);
|
|
2239
|
-
else profileCache.clear();
|
|
2240
|
-
}
|
|
2241
|
-
var dynamicChromeMajor, CHROME_MAJOR, VIEWPORTS, WEBGL_PROFILES, HARDWARE_CONCURRENCIES, DEVICE_MEMORIES, PLATFORM_VERSIONS, NOT_A_BRAND_VARIANTS, profileCache, rotationSalts;
|
|
2242
|
-
var init_fingerprint = __esm({
|
|
2243
|
-
"src/services/fingerprint.ts"() {
|
|
2244
|
-
"use strict";
|
|
2245
|
-
dynamicChromeMajor = 151;
|
|
2246
|
-
CHROME_MAJOR = 151;
|
|
2247
|
-
VIEWPORTS = [
|
|
2248
|
-
{ width: 1366, height: 768 },
|
|
2249
|
-
{ width: 1440, height: 900 },
|
|
2250
|
-
{ width: 1536, height: 864 },
|
|
2251
|
-
{ width: 1600, height: 900 },
|
|
2252
|
-
{ width: 1680, height: 1050 },
|
|
2253
|
-
{ width: 1920, height: 1080 },
|
|
2254
|
-
{ width: 1920, height: 1200 },
|
|
2255
|
-
{ width: 1280, height: 720 },
|
|
2256
|
-
{ width: 1280, height: 800 },
|
|
2257
|
-
{ width: 1536, height: 864 }
|
|
2258
|
-
];
|
|
2259
|
-
WEBGL_PROFILES = [
|
|
2260
|
-
{
|
|
2261
|
-
vendor: "Google Inc. (Intel)",
|
|
2262
|
-
renderer: "ANGLE (Intel, Intel(R) UHD Graphics 630 Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
2263
|
-
},
|
|
2264
|
-
{
|
|
2265
|
-
vendor: "Google Inc. (Intel)",
|
|
2266
|
-
renderer: "ANGLE (Intel, Intel(R) Iris(R) Xe Graphics Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
2267
|
-
},
|
|
2268
|
-
{
|
|
2269
|
-
vendor: "Google Inc. (Intel)",
|
|
2270
|
-
renderer: "ANGLE (Intel, Intel(R) UHD Graphics 770 Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
2271
|
-
},
|
|
2272
|
-
{
|
|
2273
|
-
vendor: "Google Inc. (NVIDIA)",
|
|
2274
|
-
renderer: "ANGLE (NVIDIA, NVIDIA GeForce RTX 3060 Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
2275
|
-
},
|
|
2276
|
-
{
|
|
2277
|
-
vendor: "Google Inc. (NVIDIA)",
|
|
2278
|
-
renderer: "ANGLE (NVIDIA, NVIDIA GeForce RTX 3070 Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
2279
|
-
},
|
|
2280
|
-
{
|
|
2281
|
-
vendor: "Google Inc. (NVIDIA)",
|
|
2282
|
-
renderer: "ANGLE (NVIDIA, NVIDIA GeForce RTX 3080 Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
2283
|
-
},
|
|
2284
|
-
{
|
|
2285
|
-
vendor: "Google Inc. (NVIDIA)",
|
|
2286
|
-
renderer: "ANGLE (NVIDIA, NVIDIA GeForce RTX 4060 Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
2287
|
-
},
|
|
2288
|
-
{
|
|
2289
|
-
vendor: "Google Inc. (NVIDIA)",
|
|
2290
|
-
renderer: "ANGLE (NVIDIA, NVIDIA GeForce RTX 4070 Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
2291
|
-
},
|
|
2292
|
-
{
|
|
2293
|
-
vendor: "Google Inc. (NVIDIA)",
|
|
2294
|
-
renderer: "ANGLE (NVIDIA, NVIDIA GeForce GTX 1660 SUPER Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
2295
|
-
},
|
|
2296
|
-
{
|
|
2297
|
-
vendor: "Google Inc. (AMD)",
|
|
2298
|
-
renderer: "ANGLE (AMD, AMD Radeon RX 6600 Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
2299
|
-
},
|
|
2300
|
-
{
|
|
2301
|
-
vendor: "Google Inc. (AMD)",
|
|
2302
|
-
renderer: "ANGLE (AMD, AMD Radeon RX 7600 Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
2303
|
-
},
|
|
2304
|
-
{
|
|
2305
|
-
vendor: "Google Inc. (AMD)",
|
|
2306
|
-
renderer: "ANGLE (AMD, AMD Radeon RX 580 Direct3D11 vs_5_0 ps_5_0, D3D11)"
|
|
2380
|
+
if (released) return;
|
|
2381
|
+
released = true;
|
|
2382
|
+
if (epoch !== this.epoch) return;
|
|
2383
|
+
this.release();
|
|
2384
|
+
};
|
|
2307
2385
|
}
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2386
|
+
release() {
|
|
2387
|
+
const next = this.queue.shift();
|
|
2388
|
+
if (next) {
|
|
2389
|
+
const waitTime = Date.now() - next.enqueuedAt;
|
|
2390
|
+
if (waitTime > 1e3 && logger.isLevelEnabled("debug")) {
|
|
2391
|
+
logger.debug(`[Mutex:${this.name}] dequeued key=${next.key} waited=${waitTime}ms`);
|
|
2392
|
+
}
|
|
2393
|
+
next.waiter();
|
|
2394
|
+
return;
|
|
2395
|
+
}
|
|
2396
|
+
this.locked = false;
|
|
2397
|
+
this.lockedAt = 0;
|
|
2398
|
+
this.lockedByKey = "";
|
|
2399
|
+
}
|
|
2400
|
+
/**
|
|
2401
|
+
* Heartbeat the lock: extend lockedAt while the holder is actively making progress.
|
|
2402
|
+
* Prevents premature force-release during long-running streaming generations.
|
|
2403
|
+
*/
|
|
2404
|
+
touch(key) {
|
|
2405
|
+
if (this.locked && (!key || this.lockedByKey === key)) {
|
|
2406
|
+
this.lockedAt = Date.now();
|
|
2407
|
+
}
|
|
2408
|
+
}
|
|
2409
|
+
/** Returns true if the mutex is not locked and has no waiting queue. */
|
|
2410
|
+
isIdle() {
|
|
2411
|
+
return !this.locked && this.queue.length === 0;
|
|
2412
|
+
}
|
|
2413
|
+
/** Returns diagnostic info about the current lock state. */
|
|
2414
|
+
state() {
|
|
2415
|
+
return {
|
|
2416
|
+
locked: this.locked,
|
|
2417
|
+
heldBy: this.lockedByKey,
|
|
2418
|
+
heldForMs: this.locked ? Date.now() - this.lockedAt : 0,
|
|
2419
|
+
queueLength: this.queue.length
|
|
2420
|
+
};
|
|
2421
|
+
}
|
|
2422
|
+
};
|
|
2326
2423
|
}
|
|
2327
2424
|
});
|
|
2328
2425
|
|
|
@@ -2410,6 +2507,294 @@ function logBaxiaCaptcha(event, fields = {}, important = false) {
|
|
|
2410
2507
|
console.log(line);
|
|
2411
2508
|
}
|
|
2412
2509
|
}
|
|
2510
|
+
async function findVisibleLocatorWithin(page, selectors, timeoutMs) {
|
|
2511
|
+
const deadline = Date.now() + Math.max(0, timeoutMs);
|
|
2512
|
+
while (true) {
|
|
2513
|
+
const found = await findVisibleLocator(page, selectors);
|
|
2514
|
+
if (found) return found;
|
|
2515
|
+
if (Date.now() >= deadline) return null;
|
|
2516
|
+
await sleep(Math.min(150, Math.max(1, deadline - Date.now())));
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2519
|
+
async function waitForHidden(locator, timeoutMs) {
|
|
2520
|
+
const deadline = Date.now() + Math.max(0, timeoutMs);
|
|
2521
|
+
while (true) {
|
|
2522
|
+
if (!await isVisible(locator)) return true;
|
|
2523
|
+
if (Date.now() >= deadline) return false;
|
|
2524
|
+
await sleep(Math.min(100, Math.max(1, deadline - Date.now())));
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
async function computeAliyunPuzzleOffset(page) {
|
|
2528
|
+
return page.evaluate(() => {
|
|
2529
|
+
const background = document.querySelector(
|
|
2530
|
+
"#aliyunCaptcha-img"
|
|
2531
|
+
);
|
|
2532
|
+
const piece = document.querySelector(
|
|
2533
|
+
"#aliyunCaptcha-puzzle"
|
|
2534
|
+
);
|
|
2535
|
+
if (!background || !piece) {
|
|
2536
|
+
return Promise.resolve({ ok: false, reason: "missing puzzle images" });
|
|
2537
|
+
}
|
|
2538
|
+
const compute = () => {
|
|
2539
|
+
try {
|
|
2540
|
+
const width = background.naturalWidth;
|
|
2541
|
+
const height = background.naturalHeight;
|
|
2542
|
+
const pieceWidth = piece.naturalWidth;
|
|
2543
|
+
const pieceHeight = piece.naturalHeight;
|
|
2544
|
+
if (!width || !height || !pieceWidth || !pieceHeight) {
|
|
2545
|
+
return { ok: false, reason: "image dimensions unavailable" };
|
|
2546
|
+
}
|
|
2547
|
+
const backgroundCanvas = document.createElement("canvas");
|
|
2548
|
+
backgroundCanvas.id = "captcha-solver-canvas";
|
|
2549
|
+
backgroundCanvas.width = width;
|
|
2550
|
+
backgroundCanvas.height = height;
|
|
2551
|
+
const backgroundContext = backgroundCanvas.getContext("2d");
|
|
2552
|
+
if (!backgroundContext) {
|
|
2553
|
+
return { ok: false, reason: "no background context" };
|
|
2554
|
+
}
|
|
2555
|
+
const pieceCanvas = document.createElement("canvas");
|
|
2556
|
+
pieceCanvas.id = "captcha-solver-canvas";
|
|
2557
|
+
pieceCanvas.width = pieceWidth;
|
|
2558
|
+
pieceCanvas.height = pieceHeight;
|
|
2559
|
+
const pieceContext = pieceCanvas.getContext("2d");
|
|
2560
|
+
if (!pieceContext) {
|
|
2561
|
+
return { ok: false, reason: "no piece context" };
|
|
2562
|
+
}
|
|
2563
|
+
try {
|
|
2564
|
+
backgroundContext.drawImage(background, 0, 0);
|
|
2565
|
+
} catch {
|
|
2566
|
+
return { ok: false, reason: "background canvas tainted" };
|
|
2567
|
+
}
|
|
2568
|
+
try {
|
|
2569
|
+
pieceContext.drawImage(piece, 0, 0);
|
|
2570
|
+
} catch {
|
|
2571
|
+
return { ok: false, reason: "puzzle canvas tainted" };
|
|
2572
|
+
}
|
|
2573
|
+
const backgroundData = backgroundContext.getImageData(
|
|
2574
|
+
0,
|
|
2575
|
+
0,
|
|
2576
|
+
width,
|
|
2577
|
+
height
|
|
2578
|
+
).data;
|
|
2579
|
+
const pieceData = pieceContext.getImageData(
|
|
2580
|
+
0,
|
|
2581
|
+
0,
|
|
2582
|
+
pieceWidth,
|
|
2583
|
+
pieceHeight
|
|
2584
|
+
).data;
|
|
2585
|
+
let pieceMinX = pieceWidth;
|
|
2586
|
+
let pieceMaxX = -1;
|
|
2587
|
+
let pieceMinY = pieceHeight;
|
|
2588
|
+
let pieceMaxY = -1;
|
|
2589
|
+
for (let y = 0; y < pieceHeight; y++) {
|
|
2590
|
+
for (let x = 0; x < pieceWidth; x++) {
|
|
2591
|
+
if (pieceData[(y * pieceWidth + x) * 4 + 3] > 100) {
|
|
2592
|
+
if (x < pieceMinX) pieceMinX = x;
|
|
2593
|
+
if (x > pieceMaxX) pieceMaxX = x;
|
|
2594
|
+
if (y < pieceMinY) pieceMinY = y;
|
|
2595
|
+
if (y > pieceMaxY) pieceMaxY = y;
|
|
2596
|
+
}
|
|
2597
|
+
}
|
|
2598
|
+
}
|
|
2599
|
+
const puzzleWidth = pieceMaxX - pieceMinX + 1;
|
|
2600
|
+
if (puzzleWidth <= 0) {
|
|
2601
|
+
return { ok: false, reason: "empty puzzle piece" };
|
|
2602
|
+
}
|
|
2603
|
+
const yStart = Math.max(1, Math.min(height - 2, pieceMinY + 5));
|
|
2604
|
+
const yEnd = Math.max(
|
|
2605
|
+
yStart,
|
|
2606
|
+
Math.min(height - 2, pieceMaxY - 5)
|
|
2607
|
+
);
|
|
2608
|
+
const columnGradients = new Float32Array(width);
|
|
2609
|
+
for (let x = 1; x < width - 1; x++) {
|
|
2610
|
+
let gradient = 0;
|
|
2611
|
+
for (let y = yStart; y <= yEnd; y++) {
|
|
2612
|
+
const left = (y * width + x - 1) * 4;
|
|
2613
|
+
const right = (y * width + x + 1) * 4;
|
|
2614
|
+
gradient += Math.abs(backgroundData[right] - backgroundData[left]) + Math.abs(backgroundData[right + 1] - backgroundData[left + 1]) + Math.abs(backgroundData[right + 2] - backgroundData[left + 2]);
|
|
2615
|
+
}
|
|
2616
|
+
columnGradients[x] = gradient;
|
|
2617
|
+
}
|
|
2618
|
+
let bestX = 0;
|
|
2619
|
+
let bestScore = 0;
|
|
2620
|
+
const minCandidateX = 30;
|
|
2621
|
+
const maxCandidateX = width - puzzleWidth - 20;
|
|
2622
|
+
for (let candidateX = minCandidateX; candidateX <= maxCandidateX; candidateX++) {
|
|
2623
|
+
let leftMax = 0;
|
|
2624
|
+
for (let dx = -2; dx <= 2; dx++) {
|
|
2625
|
+
const value = columnGradients[candidateX + pieceMinX + dx] || 0;
|
|
2626
|
+
if (value > leftMax) leftMax = value;
|
|
2627
|
+
}
|
|
2628
|
+
let rightMax = 0;
|
|
2629
|
+
for (let dx = -3; dx <= 1; dx++) {
|
|
2630
|
+
const value = columnGradients[candidateX + pieceMaxX + dx] || 0;
|
|
2631
|
+
if (value > rightMax) rightMax = value;
|
|
2632
|
+
}
|
|
2633
|
+
const score = Math.sqrt(leftMax * rightMax);
|
|
2634
|
+
if (score > bestScore) {
|
|
2635
|
+
bestScore = score;
|
|
2636
|
+
bestX = candidateX;
|
|
2637
|
+
}
|
|
2638
|
+
}
|
|
2639
|
+
if (bestScore <= 0) {
|
|
2640
|
+
return { ok: false, reason: "no matching hole edge" };
|
|
2641
|
+
}
|
|
2642
|
+
return {
|
|
2643
|
+
ok: true,
|
|
2644
|
+
offsetX: bestX - pieceMinX,
|
|
2645
|
+
naturalWidth: width
|
|
2646
|
+
};
|
|
2647
|
+
} catch (error) {
|
|
2648
|
+
return {
|
|
2649
|
+
ok: false,
|
|
2650
|
+
reason: error instanceof Error ? error.message : String(error)
|
|
2651
|
+
};
|
|
2652
|
+
}
|
|
2653
|
+
};
|
|
2654
|
+
return new Promise((resolve) => {
|
|
2655
|
+
if (background.complete && piece.complete) {
|
|
2656
|
+
resolve(compute());
|
|
2657
|
+
return;
|
|
2658
|
+
}
|
|
2659
|
+
let settled = false;
|
|
2660
|
+
const finish = () => {
|
|
2661
|
+
if (settled) return;
|
|
2662
|
+
settled = true;
|
|
2663
|
+
resolve(compute());
|
|
2664
|
+
};
|
|
2665
|
+
const fail = () => {
|
|
2666
|
+
if (settled) return;
|
|
2667
|
+
settled = true;
|
|
2668
|
+
resolve({ ok: false, reason: "puzzle image load error" });
|
|
2669
|
+
};
|
|
2670
|
+
background.addEventListener("load", finish, { once: true });
|
|
2671
|
+
piece.addEventListener("load", finish, { once: true });
|
|
2672
|
+
background.addEventListener("error", fail, { once: true });
|
|
2673
|
+
piece.addEventListener("error", fail, { once: true });
|
|
2674
|
+
setTimeout(() => {
|
|
2675
|
+
if (settled) return;
|
|
2676
|
+
settled = true;
|
|
2677
|
+
resolve({ ok: false, reason: "puzzle image load timeout" });
|
|
2678
|
+
}, 2e3);
|
|
2679
|
+
});
|
|
2680
|
+
});
|
|
2681
|
+
}
|
|
2682
|
+
async function solveAliyunWafCaptcha(page, options = {}) {
|
|
2683
|
+
const waitForMs = Math.max(0, options.waitForMs ?? 0);
|
|
2684
|
+
const maxAttempts = Math.max(
|
|
2685
|
+
1,
|
|
2686
|
+
Math.min(5, options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS)
|
|
2687
|
+
);
|
|
2688
|
+
const retryDelayMs = Math.max(
|
|
2689
|
+
0,
|
|
2690
|
+
options.retryDelayMs ?? DEFAULT_RETRY_DELAY_MS
|
|
2691
|
+
);
|
|
2692
|
+
const settleMs = Math.max(0, options.settleMs ?? DEFAULT_SETTLE_MS);
|
|
2693
|
+
const sliderTimeoutMs = Math.max(
|
|
2694
|
+
500,
|
|
2695
|
+
options.sliderTimeoutMs ?? DEFAULT_SLIDER_TIMEOUT_MS
|
|
2696
|
+
);
|
|
2697
|
+
const detected = await findVisibleLocatorWithin(
|
|
2698
|
+
page,
|
|
2699
|
+
ALIYUN_WAF_BLOCK_SELECTORS,
|
|
2700
|
+
waitForMs
|
|
2701
|
+
);
|
|
2702
|
+
if (!detected) return false;
|
|
2703
|
+
return withCaptchaMouseLock(async () => {
|
|
2704
|
+
const block = detected.locator;
|
|
2705
|
+
if (!await isVisible(block)) return false;
|
|
2706
|
+
logBaxiaCaptcha("aliyun_detected", { selector: detected.selector });
|
|
2707
|
+
let lastReason = "unknown";
|
|
2708
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
2709
|
+
try {
|
|
2710
|
+
const offset = await computeAliyunPuzzleOffset(page);
|
|
2711
|
+
if (!offset.ok || typeof offset.offsetX !== "number" || typeof offset.naturalWidth !== "number" || offset.naturalWidth <= 0) {
|
|
2712
|
+
lastReason = offset.reason || "offset_unavailable";
|
|
2713
|
+
logBaxiaCaptcha("aliyun_offset_failed", {
|
|
2714
|
+
attempt,
|
|
2715
|
+
reason: lastReason
|
|
2716
|
+
});
|
|
2717
|
+
} else {
|
|
2718
|
+
const slider = page.locator(ALIYUN_PUZZLE_SLIDER_SELECTOR).first();
|
|
2719
|
+
const track = page.locator(ALIYUN_PUZZLE_TRACK_SELECTOR).first();
|
|
2720
|
+
await slider.waitFor({ state: "visible", timeout: sliderTimeoutMs });
|
|
2721
|
+
const [sliderBox, trackBox] = await Promise.all([
|
|
2722
|
+
slider.boundingBox(),
|
|
2723
|
+
track.boundingBox()
|
|
2724
|
+
]);
|
|
2725
|
+
if (!sliderBox || !trackBox || trackBox.width <= 0) {
|
|
2726
|
+
lastReason = "bounds_unavailable";
|
|
2727
|
+
logBaxiaCaptcha("aliyun_offset_failed", {
|
|
2728
|
+
attempt,
|
|
2729
|
+
reason: lastReason
|
|
2730
|
+
});
|
|
2731
|
+
} else {
|
|
2732
|
+
const scale = trackBox.width / offset.naturalWidth;
|
|
2733
|
+
const dragDistance = Math.round(offset.offsetX * scale);
|
|
2734
|
+
logBaxiaCaptcha("aliyun_geometry", {
|
|
2735
|
+
attempt,
|
|
2736
|
+
offset: offset.offsetX,
|
|
2737
|
+
scale: Number(scale.toFixed(2)),
|
|
2738
|
+
distance: dragDistance
|
|
2739
|
+
});
|
|
2740
|
+
if (dragDistance <= 0) {
|
|
2741
|
+
lastReason = "non_positive_distance";
|
|
2742
|
+
} else {
|
|
2743
|
+
const startX = sliderBox.x + sliderBox.width / 2;
|
|
2744
|
+
const startY = sliderBox.y + sliderBox.height / 2;
|
|
2745
|
+
await humanDrag(
|
|
2746
|
+
page,
|
|
2747
|
+
startX,
|
|
2748
|
+
startY,
|
|
2749
|
+
startX + dragDistance,
|
|
2750
|
+
startY
|
|
2751
|
+
);
|
|
2752
|
+
if (await waitForHidden(block, settleMs)) {
|
|
2753
|
+
logBaxiaCaptcha(
|
|
2754
|
+
"aliyun_solve_succeeded",
|
|
2755
|
+
{ attempt, distance: dragDistance },
|
|
2756
|
+
true
|
|
2757
|
+
);
|
|
2758
|
+
return true;
|
|
2759
|
+
}
|
|
2760
|
+
lastReason = "not_solved";
|
|
2761
|
+
}
|
|
2762
|
+
}
|
|
2763
|
+
}
|
|
2764
|
+
} catch (error) {
|
|
2765
|
+
lastReason = error instanceof Error ? error.name : "UnknownError";
|
|
2766
|
+
logBaxiaCaptcha("aliyun_offset_failed", {
|
|
2767
|
+
attempt,
|
|
2768
|
+
error: lastReason,
|
|
2769
|
+
detail: sanitizeCaptchaErrorDetail(error)
|
|
2770
|
+
});
|
|
2771
|
+
}
|
|
2772
|
+
if (attempt < maxAttempts && retryDelayMs > 0) {
|
|
2773
|
+
await sleep(retryDelayMs);
|
|
2774
|
+
}
|
|
2775
|
+
}
|
|
2776
|
+
logBaxiaCaptcha(
|
|
2777
|
+
"aliyun_solve_failed",
|
|
2778
|
+
{ attempts: maxAttempts, reason: lastReason },
|
|
2779
|
+
true
|
|
2780
|
+
);
|
|
2781
|
+
return false;
|
|
2782
|
+
});
|
|
2783
|
+
}
|
|
2784
|
+
async function solveVisibleCaptcha(page, options = {}) {
|
|
2785
|
+
if (typeof page.isClosed === "function" && page.isClosed()) return false;
|
|
2786
|
+
const totalWaitMs = Math.max(0, options.waitForMs ?? 0);
|
|
2787
|
+
const aliyunWaitMs = Math.min(totalWaitMs, ALIYUN_PROBE_MAX_WAIT_MS);
|
|
2788
|
+
const startedAt = Date.now();
|
|
2789
|
+
if (await solveAliyunWafCaptcha(page, { ...options, waitForMs: aliyunWaitMs })) {
|
|
2790
|
+
return true;
|
|
2791
|
+
}
|
|
2792
|
+
const remainingWaitMs = Math.max(
|
|
2793
|
+
0,
|
|
2794
|
+
totalWaitMs - (Date.now() - startedAt)
|
|
2795
|
+
);
|
|
2796
|
+
return solveBaxiaCaptcha(page, { ...options, waitForMs: remainingWaitMs });
|
|
2797
|
+
}
|
|
2413
2798
|
async function isVisible(locator) {
|
|
2414
2799
|
return locator.isVisible().catch(() => false);
|
|
2415
2800
|
}
|
|
@@ -2652,7 +3037,7 @@ async function solveBaxiaCaptchaUnlocked(page, options = {}) {
|
|
|
2652
3037
|
);
|
|
2653
3038
|
return false;
|
|
2654
3039
|
}
|
|
2655
|
-
var BAXIA_DIALOG_SELECTOR, BAXIA_CONTENT_SELECTOR, CAPTCHA_EVENT_EMOJI, captchaDebugEnabled, BAXIA_IFRAME_SELECTORS, BAXIA_DOCUMENT_SELECTORS, BAXIA_IFRAME_SELECTOR, BAXIA_SLIDER_SELECTOR, BAXIA_TRACK_SELECTOR, BAXIA_SUCCESS_SELECTOR, BAXIA_RELOAD_SELECTOR, DEFAULT_MAX_ATTEMPTS, DEFAULT_RETRY_DELAY_MS, DEFAULT_SETTLE_MS, DEFAULT_SLIDER_TIMEOUT_MS, captchaMouseLock;
|
|
3040
|
+
var BAXIA_DIALOG_SELECTOR, BAXIA_CONTENT_SELECTOR, CAPTCHA_EVENT_EMOJI, captchaDebugEnabled, BAXIA_IFRAME_SELECTORS, BAXIA_DOCUMENT_SELECTORS, BAXIA_IFRAME_SELECTOR, BAXIA_SLIDER_SELECTOR, BAXIA_TRACK_SELECTOR, BAXIA_SUCCESS_SELECTOR, BAXIA_RELOAD_SELECTOR, DEFAULT_MAX_ATTEMPTS, DEFAULT_RETRY_DELAY_MS, DEFAULT_SETTLE_MS, DEFAULT_SLIDER_TIMEOUT_MS, ALIYUN_WAF_CAPTCHA_SELECTOR, ALIYUN_WAF_CAPTCHA_WIDGET, ALIYUN_WAF_BLOCK_SELECTORS, ALIYUN_PUZZLE_SLIDER_SELECTOR, ALIYUN_PUZZLE_TRACK_SELECTOR, ALIYUN_PROBE_MAX_WAIT_MS, captchaMouseLock;
|
|
2656
3041
|
var init_captcha_solver = __esm({
|
|
2657
3042
|
"src/services/captcha-solver.ts"() {
|
|
2658
3043
|
"use strict";
|
|
@@ -2678,14 +3063,20 @@ var init_captcha_solver = __esm({
|
|
|
2678
3063
|
solve_failed: "\u274C",
|
|
2679
3064
|
recovery_succeeded: "\u2705",
|
|
2680
3065
|
recovery_not_solved: "\u26A0\uFE0F",
|
|
2681
|
-
recovery_failed: "\u274C"
|
|
3066
|
+
recovery_failed: "\u274C",
|
|
3067
|
+
aliyun_detected: "\u{1F9E9}",
|
|
3068
|
+
aliyun_offset_failed: "\u{1F4D0}",
|
|
3069
|
+
aliyun_geometry: "\u{1F4D0}",
|
|
3070
|
+
aliyun_solve_succeeded: "\u2705",
|
|
3071
|
+
aliyun_solve_failed: "\u274C"
|
|
2682
3072
|
};
|
|
2683
3073
|
captchaDebugEnabled = process.env.CAPTCHA_DEBUG === "true";
|
|
2684
3074
|
BAXIA_IFRAME_SELECTORS = [
|
|
2685
3075
|
`${BAXIA_DIALOG_SELECTOR} ${BAXIA_CONTENT_SELECTOR} iframe`,
|
|
2686
3076
|
`${BAXIA_CONTENT_SELECTOR} iframe`,
|
|
2687
3077
|
"iframe#baxia-dialog-content",
|
|
2688
|
-
'iframe[src*="_____tmd_____/punish"]'
|
|
3078
|
+
'iframe[src*="_____tmd_____/punish"]',
|
|
3079
|
+
'iframe[src*="nocaptcha"]'
|
|
2689
3080
|
];
|
|
2690
3081
|
BAXIA_DOCUMENT_SELECTORS = [
|
|
2691
3082
|
"#nocaptcha",
|
|
@@ -2693,36 +3084,27 @@ var init_captcha_solver = __esm({
|
|
|
2693
3084
|
"#baxia-punish"
|
|
2694
3085
|
];
|
|
2695
3086
|
BAXIA_IFRAME_SELECTOR = BAXIA_IFRAME_SELECTORS.join(", ");
|
|
2696
|
-
BAXIA_SLIDER_SELECTOR =
|
|
2697
|
-
BAXIA_TRACK_SELECTOR =
|
|
3087
|
+
BAXIA_SLIDER_SELECTOR = '#nc_1_n1z, .nc_1_n1z, .btn_slide, .nc_iconfont.btn_slide, span[id*="_n1z"], .nc_wrapper .btn_slide, ._nc .btn_slide, .nc-container .btn_slide';
|
|
3088
|
+
BAXIA_TRACK_SELECTOR = '#nc_1_n1t, .nc_scale, span[id*="_n1t"], .nc_wrapper .nc_scale, ._nc .nc_scale, .nc-container .nc_scale';
|
|
2698
3089
|
BAXIA_SUCCESS_SELECTOR = '.btn_ok, .nc_ok, .nc_success, .nc_result, .nc_wrapper.nc-success, .nc_wrapper.success, [data-nc-lang="SUCCESS"], [data-nc-lang="success"], #nc-loading-circle';
|
|
2699
3090
|
BAXIA_RELOAD_SELECTOR = '#nc_1_refresh1, .errloading a, .nc-container .errloading a, .btn_refresh, .clickCaptcha_text .btn_refresh, [data-nc-lang="REFRESH"], a[id*="refresh"]';
|
|
2700
3091
|
DEFAULT_MAX_ATTEMPTS = 3;
|
|
2701
3092
|
DEFAULT_RETRY_DELAY_MS = 1e3;
|
|
2702
3093
|
DEFAULT_SETTLE_MS = 2e3;
|
|
2703
3094
|
DEFAULT_SLIDER_TIMEOUT_MS = 8e3;
|
|
3095
|
+
ALIYUN_WAF_CAPTCHA_SELECTOR = "#waf_nc_block";
|
|
3096
|
+
ALIYUN_WAF_CAPTCHA_WIDGET = "#aliyunCaptcha-window-embed";
|
|
3097
|
+
ALIYUN_WAF_BLOCK_SELECTORS = [
|
|
3098
|
+
ALIYUN_WAF_CAPTCHA_SELECTOR,
|
|
3099
|
+
ALIYUN_WAF_CAPTCHA_WIDGET
|
|
3100
|
+
];
|
|
3101
|
+
ALIYUN_PUZZLE_SLIDER_SELECTOR = "#aliyunCaptcha-sliding-slider";
|
|
3102
|
+
ALIYUN_PUZZLE_TRACK_SELECTOR = "#aliyunCaptcha-sliding-body";
|
|
3103
|
+
ALIYUN_PROBE_MAX_WAIT_MS = 2e3;
|
|
2704
3104
|
captchaMouseLock = Promise.resolve();
|
|
2705
3105
|
}
|
|
2706
3106
|
});
|
|
2707
3107
|
|
|
2708
|
-
// src/services/qwen-url.ts
|
|
2709
|
-
function qwenUrl(path6 = "") {
|
|
2710
|
-
const normalizedPath = path6.replace(/^\/+/, "");
|
|
2711
|
-
return normalizedPath ? `${QWEN_BASE_URL}/${normalizedPath}` : QWEN_BASE_URL;
|
|
2712
|
-
}
|
|
2713
|
-
function qwenOrigin() {
|
|
2714
|
-
return QWEN_ORIGIN;
|
|
2715
|
-
}
|
|
2716
|
-
var QWEN_BASE_URL, QWEN_ORIGIN;
|
|
2717
|
-
var init_qwen_url = __esm({
|
|
2718
|
-
"src/services/qwen-url.ts"() {
|
|
2719
|
-
"use strict";
|
|
2720
|
-
init_config();
|
|
2721
|
-
QWEN_BASE_URL = config.qwen.baseUrl.trim().replace(/\/+$/, "");
|
|
2722
|
-
QWEN_ORIGIN = new URL(QWEN_BASE_URL).origin;
|
|
2723
|
-
}
|
|
2724
|
-
});
|
|
2725
|
-
|
|
2726
3108
|
// src/core/waf-isolation.ts
|
|
2727
3109
|
function setWafContextResetListener(fn) {
|
|
2728
3110
|
contextResetListener = fn;
|
|
@@ -2739,73 +3121,6 @@ var init_waf_isolation = __esm({
|
|
|
2739
3121
|
}
|
|
2740
3122
|
});
|
|
2741
3123
|
|
|
2742
|
-
// src/utils/timezone.ts
|
|
2743
|
-
function formatAsciiTimezone(date = /* @__PURE__ */ new Date()) {
|
|
2744
|
-
const dayName = DAYS[date.getDay()];
|
|
2745
|
-
const monthName = MONTHS[date.getMonth()];
|
|
2746
|
-
const day = String(date.getDate()).padStart(2, "0");
|
|
2747
|
-
const year = date.getFullYear();
|
|
2748
|
-
const hours = String(date.getHours()).padStart(2, "0");
|
|
2749
|
-
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
2750
|
-
const seconds = String(date.getSeconds()).padStart(2, "0");
|
|
2751
|
-
const offsetMinutes = -date.getTimezoneOffset();
|
|
2752
|
-
const sign = offsetMinutes >= 0 ? "+" : "-";
|
|
2753
|
-
const absOffset = Math.abs(offsetMinutes);
|
|
2754
|
-
const offsetHours = String(Math.floor(absOffset / 60)).padStart(2, "0");
|
|
2755
|
-
const offsetMins = String(absOffset % 60).padStart(2, "0");
|
|
2756
|
-
const tzOffset = `GMT${sign}${offsetHours}${offsetMins}`;
|
|
2757
|
-
return `${dayName} ${monthName} ${day} ${year} ${hours}:${minutes}:${seconds} ${tzOffset}`;
|
|
2758
|
-
}
|
|
2759
|
-
var DAYS, MONTHS;
|
|
2760
|
-
var init_timezone = __esm({
|
|
2761
|
-
"src/utils/timezone.ts"() {
|
|
2762
|
-
"use strict";
|
|
2763
|
-
DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
2764
|
-
MONTHS = [
|
|
2765
|
-
"Jan",
|
|
2766
|
-
"Feb",
|
|
2767
|
-
"Mar",
|
|
2768
|
-
"Apr",
|
|
2769
|
-
"May",
|
|
2770
|
-
"Jun",
|
|
2771
|
-
"Jul",
|
|
2772
|
-
"Aug",
|
|
2773
|
-
"Sep",
|
|
2774
|
-
"Oct",
|
|
2775
|
-
"Nov",
|
|
2776
|
-
"Dec"
|
|
2777
|
-
];
|
|
2778
|
-
}
|
|
2779
|
-
});
|
|
2780
|
-
|
|
2781
|
-
// src/services/qwen-headers.ts
|
|
2782
|
-
import { v4 as uuidv4 } from "uuid";
|
|
2783
|
-
function getDefaultQwenUserAgent(major = getChromeMajor()) {
|
|
2784
|
-
return `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${major}.0.0.0 Safari/537.36`;
|
|
2785
|
-
}
|
|
2786
|
-
function updateQwenWebVersion(version) {
|
|
2787
|
-
if (version && typeof version === "string" && /^\d+\.\d+\.\d+/.test(version)) {
|
|
2788
|
-
dynamicWebVersion = version.trim();
|
|
2789
|
-
}
|
|
2790
|
-
}
|
|
2791
|
-
function getQwenWebVersion() {
|
|
2792
|
-
return dynamicWebVersion || config.qwen.webVersion;
|
|
2793
|
-
}
|
|
2794
|
-
var dynamicWebVersion, QWEN_WEB_VERSION, DEFAULT_QWEN_USER_AGENT, QWEN_TIMEZONE_HEADER;
|
|
2795
|
-
var init_qwen_headers = __esm({
|
|
2796
|
-
"src/services/qwen-headers.ts"() {
|
|
2797
|
-
"use strict";
|
|
2798
|
-
init_qwen_url();
|
|
2799
|
-
init_config();
|
|
2800
|
-
init_fingerprint();
|
|
2801
|
-
init_timezone();
|
|
2802
|
-
dynamicWebVersion = null;
|
|
2803
|
-
QWEN_WEB_VERSION = config.qwen.webVersion;
|
|
2804
|
-
DEFAULT_QWEN_USER_AGENT = getDefaultQwenUserAgent(151);
|
|
2805
|
-
QWEN_TIMEZONE_HEADER = (/* @__PURE__ */ new Date()).toString().split(" (")[0];
|
|
2806
|
-
}
|
|
2807
|
-
});
|
|
2808
|
-
|
|
2809
3124
|
// src/utils/jwt.ts
|
|
2810
3125
|
var jwt_exports = {};
|
|
2811
3126
|
__export(jwt_exports, {
|
|
@@ -3340,11 +3655,12 @@ async function isPageLoggedIn(page, timeoutMs = SESSION_PROBE_NAVIGATION_TIMEOUT
|
|
|
3340
3655
|
async function clearVisibleChallenge(page) {
|
|
3341
3656
|
if (page.isClosed()) return;
|
|
3342
3657
|
if (config.captcha.enabled) {
|
|
3343
|
-
await
|
|
3658
|
+
await solveVisibleCaptcha(page, {
|
|
3344
3659
|
waitForMs: 0,
|
|
3345
3660
|
maxAttempts: config.captcha.maxAttempts,
|
|
3346
3661
|
retryDelayMs: config.captcha.retryDelayMs,
|
|
3347
|
-
settleMs: config.captcha.settleMs
|
|
3662
|
+
settleMs: config.captcha.settleMs,
|
|
3663
|
+
sliderTimeoutMs: config.captcha.sliderTimeoutMs
|
|
3348
3664
|
}).catch(() => false);
|
|
3349
3665
|
}
|
|
3350
3666
|
try {
|
|
@@ -4090,6 +4406,9 @@ async function initPlaywrightForAccount(rawAccount, headless = config.playwright
|
|
|
4090
4406
|
if (persisted.version) {
|
|
4091
4407
|
updateQwenWebVersion(persisted.version);
|
|
4092
4408
|
}
|
|
4409
|
+
if (persisted.bxV) {
|
|
4410
|
+
updateQwenBxVersion(persisted.bxV);
|
|
4411
|
+
}
|
|
4093
4412
|
cache.lastRefresh = persisted.capturedAt;
|
|
4094
4413
|
markAccountHeadersReady(account.id);
|
|
4095
4414
|
restoredFromDb = true;
|
|
@@ -4286,7 +4605,7 @@ async function loginToQwen(accountId, email, password) {
|
|
|
4286
4605
|
saveAuthSession2(accountId, {
|
|
4287
4606
|
cookie: cookieStr,
|
|
4288
4607
|
userAgent: cache.headers["user-agent"] || "",
|
|
4289
|
-
bxV: cache.headers["bx-v"] ||
|
|
4608
|
+
bxV: cache.headers["bx-v"] || getQwenBxVersion(),
|
|
4290
4609
|
bxUa: cache.headers["bx-ua"] || "",
|
|
4291
4610
|
bxUmidtoken: cache.headers["bx-umidtoken"] || "",
|
|
4292
4611
|
secChUa: cache.headers["sec-ch-ua"] || void 0,
|
|
@@ -4358,7 +4677,7 @@ async function loginToQwen(accountId, email, password) {
|
|
|
4358
4677
|
saveAuthSession2(accountId, {
|
|
4359
4678
|
cookie: cookieStr,
|
|
4360
4679
|
userAgent: cache.headers["user-agent"] || "",
|
|
4361
|
-
bxV: cache.headers["bx-v"] ||
|
|
4680
|
+
bxV: cache.headers["bx-v"] || getQwenBxVersion(),
|
|
4362
4681
|
bxUa: cache.headers["bx-ua"] || "",
|
|
4363
4682
|
bxUmidtoken: cache.headers["bx-umidtoken"] || "",
|
|
4364
4683
|
secChUa: cache.headers["sec-ch-ua"] || void 0,
|
|
@@ -4429,7 +4748,7 @@ async function loginViaApi(page, email, password) {
|
|
|
4429
4748
|
}
|
|
4430
4749
|
const signinUrl = "https://auth.qwen.ai/api/v2/auths/signin";
|
|
4431
4750
|
const requestId = crypto3.randomUUID();
|
|
4432
|
-
const webVersion = getQwenWebVersion()
|
|
4751
|
+
const webVersion = getQwenWebVersion();
|
|
4433
4752
|
const evalRes = await page.evaluate(
|
|
4434
4753
|
async ({ email: email2, password: password2, signinUrl: signinUrl2, requestId: requestId2, tz, version }) => {
|
|
4435
4754
|
try {
|
|
@@ -4601,6 +4920,15 @@ async function loginViaUi(page, email, password) {
|
|
|
4601
4920
|
if (!page.url().includes("/auth") && await isPageLoggedIn(page, 3e3).catch(() => false)) {
|
|
4602
4921
|
return { success: true };
|
|
4603
4922
|
}
|
|
4923
|
+
if (config.captcha.enabled) {
|
|
4924
|
+
await solveVisibleCaptcha(page, {
|
|
4925
|
+
waitForMs: 1500,
|
|
4926
|
+
maxAttempts: config.captcha.maxAttempts,
|
|
4927
|
+
retryDelayMs: config.captcha.retryDelayMs,
|
|
4928
|
+
settleMs: config.captcha.settleMs,
|
|
4929
|
+
sliderTimeoutMs: config.captcha.sliderTimeoutMs
|
|
4930
|
+
}).catch(() => false);
|
|
4931
|
+
}
|
|
4604
4932
|
const emailSelector = [
|
|
4605
4933
|
'input[type="email"]',
|
|
4606
4934
|
'input[name="email"]',
|
|
@@ -4756,10 +5084,11 @@ async function loginViaUi(page, email, password) {
|
|
|
4756
5084
|
while (Date.now() < postSubmitDeadline) {
|
|
4757
5085
|
if (page.isClosed()) break;
|
|
4758
5086
|
if (config.captcha.enabled) {
|
|
4759
|
-
await
|
|
5087
|
+
await solveVisibleCaptcha(page, {
|
|
4760
5088
|
waitForMs: 1500,
|
|
4761
5089
|
maxAttempts: config.captcha.maxAttempts,
|
|
4762
|
-
retryDelayMs: config.captcha.retryDelayMs
|
|
5090
|
+
retryDelayMs: config.captcha.retryDelayMs,
|
|
5091
|
+
sliderTimeoutMs: config.captcha.sliderTimeoutMs
|
|
4763
5092
|
}).catch(() => {
|
|
4764
5093
|
});
|
|
4765
5094
|
}
|
|
@@ -4882,7 +5211,7 @@ async function refreshAccountToken(accountId) {
|
|
|
4882
5211
|
}
|
|
4883
5212
|
if (refreshToken) {
|
|
4884
5213
|
try {
|
|
4885
|
-
const webVersion = getQwenWebVersion()
|
|
5214
|
+
const webVersion = getQwenWebVersion();
|
|
4886
5215
|
const refreshResult = await page.evaluate(
|
|
4887
5216
|
async ({ rTok, tz, version }) => {
|
|
4888
5217
|
try {
|
|
@@ -4947,7 +5276,7 @@ async function refreshAccountToken(accountId) {
|
|
|
4947
5276
|
saveAuthSession2(accountId, {
|
|
4948
5277
|
cookie: cookieStr,
|
|
4949
5278
|
userAgent: cache.headers["user-agent"] || session?.userAgent || "",
|
|
4950
|
-
bxV: cache.headers["bx-v"] || session?.bxV ||
|
|
5279
|
+
bxV: cache.headers["bx-v"] || session?.bxV || getQwenBxVersion(),
|
|
4951
5280
|
bxUa: cache.headers["bx-ua"] || session?.bxUa || "",
|
|
4952
5281
|
bxUmidtoken: cache.headers["bx-umidtoken"] || session?.bxUmidtoken || "",
|
|
4953
5282
|
secChUa: cache.headers["sec-ch-ua"] || session?.secChUa,
|
|
@@ -4982,7 +5311,7 @@ async function refreshAccountToken(accountId) {
|
|
|
4982
5311
|
saveAuthSession2(accountId, {
|
|
4983
5312
|
cookie: cookieStr,
|
|
4984
5313
|
userAgent: cache.headers["user-agent"] || session?.userAgent || "",
|
|
4985
|
-
bxV: cache.headers["bx-v"] || session?.bxV ||
|
|
5314
|
+
bxV: cache.headers["bx-v"] || session?.bxV || getQwenBxVersion(),
|
|
4986
5315
|
bxUa: cache.headers["bx-ua"] || session?.bxUa || "",
|
|
4987
5316
|
bxUmidtoken: cache.headers["bx-umidtoken"] || session?.bxUmidtoken || "",
|
|
4988
5317
|
secChUa: cache.headers["sec-ch-ua"] || session?.secChUa,
|
|
@@ -5130,7 +5459,7 @@ async function captureQwenHeaders(accountId, pageOverride, timeoutMs = config.ti
|
|
|
5130
5459
|
cookie: reqHeaders["cookie"] || "",
|
|
5131
5460
|
"bx-ua": reqHeaders["bx-ua"] || "",
|
|
5132
5461
|
"bx-umidtoken": reqHeaders["bx-umidtoken"] || "",
|
|
5133
|
-
"bx-v": reqHeaders["bx-v"] ||
|
|
5462
|
+
"bx-v": reqHeaders["bx-v"] || getQwenBxVersion(),
|
|
5134
5463
|
"user-agent": reqHeaders["user-agent"] || "",
|
|
5135
5464
|
"x-request-id": reqHeaders["x-request-id"] || "",
|
|
5136
5465
|
"version": reqHeaders["version"] || "",
|
|
@@ -5162,6 +5491,9 @@ async function captureQwenHeaders(accountId, pageOverride, timeoutMs = config.ti
|
|
|
5162
5491
|
if (capturedHeaders["version"]) {
|
|
5163
5492
|
updateQwenWebVersion(capturedHeaders["version"]);
|
|
5164
5493
|
}
|
|
5494
|
+
if (capturedHeaders["bx-v"]) {
|
|
5495
|
+
updateQwenBxVersion(capturedHeaders["bx-v"]);
|
|
5496
|
+
}
|
|
5165
5497
|
markAccountHeadersReady(accountId);
|
|
5166
5498
|
cache.lastRefresh = Date.now();
|
|
5167
5499
|
cookieCaches.delete(accountId);
|
|
@@ -5907,6 +6239,7 @@ var init_auth_playwright = __esm({
|
|
|
5907
6239
|
init_errors();
|
|
5908
6240
|
init_accounts();
|
|
5909
6241
|
init_config();
|
|
6242
|
+
init_qwen_headers();
|
|
5910
6243
|
init_playwright();
|
|
5911
6244
|
init_jwt();
|
|
5912
6245
|
}
|
|
@@ -6072,6 +6405,7 @@ var init_qwen_chat_pool = __esm({
|
|
|
6072
6405
|
init_config();
|
|
6073
6406
|
init_logger();
|
|
6074
6407
|
init_account_manager();
|
|
6408
|
+
init_waf_isolation();
|
|
6075
6409
|
init_model_alias();
|
|
6076
6410
|
init_qwen_url();
|
|
6077
6411
|
init_qwen_errors();
|