添加账号修改,后台管理
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import React, { createContext, useContext, useEffect, useState } from 'react';
|
||||
|
||||
import { apiRequest } from '@/src/lib/api';
|
||||
import { fetchAdminAccessStatus } from './admin-access';
|
||||
import {
|
||||
clearStoredSession,
|
||||
createSession,
|
||||
@@ -19,6 +20,7 @@ interface AuthContextValue {
|
||||
ready: boolean;
|
||||
session: AuthSession | null;
|
||||
user: UserProfile | null;
|
||||
isAdmin: boolean;
|
||||
login: (payload: LoginPayload) => Promise<void>;
|
||||
devLogin: (username?: string) => Promise<void>;
|
||||
logout: () => void;
|
||||
@@ -34,6 +36,7 @@ function buildSession(auth: AuthResponse): AuthSession {
|
||||
export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
const [session, setSession] = useState<AuthSession | null>(() => readStoredSession());
|
||||
const [ready, setReady] = useState(false);
|
||||
const [isAdmin, setIsAdmin] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const syncSession = () => {
|
||||
@@ -93,6 +96,36 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
let active = true;
|
||||
|
||||
async function syncAdminAccess() {
|
||||
if (!session?.token) {
|
||||
if (active) {
|
||||
setIsAdmin(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const allowed = await fetchAdminAccessStatus();
|
||||
if (active) {
|
||||
setIsAdmin(allowed);
|
||||
}
|
||||
} catch {
|
||||
if (active) {
|
||||
setIsAdmin(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
syncAdminAccess();
|
||||
|
||||
return () => {
|
||||
active = false;
|
||||
};
|
||||
}, [session?.token]);
|
||||
|
||||
async function refreshProfile() {
|
||||
const currentSession = readStoredSession();
|
||||
if (!currentSession) {
|
||||
@@ -146,6 +179,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
ready,
|
||||
session,
|
||||
user: session?.user || null,
|
||||
isAdmin,
|
||||
login,
|
||||
devLogin,
|
||||
logout,
|
||||
|
||||
28
front/src/auth/admin-access.test.ts
Normal file
28
front/src/auth/admin-access.test.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import { ApiError } from '@/src/lib/api';
|
||||
|
||||
import { fetchAdminAccessStatus } from './admin-access';
|
||||
|
||||
test('fetchAdminAccessStatus returns true when the admin summary request succeeds', async () => {
|
||||
const request = async () => ({
|
||||
totalUsers: 1,
|
||||
totalFiles: 2,
|
||||
usersWithSchoolCache: 3,
|
||||
});
|
||||
|
||||
await assert.doesNotReject(async () => {
|
||||
const allowed = await fetchAdminAccessStatus(request);
|
||||
assert.equal(allowed, true);
|
||||
});
|
||||
});
|
||||
|
||||
test('fetchAdminAccessStatus returns false when the server rejects the user with 403', async () => {
|
||||
const request = async () => {
|
||||
throw new ApiError('没有后台权限', 403);
|
||||
};
|
||||
|
||||
const allowed = await fetchAdminAccessStatus(request);
|
||||
assert.equal(allowed, false);
|
||||
});
|
||||
19
front/src/auth/admin-access.ts
Normal file
19
front/src/auth/admin-access.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { ApiError, apiRequest } from '@/src/lib/api';
|
||||
import type { AdminSummary } from '@/src/lib/types';
|
||||
|
||||
type AdminSummaryRequest = () => Promise<AdminSummary>;
|
||||
|
||||
export async function fetchAdminAccessStatus(
|
||||
request: AdminSummaryRequest = () => apiRequest<AdminSummary>('/admin/summary'),
|
||||
) {
|
||||
try {
|
||||
await request();
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (error instanceof ApiError && error.status === 403) {
|
||||
return false;
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user