Feat: Enable admin password in admin mode (#540)

* WIP: save local changes before merging

* Enable admin password in admin mode #374
This commit is contained in:
Burt
2025-11-05 21:48:28 +08:00
committed by GitHub
parent 87a834c4f5
commit 5f98e09920
13 changed files with 421 additions and 91 deletions

View File

@@ -18,6 +18,12 @@ interface AuthContextType {
userID?: string
requiresOTP?: boolean
}>
loginAdmin: (
password: string
) => Promise<{
success: boolean;
message?: string
}>;
register: (
email: string,
password: string,
@@ -56,21 +62,15 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
useEffect(() => {
// 先检查是否为管理员模式(使用带缓存的系统配置获取)
getSystemConfig()
.then((data) => {
if (data.admin_mode) {
// 管理员模式下模拟admin用户
setUser({ id: 'admin', email: 'admin@localhost' })
setToken('admin-mode')
} else {
// 非管理员模式检查本地存储中是否有token
const savedToken = localStorage.getItem('auth_token')
const savedUser = localStorage.getItem('auth_user')
if (savedToken && savedUser) {
setToken(savedToken)
setUser(JSON.parse(savedUser))
}
.then(() => {
// 不再在管理员模式下模拟登录;统一检查本地存储
const savedToken = localStorage.getItem('auth_token');
const savedUser = localStorage.getItem('auth_user');
if (savedToken && savedUser) {
setToken(savedToken);
setUser(JSON.parse(savedUser));
}
setIsLoading(false)
})
.catch((err) => {
@@ -118,6 +118,32 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
return { success: false, message: '未知错误' }
}
const loginAdmin = async (password: string) => {
try {
const response = await fetch('/api/admin-login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ password }),
});
const data = await response.json();
if (response.ok) {
const userInfo = { id: data.user_id || 'admin', email: data.email || 'admin@localhost' };
setToken(data.token);
setUser(userInfo);
localStorage.setItem('auth_token', data.token);
localStorage.setItem('auth_user', JSON.stringify(userInfo));
// 跳转到仪表盘
window.history.pushState({}, '', '/dashboard');
window.dispatchEvent(new PopStateEvent('popstate'));
return { success: true };
} else {
return { success: false, message: data.error || '登录失败' };
}
} catch (e) {
return { success: false, message: '登录失败,请重试' };
}
};
const register = async (
email: string,
password: string,
@@ -256,6 +282,13 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
}
const logout = () => {
const savedToken = localStorage.getItem('auth_token');
if (savedToken) {
fetch('/api/logout', {
method: 'POST',
headers: { 'Authorization': `Bearer ${savedToken}` },
}).catch(() => {/* ignore network errors on logout */});
}
setUser(null)
setToken(null)
localStorage.removeItem('auth_token')
@@ -268,6 +301,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
user,
token,
login,
loginAdmin,
register,
verifyOTP,
completeRegistration,