auth-server-helper/lib/AuthHandler.ts
Timo Hocker 83a402db8b
Some checks failed
continuous-integration/drone/push Build is failing
auth handler
2020-12-30 19:39:49 +01:00

103 lines
2.7 KiB
TypeScript

import { IncomingMessage, ServerResponse } from 'http';
import auth from './Authority';
interface AccessSettings {
access_token_expires_in?: number
include_refresh_token?: boolean
refresh_token_expires_in?: number
}
class AuthRequest {
public request: IncomingMessage;
public response: ServerResponse;
public constructor (req: IncomingMessage, res: ServerResponse) {
this.request = req;
this.response = res;
}
private default_header () {
this.response.setHeader ('Cache-Control', 'no-store');
this.response.setHeader ('Pragma', 'no-cache');
this.response.setHeader ('Content-Type', 'application/json');
}
public allow_access ({
access_token_expires_in,
include_refresh_token,
refresh_token_expires_in
}: AccessSettings): void {
this.default_header ();
this.response.writeHead (200);
const res = {
token_type: 'bearer',
access_token: auth.sign ('access_token', access_token_expires_in),
expires_in: access_token_expires_in,
scope
};
if (include_refresh_token) {
res.refresh_token = auth.sign ('refresh_token', refresh_token_expires_in);
res.refresh_token_expires_in = refresh_token_expires_in;
}
this.response.end (JSON.stringify (res));
}
public invalid (error_description) {
this.default_header ();
this.response.writeHead (400);
this.response.end (JSON.stringify ({
error: 'invalid_request',
error_description
}));
}
public deny () {
this.default_header ();
this.response.writeHead (401);
this.response.end (JSON.stringify ({ error: 'invalid_client' }));
}
}
type AuthRequestHandler = (req: AuthRequest) => void|Promise<void>;
interface CreateHandlerOptions {
refresh?: AccessSettings;
modules?: Record<string, AuthRequestHandler>;
}
export default function create_auth_handler (
default_handler: AuthRequestHandler,
{ refresh, modules }: CreateHandlerOptions
) {
return function process_request (
req: IncomingMessage,
res: ServerResponse
): Promise<void>|void {
const request = new AuthRequest (req, res);
const token = (/Bearer (?<token>.+)/ui).exec (req.headers.authorization);
if (token === null)
return default_handler (request);
const token_data = auth.verify (token.groups.token);
if (!token_data.valid) {
request.deny ();
return Promise.resolve ();
}
if (token_data.type === 'refresh_token') {
request.allow_access (refresh);
return Promise.resolve ();
}
if (token_data.type === 'part_token' && Object.keys (modules)
.includes (token_data.next_module))
return modules[token_data.next_module] (request);
request.invalid ('invalid bearer token');
return Promise.resolve ();
};
}