UNPKG

@rytass/member-base-nestjs-module

Version:

Rytass Member System NestJS Base Module

99 lines (96 loc) 4.57 kB
import { Injectable, Inject } from '@nestjs/common'; import { COOKIE_MODE, CASBIN_ENFORCER, ACCESS_TOKEN_SECRET, REFRESH_TOKEN_SECRET, ENABLE_GLOBAL_GUARD, CASBIN_PERMISSION_DECORATOR, CASBIN_PERMISSION_CHECKER } from '../typings/member-base-providers.js'; import { Reflector } from '@nestjs/core'; import { IS_ROUTE_PUBLIC } from '../decorators/is-public.decorator.js'; import { AllowActions } from '../decorators/action.decorator.js'; import { verify } from 'jsonwebtoken'; import { IS_ROUTE_ONLY_AUTHENTICATED } from '../decorators/authenticated.decorator.js'; function _ts_decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function _ts_param(paramIndex, decorator) { return function(target, key) { decorator(target, key, paramIndex); }; } class CasbinGuard { cookieMode; enforcer; accessTokenSecret; refreshTokenSecret; enableGlobalGuard; permissionDecorator; permissionChecker; constructor(cookieMode, enforcer, accessTokenSecret, refreshTokenSecret, enableGlobalGuard, permissionDecorator, permissionChecker){ this.cookieMode = cookieMode; this.enforcer = enforcer; this.accessTokenSecret = accessTokenSecret; this.refreshTokenSecret = refreshTokenSecret; this.enableGlobalGuard = enableGlobalGuard; this.permissionDecorator = permissionDecorator; this.permissionChecker = permissionChecker; } async canActivate(context) { if (!this.enableGlobalGuard) return true; const reflector = new Reflector(); const isPublic = reflector.get(IS_ROUTE_PUBLIC, context.getHandler()); const onlyAuthenticated = reflector.get(IS_ROUTE_ONLY_AUTHENTICATED, context.getHandler()); if (isPublic) return true; const allowActions = reflector.get(this.permissionDecorator ?? AllowActions, context.getHandler()); if (!allowActions?.length && !onlyAuthenticated) return false; const contextType = context.getType(); let token; switch(contextType){ case 'graphql': { const { GqlExecutionContext } = await import('@nestjs/graphql'); const ctx = GqlExecutionContext.create(context).getContext(); token = (this.cookieMode ? ctx.req.cookies.token : (ctx.req.headers.authorization ?? '').replace(/^Bearer\s/, '').trim()) ?? null; break; } case 'http': default: token = (this.cookieMode ? context.switchToHttp().getRequest().cookies.token : context.switchToHttp().getRequest().headers.authorization ?? '').replace(/^Bearer\s/, '').trim(); break; } if (!token) return false; try { const payload = verify(token, this.cookieMode ? this.refreshTokenSecret : this.accessTokenSecret); switch(contextType){ case 'graphql': { const { GqlExecutionContext } = await import('@nestjs/graphql'); const ctx = GqlExecutionContext.create(context).getContext(); ctx.payload = payload; break; } case 'http': default: context.switchToHttp().getRequest().payload = payload; break; } if (onlyAuthenticated) return true; return this.permissionChecker({ enforcer: this.enforcer, payload, actions: allowActions }); } catch (ex) { return false; } } } CasbinGuard = _ts_decorate([ Injectable(), _ts_param(0, Inject(COOKIE_MODE)), _ts_param(1, Inject(CASBIN_ENFORCER)), _ts_param(2, Inject(ACCESS_TOKEN_SECRET)), _ts_param(3, Inject(REFRESH_TOKEN_SECRET)), _ts_param(4, Inject(ENABLE_GLOBAL_GUARD)), _ts_param(5, Inject(CASBIN_PERMISSION_DECORATOR)), _ts_param(6, Inject(CASBIN_PERMISSION_CHECKER)) ], CasbinGuard); export { CasbinGuard };