authentication authorization
This commit is contained in:
76
apps/api/src/domain/auth/AuthorizationService.ts
Normal file
76
apps/api/src/domain/auth/AuthorizationService.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
export type SystemRole = string;
|
||||
|
||||
@Injectable()
|
||||
export class AuthorizationService {
|
||||
private cache:
|
||||
| {
|
||||
rolesByUserId: Readonly<Record<string, readonly SystemRole[]>>;
|
||||
expiresAtMs: number;
|
||||
}
|
||||
| null = null;
|
||||
|
||||
getRolesForUser(userId: string): readonly SystemRole[] {
|
||||
const now = Date.now();
|
||||
if (this.cache && now < this.cache.expiresAtMs) {
|
||||
return this.cache.rolesByUserId[userId] ?? [];
|
||||
}
|
||||
|
||||
const cacheMs = parseCacheMs(process.env.GRIDPILOT_AUTHZ_CACHE_MS);
|
||||
const rolesByUserId = parseUserRolesJson(process.env.GRIDPILOT_USER_ROLES_JSON);
|
||||
|
||||
this.cache = {
|
||||
rolesByUserId,
|
||||
expiresAtMs: now + cacheMs,
|
||||
};
|
||||
|
||||
return rolesByUserId[userId] ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
function parseCacheMs(raw: string | undefined): number {
|
||||
if (!raw) {
|
||||
return 5_000;
|
||||
}
|
||||
const parsed = Number(raw);
|
||||
if (!Number.isFinite(parsed) || parsed < 0) {
|
||||
return 5_000;
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
|
||||
function parseUserRolesJson(raw: string | undefined): Readonly<Record<string, readonly SystemRole[]>> {
|
||||
if (!raw) {
|
||||
return {};
|
||||
}
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(raw) as unknown;
|
||||
if (!parsed || typeof parsed !== 'object') {
|
||||
return {};
|
||||
}
|
||||
|
||||
const record = parsed as Record<string, unknown>;
|
||||
const normalized: Record<string, readonly SystemRole[]> = {};
|
||||
|
||||
for (const [userId, roles] of Object.entries(record)) {
|
||||
if (!userId || !Array.isArray(roles)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const cleaned = roles
|
||||
.filter((v) => typeof v === 'string')
|
||||
.map((v) => v.trim())
|
||||
.filter(Boolean);
|
||||
|
||||
if (cleaned.length > 0) {
|
||||
normalized[userId] = cleaned;
|
||||
}
|
||||
}
|
||||
|
||||
return normalized;
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user