import * as passport from 'passport' ; import { promisify } from 'es6-promisify' ; import { forbidden , badRequest , notFound } from '@hapi/boom' ; import { User } from '@models/user.model' ; import { ROLE } from '@enums' ; import { list } from '@utils/enum.util' ; import { IUserRequest , IResponse } from '@interfaces' ; import { OAuthProvider } from '@types' ; description class Guard { description private static instance : Guard ; private constructor ( ) { } description static get ( ) { if ( ! Guard . instance ) { Guard . instance = new Guard ( ) ; } return Guard . instance ; } description param req param res param next param roles handleJWT = ( req , res , next , roles ) => async ( err , user , info ) : Promise < void > => { const error = err || info ; const logIn = promisify ( req . logIn ) as ( user , { session } ) => Promise < void > ; try { if ( error || ! user ) throw error ; await logIn ( user , { session : false } ) ; } catch ( e ) { const scopedError = e as Error ; return next ( forbidden ( scopedError . message ) ) ; } if ( ! roles . includes ( user . role ) ) { return next ( forbidden ( 'Forbidden area' ) ) ; } else if ( user . role !== ROLE . admin && ( req . params . userId && parseInt ( req . params . userId , 10 ) !== user . id ) ) { return next ( forbidden ( 'Forbidden area' ) ) ; } req . user = user ; return next ( ) ; } ; description param req param res param nex handleOauth = ( req , res , next ) => async ( err , user ) : Promise < void > => { if ( err ) { return next ( badRequest ( err ?. message ) ) ; } else if ( ! user ) { return next ( notFound ( err ?. message ) ) ; } else if ( ! list ( ROLE ) . includes ( user . role ) ) { return next ( forbidden ( 'Forbidden area' ) ) ; } req . user = user ; next ( ) ; } ; description param req param res param next param roles param cb dependency see http authentify = ( req , res , next , roles , callback ) => passport . authenticate ( 'jwt' , { session : false } , callback ( req , res , next , roles ) ) ( req , res , next ) ; description param req param res param next param service param cb dependency see http oAuthentify = ( req , res , next , service , callback ) => passport . authenticate ( service , { session : false } , callback ( req , res , next ) ) ( req , res , next ) ; description param roles authorize = ( roles ) => ( req , res , next ) : void => this . authentify ( req , res , next , roles , this . handleJWT ) ; description param service oAuth = ( service ) => passport . authenticate ( service , { session : false } ) ; description param service oAuthCallback = ( service ) => ( req , res , next ) : void => this . oAuthentify ( req , res , next , service , this . handleOauth ) ; } const guard = Guard . get ( ) ; export { guard as Guard } ;