@rytass/member-base-nestjs-module
Version:
Rytass Member System NestJS Base Module
99 lines (96 loc) • 4.57 kB
JavaScript
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 };