import { Controller , ValidationService , FieldErrors , ValidateError , TsoaRoute } from 'tsoa' ; import { AuthorizationsController } from './../../service-layer/controllers/AuthorizationController' ; import { UsersController } from './../../service-layer/controllers/UsersController' ; import { expressAuthentication } from './../../business-layer/security/Authentication' ; import * as express from 'express' ; const models = { "IUserResponse" : { "properties" : { "id" : { "dataType" : "string" } , "username" : { "dataType" : "string" } , "firstname" : { "dataType" : "string" } , "lastname" : { "dataType" : "string" } , "email" : { "dataType" : "string" } , } , } , "IUserLoginRequest" : { "properties" : { "username" : { "dataType" : "string" , "required" : true } , "password" : { "dataType" : "string" , "required" : true } , } , } , "IMessageResponse" : { "properties" : { "success" : { "dataType" : "boolean" , "required" : true } , "message" : { "dataType" : "string" , "required" : true } , } , } , "IUserCreateRequest" : { "properties" : { "username" : { "dataType" : "string" , "required" : true } , "firstname" : { "dataType" : "string" , "required" : true } , "lastname" : { "dataType" : "string" , "required" : true } , "password" : { "dataType" : "string" , "required" : true } , "email" : { "dataType" : "string" , "required" : true } , } , } , "IErrorResponse" : { "properties" : { "status" : { "dataType" : "double" , "required" : true } , "message" : { "dataType" : "string" , "required" : true } , } , } , "IUserUpdateRequest" : { "properties" : { "id" : { "dataType" : "string" } , "username" : { "dataType" : "string" } , "firstname" : { "dataType" : "string" } , "lastname" : { "dataType" : "string" } , "email" : { "dataType" : "string" } , "admin" : { "dataType" : "boolean" } , } , } , } ; const validationService = new ValidationService ( models ) ; export function RegisterRoutes ( app ) { app . post ( '/api/Authorizations/Login' , function ( request , response , next ) { const args = { request : { "in" : "body" , "name" : "request" , "required" : true , "ref" : "IUserLoginRequest" } , } ; let validatedArgs = [ ] ; try { validatedArgs = getValidatedArgs ( args , request ) ; } catch ( err ) { return next ( err ) ; } const controller = new AuthorizationsController ( ) ; const promise = controller . login . apply ( controller , validatedArgs as any ) ; promiseHandler ( controller , promise , response , next ) ; } ) ; app . post ( '/api/Authorizations/Logout' , function ( request , response , next ) { const args = { authentication : { "in" : "header" , "name" : "x-access-token" , "required" : true , "dataType" : "string" } , } ; let validatedArgs = [ ] ; try { validatedArgs = getValidatedArgs ( args , request ) ; } catch ( err ) { return next ( err ) ; } const controller = new AuthorizationsController ( ) ; const promise = controller . logout . apply ( controller , validatedArgs as any ) ; promiseHandler ( controller , promise , response , next ) ; } ) ; app . post ( '/api/Users' , function ( request , response , next ) { const args = { request : { "in" : "body" , "name" : "request" , "required" : true , "ref" : "IUserCreateRequest" } , } ; let validatedArgs = [ ] ; try { validatedArgs = getValidatedArgs ( args , request ) ; } catch ( err ) { return next ( err ) ; } const controller = new UsersController ( ) ; const promise = controller . RegisterNewUser . apply ( controller , validatedArgs as any ) ; promiseHandler ( controller , promise , response , next ) ; } ) ; app . get ( '/api/Users/:userId' , authenticateMiddleware ( [ { "api_key" : [ ] } ] ) , function ( request , response , next ) { const args = { userId : { "in" : "path" , "name" : "userId" , "required" : true , "dataType" : "string" } , authentication : { "in" : "header" , "name" : "x-access-token" , "required" : true , "dataType" : "string" } , } ; let validatedArgs = [ ] ; try { validatedArgs = getValidatedArgs ( args , request ) ; } catch ( err ) { return next ( err ) ; } const controller = new UsersController ( ) ; const promise = controller . GetUserById . apply ( controller , validatedArgs as any ) ; promiseHandler ( controller , promise , response , next ) ; } ) ; app . get ( '/api/Users/username/:username' , function ( request , response , next ) { const args = { username : { "in" : "path" , "name" : "username" , "required" : true , "dataType" : "string" } , } ; let validatedArgs = [ ] ; try { validatedArgs = getValidatedArgs ( args , request ) ; } catch ( err ) { return next ( err ) ; } const controller = new UsersController ( ) ; const promise = controller . GetUserByUsername . apply ( controller , validatedArgs as any ) ; promiseHandler ( controller , promise , response , next ) ; } ) ; app . patch ( '/api/Users' , function ( request , response , next ) { const args = { request : { "in" : "body" , "name" : "request" , "required" : true , "ref" : "IUserUpdateRequest" } , } ; let validatedArgs = [ ] ; try { validatedArgs = getValidatedArgs ( args , request ) ; } catch ( err ) { return next ( err ) ; } const controller = new UsersController ( ) ; const promise = controller . Update . apply ( controller , validatedArgs as any ) ; promiseHandler ( controller , promise , response , next ) ; } ) ; function authenticateMiddleware ( security = [ ] ) { return ( request , _response , next ) => { let responded = 0 ; let success = false ; const succeed = function ( user ) { if ( ! success ) { success = true ; responded ++ ; request [ 'user' ] = user ; next ( ) ; } } ; const fail = function ( error ) { responded ++ ; if ( responded == security . length && ! success ) { error . status = 401 ; next ( error ) ; } } ; for ( const secMethod of security ) { if ( Object . keys ( secMethod ) . length > 1 ) { let promises = [ ] ; for ( const name in secMethod ) { promises . push ( expressAuthentication ( request , name , secMethod [ name ] ) ) ; } Promise . all ( promises ) . then ( ( users ) => { succeed ( users [ 0 ] ) ; } ) . catch ( fail ) ; } else { for ( const name in secMethod ) { expressAuthentication ( request , name , secMethod [ name ] ) . then ( succeed ) . catch ( fail ) ; } } } } ; } function isController ( object ) { return 'getHeaders' in object && 'getStatus' in object && 'setStatus' in object ; } function promiseHandler ( controllerObj , promise , response , next ) { return Promise . resolve ( promise ) . then ( ( data ) => { let statusCode ; if ( isController ( controllerObj ) ) { const headers = controllerObj . getHeaders ( ) ; Object . keys ( headers ) . forEach ( ( name ) => { response . set ( name , headers [ name ] ) ; } ) ; statusCode = controllerObj . getStatus ( ) ; } if ( data || data === false ) { response . status ( statusCode || 200 ) . json ( data ) ; } else { response . status ( statusCode || 204 ) . end ( ) ; } } ) . catch ( ( error ) => next ( error ) ) ; } function getValidatedArgs ( args , request ) { const fieldErrors = { } ; const values = Object . keys ( args ) . map ( ( key ) => { const name = args [ key ] . name ; switch ( args [ key ] . in ) { case 'request' : return request ; case 'query' : return validationService . ValidateParam ( args [ key ] , request . query [ name ] , name , fieldErrors ) ; case 'path' : return validationService . ValidateParam ( args [ key ] , request . params [ name ] , name , fieldErrors ) ; case 'header' : return validationService . ValidateParam ( args [ key ] , request . header ( name ) , name , fieldErrors ) ; case 'body' : return validationService . ValidateParam ( args [ key ] , request . body , name , fieldErrors , name + '.' ) ; case 'body-prop' : return validationService . ValidateParam ( args [ key ] , request . body [ name ] , name , fieldErrors , 'body.' ) ; } } ) ; if ( Object . keys ( fieldErrors ) . length > 0 ) { throw new ValidateError ( fieldErrors , '' ) ; } return values ; } }