All files / src/pages/api check-status.ts

66.66% Statements 22/33
59.09% Branches 13/22
100% Functions 2/2
66.66% Lines 22/33

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98                    1x           3x 1x 1x 1x     2x 2x             2x 2x                         1x       2x                 2x 2x           2x 2x 2x   2x                                 2x 1x         1x     1x 1x    
import { NextApiRequest, NextApiResponse } from 'next'
 
import { mapToCheckStatusApiResponse } from '../../lib/mappers/checkStatusApiResponseMapper'
import {
  CheckStatusApiRequestQuery,
  CheckStatusApiResponse,
  PassportStatusesSearchResult,
} from '../../lib/types'
import { getLogger } from '../../logging/log-util'
 
const logger = getLogger('check-status')
 
export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse<CheckStatusApiResponse | string>,
) {
  if (req.method !== 'GET') {
    logger.debug(`error 405: Invalid request method ${req.method}`)
    res.status(405).send(`Invalid request method ${req.method}`)
    return
  }
 
  const { searchParams } = new URL(req.url ?? '', `http://${req.headers.host}`)
  const checkStatusRequest: CheckStatusApiRequestQuery = {
    dateOfBirth: searchParams.get('dateOfBirth') ?? '',
    esrf: searchParams.get('esrf') ?? '',
    givenName: searchParams.get('givenName') ?? '',
    surname: searchParams.get('surname') ?? '',
  }
 
  try {
    await searchPassportStatusApi(res, checkStatusRequest)
  } catch (error) {
    logger.error(error, 'Unhandled exception: Internal Server Error (500)')
    res.status(500).send('Something went wrong.')
  }
}
 
/**
 * Search passport status from passport status API
 * @param res
 * @param checkStatusApiRequestQuery Check status request object
 * @returns Passport status API search response
 */
export const searchPassportStatusApi = async (
  res: NextApiResponse<CheckStatusApiResponse | string>,
  checkStatusApiRequestQuery: CheckStatusApiRequestQuery,
) => {
  Iif (!process.env.PASSPORT_STATUS_API_BASE_URI) {
    logger.error(
      'PASSPORT_STATUS_API_BASE_URI must not be undefined, null or empty',
    )
    throw Error(
      'process.env.PASSPORT_STATUS_API_BASE_URI must not be undefined, null or empty',
    )
  }
 
  const { dateOfBirth, esrf, givenName, surname } = checkStatusApiRequestQuery
  const query = new URLSearchParams({
    dateOfBirth,
    fileNumber: esrf,
    givenName,
    surname,
  }).toString()
  const url = `${process.env.PASSPORT_STATUS_API_BASE_URI}/api/v1/passport-statuses/_search?${query}`
  logger.debug({ url }, 'performing status check')
  const response = await fetch(url)
 
  Iif (response.ok) {
    logger.debug('Check status returned OK')
    const searchResult: PassportStatusesSearchResult = await response.json()
    const { GetCertificateApplicationResponse } = searchResult._embedded
 
    if (GetCertificateApplicationResponse.length === 0) {
      logger.debug(
        'error 404: searchResult._embedded is empty, passport status not found',
      )
      return res.status(404).send('Passport Status Not Found')
    }
 
    return res.json(
      mapToCheckStatusApiResponse(GetCertificateApplicationResponse[0]),
    )
  }
 
  if (response.status === 404 || response.status === 422) {
    logger.debug(
      `Check status returned not OK - error ${response.status}: ${response.body}`,
    )
    // 404 and 422 responses should both be handled as
    // `not found` results to mitigate data probing attacks
    return res.status(404).send('Passport Status Not Found')
  }
 
  logger.debug(`Status: ${response.status}: ${response.statusText}`)
  return res.status(response.status).send(response.statusText)
}