import { GuidGenerator , ServiceConfiguration } from 'common' ; import { inject , injectable } from 'inversify' ; import { isEmpty , Dictionary } from 'lodash' ; import { ContextAwareLogger } from 'logger' ; import { OnDemandPageScanRunResultProvider , ScanBatchRequest , ScanResultResponse , WebApiErrorCodes , WebsiteScanResultProvider , } from 'service-library' ; import { OnDemandPageScanResult } from 'storage-documents' ; import { ScanResponseConverter } from '../converters/scan-response-converter' ; import { BaseScanResultController } from './base-scan-result-controller' ; @ injectable ( ) export class BatchScanResultController extends BaseScanResultController { public readonly apiVersion = '1.0' ; public readonly apiName = 'web-api-get-scans' ; public constructor ( @ inject ( OnDemandPageScanRunResultProvider ) protected readonly onDemandPageScanRunResultProvider , @ inject ( WebsiteScanResultProvider ) protected readonly websiteScanResultProvider , @ inject ( ScanResponseConverter ) protected readonly scanResponseConverter , @ inject ( GuidGenerator ) protected readonly guidGenerator , @ inject ( ServiceConfiguration ) protected readonly serviceConfig , @ inject ( ContextAwareLogger ) logger ) { super ( logger ) ; } public async handleRequest ( ) { this . logger . setCommonProperties ( { source : 'getBatchScanResultRESTApi' } ) ; const payload = this . tryGetPayload < ScanBatchRequest [ ] > ( ) ; const scanIds = payload . map ( ( request ) => request . scanId ) ; const responseBody = [ ] ; const scanIdsToQueryFromDb = [ ] ; for ( const scanId of scanIds ) { if ( ! this . isScanIdValid ( scanId ) ) { responseBody . push ( { scanId : scanId , error : WebApiErrorCodes . invalidResourceId . error , } ) ; continue ; } const isRequestMadeTooSoon = await this . isRequestMadeTooSoon ( scanId ) ; if ( isRequestMadeTooSoon === true ) { responseBody . push ( this . getTooSoonRequestResponse ( scanId ) ) ; } else { scanIdsToQueryFromDb . push ( scanId ) ; } } const scanResultItemMap = await this . getScanResultMapKeyByScanId ( scanIdsToQueryFromDb ) ; const scanResponseBody = await this . getScanResponseBody ( scanIdsToQueryFromDb , scanResultItemMap ) ; responseBody . push ( ... scanResponseBody ) ; this . context . res = { status : 200 , body : responseBody , } ; this . logger . logInfo ( 'Batch scan result successfully fetched.' , { scanIds : JSON . stringify ( scanIdsToQueryFromDb ) } ) ; } private async getScanResponseBody ( scanIds , pageScanResults ) { const responses = [ ] ; await Promise . all ( scanIds . map ( async ( scanId ) => { const pageScanResult = pageScanResults [ scanId ] ; if ( isEmpty ( pageScanResult ) ) { responses . push ( { scanId : scanId , error : WebApiErrorCodes . resourceNotFound . error , } ) ; } else { const websiteScanResult = await this . getWebsiteScanResult ( pageScanResult ) ; responses . push ( this . getScanResultResponse ( pageScanResult , websiteScanResult ) ) ; } } ) ) ; return responses ; } }