admin area

This commit is contained in:
2026-01-01 12:10:35 +01:00
parent 02c0cc44e1
commit f001df3744
68 changed files with 10324 additions and 32 deletions

View File

@@ -0,0 +1,105 @@
/**
* Blocker: AuthorizationBlocker
*
* Frontend blocker that prevents unauthorized access to admin features.
* This is a UX improvement, NOT a security mechanism.
* Security is enforced by backend Guards.
*/
import { Blocker } from './Blocker';
import type { SessionViewModel } from '@/lib/view-models/SessionViewModel';
export type AuthorizationBlockReason =
| 'loading' // User data not loaded yet
| 'unauthenticated' // User not logged in
| 'unauthorized' // User logged in but lacks required role
| 'insufficient_role' // User has role but not high enough
| 'enabled'; // Access granted
export class AuthorizationBlocker extends Blocker {
private currentSession: SessionViewModel | null = null;
private requiredRoles: string[] = [];
constructor(requiredRoles: string[]) {
super();
this.requiredRoles = requiredRoles;
}
/**
* Update the current session state
*/
updateSession(session: SessionViewModel | null): void {
this.currentSession = session;
}
/**
* Check if user can execute (access admin area)
*/
canExecute(): boolean {
return this.getReason() === 'enabled';
}
/**
* Get the current block reason
*/
getReason(): AuthorizationBlockReason {
if (!this.currentSession) {
return 'loading';
}
if (!this.currentSession.isAuthenticated) {
return 'unauthenticated';
}
// Note: SessionViewModel doesn't currently have role property
// This is a known architectural gap. For now, we'll check if
// the user has admin capabilities through other means
// In a real implementation, we would need to:
// 1. Add role to SessionViewModel
// 2. Add role to AuthenticatedUserDTO
// 3. Add role to User entity
// For now, we'll simulate based on email or other indicators
// This is a temporary workaround until the backend role system is implemented
return 'enabled'; // Allow access for demo purposes
}
/**
* Block access (for testing/demo purposes)
*/
block(): void {
// Simulate blocking by setting session to null
this.currentSession = null;
}
/**
* Release the block
*/
release(): void {
// No-op - blocking is state-based, not persistent
}
/**
* Get user-friendly message for block reason
*/
getBlockMessage(): string {
const reason = this.getReason();
switch (reason) {
case 'loading':
return 'Loading user data...';
case 'unauthenticated':
return 'You must be logged in to access the admin area.';
case 'unauthorized':
return 'You do not have permission to access the admin area.';
case 'insufficient_role':
return `Admin access requires one of: ${this.requiredRoles.join(', ')}`;
case 'enabled':
return 'Access granted';
default:
return 'Access denied';
}
}
}