import { Request, Response } from 'express'; import { DyFM_Error } from '@futdevpro/fsm-dynamo'; import { DyNTS_SingletonService } from '../base/singleton.service'; import { DyNTS_global_settings } from '../../_collections/global-settings.const'; /** * Extend this class as an Auth Service implementation * * You should use singleton instance getting function by implementing a * static getInstance() function * @example * export class AuthService extends DyNTS_AuthService { * * static getInstance(): AuthService { * return AuthService.getSingletonInstance(); * } * ... */ export abstract class DyNTS_AuthService extends DyNTS_SingletonService { readonly serviceName: string = 'AuthService'; override readonly defaultErrorUserMsg = `We encountered an unhandled Auth Error, ` + `\nplease contact the responsible development team.`; /** * this function returns the 'authorization' header from the Request, * or throws error, if its missing * * @param req * @returns */ getTokenFromRequest(req: Request): string { const authHeader = req?.headers?.['authorization']; if (!authHeader) { throw new DyFM_Error({ status: 401, errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-GT0`, addECToUserMsg: true, message: 'AuthHeader missing!', userMessage: this.defaultErrorUserMsg, issuerService: this.serviceName, confidentialContent: { headers: req?.headers }, }); } const token = authHeader.split(' ')[1]; if (!token) { throw new DyFM_Error({ status: 401, errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-GT1`, addECToUserMsg: true, message: 'Token missing!', userMessage: this.defaultErrorUserMsg, issuerService: this.serviceName, confidentialContent: { headers: req?.headers }, }); } return token; } /** * You need to implement a token validation logic, * when if the token is invalid, or the authentication fails, it sends or throws an error * * @example * * async authenticateToken(req: Request, res: Response, next: NextFunction) { * try { * let token = AuthService.getTokenFromRequest(req); * token = await AuthService.verifyToken(token); * * DyFM_Log.success('token authenticated'); * res.setHeader('authorization', `Bearer ${token}`); * next(); * } catch (error) { * error = new DyFM_Error({ * status: 401, * message: `authenticateToken (WB-ERROR)`, * addECToUserMsg: true, * userMessage: `Authorization failed.`, * error * }); * DyFM_Log.error(error?.message, error); * * res.status(error.status); * res.send(error); * } * } * */ abstract authenticate_token: (req: Request, res: Response) => Promise; /** * You need to implement a token validation logic, * when if the token is invalid, or the authentication fails, it sends or throws an error * * @param req * @param res * @param next * * @example * * async authenticate_tokenSelf(req: Request, res: Response, next: NextFunction): Promise { * try { * let token = AuthService.getTokenFromRequest(req); * token = await AuthService.verifyTokenSelf(token, req?.params?.userId); * DyFM_Log.success('selftoken authenticated'); * * res.setHeader('authorization', `Bearer ${token}`); * next(); * } catch (error) { * error = new DyFM_Error({ * status: 401, * message: `authenticate_tokenSelf (WB-ERROR)`, * addECToUserMsg: true, * userMessage: `Authorization failed.`, * error * }); * DyFM_Log.error(error?.message, error); * * res.status(error.status); * res.send(error); * } * } * */ abstract authenticate_tokenSelf: (req: Request, res: Response) => Promise; /** * Authenticate Token for Permission to Access UsageData * @param req * @param res * @param next * * @example * You need to implement a token validation logic, * when if the token is invalid, or the authentication fails, it sends or throws an error * * async authTokenPermAccUsageData(req: Request, res: Response, next: NextFunction): Promise { * AuthService.authTokenAndPerm(req, res, next, Permission.accessUsageData); * } */ abstract authenticate_tokenPerm_accUsageData: (req: Request, res: Response) => Promise; /** * The DynamoNTS System is using this to get issuer, that will be set on DBServices * Don't throw error in this function, since it will be used in every request * @param req * * @example * getAccountIdFromRequest(req: Request): string { * try { * const authHeader = req.headers['authorization']; * const token = authHeader.split(' ')[1]; * return this.getAccountIdFromToken(token); * } catch { * return undefined; * } * } */ abstract getIssuerFromRequest(req: Request): string; /** * Basic Module: UsageModule uses this function * @param req */ abstract getUsernameFromRequest(req: Request): string; }