pos-be/src/core/guards/domain/jwt.guard.ts

76 lines
2.2 KiB
TypeScript

import {
Injectable,
CanActivate,
ExecutionContext,
Scope,
Logger,
UnauthorizedException,
} from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Observable } from 'rxjs';
import { SessionService, UsersSession } from 'src/core/sessions';
import { UNPROTECTED_URL } from '../constants';
import { PrivilegeService } from './services/privilege.service';
@Injectable({ scope: Scope.REQUEST })
export class JWTGuard implements CanActivate {
constructor(
protected readonly session: SessionService,
protected readonly reflector: Reflector,
protected readonly privilege: PrivilegeService,
) {}
protected isPublic = false;
protected userSession: UsersSession;
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
/**
* Check if access url is protected or not
* By default `isUnprotected` equals `false`
*/
const isUnprotected = this.reflector.getAllAndOverride<boolean>(
UNPROTECTED_URL,
[context.getHandler(), context.getClass()],
);
this.isPublic = isUnprotected;
this.session.setPublic(isUnprotected);
if (isUnprotected) return true;
/**
* Check if request give the token or not
* If there is not token in request, the transaction is failed
* and return 401 `Unauthorize`
*/
const request = context.switchToHttp().getRequest();
const authorization = request.headers['authorization'];
if (!authorization)
throw new UnauthorizedException({
code: 10002,
message: 'Access denied, please login first!',
error: 'TOKEN_NOT_PROVIDE',
});
const [, token] = authorization.split(' ');
/**
* Verify if token is valid token from login
* if the token is'nt valid token, the transaction is failed
* and return 401
*/
try {
this.userSession = this.session.verifyToken(token);
Logger.log(`Access from ${this.userSession.name}`, 'AuthGuard');
return true;
} catch (error) {
throw new UnauthorizedException({
code: 10001,
message:
'You cant access this endpoint, because authentication inst valid',
error: 'INVALID_TOKEN',
});
}
}
}