qwenproxy-cli 1.3.1 → 1.3.2
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/package.json +1 -1
- package/src/services/playwright.ts +72 -72
- package/src/services/qwen.ts +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qwenproxy-cli",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
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": {
|
|
@@ -1889,94 +1889,94 @@ async function loginViaApi(
|
|
|
1889
1889
|
.digest("hex");
|
|
1890
1890
|
const signinUrl = qwenUrl("/api/v2/auths/signin");
|
|
1891
1891
|
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
}
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1892
|
+
let signinSuccess = false;
|
|
1893
|
+
let data: any = null;
|
|
1894
|
+
|
|
1895
|
+
if (page.request && typeof page.request.post === "function") {
|
|
1896
|
+
try {
|
|
1897
|
+
const response = await page.request.post(signinUrl, {
|
|
1898
|
+
data: {
|
|
1899
|
+
email,
|
|
1900
|
+
password: hashedPassword,
|
|
1901
|
+
login_type: "email",
|
|
1902
|
+
},
|
|
1903
|
+
headers: {
|
|
1904
|
+
"content-type": "application/json",
|
|
1905
|
+
accept: "application/json, text/plain, */*",
|
|
1906
|
+
referer: qwenUrl("/auth"),
|
|
1907
|
+
origin: qwenOrigin(),
|
|
1908
|
+
},
|
|
1909
|
+
timeout: 10_000,
|
|
1910
|
+
});
|
|
1911
|
+
data = await response.json().catch(() => null);
|
|
1912
|
+
signinSuccess = Boolean(data && (data.success === true || data.token));
|
|
1913
|
+
} catch {}
|
|
1914
|
+
}
|
|
1915
|
+
|
|
1916
|
+
if (!signinSuccess && !data) {
|
|
1917
|
+
// Fallback to in-page evaluate fetch if page.request was unavailable
|
|
1918
|
+
const requestId = crypto.randomUUID();
|
|
1919
|
+
const evalRes = await page
|
|
1920
|
+
.evaluate(
|
|
1921
|
+
async ({ email, password, signinUrl, requestId }) => {
|
|
1912
1922
|
try {
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1923
|
+
const response = await fetch(signinUrl, {
|
|
1924
|
+
method: "POST",
|
|
1925
|
+
signal: AbortSignal.timeout(10_000),
|
|
1926
|
+
credentials: "include",
|
|
1927
|
+
headers: {
|
|
1928
|
+
accept: "application/json, text/plain, */*",
|
|
1929
|
+
"content-type": "application/json",
|
|
1930
|
+
source: "web",
|
|
1931
|
+
timezone: new Date().toString().split(" (")[0],
|
|
1932
|
+
"x-request-id": requestId,
|
|
1933
|
+
},
|
|
1934
|
+
body: JSON.stringify({ email, password, login_type: "email" }),
|
|
1935
|
+
});
|
|
1936
|
+
const json = await response.json().catch(() => null);
|
|
1937
|
+
return { ok: response.ok, status: response.status, data: json };
|
|
1938
|
+
} catch (e: any) {
|
|
1939
|
+
return { ok: false, error: e.message };
|
|
1940
|
+
}
|
|
1941
|
+
},
|
|
1942
|
+
{ email, password: hashedPassword, signinUrl, requestId },
|
|
1943
|
+
)
|
|
1944
|
+
.catch(() => null);
|
|
1924
1945
|
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
.goto(qwenUrl("/"), {
|
|
1929
|
-
waitUntil: "domcontentloaded",
|
|
1930
|
-
timeout: config.timeouts.navigation,
|
|
1931
|
-
})
|
|
1932
|
-
.catch(() => {});
|
|
1933
|
-
await sleep(1000);
|
|
1934
|
-
const url = page.url();
|
|
1935
|
-
const isLogged = !(url.includes("/auth") || url.includes("/login"));
|
|
1936
|
-
if (isLogged) {
|
|
1937
|
-
return { success: true };
|
|
1938
|
-
}
|
|
1939
|
-
const loggedIn = await isPageLoggedIn(page);
|
|
1940
|
-
if (loggedIn) {
|
|
1941
|
-
return { success: true };
|
|
1942
|
-
}
|
|
1943
|
-
} else if (result.data.success === false) {
|
|
1944
|
-
const code = result.data?.data?.code || result.data?.code;
|
|
1945
|
-
const details =
|
|
1946
|
-
result.data?.data?.details ||
|
|
1947
|
-
result.data?.details ||
|
|
1948
|
-
result.data?.message;
|
|
1949
|
-
const classified = classifyQwenAuthError(code, details);
|
|
1950
|
-
return {
|
|
1951
|
-
success: false,
|
|
1952
|
-
permanentFailure: classified.isPermanent,
|
|
1953
|
-
reason: classified.reason,
|
|
1954
|
-
};
|
|
1946
|
+
if (evalRes?.data) {
|
|
1947
|
+
data = evalRes.data;
|
|
1948
|
+
signinSuccess = Boolean(data && (data.success === true || data.token));
|
|
1955
1949
|
}
|
|
1956
1950
|
}
|
|
1957
1951
|
|
|
1958
|
-
if (
|
|
1952
|
+
if (data?.success === false) {
|
|
1953
|
+
const code = data?.data?.code || data?.code;
|
|
1954
|
+
const details = data?.data?.details || data?.details || data?.message;
|
|
1955
|
+
const classified = classifyQwenAuthError(code, details);
|
|
1956
|
+
return {
|
|
1957
|
+
success: false,
|
|
1958
|
+
permanentFailure: classified.isPermanent,
|
|
1959
|
+
reason: classified.reason,
|
|
1960
|
+
};
|
|
1961
|
+
}
|
|
1962
|
+
|
|
1963
|
+
if (signinSuccess) {
|
|
1959
1964
|
await page
|
|
1960
1965
|
.goto(qwenUrl("/"), {
|
|
1961
1966
|
waitUntil: "domcontentloaded",
|
|
1962
1967
|
timeout: config.timeouts.navigation,
|
|
1963
1968
|
})
|
|
1964
1969
|
.catch(() => {});
|
|
1965
|
-
await sleep(
|
|
1966
|
-
const
|
|
1967
|
-
|
|
1968
|
-
if (isLogged) {
|
|
1970
|
+
await sleep(1500);
|
|
1971
|
+
const loggedIn = await isPageLoggedIn(page, 4_000);
|
|
1972
|
+
if (loggedIn) {
|
|
1969
1973
|
return { success: true };
|
|
1970
1974
|
}
|
|
1971
|
-
const loggedIn = await isPageLoggedIn(page);
|
|
1972
|
-
return {
|
|
1973
|
-
success: loggedIn,
|
|
1974
|
-
reason: loggedIn ? undefined : "Sessão não autenticada após signin",
|
|
1975
|
-
};
|
|
1976
1975
|
}
|
|
1976
|
+
|
|
1977
1977
|
return {
|
|
1978
1978
|
success: false,
|
|
1979
|
-
reason:
|
|
1979
|
+
reason: "API signin não confirmou sessão autenticada",
|
|
1980
1980
|
};
|
|
1981
1981
|
} catch (err: any) {
|
|
1982
1982
|
const errMsg = err?.message || String(err);
|
package/src/services/qwen.ts
CHANGED
|
@@ -985,12 +985,12 @@ export async function requestQwenSettingsDirectFetch(
|
|
|
985
985
|
// passes the WAF.
|
|
986
986
|
let json: any = null;
|
|
987
987
|
let okShape = false;
|
|
988
|
-
if (contentType.includes("html")) {
|
|
988
|
+
if (contentType.includes("html") || !response.ok) {
|
|
989
989
|
okShape = false;
|
|
990
990
|
} else {
|
|
991
991
|
try {
|
|
992
992
|
json = JSON.parse(raw);
|
|
993
|
-
okShape = json && typeof json === "object" &&
|
|
993
|
+
okShape = json && typeof json === "object" && json.success === true;
|
|
994
994
|
} catch {
|
|
995
995
|
okShape = false;
|
|
996
996
|
}
|