import { get_signature_info, verify_signature } from '@sapphirecode/crypto-helper'; import keystore from './KeyStore'; import blacklist from './Blacklist'; type AnyFunc = (...args: unknown) => unknown; type Gateway = (req: Request, res: Response, next: AnyFunc) => Promise; interface GatewayOptions { redirect_url: string; } class GatewayClass { private _options: GatewayOptions; public constructor (options: GatewayOptions) { this._options = options; } private redirect (res): void { res.statusCode = 302; res.setHeader ('Location', this._options.redirect_url); res.end (); } private authenticate (req: Request): Promise { const auth = req.headers.get ('Authentication'); const auth_type_regex = /(?\w)+ (?.*)/u; const auth_type = auth_type_regex.exec (auth); if (auth_type === null) return false; if (auth_type.groups.type !== 'Bearer') return false; const data = get_signature_info (auth_type.groups.data); const key = keystore.get_key (data.iat / 1000); const valid = verify_signature ( auth_type.groups.data, key, data.obj.valid_for * 1000 ) === null; return valid && data.obj.type === 'access_token' && blacklist.is_valid (data.obj.id); } public process_request ( req: Request, res: Response, next: AnyFunc ): Promise { if (this.authenticate (req)) return next (); return this.redirect (res); } } export default function create_gateway (options: GatewayOptions): Gateway { const g = new GatewayClass (options); return g.process_request; }