import express from 'express' ; import logger from '@mds-core/mds-logger' ; import { isProviderId } from '@mds-core/mds-providers' ; import { isUUID , pathsFor } from '@mds-core/mds-utils' ; import { checkAccess , AccessTokenScopeValidator } from '@mds-core/mds-api-server' ; import { AgencyApiRequest , AgencyApiResponse , AgencyApiAccessTokenScopes } from './types' ; import { registerVehicle , getVehicleById , getVehiclesByProvider , updateVehicle , submitVehicleEvent , submitVehicleTelemetry , registerStop , readStop , readStops } from './request-handlers' ; import { readAllVehicleIds } from './agency-candidate-request-handlers' ; import { getCacheInfo , wipeDevice , refreshCache } from './sandbox-admin-request-handlers' ; import { validateDeviceId } from './utils' ; import { AgencyApiVersionMiddleware } from './middleware/agency-api-version' ; const checkAgencyApiAccess = ( validator ) => checkAccess ( validator ) ; function api ( app ) { /**
     * Agency-specific middleware to extract provider_id into locals, do some logging, etc.
     */ app . use ( AgencyApiVersionMiddleware ) ; app . use ( async ( req , res , next ) => { try { if ( ! ( req . path . includes ( '/health' ) || req . path === '/' ) ) { if ( res . locals . claims ) { const { provider_id } = res . locals . claims ; if ( ! isUUID ( provider_id ) ) { logger . warn ( req . originalUrl , 'invalid provider_id is not a UUID' , provider_id ) ; return res . status ( 400 ) . send ( { error : 'authentication_error' , error_description : `invalid provider_id ${ provider_id } is not a UUID` } ) ; } if ( ! isProviderId ( provider_id ) ) { return res . status ( 400 ) . send ( { error : 'authentication_error' , error_description : `invalid provider_id ${ provider_id } is not a known provider` } ) ; } res . locals . provider_id = provider_id ; } else { return res . status ( 401 ) . send ( { error : 'authentication_error' , error_description : 'Unauthorized' } ) ; } } } catch ( err ) { logger . error ( req . originalUrl , 'request validation fail:' , err . stack ) ; } next ( ) ; } ) ; /**
     * Endpoint to register vehicles
     * See  https app . post ( pathsFor ( '/vehicles' ) , registerVehicle ) ; /**
     * Read back a vehicle.
     */ app . get ( pathsFor ( '/vehicles/:device_id' ) , validateDeviceId , getVehicleById ) ; /**
     * Read back all the vehicles for this provider_id, with pagination
     */ app . get ( pathsFor ( '/vehicles' ) , getVehiclesByProvider ) ; app . put ( pathsFor ( '/vehicles/:device_id' ) , validateDeviceId , updateVehicle ) ; /**
     * Endpoint to submit vehicle events
     * See  https app . post ( pathsFor ( '/vehicles/:device_id/event' ) , validateDeviceId , submitVehicleEvent ) ; /**
     * Endpoint to submit telemetry
     * See  https app . post ( pathsFor ( '/vehicles/telemetry' ) , submitVehicleTelemetry ) ; /**
     * Not currently in Agency spec.  Ability to read back all vehicle IDs.
     */ app . get ( pathsFor ( '/admin/vehicle_ids' ) , checkAgencyApiAccess ( scopes => scopes . includes ( 'admin:all' ) ) , readAllVehicleIds ) ; app . get ( pathsFor ( '/admin/cache/info' ) , checkAgencyApiAccess ( scopes => scopes . includes ( 'admin:all' ) ) , getCacheInfo ) ; app . get ( pathsFor ( '/admin/wipe/:device_id' ) , checkAgencyApiAccess ( scopes => scopes . includes ( 'admin:all' ) ) , validateDeviceId , wipeDevice ) ; app . get ( pathsFor ( '/admin/cache/refresh' ) , checkAgencyApiAccess ( scopes => scopes . includes ( 'admin:all' ) ) , refreshCache ) ; app . post ( pathsFor ( '/stops' ) , checkAgencyApiAccess ( scopes => scopes . includes ( 'admin:all' ) ) , registerStop ) ; app . get ( pathsFor ( '/stops/:stop_id' ) , readStop ) ; app . get ( pathsFor ( '/stops' ) , readStops ) ; return app ; } export { api } ;