From f9331131f4530785f1d1b8805387ff4374832f84 Mon Sep 17 00:00:00 2001 From: Andrew Dunkman Date: Tue, 8 Dec 2020 17:28:51 -0500 Subject: [PATCH 01/17] Add alert for public health status endpoint. --- web-client/terraform/main/main.tf | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/web-client/terraform/main/main.tf b/web-client/terraform/main/main.tf index a4de8e221cb..b14024254b1 100644 --- a/web-client/terraform/main/main.tf +++ b/web-client/terraform/main/main.tf @@ -199,3 +199,33 @@ resource "aws_route53_health_check" "ui_health_check" { failure_threshold = "2" request_interval = "30" } + +resource "aws_cloudwatch_metric_alarm" "status_health_check" { + alarm_name = "${var.dns_domain} health check endpoint" + namespace = "AWS/Route53" + metric_name = "HealthCheckStatus" + comparison_operator = "LessThanThreshold" + statistic = "Minimum" + threshold = "1" + evaluation_periods = "2" + period = "60" + + dimensions = { + HealthCheckId = aws_route53_health_check.status_health_check.id + } + + alarm_actions = [data.aws_sns_topic.system_health_alarms.arn] + insufficient_data_actions = [data.aws_sns_topic.system_health_alarms.arn] + ok_actions = [data.aws_sns_topic.system_health_alarms.arn] +} + +resource "aws_route53_health_check" "status_health_check" { + fqdn = "public-api.${var.dns_domain}" + port = 443 + type = "HTTPS_STR_MATCH" + resource_path = "/public-api/health" + failure_threshold = "2" + request_interval = "30" + invert_healthcheck = true + search_string = "false" # Search for any JSON property returning "false" +} From 4cf5779989c8d6c67febd8c3357d22bcff0ac99d Mon Sep 17 00:00:00 2001 From: Andrew Dunkman Date: Tue, 8 Dec 2020 18:30:49 -0500 Subject: [PATCH 02/17] Remove ClamAV from health endpoint. This causes our health check to fail, as it is rightfully checking that ClamAV is available (because it is not implemented). --- .../useCases/health/getHealthCheckInteractor.js | 11 ----------- .../useCases/health/getHealthCheckInteractor.test.js | 2 -- .../journey/unauthedUserViewsHealthCheck.js | 1 - 3 files changed, 14 deletions(-) diff --git a/shared/src/business/useCases/health/getHealthCheckInteractor.js b/shared/src/business/useCases/health/getHealthCheckInteractor.js index b0118df539c..b995197363e 100644 --- a/shared/src/business/useCases/health/getHealthCheckInteractor.js +++ b/shared/src/business/useCases/health/getHealthCheckInteractor.js @@ -163,12 +163,6 @@ const getEmailServiceStatus = async ({ applicationContext }) => { } }; -const getClamAVStatus = async () => { - // eslint-disable-next-line spellcheck/spell-checker - // TODO - implement once #6282 (Implement ClamAV Fargate Solution) has been completed - return false; -}; - /** * getHealthCheckInteractor * @@ -195,12 +189,7 @@ exports.getHealthCheckInteractor = async ({ applicationContext }) => { applicationContext, }); - const clamAVStatus = await getClamAVStatus({ - applicationContext, - }); - return { - clamAV: clamAVStatus, cognito: cognitoStatus, dynamo: { efcms: dynamoStatus, diff --git a/shared/src/business/useCases/health/getHealthCheckInteractor.test.js b/shared/src/business/useCases/health/getHealthCheckInteractor.test.js index 004277be1d9..df1b571b3d9 100644 --- a/shared/src/business/useCases/health/getHealthCheckInteractor.test.js +++ b/shared/src/business/useCases/health/getHealthCheckInteractor.test.js @@ -40,7 +40,6 @@ describe('getHealthCheckInteractor', () => { }); expect(status).toEqual({ - clamAV: false, cognito: true, dynamo: { efcms: true, @@ -110,7 +109,6 @@ describe('getHealthCheckInteractor', () => { }, }); expect(status).toEqual({ - clamAV: false, cognito: false, dynamo: { efcms: false, diff --git a/web-client/integration-tests-public/journey/unauthedUserViewsHealthCheck.js b/web-client/integration-tests-public/journey/unauthedUserViewsHealthCheck.js index 2cca5662c4e..93a3d1b3764 100644 --- a/web-client/integration-tests-public/journey/unauthedUserViewsHealthCheck.js +++ b/web-client/integration-tests-public/journey/unauthedUserViewsHealthCheck.js @@ -4,7 +4,6 @@ export const unauthedUserViewsHealthCheck = test => { expect(test.getState('health')).toEqual( expect.objectContaining({ - clamAV: expect.anything(), cognito: expect.anything(), dynamo: expect.objectContaining({ efcms: expect.anything(), From 1b61218065126e5d78bd6fbe5fe0fb04ad637908 Mon Sep 17 00:00:00 2001 From: Michael Marcotte Date: Thu, 10 Dec 2020 11:21:15 -0500 Subject: [PATCH 03/17] ustc-591: remove interstitial page --- .../presenter/sequences/submitUpdatePractitionerUserSequence.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/web-client/src/presenter/sequences/submitUpdatePractitionerUserSequence.js b/web-client/src/presenter/sequences/submitUpdatePractitionerUserSequence.js index 99cfd314d45..a1144ac71b2 100644 --- a/web-client/src/presenter/sequences/submitUpdatePractitionerUserSequence.js +++ b/web-client/src/presenter/sequences/submitUpdatePractitionerUserSequence.js @@ -2,7 +2,6 @@ import { clearAlertsAction } from '../actions/clearAlertsAction'; import { computeFormDateAction } from '../actions/computeFormDateAction'; import { navigateToPractitionerDetailAction } from '../actions/navigateToPractitionerDetailAction'; import { setAlertSuccessAction } from '../actions/setAlertSuccessAction'; -import { setCurrentPageAction } from '../actions/setCurrentPageAction'; import { setPractitionerDetailAction } from '../actions/setPractitionerDetailAction'; import { setSaveAlertsForNavigationAction } from '../actions/setSaveAlertsForNavigationAction'; import { setShowModalFactoryAction } from '../actions/setShowModalFactoryAction'; @@ -23,7 +22,6 @@ export const submitUpdatePractitionerUserSequence = [ { error: [setValidationErrorsAction, setValidationAlertErrorsAction], success: [ - setCurrentPageAction('Interstitial'), setWaitingForResponseAction, startWebSocketConnectionAction, { From 67d7b470941229627fd1356c666851b5ca465b67 Mon Sep 17 00:00:00 2001 From: Michael Marcotte Date: Thu, 10 Dec 2020 14:44:17 -0500 Subject: [PATCH 04/17] ustc-591: try to reintroduce interstitial --- .../sequences/submitUpdatePractitionerUserSequence.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web-client/src/presenter/sequences/submitUpdatePractitionerUserSequence.js b/web-client/src/presenter/sequences/submitUpdatePractitionerUserSequence.js index a1144ac71b2..52d75d25f0f 100644 --- a/web-client/src/presenter/sequences/submitUpdatePractitionerUserSequence.js +++ b/web-client/src/presenter/sequences/submitUpdatePractitionerUserSequence.js @@ -2,6 +2,7 @@ import { clearAlertsAction } from '../actions/clearAlertsAction'; import { computeFormDateAction } from '../actions/computeFormDateAction'; import { navigateToPractitionerDetailAction } from '../actions/navigateToPractitionerDetailAction'; import { setAlertSuccessAction } from '../actions/setAlertSuccessAction'; +import { setCurrentPageAction } from '../actions/setCurrentPageAction'; import { setPractitionerDetailAction } from '../actions/setPractitionerDetailAction'; import { setSaveAlertsForNavigationAction } from '../actions/setSaveAlertsForNavigationAction'; import { setShowModalFactoryAction } from '../actions/setShowModalFactoryAction'; @@ -30,13 +31,14 @@ export const submitUpdatePractitionerUserSequence = [ setShowModalFactoryAction('WebSocketErrorModal'), ], success: [ + setCurrentPageAction('Interstitial'), updatePractitionerUserAction, { error: [], success: [ setPractitionerDetailAction, - setSaveAlertsForNavigationAction, navigateToPractitionerDetailAction, + setSaveAlertsForNavigationAction, setAlertSuccessAction, ], }, From dba10a23198a90258562523330c52cab493f3cad Mon Sep 17 00:00:00 2001 From: Michael Marcotte Date: Thu, 10 Dec 2020 16:01:31 -0500 Subject: [PATCH 05/17] ustc-591: remove interstitial page --- .../presenter/sequences/submitUpdatePractitionerUserSequence.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/web-client/src/presenter/sequences/submitUpdatePractitionerUserSequence.js b/web-client/src/presenter/sequences/submitUpdatePractitionerUserSequence.js index 52d75d25f0f..1e0a31982e5 100644 --- a/web-client/src/presenter/sequences/submitUpdatePractitionerUserSequence.js +++ b/web-client/src/presenter/sequences/submitUpdatePractitionerUserSequence.js @@ -2,7 +2,6 @@ import { clearAlertsAction } from '../actions/clearAlertsAction'; import { computeFormDateAction } from '../actions/computeFormDateAction'; import { navigateToPractitionerDetailAction } from '../actions/navigateToPractitionerDetailAction'; import { setAlertSuccessAction } from '../actions/setAlertSuccessAction'; -import { setCurrentPageAction } from '../actions/setCurrentPageAction'; import { setPractitionerDetailAction } from '../actions/setPractitionerDetailAction'; import { setSaveAlertsForNavigationAction } from '../actions/setSaveAlertsForNavigationAction'; import { setShowModalFactoryAction } from '../actions/setShowModalFactoryAction'; @@ -31,7 +30,6 @@ export const submitUpdatePractitionerUserSequence = [ setShowModalFactoryAction('WebSocketErrorModal'), ], success: [ - setCurrentPageAction('Interstitial'), updatePractitionerUserAction, { error: [], From fb0507403a114a67834b6bb5068f33ac49317135 Mon Sep 17 00:00:00 2001 From: Michael Marcotte Date: Thu, 10 Dec 2020 18:04:02 -0500 Subject: [PATCH 06/17] ustc-591: fix react wonkiness --- .../actions/navigateToPractitionerDetailAction.js | 11 +++++++++-- .../sequences/adminContactUpdateCompleteSequence.js | 6 ++++++ ...adminContactUpdateInitialUpdateCompleteSequence.js | 2 ++ .../sequences/submitUpdatePractitionerUserSequence.js | 10 +--------- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/web-client/src/presenter/actions/navigateToPractitionerDetailAction.js b/web-client/src/presenter/actions/navigateToPractitionerDetailAction.js index a5043e0fd21..e1ffbfceae5 100644 --- a/web-client/src/presenter/actions/navigateToPractitionerDetailAction.js +++ b/web-client/src/presenter/actions/navigateToPractitionerDetailAction.js @@ -1,3 +1,5 @@ +import { state } from 'cerebral'; + /** * changes the route to the practitioner detail page for the given props.barNumber * @@ -6,8 +8,13 @@ * @param {object} providers.props the cerebral props object * @returns {Promise} async action */ -export const navigateToPractitionerDetailAction = async ({ props, router }) => { - const { barNumber } = props; +export const navigateToPractitionerDetailAction = async ({ + get, + props, + router, +}) => { + const user = get(state.form); + const barNumber = props.barNumber || user.barNumber; if (barNumber) { await router.route(`/practitioner-detail/${barNumber}`); diff --git a/web-client/src/presenter/sequences/adminContactUpdateCompleteSequence.js b/web-client/src/presenter/sequences/adminContactUpdateCompleteSequence.js index 16064ed633f..e1332dd05b4 100644 --- a/web-client/src/presenter/sequences/adminContactUpdateCompleteSequence.js +++ b/web-client/src/presenter/sequences/adminContactUpdateCompleteSequence.js @@ -1,7 +1,13 @@ +import { getUserContactEditCompleteAlertSuccessAction } from '../actions/getUserContactEditCompleteAlertSuccessAction'; +import { setAlertSuccessAction } from '../actions/setAlertSuccessAction'; +import { setSaveAlertsForNavigationAction } from '../actions/setSaveAlertsForNavigationAction'; import { stopWebSocketConnectionAction } from '../actions/webSocketConnection/stopWebSocketConnectionAction'; import { unsetUserContactEditProgressAction } from '../actions/unsetUserContactEditProgressAction'; export const adminContactUpdateCompleteSequence = [ stopWebSocketConnectionAction, unsetUserContactEditProgressAction, + getUserContactEditCompleteAlertSuccessAction, + setAlertSuccessAction, + setSaveAlertsForNavigationAction, ]; diff --git a/web-client/src/presenter/sequences/adminContactUpdateInitialUpdateCompleteSequence.js b/web-client/src/presenter/sequences/adminContactUpdateInitialUpdateCompleteSequence.js index bb02b200e38..f36a38a78eb 100644 --- a/web-client/src/presenter/sequences/adminContactUpdateInitialUpdateCompleteSequence.js +++ b/web-client/src/presenter/sequences/adminContactUpdateInitialUpdateCompleteSequence.js @@ -1,5 +1,7 @@ +import { navigateToPractitionerDetailAction } from '../actions/navigateToPractitionerDetailAction'; import { unsetWaitingForResponseAction } from '../actions/unsetWaitingForResponseAction'; export const adminContactUpdateInitialUpdateCompleteSequence = [ unsetWaitingForResponseAction, + navigateToPractitionerDetailAction, ]; diff --git a/web-client/src/presenter/sequences/submitUpdatePractitionerUserSequence.js b/web-client/src/presenter/sequences/submitUpdatePractitionerUserSequence.js index 1e0a31982e5..80a5cc24ba0 100644 --- a/web-client/src/presenter/sequences/submitUpdatePractitionerUserSequence.js +++ b/web-client/src/presenter/sequences/submitUpdatePractitionerUserSequence.js @@ -1,9 +1,6 @@ import { clearAlertsAction } from '../actions/clearAlertsAction'; import { computeFormDateAction } from '../actions/computeFormDateAction'; -import { navigateToPractitionerDetailAction } from '../actions/navigateToPractitionerDetailAction'; -import { setAlertSuccessAction } from '../actions/setAlertSuccessAction'; import { setPractitionerDetailAction } from '../actions/setPractitionerDetailAction'; -import { setSaveAlertsForNavigationAction } from '../actions/setSaveAlertsForNavigationAction'; import { setShowModalFactoryAction } from '../actions/setShowModalFactoryAction'; import { setValidationAlertErrorsAction } from '../actions/setValidationAlertErrorsAction'; import { setValidationErrorsAction } from '../actions/setValidationErrorsAction'; @@ -33,12 +30,7 @@ export const submitUpdatePractitionerUserSequence = [ updatePractitionerUserAction, { error: [], - success: [ - setPractitionerDetailAction, - navigateToPractitionerDetailAction, - setSaveAlertsForNavigationAction, - setAlertSuccessAction, - ], + success: [setPractitionerDetailAction], }, ], }, From c80166674e833f3cc71bb1756de9eafa9bdb7910 Mon Sep 17 00:00:00 2001 From: Michael Marcotte Date: Thu, 10 Dec 2020 18:28:37 -0500 Subject: [PATCH 07/17] ustc-591: add get to jsdoc --- .../src/presenter/actions/navigateToPractitionerDetailAction.js | 1 + 1 file changed, 1 insertion(+) diff --git a/web-client/src/presenter/actions/navigateToPractitionerDetailAction.js b/web-client/src/presenter/actions/navigateToPractitionerDetailAction.js index e1ffbfceae5..9597aa54967 100644 --- a/web-client/src/presenter/actions/navigateToPractitionerDetailAction.js +++ b/web-client/src/presenter/actions/navigateToPractitionerDetailAction.js @@ -4,6 +4,7 @@ import { state } from 'cerebral'; * changes the route to the practitioner detail page for the given props.barNumber * * @param {object} providers the providers object + * @param {object} providers.get the cerebral function to retrieve information from state * @param {object} providers.router the riot.router object that is used for changing the route * @param {object} providers.props the cerebral props object * @returns {Promise} async action From 585f3bb69b7001c61fea71efd1069139e91ed236 Mon Sep 17 00:00:00 2001 From: Andrew Dunkman Date: Fri, 11 Dec 2020 10:01:09 -0500 Subject: [PATCH 08/17] Specify JSON mime type for JSON file. --- .../fileCourtIssuedOrderInteractor.js | 1 + .../migration/parseLegacyDocumentsInteractor.js | 1 + .../parseLegacyDocumentsInteractor.test.js | 14 ++++++-------- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/shared/src/business/useCases/courtIssuedOrder/fileCourtIssuedOrderInteractor.js b/shared/src/business/useCases/courtIssuedOrder/fileCourtIssuedOrderInteractor.js index 21f119509e8..be246d3c148 100644 --- a/shared/src/business/useCases/courtIssuedOrder/fileCourtIssuedOrderInteractor.js +++ b/shared/src/business/useCases/courtIssuedOrder/fileCourtIssuedOrderInteractor.js @@ -81,6 +81,7 @@ exports.fileCourtIssuedOrderInteractor = async ({ await applicationContext.getPersistenceGateway().saveDocumentFromLambda({ applicationContext, + contentType: 'application/json', document: Buffer.from(JSON.stringify(contentToStore)), key: documentContentsId, useTempBucket: false, diff --git a/shared/src/business/useCases/migration/parseLegacyDocumentsInteractor.js b/shared/src/business/useCases/migration/parseLegacyDocumentsInteractor.js index 92456df7086..e12624077f2 100644 --- a/shared/src/business/useCases/migration/parseLegacyDocumentsInteractor.js +++ b/shared/src/business/useCases/migration/parseLegacyDocumentsInteractor.js @@ -61,6 +61,7 @@ exports.parseLegacyDocumentsInteractor = async ({ // Save text contents to JSON file in S3 await applicationContext.getPersistenceGateway().saveDocumentFromLambda({ applicationContext, + contentType: 'application/json', document: Buffer.from( JSON.stringify({ documentContents: pdfTextContents }), ), diff --git a/shared/src/business/useCases/migration/parseLegacyDocumentsInteractor.test.js b/shared/src/business/useCases/migration/parseLegacyDocumentsInteractor.test.js index 77a342efc14..19a1f527e42 100644 --- a/shared/src/business/useCases/migration/parseLegacyDocumentsInteractor.test.js +++ b/shared/src/business/useCases/migration/parseLegacyDocumentsInteractor.test.js @@ -130,14 +130,12 @@ describe('parseLegacyDocumentsInteractor', () => { docketNumber: mockDocketNumber, }); - expect( - applicationContext.getPersistenceGateway().saveDocumentFromLambda.mock - .calls[0][0].key, - ).toEqual(mockUniqueID); - expect( - applicationContext.getPersistenceGateway().saveDocumentFromLambda.mock - .calls[0][0].document, - ).toEqual( + const saveParams = applicationContext.getPersistenceGateway() + .saveDocumentFromLambda.mock.calls[0][0]; + + expect(saveParams.key).toEqual(mockUniqueID); + expect(saveParams.contentType).toEqual('application/json'); + expect(saveParams.document).toEqual( Buffer.from(JSON.stringify({ documentContents: mockPdfTextContents })), ); }); From 11644949386d00d95c060416bb474904523414b0 Mon Sep 17 00:00:00 2001 From: Michael Marcotte Date: Fri, 11 Dec 2020 11:04:29 -0500 Subject: [PATCH 09/17] add stage to parcel build command --- web-client/build-dist-public.sh | 2 +- web-client/build-dist.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web-client/build-dist-public.sh b/web-client/build-dist-public.sh index a3e4bdc4fe2..1a97234fc51 100755 --- a/web-client/build-dist-public.sh +++ b/web-client/build-dist-public.sh @@ -17,4 +17,4 @@ CLIENT_ID=$(aws cognito-idp list-user-pool-clients --user-pool-id "${USER_POOL_I COGNITO_LOGIN_URL="https://auth-${ENV}-${COGNITO_SUFFIX}.auth.us-east-1.amazoncognito.com/login?response_type=code&client_id=${CLIENT_ID}&redirect_uri=${COGNITO_REDIRECT_URL}" -COGNITO_LOGIN_URL="${COGNITO_LOGIN_URL}" CIRCLE_SHA1="${CIRCLE_SHA1}" SESSION_TIMEOUT=3300000 API_URL="${API_URL}" npm run build:public +STAGE="${ENV}" COGNITO_LOGIN_URL="${COGNITO_LOGIN_URL}" CIRCLE_SHA1="${CIRCLE_SHA1}" SESSION_TIMEOUT=3300000 API_URL="${API_URL}" npm run build:public diff --git a/web-client/build-dist.sh b/web-client/build-dist.sh index 1b34cded61f..3e54e2c344f 100755 --- a/web-client/build-dist.sh +++ b/web-client/build-dist.sh @@ -27,4 +27,4 @@ else SCANNER_RESOURCE_URI="${DYNAMSOFT_URL_OVERRIDE}/dynamic-web-twain-sdk-14.3.1" fi -CIRCLE_SHA1="${CIRCLE_SHA1}" SESSION_TIMEOUT=3300000 COGNITO_CLIENT_ID="${CLIENT_ID}" SCANNER_RESOURCE_URI="${SCANNER_RESOURCE_URI}" COGNITO_TOKEN_URL="${COGNITO_TOKEN_URL}" COGNITO_REDIRECT_URI="${COGNITO_REDIRECT_URI}" WS_URL="${WS_URL}" API_URL="${API_URL}" COGNITO_LOGIN_URL="${COGNITO_LOGIN_URL}" CIRCLE_HONEYBADGER_API_KEY="${CIRCLE_HONEYBADGER_API_KEY}" npm run build:client +STAGE="${ENV}" CIRCLE_SHA1="${CIRCLE_SHA1}" SESSION_TIMEOUT=3300000 COGNITO_CLIENT_ID="${CLIENT_ID}" SCANNER_RESOURCE_URI="${SCANNER_RESOURCE_URI}" COGNITO_TOKEN_URL="${COGNITO_TOKEN_URL}" COGNITO_REDIRECT_URI="${COGNITO_REDIRECT_URI}" WS_URL="${WS_URL}" API_URL="${API_URL}" COGNITO_LOGIN_URL="${COGNITO_LOGIN_URL}" CIRCLE_HONEYBADGER_API_KEY="${CIRCLE_HONEYBADGER_API_KEY}" npm run build:client From 1ed5389b579d220c153b8614f2e4156fc892dff0 Mon Sep 17 00:00:00 2001 From: Michael Marcotte Date: Fri, 11 Dec 2020 11:56:35 -0500 Subject: [PATCH 10/17] introduce CLIENT_STAGE env var --- docs/environments/setup.md | 1 + web-client/build-dist-public.sh | 2 +- web-client/build-dist.sh | 3 +-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/environments/setup.md b/docs/environments/setup.md index 3bf9efdd2de..b51fd9120cb 100644 --- a/docs/environments/setup.md +++ b/docs/environments/setup.md @@ -88,6 +88,7 @@ A prerequisite for a successful build within CircleCI is [access to CircleCI’s | `IRS_SUPERUSER_EMAIL_PROD` | Email address used to serve all new petitions to the IRS for PROD | | `DEFAULT_ACCOUNT_PASS` | Default password for all test accounts and some password resets | | `STATUSPAGE_DNS_RECORD` | DNS record for Statuspage of CNAME `status.${EFCMS_DOMAIN}` (optional) | + | `CLIENT_STAGE` | The `process.env.STAGE` for the React application | - Run a build in CircleCI. - The build may fail the first time, as provisioning new security certificates can take some time (and cause a timeout). See [the troubleshooting guide](../TROUBLESHOOTING.md) for solutions to common problems. diff --git a/web-client/build-dist-public.sh b/web-client/build-dist-public.sh index 1a97234fc51..9d05401a722 100755 --- a/web-client/build-dist-public.sh +++ b/web-client/build-dist-public.sh @@ -17,4 +17,4 @@ CLIENT_ID=$(aws cognito-idp list-user-pool-clients --user-pool-id "${USER_POOL_I COGNITO_LOGIN_URL="https://auth-${ENV}-${COGNITO_SUFFIX}.auth.us-east-1.amazoncognito.com/login?response_type=code&client_id=${CLIENT_ID}&redirect_uri=${COGNITO_REDIRECT_URL}" -STAGE="${ENV}" COGNITO_LOGIN_URL="${COGNITO_LOGIN_URL}" CIRCLE_SHA1="${CIRCLE_SHA1}" SESSION_TIMEOUT=3300000 API_URL="${API_URL}" npm run build:public +STAGE="${CLIENT_STAGE}" COGNITO_LOGIN_URL="${COGNITO_LOGIN_URL}" CIRCLE_SHA1="${CIRCLE_SHA1}" SESSION_TIMEOUT=3300000 API_URL="${API_URL}" npm run build:public diff --git a/web-client/build-dist.sh b/web-client/build-dist.sh index 3e54e2c344f..4e817bf9645 100755 --- a/web-client/build-dist.sh +++ b/web-client/build-dist.sh @@ -7,7 +7,6 @@ DEPLOYING_COLOR=$2 [ -z "${ENV}" ] && echo 'You must pass ENV as argument $1' && exit 1 [ -z "${DEPLOYING_COLOR}" ] && echo 'You must pass DEPLOYING_COLOR as argument $2' && exit 1 - REGION="us-east-1" API_URL="https://api-${DEPLOYING_COLOR}.${EFCMS_DOMAIN}" WS_URL="wss://ws-${DEPLOYING_COLOR}.${EFCMS_DOMAIN}" @@ -27,4 +26,4 @@ else SCANNER_RESOURCE_URI="${DYNAMSOFT_URL_OVERRIDE}/dynamic-web-twain-sdk-14.3.1" fi -STAGE="${ENV}" CIRCLE_SHA1="${CIRCLE_SHA1}" SESSION_TIMEOUT=3300000 COGNITO_CLIENT_ID="${CLIENT_ID}" SCANNER_RESOURCE_URI="${SCANNER_RESOURCE_URI}" COGNITO_TOKEN_URL="${COGNITO_TOKEN_URL}" COGNITO_REDIRECT_URI="${COGNITO_REDIRECT_URI}" WS_URL="${WS_URL}" API_URL="${API_URL}" COGNITO_LOGIN_URL="${COGNITO_LOGIN_URL}" CIRCLE_HONEYBADGER_API_KEY="${CIRCLE_HONEYBADGER_API_KEY}" npm run build:client +STAGE="${CLIENT_STAGE}" CIRCLE_SHA1="${CIRCLE_SHA1}" SESSION_TIMEOUT=3300000 COGNITO_CLIENT_ID="${CLIENT_ID}" SCANNER_RESOURCE_URI="${SCANNER_RESOURCE_URI}" COGNITO_TOKEN_URL="${COGNITO_TOKEN_URL}" COGNITO_REDIRECT_URI="${COGNITO_REDIRECT_URI}" WS_URL="${WS_URL}" API_URL="${API_URL}" COGNITO_LOGIN_URL="${COGNITO_LOGIN_URL}" CIRCLE_HONEYBADGER_API_KEY="${CIRCLE_HONEYBADGER_API_KEY}" npm run build:client From 857b394f015339d0d5dbe29c45fa7ada6e2fe695 Mon Sep 17 00:00:00 2001 From: Michael Marcotte Date: Fri, 11 Dec 2020 15:53:04 -0500 Subject: [PATCH 11/17] ensure CLIENT_STAGE env var is available --- .circleci/config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index c1c9cfe96de..73ca2919e92 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -583,6 +583,7 @@ jobs: -e "AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}" \ -e "CIRCLE_HONEYBADGER_API_KEY=${CIRCLE_HONEYBADGER_API_KEY}" \ -e "CIRCLE_SHA1=${CIRCLE_SHA1}" \ + -e "CLIENT_STAGE=${CLIENT_STAGE}" \ -e "COGNITO_SUFFIX=${COGNITO_SUFFIX}" \ -e "CURRENT_COLOR=${CURRENT_COLOR}" \ -e "DEPLOYING_COLOR=${DEPLOYING_COLOR}" \ @@ -596,6 +597,7 @@ jobs: -e "AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}" \ -e "AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}" \ -e "CIRCLE_SHA1=${CIRCLE_SHA1}" \ + -e "CLIENT_STAGE=${CLIENT_STAGE}" \ -e "COGNITO_SUFFIX=${COGNITO_SUFFIX}" \ -e "CURRENT_COLOR=${CURRENT_COLOR}" \ -e "DEPLOYING_COLOR=${DEPLOYING_COLOR}" \ From a4b901cb4a8d77023eae78fed1d7ea523ac04ec0 Mon Sep 17 00:00:00 2001 From: Michael Marcotte Date: Mon, 14 Dec 2020 01:18:17 -0500 Subject: [PATCH 12/17] ustc-581: improve visibility for scraping pdfs --- .../account-specific/main/lambda-logs-to-elasticsearch.tf | 8 ++++++++ web-api/terraform/template/legacy-document-migration.tf | 1 + 2 files changed, 9 insertions(+) diff --git a/iam/terraform/account-specific/main/lambda-logs-to-elasticsearch.tf b/iam/terraform/account-specific/main/lambda-logs-to-elasticsearch.tf index 28ea1be4d6a..41853dcb27d 100644 --- a/iam/terraform/account-specific/main/lambda-logs-to-elasticsearch.tf +++ b/iam/terraform/account-specific/main/lambda-logs-to-elasticsearch.tf @@ -111,3 +111,11 @@ resource "aws_cloudwatch_log_subscription_filter" "api_stage_logs_green" { name = "api_stage_logs_lambda_filter" log_group_name = "/aws/apigateway/gateway_api_${element(var.log_group_environments, count.index)}_green" } + +resource "aws_cloudwatch_log_subscription_filter" "legacy_documents_lambda_filter" { + count = length(var.log_group_environments) + destination_arn = aws_lambda_function.logs_to_es.arn + filter_pattern = "" + name = "legacy_documents_${element(var.log_group_environments, count.index)}_lambda_filter" + log_group_name = "/aws/lambda/legacy_documents_migration_lambda_${element(var.log_group_environments, count.index)}" +} \ No newline at end of file diff --git a/web-api/terraform/template/legacy-document-migration.tf b/web-api/terraform/template/legacy-document-migration.tf index 9449ae5e72c..0b9d40b6b35 100644 --- a/web-api/terraform/template/legacy-document-migration.tf +++ b/web-api/terraform/template/legacy-document-migration.tf @@ -26,6 +26,7 @@ resource "aws_lambda_function" "legacy_documents_migration_lambda" { DYNAMODB_ENDPOINT = "dynamodb.us-east-1.amazonaws.com" STAGE = var.environment DYNAMODB_TABLE_NAME = var.destination_table + NODE_ENV = "production" } } } From 09483a09f1b46ebd295be96680a99200080f0b85 Mon Sep 17 00:00:00 2001 From: Michael Marcotte Date: Mon, 14 Dec 2020 01:22:44 -0500 Subject: [PATCH 13/17] ustc-581: validate before sending to persistance --- .../useCases/migration/parseLegacyDocumentsInteractor.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/shared/src/business/useCases/migration/parseLegacyDocumentsInteractor.js b/shared/src/business/useCases/migration/parseLegacyDocumentsInteractor.js index e12624077f2..dd44d6771e8 100644 --- a/shared/src/business/useCases/migration/parseLegacyDocumentsInteractor.js +++ b/shared/src/business/useCases/migration/parseLegacyDocumentsInteractor.js @@ -1,4 +1,5 @@ const { Case } = require('../../entities/cases/Case'); +const { DocketEntry } = require('../../entities/DocketEntry'); /** * @@ -75,10 +76,14 @@ exports.parseLegacyDocumentsInteractor = async ({ foundDocketEntry.documentContentsId = documentContentsId; + const validatedDocketEntry = new DocketEntry(foundDocketEntry, { + applicationContext, + }).validate(); + await applicationContext.getPersistenceGateway().updateDocketEntry({ applicationContext, docketEntryId: foundDocketEntry.docketEntryId, docketNumber: caseEntity.docketNumber, - document: foundDocketEntry, + document: validatedDocketEntry, }); }; From cd4bf08eeccb5da45bd510a1323303b46e8ccb55 Mon Sep 17 00:00:00 2001 From: Michael Marcotte Date: Mon, 14 Dec 2020 01:24:09 -0500 Subject: [PATCH 14/17] ustc-591: fix whitespace --- .../account-specific/main/lambda-logs-to-elasticsearch.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iam/terraform/account-specific/main/lambda-logs-to-elasticsearch.tf b/iam/terraform/account-specific/main/lambda-logs-to-elasticsearch.tf index 41853dcb27d..32ec0d8d101 100644 --- a/iam/terraform/account-specific/main/lambda-logs-to-elasticsearch.tf +++ b/iam/terraform/account-specific/main/lambda-logs-to-elasticsearch.tf @@ -118,4 +118,4 @@ resource "aws_cloudwatch_log_subscription_filter" "legacy_documents_lambda_filte filter_pattern = "" name = "legacy_documents_${element(var.log_group_environments, count.index)}_lambda_filter" log_group_name = "/aws/lambda/legacy_documents_migration_lambda_${element(var.log_group_environments, count.index)}" -} \ No newline at end of file +} From fb776fb966f5f66e00c048744430d1319abd520c Mon Sep 17 00:00:00 2001 From: Michael Marcotte Date: Mon, 14 Dec 2020 09:45:03 -0500 Subject: [PATCH 15/17] ustc-581: improve logging for scraping --- .../parseLegacyDocumentsInteractor.js | 3 ++ .../lambdas/legacy-documents-migration.js | 31 ++++++++++++------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/shared/src/business/useCases/migration/parseLegacyDocumentsInteractor.js b/shared/src/business/useCases/migration/parseLegacyDocumentsInteractor.js index dd44d6771e8..a41c90ea2d3 100644 --- a/shared/src/business/useCases/migration/parseLegacyDocumentsInteractor.js +++ b/shared/src/business/useCases/migration/parseLegacyDocumentsInteractor.js @@ -86,4 +86,7 @@ exports.parseLegacyDocumentsInteractor = async ({ docketNumber: caseEntity.docketNumber, document: validatedDocketEntry, }); + applicationContext.logger.info( + `Successfully scraped ${docketNumber}: ${docketEntryId}`, + ); }; diff --git a/web-api/terraform/template/lambdas/legacy-documents-migration.js b/web-api/terraform/template/lambdas/legacy-documents-migration.js index 672f189a146..3581282d9a3 100644 --- a/web-api/terraform/template/lambdas/legacy-documents-migration.js +++ b/web-api/terraform/template/lambdas/legacy-documents-migration.js @@ -11,17 +11,24 @@ exports.handler = async event => { `About to process legacy document for case:${docketNumber}, docketEntryId: ${docketEntryId}`, ); - await applicationContext.getUseCases().parseLegacyDocumentsInteractor({ - applicationContext, - docketEntryId, - docketNumber, - }); + try { + await applicationContext.getUseCases().parseLegacyDocumentsInteractor({ + applicationContext, + docketEntryId, + docketNumber, + }); - const sqs = applicationContext.getQueueService(); - await sqs - .deleteMessage({ - QueueUrl: process.env.MIGRATE_LEGACY_DOCUMENTS_QUEUE_URL, - ReceiptHandle: receiptHandle, - }) - .promise(); + const sqs = applicationContext.getQueueService(); + await sqs + .deleteMessage({ + QueueUrl: process.env.MIGRATE_LEGACY_DOCUMENTS_QUEUE_URL, + ReceiptHandle: receiptHandle, + }) + .promise(); + } catch (err) { + applicationContext.logger.error( + `Failed processing legacy document ${docketNumber}, ${docketEntryId}: ${err.message}`, + err, + ); + } }; From 0244c6cf42854c839cb1bf7126bbb0b7e9efd10e Mon Sep 17 00:00:00 2001 From: Michael Marcotte Date: Mon, 14 Dec 2020 10:19:39 -0500 Subject: [PATCH 16/17] ustc-581: decide when we throw the error --- .../lambdas/legacy-documents-migration.js | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/web-api/terraform/template/lambdas/legacy-documents-migration.js b/web-api/terraform/template/lambdas/legacy-documents-migration.js index 3581282d9a3..2f34944a8ee 100644 --- a/web-api/terraform/template/lambdas/legacy-documents-migration.js +++ b/web-api/terraform/template/lambdas/legacy-documents-migration.js @@ -17,18 +17,28 @@ exports.handler = async event => { docketEntryId, docketNumber, }); - - const sqs = applicationContext.getQueueService(); - await sqs - .deleteMessage({ - QueueUrl: process.env.MIGRATE_LEGACY_DOCUMENTS_QUEUE_URL, - ReceiptHandle: receiptHandle, - }) - .promise(); } catch (err) { applicationContext.logger.error( `Failed processing legacy document ${docketNumber}, ${docketEntryId}: ${err.message}`, err, ); + + // try again if error does not have one of the following + if ( + !( + err.message.includes('Docket entry document not found in S3.') || + err.message.includes('Docket entry not found.') + ) + ) { + throw err; + } } + + const sqs = applicationContext.getQueueService(); + await sqs + .deleteMessage({ + QueueUrl: process.env.MIGRATE_LEGACY_DOCUMENTS_QUEUE_URL, + ReceiptHandle: receiptHandle, + }) + .promise(); }; From 6fb811130d8dde42e6b1b885109ec3ac2a999527 Mon Sep 17 00:00:00 2001 From: Andrew Dunkman Date: Mon, 14 Dec 2020 10:55:55 -0500 Subject: [PATCH 17/17] Add statuspage embed to CSP. --- .../common/cloudfront-edge/header-security-lambda.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/web-client/terraform/common/cloudfront-edge/header-security-lambda.js b/web-client/terraform/common/cloudfront-edge/header-security-lambda.js index 82c0af1e80b..711631daf50 100644 --- a/web-client/terraform/common/cloudfront-edge/header-security-lambda.js +++ b/web-client/terraform/common/cloudfront-edge/header-security-lambda.js @@ -37,6 +37,7 @@ exports.handler = (event, context, callback) => { const localUrl = 'https://127.0.0.1:*'; const localWebsocketUrl = 'ws://127.0.0.1:*'; const s3Url = 'https://s3.us-east-1.amazonaws.com'; + const statuspageUrl = 'https://lynmjtcq5px1.statuspage.io'; const contentSecurityPolicy = [ 'base-uri resource://pdf.js', `connect-src ${subdomainsUrl} ${applicationUrl} ${cognitoUrl} ${s3Url} ${dynamsoftUrl} ${localUrl} ${websocketUrl} ${localWebsocketUrl} ${honeybadgerApiUrl}`, @@ -44,11 +45,11 @@ exports.handler = (event, context, callback) => { "manifest-src 'self'", `form-action ${applicationUrl} ${subdomainsUrl}`, `object-src ${subdomainsUrl} ${applicationUrl} ${s3Url}`, - `script-src 'self' 'unsafe-inline' ${dynamsoftUrl} resource://pdf.js`, + `script-src 'self' 'unsafe-inline' ${dynamsoftUrl} ${statuspageUrl} resource://pdf.js`, `style-src 'self' 'unsafe-inline' ${dynamsoftUrl}`, `img-src ${applicationUrl} ${subdomainsUrl} data:`, `font-src ${applicationUrl} ${subdomainsUrl}`, - `frame-src ${s3Url} ${subdomainsUrl} blob: data:`, + `frame-src ${s3Url} ${subdomainsUrl} ${statuspageUrl} blob: data:`, "frame-ancestors 'none'", ]; headers['content-security-policy'] = [