import express from 'express' ; import { Policy , UUID } from '@mds-core/mds-types' ; import db from '@mds-core/mds-db' ; import { now , pathsFor , NotFoundError , isUUID , BadParamsError , ServerError } from '@mds-core/mds-utils' ; import logger from '@mds-core/mds-logger' ; import { parseRequest } from '@mds-core/mds-api-helpers' ; import { ApiRequest , ApiResponse } from '@mds-core/mds-api-server' ; import { PolicyApiRequest , PolicyApiResponse , GetPoliciesResponse , GetPolicyResponse } from './types' ; import { PolicyApiVersionMiddleware } from './middleware' ; function api ( app ) { app . use ( PolicyApiVersionMiddleware ) ; /**
     * Policy-specific middleware to extract provider_id into locals, do some logging, etc.
     */ app . use ( async ( req , res , next ) => { res . header ( 'Access-Control-Allow-Origin' , '*' ) ; try { if ( ! ( req . path . includes ( '/health' ) || req . path === '/' || req . path === '/schema/policy' ) ) { if ( res . locals . claims ) { } else { return res . status ( 401 ) . send ( { error : 'Unauthorized' } ) ; } } } catch ( err ) { logger . error ( req . originalUrl , 'request validation fail:' , err . stack ) ; } next ( ) ; } ) ; app . get ( pathsFor ( '/policies' ) , async ( req , res , next ) => { const { start_date = now ( ) , end_date = now ( ) } = req . query ; const { scopes } = res . locals ; try { const { get_published = null , get_unpublished = null } = scopes . includes ( 'policies:read' ) ? parseRequest ( req , { parser : x => ( x ? JSON . parse ( x ) : null ) } ) . query ( 'get_published' , 'get_unpublished' ) : { get_published : true } ; if ( start_date > end_date ) { throw new BadParamsError ( `start_date ${ start_date } > end_date ${ end_date }` ) ; } const policies = await db . readPolicies ( { get_published , get_unpublished } ) ; const prev_policies = policies . reduce ( ( prev_policies_acc , policy ) => { if ( policy . prev_policies ) { prev_policies_acc . push ( ... policy . prev_policies ) ; } return prev_policies_acc ; } , [ ] ) ; const active = policies . filter ( p => { const p_start_date = p . start_date ; const p_end_date = p . end_date || Number . MAX_SAFE_INTEGER ; return end_date >= p_start_date && p_end_date >= start_date && ! prev_policies . includes ( p . policy_id ) ; } ) ; if ( active . length === 0 ) { throw new NotFoundError ( 'No policies found!' ) ; } res . status ( 200 ) . send ( { version : res . locals . version , data : { policies : active } } ) ; } catch ( error ) { if ( error instanceof NotFoundError ) { return res . status ( 404 ) . send ( { error } ) ; } if ( error instanceof BadParamsError ) { return res . status ( 400 ) . send ( { error } ) ; } next ( new ServerError ( error ) ) ; } } ) ; app . get ( pathsFor ( '/policies/:policy_id' ) , async ( req , res , next ) => { const { policy_id } = req . params ; const { scopes } = res . locals ; try { if ( ! isUUID ( policy_id ) ) { throw new BadParamsError ( `policy_id ${ policy_id } is not a valid UUID` ) ; } const { get_published = null , get_unpublished = null } = scopes . includes ( 'policies:read' ) ? parseRequest ( req , { parser : x => ( x ? JSON . parse ( x ) : null ) } ) . query ( 'get_published' , 'get_unpublished' ) : { get_published : true } ; const policies = await db . readPolicies ( { policy_id , get_published , get_unpublished } ) ; if ( policies . length === 0 ) { throw new NotFoundError ( `policy_id ${ policy_id } not found` ) ; } const [ policy ] = policies ; res . status ( 200 ) . send ( { version : res . locals . version , data : { policy } } ) ; } catch ( error ) { if ( error instanceof BadParamsError ) { return res . status ( 400 ) . send ( { error } ) ; } if ( error instanceof NotFoundError ) { return res . status ( 404 ) . send ( { error } ) ; } return next ( new ServerError ( error ) ) ; } } ) ; app . use ( async ( error , req , res ) => { await logger . error ( req . method , req . originalUrl , error ) ; return res . status ( 500 ) . send ( { error } ) ; } ) ; return app ; } export { api } ;