feat(auth): matrice permessi 3 ruoli + landingFor

This commit is contained in:
2026-07-05 21:44:30 +02:00
parent 5cea895d51
commit e87a464090
2 changed files with 69 additions and 27 deletions
+20 -4
View File
@@ -5,7 +5,7 @@ import { randomBytes } from 'node:crypto';
export const SESSION_COOKIE = 'session';
const SESSION_DAYS = 7;
export type Role = 'admin' | 'editor';
export type Role = 'admin' | 'superuser' | 'user';
export function hashPassword(plain: string): string {
return bcrypt.hashSync(plain, 12);
@@ -49,10 +49,26 @@ export function logout(db: Database.Database, token: string): void {
db.prepare('DELETE FROM sessions WHERE token = ?').run(token);
}
// Percorsi admin consentiti anche al ruolo editor.
const EDITOR_ALLOWED = [/^\/admin\/content(\/|$)/, /^\/api\/admin\/content(\/|$)/, /^\/admin\/logout$/];
// Autorizzazione per prefisso di rotta. L'admin passa sempre; per gli altri, la prima regola
// che matcha decide; se nessuna regola matcha la rotta è "blog/upload/logout" → consentita a
// qualsiasi loggato (il middleware protegge solo /admin e /api/admin, quindi qui arrivano solo
// utenti già autenticati).
const RULES: [RegExp, Role[]][] = [
[/^\/admin\/users(\/|$)/, ['admin']],
[/^\/api\/admin\/users(\/|$)/, ['admin']],
[/^\/admin\/content(\/|$)/, ['admin', 'superuser']],
[/^\/api\/admin\/content(\/|$)/, ['admin', 'superuser']],
];
export function canAccessAdminPath(role: string, pathname: string): boolean {
if (role === 'admin') return true;
return EDITOR_ALLOWED.some((re) => re.test(pathname));
for (const [re, roles] of RULES) {
if (re.test(pathname)) return roles.includes(role as Role);
}
return true; // blog, upload, logout, showtags: tutti i loggati
}
export function landingFor(role: string): string {
if (role === 'superuser') return '/admin/content';
return '/admin';
}