sync: 鍚屾灞€鍩熺綉鏈€鏂颁唬鐮?(source master @ b69568e4)

This commit is contained in:
gozeros committed 2026-10-21 14:51:31 +08:00
1 parent 4f7f07504a
commit 8bc8b0e082
1651 files changed
+278599 -11416

No files matched your search

+79
View File
@@ -0,0 +1,79 @@
import { apiFetch } from "@/core/api/fetch-client";
import { getBackendBaseURL } from "@/core/config";
import type { LoginByUsernameResponse } from "./index";
export interface AuthenticationOptions {
password_login_enabled: boolean;
registration_enabled: boolean;
sso_enabled: boolean;
single_session_enabled?: boolean;
needs_setup?: boolean;
}
function accountError(body: unknown, fallback: string): string {
const detail = (body as { detail?: unknown } | null)?.detail ?? body;
if (typeof detail === "string") return detail;
if (Array.isArray(detail)) {
return detail.map((item) => item?.msg).filter(Boolean).join(";") || fallback;
}
if (detail && typeof detail === "object") {
const value = detail as { message?: string; msg?: string };
return value.message || value.msg || fallback;
}
return fallback;
}
/** Bound unauthenticated requests so an unreachable gateway offers a retry. */
async function accountRequest<T>(path: string, init: RequestInit = {}): Promise<T> {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 20_000);
try {
const response = await apiFetch(`${getBackendBaseURL()}/api/v1/auth${path}`, {
...init,
signal: controller.signal,
});
const body: unknown = await response.json().catch(() => null);
if (!response.ok) throw new Error(accountError(body, "请求失败,请稍后重试"));
return body as T;
} catch (error) {
if (controller.signal.aborted) throw new Error("连接超时,请检查网络后重试");
if (error instanceof TypeError) throw new Error("无法连接服务器,请检查网络后重试");
throw error;
} finally {
clearTimeout(timer);
}
}
export async function fetchAuthenticationOptions(): Promise<AuthenticationOptions> {
const options = await accountRequest<AuthenticationOptions>("/options", { cache: "no-store" });
if (!options || [options.password_login_enabled, options.registration_enabled, options.sso_enabled]
.some((value) => typeof value !== "boolean")) {
throw new Error("无法读取登录设置,请联系管理员或重试");
}
return options;
}
export function loginWithPassword(username: string, password: string): Promise<LoginByUsernameResponse> {
return accountRequest("/login/local", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({ username, password }),
});
}
export function registerAccount(username: string, password: string): Promise<LoginByUsernameResponse> {
return accountRequest("/register", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username, password }),
});
}
export function initializeAdministrator(email: string, password: string): Promise<LoginByUsernameResponse> {
return accountRequest<LoginByUsernameResponse>("/initialize", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, password }),
});
}