feat(auth): wire permission gating through menu, routes and actions
The store's can()/useCan() helpers existed but were unused. Now: - src/auth/permissions.ts PERM catalog mirrors backend keys - every nav item carries a permission; sidebar filter reuses can() - requirePermission() beforeLoad guard on all child routes (direct URLs redirect home when the session lacks the key) - useCan() hides/disables mutation buttons: moderation actions, retranslate, robot-author edit/pause, category + locale CRUD, and the reserved-SID assign path (admin:sid:override hint) - 403 responses toast 无权限执行此操作; can() unit tests added Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import { createFileRoute } from '@tanstack/react-router'
|
||||
import { PERM, requirePermission } from '@/auth/permissions'
|
||||
import { useCan } from '@/auth/store'
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import { useState } from 'react'
|
||||
import { Plus, Trash2 } from 'lucide-react'
|
||||
@@ -26,6 +28,7 @@ import { Switch } from '@/components/ui/switch'
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
|
||||
|
||||
export const Route = createFileRoute('/_authed/sid')({
|
||||
beforeLoad: () => requirePermission(PERM.SID_MANAGE),
|
||||
component: SidPage,
|
||||
})
|
||||
|
||||
@@ -190,6 +193,7 @@ function LuckyTab() {
|
||||
}
|
||||
|
||||
function AssignTab() {
|
||||
const canOverride = useCan(PERM.SID_OVERRIDE)
|
||||
const [sid, setSid] = useState('')
|
||||
const [checkResult, setCheckResult] = useState<SidCheckResult | null>(null)
|
||||
const [userUid, setUserUid] = useState('')
|
||||
@@ -254,6 +258,11 @@ function AssignTab() {
|
||||
可分配
|
||||
</Badge>
|
||||
)}
|
||||
{checkResult.reserved && !canOverride && (
|
||||
<p className="mt-1 text-xs text-muted-foreground">
|
||||
分配保留号段需要 admin:sid:override 权限
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<div className="grid gap-1.5">
|
||||
@@ -266,7 +275,10 @@ function AssignTab() {
|
||||
placeholder="01JXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
/>
|
||||
</div>
|
||||
<Button onClick={assign} disabled={!sid || !userUid || busy}>
|
||||
<Button
|
||||
onClick={assign}
|
||||
disabled={!sid || !userUid || busy || (checkResult?.reserved === true && !canOverride)}
|
||||
>
|
||||
分配 SID
|
||||
</Button>
|
||||
</CardContent>
|
||||
|
||||
Reference in New Issue
Block a user