69 lines
2.1 KiB
TypeScript
69 lines
2.1 KiB
TypeScript
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
|
|
import { Reflector } from '@nestjs/core';
|
|
import { ApiError } from '../../common/errors/api-error';
|
|
import { ErrorCode } from '../../common/errors/error-codes';
|
|
import { AppConfigService } from '../../config/config.service';
|
|
import { SessionsService } from '../../sessions/sessions.service';
|
|
import type { Permission } from '../../roles/permissions';
|
|
import { IS_PUBLIC_KEY } from './public.decorator';
|
|
import { REQUIRED_PERMISSIONS_KEY } from './require-permissions.decorator';
|
|
import type { AuthenticatedRequest } from '../authenticated-request';
|
|
|
|
@Injectable()
|
|
export class PermissionsGuard implements CanActivate {
|
|
constructor(
|
|
private readonly reflector: Reflector,
|
|
private readonly sessions: SessionsService,
|
|
private readonly config: AppConfigService,
|
|
) {}
|
|
|
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
|
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
|
|
context.getHandler(),
|
|
context.getClass(),
|
|
]);
|
|
const required = this.reflector.getAllAndOverride<Permission[]>(
|
|
REQUIRED_PERMISSIONS_KEY,
|
|
[context.getHandler(), context.getClass()],
|
|
);
|
|
if (isPublic || !required?.length) {
|
|
return true;
|
|
}
|
|
|
|
const request = context.switchToHttp().getRequest<AuthenticatedRequest>();
|
|
const sessionId = request.signedCookies?.[
|
|
this.config.session.cookieName
|
|
] as string | undefined;
|
|
if (!sessionId) {
|
|
throw new ApiError(
|
|
ErrorCode.Unauthorized,
|
|
'Bitte melden Sie sich an.',
|
|
401,
|
|
);
|
|
}
|
|
|
|
const session = await this.sessions.resolveSession(
|
|
sessionId,
|
|
request.ip,
|
|
request.get('user-agent'),
|
|
);
|
|
request.user = {
|
|
id: session.user.id,
|
|
sessionId,
|
|
permissions: session.permissions,
|
|
};
|
|
|
|
const allowed = required.every((permission) =>
|
|
session.permissions.includes(permission),
|
|
);
|
|
if (!allowed) {
|
|
throw new ApiError(
|
|
ErrorCode.PermissionDenied,
|
|
'Keine Berechtigung fuer diese Aktion.',
|
|
403,
|
|
);
|
|
}
|
|
return true;
|
|
}
|
|
}
|