Files
gitlab-instance-0a899031_cn…/app/lib/pocketbase/auth.ts
root 283d65d1d1 ;s
2026-06-07 12:48:17 +08:00

97 lines
2.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 认证服务 - 前端只调用 FastAPI不直连 PocketBase。
*/
import { PB_STORAGE_KEYS } from "./constants";
import { apiUrl } from "@/app/lib/api-client";
export interface AuthUser {
id: string;
email: string;
[key: string]: unknown;
}
export interface AuthResult {
token: string;
record: AuthUser;
is_new?: boolean;
provider?: string;
}
async function authRequest(path: string, body: Record<string, unknown>): Promise<AuthResult> {
const res = await fetch(apiUrl(path), {
method: "POST",
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify(body),
});
if (!res.ok) {
const err = await res.json();
throw new Error(err?.detail || err?.message || "认证失败");
}
const data = await res.json();
if (!data?.token) throw new Error("登录响应异常");
return {
token: data.token,
record: data.record,
is_new: data.is_new,
provider: data.provider,
};
}
export async function emailLogin(email: string): Promise<AuthResult> {
return authRequest("/api/auth/email", { email });
}
export async function googleLogin(idToken: string): Promise<AuthResult> {
return authRequest("/api/auth/google", { id_token: idToken });
}
export function pbSaveAuth(token: string, record: AuthUser): void {
if (typeof window === "undefined") return;
localStorage.setItem(PB_STORAGE_KEYS.token, token);
localStorage.setItem(PB_STORAGE_KEYS.user, JSON.stringify(record));
}
/** 登出 - 清除本地存储、支付订单、根域 Cookie */
export async function pbLogout(): Promise<void> {
if (typeof window === "undefined") return;
localStorage.removeItem(PB_STORAGE_KEYS.token);
localStorage.removeItem(PB_STORAGE_KEYS.user);
localStorage.removeItem("join_pay_order");
try {
document.cookie = "join_pay_order=; path=/; max-age=0";
} catch {
/* ignore */
}
try {
await fetch(apiUrl("/api/auth/logout"), { method: "POST", credentials: "include" });
} catch {
/* ignore */
}
window.dispatchEvent(new CustomEvent("auth:updated"));
}
export function getStoredUser(): AuthUser | null {
if (typeof window === "undefined") return null;
try {
const raw = localStorage.getItem(PB_STORAGE_KEYS.user);
if (!raw) return null;
const user = JSON.parse(raw);
if (!user?.id || !user?.email) return null;
return user;
} catch {
return null;
}
}
export function getStoredUserEmail(): string | null {
const user = getStoredUser();
return user?.email ?? null;
}
export function getStoredToken(): string | null {
if (typeof window === "undefined") return null;
return localStorage.getItem(PB_STORAGE_KEYS.token);
}