import express from 'express' ; import logger from '@mds-core/mds-logger' ; import cache from '@mds-core/mds-agency-cache' ; import { providerName , isProviderId } from '@mds-core/mds-providers' ; import { isUUID , pathsFor , now } from '@mds-core/mds-utils' ; import { checkAccess , AccessTokenScopeValidator } from '@mds-core/mds-api-server' ; import { DailyApiRequest , DailyApiResponse , DailyApiAccessTokenScopes } from './types' ; import { getRawTripData , getVehicleCounts , getLastDayTripsByProvider , getLastDayStatsByProvider , getTimeSinceLastEventHandler , getNumVehiclesRegisteredLast24HoursHandler , getNumEventsLast24HoursHandler , getTripCountsSinceHandler , getEventCountsPerProviderSinceHandler , getTelemetryCountsPerProviderSinceHandler , getConformanceLast24HoursHandler } from './request-handlers' ; async function agencyMiddleware ( req , res , next ) { try { if ( ! ( req . path . includes ( '/health' ) || req . path === '/' ) ) { if ( res . locals . claims ) { const { provider_id , scope } = res . locals . claims ; if ( req . path . includes ( '/admin/' ) ) { if ( ! scope || ! scope . includes ( 'admin:all' ) ) { return res . status ( 403 ) . send ( { result : `no admin access without admin:all scope (${ scope })` } ) ; } } if ( provider_id ) { if ( ! isUUID ( provider_id ) ) { logger . warn ( req . originalUrl , 'bogus provider_id' , provider_id ) ; return res . status ( 400 ) . send ( { result : `invalid provider_id ${ provider_id } is not a UUID` } ) ; } if ( ! isProviderId ( provider_id ) ) { return res . status ( 400 ) . send ( { result : `invalid provider_id ${ provider_id } is not a known provider` } ) ; } logger . info ( providerName ( provider_id ) , req . method , req . originalUrl ) ; } } else { return res . status ( 401 ) . send ( 'Unauthorized' ) ; } } } catch ( err ) { logger . error ( req . originalUrl , 'request validation fail:' , err . stack ) ; } next ( ) ; } const checkDailyApiAccess = ( validator ) => checkAccess ( validator ) ; function api ( app ) { /**
     * Agency-specific middleware to extract provider_id into locals, do some logging, etc.
     */ app . use ( agencyMiddleware ) ; app . get ( pathsFor ( '/admin/vehicle_counts' ) , checkDailyApiAccess ( scopes => scopes . includes ( 'admin:all' ) ) , getVehicleCounts ) ; app . get ( pathsFor ( '/admin/events' ) , checkDailyApiAccess ( scopes => scopes . includes ( 'admin:all' ) ) , async ( req , res ) => { const start = now ( ) ; const events = await cache . readAllEvents ( ) ; const finish = now ( ) ; const timeElapsed = finish - start ; logger . info ( `MDS-DAILY /admin/events -> cache.readAllEvents() time elapsed: ${ timeElapsed }` ) ; res . status ( 200 ) . send ( { events } ) ; } ) ; app . get ( pathsFor ( '/admin/last_day_trips_by_provider' ) , checkDailyApiAccess ( scopes => scopes . includes ( 'admin:all' ) ) , getLastDayTripsByProvider ) ; app . get ( pathsFor ( '/admin/raw_trip_data/:trip_id' ) , checkDailyApiAccess ( scopes => scopes . includes ( 'admin:all' ) ) , getRawTripData ) ; app . get ( pathsFor ( '/admin/last_day_stats_by_provider' ) , checkDailyApiAccess ( scopes => scopes . includes ( 'admin:all' ) ) , getLastDayStatsByProvider ) ; app . get ( pathsFor ( '/admin/time_since_last_event' ) , checkDailyApiAccess ( scopes => scopes . includes ( 'admin:all' ) ) , getTimeSinceLastEventHandler ) ; app . get ( pathsFor ( '/admin/num_vehicles_registered_last_24_hours' ) , checkDailyApiAccess ( scopes => scopes . includes ( 'admin:all' ) ) , getNumVehiclesRegisteredLast24HoursHandler ) ; app . get ( pathsFor ( '/admin/num_event_last_24_hours' ) , checkDailyApiAccess ( scopes => scopes . includes ( 'admin:all' ) ) , getNumEventsLast24HoursHandler ) ; app . get ( pathsFor ( '/admin/trip_counts_since' ) , checkDailyApiAccess ( scopes => scopes . includes ( 'admin:all' ) ) , getTripCountsSinceHandler ) ; app . get ( pathsFor ( '/admin/event_counts_per_provider_since' ) , checkDailyApiAccess ( scopes => scopes . includes ( 'admin:all' ) ) , getEventCountsPerProviderSinceHandler ) ; app . get ( pathsFor ( '/admin/telemetry_counts_per_provider_since' ) , checkDailyApiAccess ( scopes => scopes . includes ( 'admin:all' ) ) , getTelemetryCountsPerProviderSinceHandler ) ; app . get ( pathsFor ( '/admin/conformance_last_24_hours' ) , checkDailyApiAccess ( scopes => scopes . includes ( 'admin:all' ) ) , getConformanceLast24HoursHandler ) ; return app ; } export { agencyMiddleware , api } ;