import { ForbiddenException } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; import { firstValueFrom } from 'rxjs'; import { CoreGrpcService } from './core-grpc.service'; import { assertSessionUnlocked, verifyAccessToken } from './session-auth'; interface RequesterProfile { id: string; isSuperAdmin: boolean; canViewUserDocuments?: boolean; } async function getRequesterProfile(jwt: JwtService, core: CoreGrpcService, authorization?: string): Promise { const payload = await verifyAccessToken(jwt, authorization); await assertSessionUnlocked(core, payload); if (payload.isSuperAdmin) { return { id: payload.sub, isSuperAdmin: true, canViewUserDocuments: true }; } const profile = (await firstValueFrom(core.auth.GetMe({ userId: payload.sub }))) as RequesterProfile & { id: string }; return { id: profile.id, isSuperAdmin: profile.isSuperAdmin, canViewUserDocuments: profile.canViewUserDocuments }; } export async function assertDocumentsReadAccess( jwt: JwtService, core: CoreGrpcService, authorization: string | undefined, targetUserId: string ) { const requester = await getRequesterProfile(jwt, core, authorization); if (requester.id === targetUserId) { return requester.id; } if (!requester.canViewUserDocuments && !requester.isSuperAdmin) { throw new ForbiddenException('Нет доступа к документам пользователя'); } return requester.id; } export async function assertDocumentsWriteAccess( jwt: JwtService, core: CoreGrpcService, authorization: string | undefined, targetUserId: string ) { const requester = await getRequesterProfile(jwt, core, authorization); if (requester.id !== targetUserId) { throw new ForbiddenException('Нельзя изменять документы другого пользователя'); } return requester.id; } export async function getAuthorizedUserId(jwt: JwtService, core: CoreGrpcService, authorization?: string) { const requester = await getRequesterProfile(jwt, core, authorization); return requester.id; }