2020-12-12 15:53:47 +01:00
|
|
|
import {
|
|
|
|
get_signature_info,
|
|
|
|
verify_signature
|
|
|
|
} from '@sapphirecode/crypto-helper';
|
|
|
|
import keystore from './KeyStore';
|
|
|
|
import blacklist from './Blacklist';
|
|
|
|
|
2020-12-06 15:51:59 +01:00
|
|
|
type AnyFunc = (...args: unknown) => unknown;
|
|
|
|
type Gateway = (req: Request, res: Response, next: AnyFunc) => Promise<void>;
|
|
|
|
|
|
|
|
interface GatewayOptions {
|
|
|
|
redirect_url: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
class GatewayClass {
|
2020-12-06 21:06:40 +01:00
|
|
|
private _options: GatewayOptions;
|
2020-12-06 15:51:59 +01:00
|
|
|
|
|
|
|
public constructor (options: GatewayOptions) {
|
2020-12-06 21:06:40 +01:00
|
|
|
this._options = options;
|
2020-12-06 15:51:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private redirect (res): void {
|
|
|
|
res.statusCode = 302;
|
2020-12-06 21:06:40 +01:00
|
|
|
res.setHeader ('Location', this._options.redirect_url);
|
2020-12-06 15:51:59 +01:00
|
|
|
res.end ();
|
|
|
|
}
|
|
|
|
|
2020-12-12 15:53:47 +01:00
|
|
|
private authenticate (req: Request): Promise<boolean> {
|
|
|
|
const auth = req.headers.get ('Authentication');
|
|
|
|
const auth_type_regex = /(?<type>\w)+ (?<data>.*)/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);
|
2020-12-06 15:51:59 +01:00
|
|
|
}
|
|
|
|
|
2020-12-12 15:53:47 +01:00
|
|
|
public process_request (
|
2020-12-06 21:06:40 +01:00
|
|
|
req: Request,
|
|
|
|
res: Response,
|
|
|
|
next: AnyFunc
|
|
|
|
): Promise<void> {
|
2020-12-12 15:53:47 +01:00
|
|
|
if (this.authenticate (req))
|
2020-12-06 21:06:40 +01:00
|
|
|
return next ();
|
|
|
|
return this.redirect (res);
|
2020-12-06 15:51:59 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default function create_gateway (options: GatewayOptions): Gateway {
|
|
|
|
const g = new GatewayClass (options);
|
|
|
|
return g.process_request;
|
|
|
|
}
|