feat(module-grants): Proxmox, Handelsware und DKV mit Freigabestufe Verwalten
- Proxmox-Schreibwege und Handelsware-Einstellungen auf @ModuleManage umgestellt - DKV-Fleet: ganze Klasse Verwalten-Stufe, Benutzen allein bleibt ohne Zugriff - Metadaten-Test belegt umgestellte und bewusst Administratoren vorbehaltene Handler - Webseiten (Proxmox, Handelsware, Widget) folgen canManage, DKV-Zugriffsseite erklärt die Stufe Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,24 +5,27 @@ import { cookies } from 'next/headers';
|
||||
const API_URL = process.env.API_INTERNAL_URL || process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3001';
|
||||
|
||||
/**
|
||||
* Server-side module access check for the module page route (D-07, PERM-04).
|
||||
* Server-side Freigabestufe fuer ein Modul (261002-icv): `'none'` (kein
|
||||
* Zugriff), `'use'` (Benutzen) oder `'manage'` (Verwalten).
|
||||
*
|
||||
* Reads the session cookie, forwards it to `GET /modules/active` (the same
|
||||
* ModuleAccessService.getAccessibleModuleIds resolution ModuleGuard and the
|
||||
* sidebar use — D-01), and checks whether `moduleSlug` is present in the
|
||||
* response. Mirrors `fetchCurrentUser()` in auth-actions.ts exactly: same
|
||||
* cookie-forwarding, `credentials: 'include'`, `cache: 'no-store'`.
|
||||
* Liest den Session-Cookie, leitet ihn an `GET /modules/active` weiter (die
|
||||
* gleiche ModuleAccessService-Aufloesung, die ModuleGuard und Sidebar nutzen
|
||||
* — D-01) und wertet `canManage` des Eintrags aus. Spiegelt
|
||||
* `fetchCurrentUser()` in auth-actions.ts: gleiche Cookie-Weitergabe,
|
||||
* `credentials: 'include'`, `cache: 'no-store'`.
|
||||
*
|
||||
* Fails closed (T-15-29): a missing session cookie, a non-ok API response,
|
||||
* or a thrown network error all resolve to `false`. A broken network path
|
||||
* must never open access.
|
||||
* Fails closed (T-15-29): fehlender Cookie, nicht-ok-Antwort oder ein
|
||||
* Netzwerkfehler ergeben `'none'`. Ein kaputter Netzwerkpfad darf nie
|
||||
* Zugriff oeffnen.
|
||||
*/
|
||||
export async function checkModuleAccess(moduleSlug: string): Promise<boolean> {
|
||||
export async function getModuleAccessLevel(
|
||||
moduleSlug: string,
|
||||
): Promise<'none' | 'use' | 'manage'> {
|
||||
const cookieStore = await cookies();
|
||||
const session = cookieStore.get('session')?.value;
|
||||
|
||||
if (!session) {
|
||||
return false;
|
||||
return 'none';
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -35,12 +38,27 @@ export async function checkModuleAccess(moduleSlug: string): Promise<boolean> {
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
return false;
|
||||
return 'none';
|
||||
}
|
||||
|
||||
const modules: Array<{ slug: string }> = await response.json();
|
||||
return modules.some((module) => module.slug === moduleSlug);
|
||||
const modules: Array<{ slug: string; canManage?: boolean }> = await response.json();
|
||||
const entry = modules.find((module) => module.slug === moduleSlug);
|
||||
if (!entry) {
|
||||
return 'none';
|
||||
}
|
||||
return entry.canManage === true ? 'manage' : 'use';
|
||||
} catch {
|
||||
return false;
|
||||
return 'none';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Server-side module access check for the module page route (D-07, PERM-04).
|
||||
*
|
||||
* Wahr, sobald das Modul in `GET /modules/active` vorkommt — die gleiche
|
||||
* Aufloesung wie ModuleGuard und Sidebar (D-01). Delegiert seit 261002-icv an
|
||||
* `getModuleAccessLevel` (unveraenderte Signatur). Fails closed (T-15-29).
|
||||
*/
|
||||
export async function checkModuleAccess(moduleSlug: string): Promise<boolean> {
|
||||
return (await getModuleAccessLevel(moduleSlug)) !== 'none';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user