190 lines
4.2 KiB
TypeScript
190 lines
4.2 KiB
TypeScript
|
|
import { RJLog } from "../log/RJLog";
|
|
import { RequestRequirement } from "./requirements/RequestRequirement";
|
|
import { UserManagementServer } from "./UserManagementServer";
|
|
import { FastifyRequest, FastifyReply } from 'fastify';
|
|
import { Message } from "../../browser/messages/Message";
|
|
import { UserData } from "./UserData";
|
|
import { UAParser } from 'ua-parser-js';
|
|
import { LocationData } from "./location/LocationData";
|
|
|
|
export enum RequestType
|
|
{
|
|
GET,
|
|
POST
|
|
}
|
|
|
|
export abstract class RequestHandler
|
|
{
|
|
|
|
_ums:UserManagementServer;
|
|
_type:RequestType;
|
|
_url:string;
|
|
|
|
|
|
requirements:RequestRequirement[] = [];
|
|
|
|
get app(){ return this._ums.app };
|
|
get userDB(){ return this._ums.userDB; }
|
|
|
|
constructor( rt:RequestType, url:string, requirements:RequestRequirement[] = [] )
|
|
{
|
|
this._url = url;
|
|
this._type = rt;
|
|
this.requirements = requirements;
|
|
}
|
|
|
|
|
|
async initialize( ums:UserManagementServer ):Promise<void>
|
|
{
|
|
this._ums = ums;
|
|
|
|
await this._initialize();
|
|
|
|
await this._register();
|
|
|
|
for ( let r of this.requirements )
|
|
{
|
|
await r.initialize( this );
|
|
}
|
|
|
|
return Promise.resolve();
|
|
}
|
|
|
|
protected _register():Promise<void>
|
|
{
|
|
RJLog.log( RequestType[ this._type ], this._url );
|
|
|
|
if ( RequestType.GET == this._type )
|
|
{
|
|
this.app.get( this._url, ( request, reply ) => { this.handle( request, reply ); } );
|
|
}
|
|
else if ( RequestType.POST == this._type )
|
|
{
|
|
this.app.post( this._url, ( request, reply ) => { this.handle( request, reply ); } );
|
|
}
|
|
|
|
return Promise.resolve();
|
|
}
|
|
|
|
protected _currentRequest:FastifyRequest;
|
|
protected _currentReply:FastifyReply;
|
|
|
|
async handle( request:FastifyRequest, reply:FastifyReply ):Promise<void>
|
|
{
|
|
if ( ! request || ! reply )
|
|
{
|
|
RJLog.warn( "Aborting request:", "Request:", ! request, "Reply:", ! reply );
|
|
return Promise.resolve();
|
|
}
|
|
|
|
this._currentRequest = request;
|
|
this._currentReply = reply;
|
|
|
|
RJLog.log( "Processing request:", "Request:", request.url, request.ip );
|
|
|
|
for ( let r of this._ums.globalRequirements )
|
|
{
|
|
let fullfilled = await r.handle( request, reply );
|
|
|
|
if ( ! fullfilled )
|
|
{
|
|
RJLog.log( "Global Requirement not fullfilled", r );
|
|
|
|
return this.sendError( "Error during global requirements check" );
|
|
}
|
|
}
|
|
|
|
for ( let r of this.requirements )
|
|
{
|
|
let fullfilled = await r.handle( request, reply );
|
|
|
|
if ( ! fullfilled )
|
|
{
|
|
RJLog.log( "Requirement not fullfilled", r );
|
|
|
|
return this.sendError( "Error during requirements check" );
|
|
}
|
|
}
|
|
|
|
|
|
await this._handle( request, reply );
|
|
|
|
this._currentRequest = null;
|
|
this._currentReply = null;
|
|
|
|
return Promise.resolve();
|
|
}
|
|
|
|
protected _initialize():Promise<void>
|
|
{
|
|
return Promise.resolve();
|
|
};
|
|
|
|
protected abstract _handle( request:FastifyRequest, reply:FastifyReply ):Promise<void>;
|
|
|
|
|
|
|
|
get ip()
|
|
{
|
|
return this._currentRequest.ip;
|
|
}
|
|
|
|
|
|
get userAgent()
|
|
{
|
|
return this._currentRequest.headers[ "user-agent" ];
|
|
}
|
|
|
|
getLocation():Promise<LocationData>
|
|
{
|
|
return this._ums.location.getLocation( this.ip );
|
|
}
|
|
|
|
protected sendJSON( obj:any ):Promise<void>
|
|
{
|
|
this._currentReply.send( obj );
|
|
return Promise.resolve();
|
|
}
|
|
|
|
getUser():Promise<UserData>
|
|
{
|
|
let request = this._currentRequest;
|
|
let requestBody = JSON.parse( request.body as string );
|
|
let tokenData = requestBody as { token:string };
|
|
let tokenID = tokenData.token;
|
|
|
|
let session = this._ums._sessions.get( tokenID );
|
|
return this._ums.userDB.byID( session.userID );
|
|
}
|
|
|
|
protected sendInfo( info:string ):Promise<void>
|
|
{
|
|
RJLog.log( info );
|
|
return this.sendJSON( Message.Info( info ) );
|
|
}
|
|
|
|
protected sendError( error:string, with400ErrorCode:boolean = true ):Promise<void>
|
|
{
|
|
RJLog.log( error );
|
|
|
|
if ( with400ErrorCode )
|
|
{
|
|
this._currentReply.code( 400 );
|
|
}
|
|
|
|
return this.sendJSON( Message.Error( error ) );
|
|
}
|
|
|
|
protected sendEmail( to:string, title:string, message:string )
|
|
{
|
|
this._ums.sendEmail( to, title, message );
|
|
}
|
|
|
|
protected sendDataInfo( info:string, data:any )
|
|
{
|
|
let json = Message.Info( info ) as any;
|
|
json.data = data;
|
|
return this.sendJSON( json );
|
|
}
|
|
} |