import { Handler , Router } from 'express' ; import { Authorization } from '../authorization/authorization' ; import { Forbidden } from '../authorization/authorization-engine' ; import { UserIdentity } from '../keystore' ; import { fromDescriptiveString } from '../query/descriptive-string' ; import { Trace } from '../util/trace' ; import { LoadMessage , LoadResponse , ProfileMessage , QueryMessage , QueryResponse , SaveMessage , SaveResponse , } from './messages' ; function get < U > ( method ) { return ( req , res , next ) => { const user = < RequestUser > req . user ; if ( ! user ) { res . sendStatus ( 401 ) ; } else { method ( user ) . then ( response => { res . setHeader ( 'Content-Type' , 'application/json' ) ; res . send ( JSON . stringify ( response ) ) ; next ( ) ; } ) . catch ( error => { Trace . error ( error ) ; res . sendStatus ( 500 ) ; next ( ) ; } ) ; } } ; } function post < T , U > ( method ) { return ( req , res , next ) => { const user = < RequestUser > req . user ; const message = < T > req . body ; if ( ! message ) { throw new Error ( 'Ensure that you have installed body-parser and called app.use(bodyParser.json()).' ) ; } method ( user , message ) . then ( response => { res . setHeader ( 'Content-Type' , 'application/json' ) ; res . send ( JSON . stringify ( response ) ) ; next ( ) ; } ) . catch ( error => { if ( error instanceof Forbidden ) { Trace . warn ( error . message ) ; res . status ( 403 ) . send ( error . message ) ; } else { Trace . error ( error ) ; res . sendStatus ( 500 ) ; } next ( ) ; } ) ; } ; } function serializeUserIdentity ( user ) { if ( ! user ) { return null ; } return { provider : user . provider , id : user . id } ; } export interface RequestUser { provider : string ; id : string ; profile : ProfileMessage ; } export class HttpRouter { handler : Handler ; constructor ( private authorization ) { const router = Router ( ) ; router . get ( '/login' , get ( user => this . login ( user ) ) ) ; router . post ( '/query' , post ( ( user , queryMessage ) => this . query ( user , queryMessage ) ) ) ; router . post ( '/load' , post ( ( user , loadMessage ) => this . load ( user , loadMessage ) ) ) ; router . post ( '/save' , post ( ( user , saveMessage ) => this . save ( user , saveMessage ) ) ) ; this . handler = router ; } private async login ( user ) { const userFact = await this . authorization . getUserFact ( { provider : user . provider , id : user . id } ) ; return { userFact : userFact , profile : user . profile } ; } private async query ( user , queryMessage ) { const userIdentity = serializeUserIdentity ( user ) ; const query = fromDescriptiveString ( queryMessage . query ) ; const result = await this . authorization . query ( userIdentity , queryMessage . start , query ) ; return { results : result } ; } private async load ( user , loadMessage ) { const userIdentity = serializeUserIdentity ( user ) ; const result = await this . authorization . load ( userIdentity , loadMessage . references ) ; return { facts : result } ; } private async save ( user , saveMessage ) { const userIdentity = serializeUserIdentity ( user ) ; await this . authorization . save ( userIdentity , saveMessage . facts ) ; return { } ; } }