first commit

This commit is contained in:
lendry
2026-06-24 14:37:15 +03:00
commit 995adeedd4
188 changed files with 28810 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
import { CanActivate, ExecutionContext, ForbiddenException, Injectable, UnauthorizedException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { firstValueFrom } from 'rxjs';
import { CoreGrpcService } from '../core-grpc.service';
import { assertSessionUnlocked, verifyAccessToken } from '../session-auth';
export interface AdminRequestUser {
id: string;
isSuperAdmin: boolean;
canAccessAdmin: boolean;
canManageRoles: boolean;
canManageOAuth: boolean;
canManageUsers: boolean;
canViewUsers: boolean;
canManageSettings: boolean;
roles: string[];
permissions: string[];
}
@Injectable()
export class AdminGuard implements CanActivate {
constructor(
private readonly jwt: JwtService,
private readonly core: CoreGrpcService
) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest<{ headers: { authorization?: string }; adminUser?: AdminRequestUser }>();
let payload;
try {
payload = await verifyAccessToken(this.jwt, request.headers.authorization);
await assertSessionUnlocked(this.core, payload);
} catch (error) {
if (error instanceof UnauthorizedException || error instanceof ForbiddenException) {
throw error;
}
throw new UnauthorizedException('Недействительный токен доступа');
}
const profile = (await firstValueFrom(this.core.auth.GetMe({ userId: payload.sub }))) as AdminRequestUser & { id: string };
if (!profile.canAccessAdmin) {
throw new ForbiddenException('Доступ к админ-панели запрещён');
}
request.adminUser = {
id: profile.id,
isSuperAdmin: profile.isSuperAdmin,
canAccessAdmin: Boolean(profile.canAccessAdmin),
canManageRoles: Boolean(profile.canManageRoles),
canManageOAuth: Boolean(profile.canManageOAuth),
canManageUsers: Boolean(profile.canManageUsers),
canManageSettings: Boolean(profile.canManageSettings),
canViewUsers: Boolean(profile.canViewUsers),
roles: profile.roles ?? [],
permissions: profile.permissions ?? []
};
return true;
}
}
@Injectable()
export class SuperAdminGuard implements CanActivate {
canActivate(context: ExecutionContext): boolean {
const request = context.switchToHttp().getRequest<{ adminUser?: AdminRequestUser }>();
if (!request.adminUser?.isSuperAdmin) {
throw new ForbiddenException('Только супер-администратор может выполнять это действие');
}
return true;
}
}
export function assertAdminPermission(user: AdminRequestUser | undefined, permission: keyof Pick<AdminRequestUser, 'canManageOAuth' | 'canManageUsers' | 'canManageSettings'>) {
if (!user?.[permission]) {
throw new ForbiddenException('Недостаточно прав для выполнения действия');
}
}