fix: Rollenhierarchie domain_admin/superadmin in Frontend
- useAuth: neue Rollen domain_admin/superadmin + hasRole() helper - Admin-Page: useAuth(domain_admin), isSuperAdmin-Flag - Tabs LDAP/Security/Mandanten/Module nur für superadmin - Navbar: Admin-Link für domain_admin + superadmin sichtbar - User-Anlage: domain_admin-Rolle wählbar, superadmin nur für superadmin Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -89,7 +89,8 @@ function formatBytes(bytes: number): string {
|
||||
}
|
||||
|
||||
export default function AdminPage() {
|
||||
const { user, loading: authLoading } = useAuth("admin");
|
||||
const { user, loading: authLoading } = useAuth("domain_admin");
|
||||
const isSuperAdmin = user?.role === "superadmin";
|
||||
|
||||
// Dashboard state
|
||||
const [smtpStatus, setSmtpStatus] = useState<SMTPStatus | null>(null);
|
||||
@@ -620,10 +621,10 @@ export default function AdminPage() {
|
||||
<TabsTrigger value="users">Benutzer</TabsTrigger>
|
||||
<TabsTrigger value="audit">Audit-Log</TabsTrigger>
|
||||
<TabsTrigger value="import">Import</TabsTrigger>
|
||||
<TabsTrigger value="ldap" onClick={loadLDAP}>LDAP</TabsTrigger>
|
||||
<TabsTrigger value="security">Security</TabsTrigger>
|
||||
<TabsTrigger value="tenants" onClick={loadTenants}>Mandanten</TabsTrigger>
|
||||
<TabsTrigger value="modules">Module</TabsTrigger>
|
||||
{isSuperAdmin && <TabsTrigger value="ldap" onClick={loadLDAP}>LDAP</TabsTrigger>}
|
||||
{isSuperAdmin && <TabsTrigger value="security">Security</TabsTrigger>}
|
||||
{isSuperAdmin && <TabsTrigger value="tenants" onClick={loadTenants}>Mandanten</TabsTrigger>}
|
||||
{isSuperAdmin && <TabsTrigger value="modules">Module</TabsTrigger>}
|
||||
</TabsList>
|
||||
|
||||
{/* ── Dashboard ── */}
|
||||
@@ -1166,7 +1167,8 @@ export default function AdminPage() {
|
||||
<SelectContent>
|
||||
<SelectItem value="user">User</SelectItem>
|
||||
<SelectItem value="auditor">Auditor</SelectItem>
|
||||
<SelectItem value="admin">Admin</SelectItem>
|
||||
<SelectItem value="domain_admin">Domain Admin</SelectItem>
|
||||
{isSuperAdmin && <SelectItem value="superadmin">Superadmin</SelectItem>}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
@@ -17,7 +17,7 @@ function formatBytes(bytes: number): string {
|
||||
}
|
||||
|
||||
export default function UploadPage() {
|
||||
const { user, loading: authLoading } = useAuth("admin");
|
||||
const { user, loading: authLoading } = useAuth("domain_admin");
|
||||
|
||||
const [dragOver, setDragOver] = useState(false);
|
||||
const [selectedFiles, setSelectedFiles] = useState<File[]>([]);
|
||||
|
||||
@@ -54,7 +54,7 @@ export function Navbar({ username, role }: NavbarProps) {
|
||||
>
|
||||
POP3 Import
|
||||
</Link>
|
||||
{role === "admin" && (
|
||||
{(role === "admin" || role === "domain_admin" || role === "superadmin") && (
|
||||
<Link
|
||||
href="/admin"
|
||||
className="text-sm text-muted-foreground hover:text-foreground transition-colors"
|
||||
|
||||
+16
-11
@@ -7,7 +7,20 @@ import { getCachedUser, setCachedUser } from "@/lib/auth-cache";
|
||||
|
||||
export { clearAuthCache } from "@/lib/auth-cache";
|
||||
|
||||
export function useAuth(requireRole?: "admin" | "auditor") {
|
||||
// Role hierarchy: superadmin(5) > domain_admin(4) > admin(3) > auditor(2) > user(1)
|
||||
const roleLevels: Record<string, number> = {
|
||||
user: 1,
|
||||
auditor: 2,
|
||||
admin: 3,
|
||||
domain_admin: 4,
|
||||
superadmin: 5,
|
||||
};
|
||||
|
||||
export function hasRole(userRole: string, required: string): boolean {
|
||||
return (roleLevels[userRole] ?? 0) >= (roleLevels[required] ?? 0);
|
||||
}
|
||||
|
||||
export function useAuth(requireRole?: "admin" | "domain_admin" | "superadmin" | "auditor") {
|
||||
const router = useRouter();
|
||||
const cached = getCachedUser();
|
||||
const [user, setUser] = useState(cached);
|
||||
@@ -16,11 +29,7 @@ export function useAuth(requireRole?: "admin" | "auditor") {
|
||||
const checkAuth = useCallback(async () => {
|
||||
const cached = getCachedUser();
|
||||
if (cached !== null) {
|
||||
if (requireRole === "admin" && cached.role !== "admin") {
|
||||
router.replace("/search");
|
||||
return;
|
||||
}
|
||||
if (requireRole === "auditor" && cached.role !== "auditor" && cached.role !== "admin") {
|
||||
if (requireRole && !hasRole(cached.role, requireRole)) {
|
||||
router.replace("/search");
|
||||
return;
|
||||
}
|
||||
@@ -32,11 +41,7 @@ export function useAuth(requireRole?: "admin" | "auditor") {
|
||||
try {
|
||||
const me = await getMe();
|
||||
setCachedUser(me);
|
||||
if (requireRole === "admin" && me.role !== "admin") {
|
||||
router.replace("/search");
|
||||
return;
|
||||
}
|
||||
if (requireRole === "auditor" && me.role !== "auditor" && me.role !== "admin") {
|
||||
if (requireRole && !hasRole(me.role, requireRole)) {
|
||||
router.replace("/search");
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user