import {CanActivate, ExecutionContext, Injectable} from "@nestjs/common"; import {Reflector} from "@nestjs/core"; import {AppAbility, PermissionsService} from "@gitroom/backend/services/auth/permissions/permissions.service"; import {AbilityPolicy, CHECK_POLICIES_KEY} from "@gitroom/backend/services/auth/permissions/permissions.ability"; import {Organization} from "@prisma/client"; import {SubscriptionException} from "@gitroom/backend/services/auth/permissions/subscription.exception"; import {Request} from "express"; @Injectable() export class PoliciesGuard implements CanActivate { constructor( private _reflector: Reflector, private _authorizationService: PermissionsService, ) {} async canActivate(context: ExecutionContext): Promise { const request: Request = context.switchToHttp().getRequest(); if (request.path.indexOf('/auth') > -1 || request.path.indexOf('/stripe') > -1) { return true; } const policyHandlers = this._reflector.get( CHECK_POLICIES_KEY, context.getHandler(), ) || []; if (!policyHandlers || !policyHandlers.length) { return true; } // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error const { org } : {org: Organization} = request; // @ts-ignore const ability = await this._authorizationService.check(org.id, org.createdAt, org.users[0].role, policyHandlers); const item = policyHandlers.find((handler) => !this.execPolicyHandler(handler, ability), ); if (item) { throw new SubscriptionException({ section: item[1], action: item[0] }); } return true; } private execPolicyHandler(handler: AbilityPolicy, ability: AppAbility) { return ability.can(handler[0], handler[1]); } }