diff --git a/docs/adr/assets/ADR-003/examples/python/requirements.txt b/docs/adr/assets/ADR-003/examples/python/requirements.txt index b7e317b4b..2217ba554 100644 --- a/docs/adr/assets/ADR-003/examples/python/requirements.txt +++ b/docs/adr/assets/ADR-003/examples/python/requirements.txt @@ -1,2 +1,2 @@ -PyJWT==2.8.0 +PyJWT==2.12.0 requests==2.32.4 diff --git a/docs/package-lock.json b/docs/package-lock.json index 61fcc55fb..9f15a54f7 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -1911,10 +1911,13 @@ } }, "node_modules/dompurify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.1.tgz", - "integrity": "sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.2.tgz", + "integrity": "sha512-6obghkliLdmKa56xdbLOpUZ43pAR6xFy1uOrxBaIDjT+yaRuuybLjGS9eVBoSR/UPU5fq3OXClEHLJNGvbxKpQ==", "license": "(MPL-2.0 OR Apache-2.0)", + "engines": { + "node": ">=20" + }, "optionalDependencies": { "@types/trusted-types": "^2.0.7" } diff --git a/infrastructure/terraform/components/dl/README.md b/infrastructure/terraform/components/dl/README.md index 9ccc01058..114d77e76 100644 --- a/infrastructure/terraform/components/dl/README.md +++ b/infrastructure/terraform/components/dl/README.md @@ -18,6 +18,7 @@ No requirements. | [aws\_account\_id](#input\_aws\_account\_id) | The AWS Account ID (numeric) | `string` | n/a | yes | | [aws\_account\_type](#input\_aws\_account\_type) | The AWS Account Type | `string` | n/a | yes | | [component](#input\_component) | The variable encapsulating the name of this component | `string` | `"dl"` | no | +| [core\_notify\_include\_auth\_header](#input\_core\_notify\_include\_auth\_header) | Whether to send auth tokens with core notify API calls. | `bool` | `true` | no | | [core\_notify\_url](#input\_core\_notify\_url) | The URL used to send requests to Notify | `string` | `"https://sandbox.api.service.nhs.uk"` | no | | [default\_cloudwatch\_event\_bus\_name](#input\_default\_cloudwatch\_event\_bus\_name) | The name of the default cloudwatch event bus. This is needed as GuardDuty Scan Result events are sent to the default bus | `string` | `"default"` | no | | [default\_tags](#input\_default\_tags) | A map of default tags to apply to all taggable resources within the component | `map(string)` | `{}` | no | @@ -25,7 +26,7 @@ No requirements. | [enable\_event\_anomaly\_detection](#input\_enable\_event\_anomaly\_detection) | Enable CloudWatch anomaly detection alarm for core notifier queue message reception | `bool` | `true` | no | | [enable\_event\_cache](#input\_enable\_event\_cache) | Enable caching of events to an S3 bucket | `bool` | `true` | no | | [enable\_mock\_mesh](#input\_enable\_mock\_mesh) | Enable mock mesh access (dev only). Grants lambda permission to read mock-mesh prefix in non-pii bucket. | `bool` | `false` | no | -| [enable\_pdm\_mock](#input\_enable\_pdm\_mock) | Flag indicating whether to deploy PDM mock API (should be false in production environments) | `bool` | `true` | no | +| [enable\_pdm\_mock](#input\_enable\_pdm\_mock) | Flag indicating whether to deploy PDM mock API (should be false in production environments) | `bool` | `false` | no | | [enable\_sns\_delivery\_logging](#input\_enable\_sns\_delivery\_logging) | Enable SNS Delivery Failure Notifications | `bool` | `true` | no | | [environment](#input\_environment) | The name of the tfscaffold environment | `string` | n/a | yes | | [event\_anomaly\_band\_width](#input\_event\_anomaly\_band\_width) | The width of the anomaly detection band. Higher values (e.g. 4-6) reduce sensitivity and noise, lower values (e.g. 2-3) increase sensitivity. Recommended: 2-4. | `number` | `3` | no | @@ -42,8 +43,6 @@ No requirements. | [mesh\_poll\_schedule](#input\_mesh\_poll\_schedule) | Schedule to poll MESH for messages | `string` | `"rate(5 minutes)"` | no | | [metadata\_refresh\_schedule](#input\_metadata\_refresh\_schedule) | Schedule for refreshing reporting metadata. | `string` | `"cron(10 6-22 * * ? *)"` | no | | [parent\_acct\_environment](#input\_parent\_acct\_environment) | Name of the environment responsible for the acct resources used, affects things like DNS zone. Useful for named dev environments | `string` | `"main"` | no | -| [pdm\_mock\_access\_token](#input\_pdm\_mock\_access\_token) | Mock access token for PDM API authentication (used in local/dev environments) | `string` | `"mock-pdm-token"` | no | -| [pdm\_use\_non\_mock\_token](#input\_pdm\_use\_non\_mock\_token) | Whether to use the shared APIM access token from SSM (/component/environment/apim/access\_token) instead of the mock token | `bool` | `false` | no | | [pii\_data\_retention\_non\_current\_days](#input\_pii\_data\_retention\_non\_current\_days) | The number of non current days for data retention policy for PII | `number` | `14` | no | | [pii\_data\_retention\_policy\_days](#input\_pii\_data\_retention\_policy\_days) | The number of days for data retention policy for PII | `number` | `534` | no | | [project](#input\_project) | The name of the tfscaffold project | `string` | n/a | yes | diff --git a/infrastructure/terraform/components/dl/aws_api_gateway_deployment_pdm_mock.tf b/infrastructure/terraform/components/dl/aws_api_gateway_deployment_pdm_mock.tf index c6c39b1b0..b3d9a305f 100644 --- a/infrastructure/terraform/components/dl/aws_api_gateway_deployment_pdm_mock.tf +++ b/infrastructure/terraform/components/dl/aws_api_gateway_deployment_pdm_mock.tf @@ -1,5 +1,5 @@ resource "aws_api_gateway_deployment" "pdm_mock" { - count = local.deploy_pdm_mock ? 1 : 0 + count = var.enable_pdm_mock ? 1 : 0 depends_on = [ aws_api_gateway_integration.create_document_reference, diff --git a/infrastructure/terraform/components/dl/aws_api_gateway_integration_create_document_reference.tf b/infrastructure/terraform/components/dl/aws_api_gateway_integration_create_document_reference.tf index 3d8568b4b..4db48b6cc 100644 --- a/infrastructure/terraform/components/dl/aws_api_gateway_integration_create_document_reference.tf +++ b/infrastructure/terraform/components/dl/aws_api_gateway_integration_create_document_reference.tf @@ -1,5 +1,5 @@ resource "aws_api_gateway_integration" "create_document_reference" { - count = local.deploy_pdm_mock ? 1 : 0 + count = var.enable_pdm_mock ? 1 : 0 rest_api_id = aws_api_gateway_rest_api.pdm_mock[0].id resource_id = aws_api_gateway_resource.document_reference[0].id diff --git a/infrastructure/terraform/components/dl/aws_api_gateway_integration_get_document_reference.tf b/infrastructure/terraform/components/dl/aws_api_gateway_integration_get_document_reference.tf index 6ac602e68..67a329e69 100644 --- a/infrastructure/terraform/components/dl/aws_api_gateway_integration_get_document_reference.tf +++ b/infrastructure/terraform/components/dl/aws_api_gateway_integration_get_document_reference.tf @@ -1,5 +1,5 @@ resource "aws_api_gateway_integration" "get_document_reference" { - count = local.deploy_pdm_mock ? 1 : 0 + count = var.enable_pdm_mock ? 1 : 0 rest_api_id = aws_api_gateway_rest_api.pdm_mock[0].id resource_id = aws_api_gateway_resource.document_reference_id[0].id diff --git a/infrastructure/terraform/components/dl/aws_api_gateway_method_create_document_reference.tf b/infrastructure/terraform/components/dl/aws_api_gateway_method_create_document_reference.tf index c2d1d30c9..773b9f2eb 100644 --- a/infrastructure/terraform/components/dl/aws_api_gateway_method_create_document_reference.tf +++ b/infrastructure/terraform/components/dl/aws_api_gateway_method_create_document_reference.tf @@ -1,5 +1,5 @@ resource "aws_api_gateway_method" "create_document_reference" { - count = local.deploy_pdm_mock ? 1 : 0 + count = var.enable_pdm_mock ? 1 : 0 rest_api_id = aws_api_gateway_rest_api.pdm_mock[0].id resource_id = aws_api_gateway_resource.document_reference[0].id diff --git a/infrastructure/terraform/components/dl/aws_api_gateway_method_get_document_reference.tf b/infrastructure/terraform/components/dl/aws_api_gateway_method_get_document_reference.tf index 56ac1b430..f8bb677fe 100644 --- a/infrastructure/terraform/components/dl/aws_api_gateway_method_get_document_reference.tf +++ b/infrastructure/terraform/components/dl/aws_api_gateway_method_get_document_reference.tf @@ -1,5 +1,5 @@ resource "aws_api_gateway_method" "get_document_reference" { - count = local.deploy_pdm_mock ? 1 : 0 + count = var.enable_pdm_mock ? 1 : 0 rest_api_id = aws_api_gateway_rest_api.pdm_mock[0].id resource_id = aws_api_gateway_resource.document_reference_id[0].id diff --git a/infrastructure/terraform/components/dl/aws_api_gateway_resource_document_reference.tf b/infrastructure/terraform/components/dl/aws_api_gateway_resource_document_reference.tf index e3238ab02..aafefe818 100644 --- a/infrastructure/terraform/components/dl/aws_api_gateway_resource_document_reference.tf +++ b/infrastructure/terraform/components/dl/aws_api_gateway_resource_document_reference.tf @@ -1,5 +1,5 @@ resource "aws_api_gateway_resource" "document_reference" { - count = local.deploy_pdm_mock ? 1 : 0 + count = var.enable_pdm_mock ? 1 : 0 rest_api_id = aws_api_gateway_rest_api.pdm_mock[0].id parent_id = aws_api_gateway_resource.r4[0].id diff --git a/infrastructure/terraform/components/dl/aws_api_gateway_resource_document_reference_id.tf b/infrastructure/terraform/components/dl/aws_api_gateway_resource_document_reference_id.tf index bdc24b46e..5ebe66d6a 100644 --- a/infrastructure/terraform/components/dl/aws_api_gateway_resource_document_reference_id.tf +++ b/infrastructure/terraform/components/dl/aws_api_gateway_resource_document_reference_id.tf @@ -1,5 +1,5 @@ resource "aws_api_gateway_resource" "document_reference_id" { - count = local.deploy_pdm_mock ? 1 : 0 + count = var.enable_pdm_mock ? 1 : 0 rest_api_id = aws_api_gateway_rest_api.pdm_mock[0].id parent_id = aws_api_gateway_resource.document_reference[0].id diff --git a/infrastructure/terraform/components/dl/aws_api_gateway_resource_fhir.tf b/infrastructure/terraform/components/dl/aws_api_gateway_resource_fhir.tf index 24dbdbb49..e11412ab1 100644 --- a/infrastructure/terraform/components/dl/aws_api_gateway_resource_fhir.tf +++ b/infrastructure/terraform/components/dl/aws_api_gateway_resource_fhir.tf @@ -1,5 +1,5 @@ resource "aws_api_gateway_resource" "fhir" { - count = local.deploy_pdm_mock ? 1 : 0 + count = var.enable_pdm_mock ? 1 : 0 rest_api_id = aws_api_gateway_rest_api.pdm_mock[0].id parent_id = aws_api_gateway_resource.patient_data_manager[0].id diff --git a/infrastructure/terraform/components/dl/aws_api_gateway_resource_patient_data_manager.tf b/infrastructure/terraform/components/dl/aws_api_gateway_resource_patient_data_manager.tf index d08d6b43c..bc3b1326a 100644 --- a/infrastructure/terraform/components/dl/aws_api_gateway_resource_patient_data_manager.tf +++ b/infrastructure/terraform/components/dl/aws_api_gateway_resource_patient_data_manager.tf @@ -1,5 +1,5 @@ resource "aws_api_gateway_resource" "patient_data_manager" { - count = local.deploy_pdm_mock ? 1 : 0 + count = var.enable_pdm_mock ? 1 : 0 rest_api_id = aws_api_gateway_rest_api.pdm_mock[0].id parent_id = aws_api_gateway_rest_api.pdm_mock[0].root_resource_id diff --git a/infrastructure/terraform/components/dl/aws_api_gateway_resource_r4.tf b/infrastructure/terraform/components/dl/aws_api_gateway_resource_r4.tf index e5075157e..e008f32b9 100644 --- a/infrastructure/terraform/components/dl/aws_api_gateway_resource_r4.tf +++ b/infrastructure/terraform/components/dl/aws_api_gateway_resource_r4.tf @@ -1,5 +1,5 @@ resource "aws_api_gateway_resource" "r4" { - count = local.deploy_pdm_mock ? 1 : 0 + count = var.enable_pdm_mock ? 1 : 0 rest_api_id = aws_api_gateway_rest_api.pdm_mock[0].id parent_id = aws_api_gateway_resource.fhir[0].id diff --git a/infrastructure/terraform/components/dl/aws_api_gateway_rest_api_pdm_mock.tf b/infrastructure/terraform/components/dl/aws_api_gateway_rest_api_pdm_mock.tf index b9dd89141..14053b9ac 100644 --- a/infrastructure/terraform/components/dl/aws_api_gateway_rest_api_pdm_mock.tf +++ b/infrastructure/terraform/components/dl/aws_api_gateway_rest_api_pdm_mock.tf @@ -1,5 +1,5 @@ resource "aws_api_gateway_rest_api" "pdm_mock" { - count = local.deploy_pdm_mock ? 1 : 0 + count = var.enable_pdm_mock ? 1 : 0 name = "${var.project}-${var.environment}-pdm-mock" description = "PDM Mock API for testing integration with Patient Data Manager" diff --git a/infrastructure/terraform/components/dl/aws_api_gateway_stage_pdm_mock.tf b/infrastructure/terraform/components/dl/aws_api_gateway_stage_pdm_mock.tf index 28cfd8d7b..439b2877f 100644 --- a/infrastructure/terraform/components/dl/aws_api_gateway_stage_pdm_mock.tf +++ b/infrastructure/terraform/components/dl/aws_api_gateway_stage_pdm_mock.tf @@ -1,5 +1,5 @@ resource "aws_api_gateway_stage" "pdm_mock" { - count = local.deploy_pdm_mock ? 1 : 0 + count = var.enable_pdm_mock ? 1 : 0 deployment_id = aws_api_gateway_deployment.pdm_mock[0].id rest_api_id = aws_api_gateway_rest_api.pdm_mock[0].id diff --git a/infrastructure/terraform/components/dl/aws_cloudwatch_log_group_pdm_mock_gateway.tf b/infrastructure/terraform/components/dl/aws_cloudwatch_log_group_pdm_mock_gateway.tf index fe9f3bd9c..be8b2710e 100644 --- a/infrastructure/terraform/components/dl/aws_cloudwatch_log_group_pdm_mock_gateway.tf +++ b/infrastructure/terraform/components/dl/aws_cloudwatch_log_group_pdm_mock_gateway.tf @@ -1,5 +1,5 @@ resource "aws_cloudwatch_log_group" "pdm_mock_gateway" { - count = local.deploy_pdm_mock ? 1 : 0 + count = var.enable_pdm_mock ? 1 : 0 name = "/aws/apigateway/${var.project}-${var.environment}-pdm-mock" retention_in_days = var.log_retention_in_days diff --git a/infrastructure/terraform/components/dl/aws_lambda_permission_pdm_mock_gateway.tf b/infrastructure/terraform/components/dl/aws_lambda_permission_pdm_mock_gateway.tf index 92000d638..30ed8dd15 100644 --- a/infrastructure/terraform/components/dl/aws_lambda_permission_pdm_mock_gateway.tf +++ b/infrastructure/terraform/components/dl/aws_lambda_permission_pdm_mock_gateway.tf @@ -1,5 +1,5 @@ resource "aws_lambda_permission" "pdm_mock_gateway" { - count = local.deploy_pdm_mock ? 1 : 0 + count = var.enable_pdm_mock ? 1 : 0 statement_id = "AllowAPIGatewayInvoke" action = "lambda:InvokeFunction" diff --git a/infrastructure/terraform/components/dl/locals.tf b/infrastructure/terraform/components/dl/locals.tf index 042537946..7a1ef5b92 100644 --- a/infrastructure/terraform/components/dl/locals.tf +++ b/infrastructure/terraform/components/dl/locals.tf @@ -4,7 +4,8 @@ locals { apim_keystore_s3_bucket = "nhs-${var.aws_account_id}-${var.region}-${var.environment}-${var.component}-static-assets" apim_private_key_ssm_parameter_name = "/${var.component}/${var.environment}/apim/private_key" aws_lambda_functions_dir_path = "../../../../lambdas" - deploy_pdm_mock = var.enable_pdm_mock + pdm_access_token_ssm_parameter_name = var.enable_pdm_mock ? "" : local.apim_access_token_ssm_parameter_name + pdm_url = var.enable_pdm_mock ? aws_api_gateway_stage.pdm_mock[0].invoke_url : var.apim_base_url firehose_output_path_prefix = "kinesis-firehose-output" log_destination_arn = "arn:aws:logs:${var.region}:${var.shared_infra_account_id}:destination:nhs-main-obs-firehose-logs" mock_mesh_endpoint = "s3://${module.s3bucket_non_pii_data.bucket}/mock-mesh" diff --git a/infrastructure/terraform/components/dl/module_lambda_core_notifier.tf b/infrastructure/terraform/components/dl/module_lambda_core_notifier.tf index b32c43057..e042e8812 100644 --- a/infrastructure/terraform/components/dl/module_lambda_core_notifier.tf +++ b/infrastructure/terraform/components/dl/module_lambda_core_notifier.tf @@ -36,7 +36,7 @@ module "core_notifier" { lambda_env_vars = { "APIM_BASE_URL" = var.core_notify_url - "APIM_ACCESS_TOKEN_SSM_PARAMETER_NAME" = local.apim_access_token_ssm_parameter_name + "APIM_ACCESS_TOKEN_SSM_PARAMETER_NAME" = var.core_notify_include_auth_header ? local.apim_access_token_ssm_parameter_name : "" "EVENT_PUBLISHER_EVENT_BUS_ARN" = aws_cloudwatch_event_bus.main.arn "EVENT_PUBLISHER_DLQ_URL" = module.sqs_event_publisher_errors.sqs_queue_url "ENVIRONMENT" = var.environment diff --git a/infrastructure/terraform/components/dl/module_lambda_file_scanner.tf b/infrastructure/terraform/components/dl/module_lambda_file_scanner.tf index f5aa878c1..8c82c5caf 100644 --- a/infrastructure/terraform/components/dl/module_lambda_file_scanner.tf +++ b/infrastructure/terraform/components/dl/module_lambda_file_scanner.tf @@ -37,7 +37,7 @@ module "file_scanner" { lambda_env_vars = { "DOCUMENT_REFERENCE_BUCKET" = module.s3bucket_pii_data.bucket "UNSCANNED_FILES_BUCKET" = local.unscanned_files_bucket - "UNSCANNED_FILES_PATH_PREFIX" = var.environment + "UNSCANNED_FILES_PATH_PREFIX" = local.csi "EVENT_PUBLISHER_EVENT_BUS_ARN" = aws_cloudwatch_event_bus.main.arn "EVENT_PUBLISHER_DLQ_URL" = module.sqs_event_publisher_errors.sqs_queue_url } diff --git a/infrastructure/terraform/components/dl/module_lambda_pdm_mock.tf b/infrastructure/terraform/components/dl/module_lambda_pdm_mock.tf index c12ce7b0f..e4f04231c 100644 --- a/infrastructure/terraform/components/dl/module_lambda_pdm_mock.tf +++ b/infrastructure/terraform/components/dl/module_lambda_pdm_mock.tf @@ -1,5 +1,5 @@ module "pdm_mock" { - count = local.deploy_pdm_mock ? 1 : 0 + count = var.enable_pdm_mock ? 1 : 0 source = "https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/3.0.6/terraform-lambda.zip" function_name = "pdm-mock" @@ -37,7 +37,7 @@ module "pdm_mock" { } data "aws_iam_policy_document" "pdm_mock" { - count = local.deploy_pdm_mock ? 1 : 0 + count = var.enable_pdm_mock ? 1 : 0 statement { sid = "KMSPermissions" diff --git a/infrastructure/terraform/components/dl/module_lambda_pdm_poll.tf b/infrastructure/terraform/components/dl/module_lambda_pdm_poll.tf index 9708fd250..e4b1a4705 100644 --- a/infrastructure/terraform/components/dl/module_lambda_pdm_poll.tf +++ b/infrastructure/terraform/components/dl/module_lambda_pdm_poll.tf @@ -35,8 +35,8 @@ module "pdm_poll" { log_subscription_role_arn = local.acct.log_subscription_role_arn lambda_env_vars = { - "APIM_BASE_URL" = local.deploy_pdm_mock ? aws_api_gateway_stage.pdm_mock[0].invoke_url : var.apim_base_url - "APIM_ACCESS_TOKEN_SSM_PARAMETER_NAME" = local.apim_access_token_ssm_parameter_name + "APIM_BASE_URL" = local.pdm_url + "APIM_ACCESS_TOKEN_SSM_PARAMETER_NAME" = local.pdm_access_token_ssm_parameter_name "EVENT_PUBLISHER_EVENT_BUS_ARN" = aws_cloudwatch_event_bus.main.arn "EVENT_PUBLISHER_DLQ_URL" = module.sqs_event_publisher_errors.sqs_queue_url "POLL_MAX_RETRIES" = 10 diff --git a/infrastructure/terraform/components/dl/module_lambda_pdm_uploader.tf b/infrastructure/terraform/components/dl/module_lambda_pdm_uploader.tf index 032579705..46c92c72a 100644 --- a/infrastructure/terraform/components/dl/module_lambda_pdm_uploader.tf +++ b/infrastructure/terraform/components/dl/module_lambda_pdm_uploader.tf @@ -35,8 +35,8 @@ module "pdm_uploader" { log_subscription_role_arn = local.acct.log_subscription_role_arn lambda_env_vars = { - "APIM_BASE_URL" = var.apim_base_url - "APIM_ACCESS_TOKEN_SSM_PARAMETER_NAME" = local.apim_access_token_ssm_parameter_name + "APIM_BASE_URL" = local.pdm_url + "APIM_ACCESS_TOKEN_SSM_PARAMETER_NAME" = local.pdm_access_token_ssm_parameter_name "EVENT_PUBLISHER_EVENT_BUS_ARN" = aws_cloudwatch_event_bus.main.arn "EVENT_PUBLISHER_DLQ_URL" = module.sqs_event_publisher_errors.sqs_queue_url } diff --git a/infrastructure/terraform/components/dl/ssm_parameter_access_token.tf b/infrastructure/terraform/components/dl/ssm_parameter_access_token.tf index 06bcc66fd..8bc514985 100644 --- a/infrastructure/terraform/components/dl/ssm_parameter_access_token.tf +++ b/infrastructure/terraform/components/dl/ssm_parameter_access_token.tf @@ -2,9 +2,8 @@ resource "aws_ssm_parameter" "access_token" { name = local.apim_access_token_ssm_parameter_name description = "Access token for APIM" type = "SecureString" - value = jsonencode({ - tokens = [] - }) + value = jsonencode({}) + tags = merge(local.default_tags, { Backup = "true" }) lifecycle { diff --git a/infrastructure/terraform/components/dl/variables.tf b/infrastructure/terraform/components/dl/variables.tf index c52dcfb7a..e7bd7424c 100644 --- a/infrastructure/terraform/components/dl/variables.tf +++ b/infrastructure/terraform/components/dl/variables.tf @@ -122,18 +122,6 @@ variable "ttl_poll_schedule" { default = "rate(10 minutes)" # Every 10 minutes } -variable "pdm_mock_access_token" { - type = string - description = "Mock access token for PDM API authentication (used in local/dev environments)" - default = "mock-pdm-token" -} - -variable "pdm_use_non_mock_token" { - type = bool - description = "Whether to use the shared APIM access token from SSM (/component/environment/apim/access_token) instead of the mock token" - default = false -} - variable "apim_base_url" { type = string description = "The URL used to send requests to PDM" @@ -146,6 +134,17 @@ variable "core_notify_url" { default = "https://sandbox.api.service.nhs.uk" } +variable "core_notify_include_auth_header" { + type = bool + description = "Whether to send auth tokens with core notify API calls." + default = true + + validation { + condition = var.environment == "prod" ? var.core_notify_include_auth_header == true : true + error_message = "core_notify_include_auth_header must be set to true when environment is 'prod'." + } +} + variable "apim_auth_token_url" { type = string description = "URL to generate an APIM auth token" @@ -178,7 +177,7 @@ variable "force_destroy" { variable "enable_pdm_mock" { type = bool description = "Flag indicating whether to deploy PDM mock API (should be false in production environments)" - default = true + default = false } variable "aws_account_type" { diff --git a/lambdas/pdm-mock-lambda/README.md b/lambdas/pdm-mock-lambda/README.md index c0ec5b0cd..18367161b 100644 --- a/lambdas/pdm-mock-lambda/README.md +++ b/lambdas/pdm-mock-lambda/README.md @@ -19,7 +19,6 @@ Creates a new PDM DocumentReference. ```bash curl -X POST https:///patient-data-manager/FHIR/R4/DocumentReference \ - -H "Authorization: Bearer " \ -H "Content-Type: application/fhir+json" \ -H "X-Request-ID: 4a0e5f18-1747-4438-ac52-5ba2c21575f5" \ -d '{}' @@ -27,7 +26,6 @@ curl -X POST https:///patient-data-manager/FHIR/R4/DocumentRefe **Headers:** -- `Authorization: Bearer ` - Authentication token is not validated and can be any string value. - `Content-Type: application/fhir+json` - Required content type. - `X-Request-ID: ` - This uuid will be used as the DocumentReference `id` in the response. @@ -69,14 +67,12 @@ Retrieves a specific PDM DocumentReference by ID. ```bash curl https:///patient-data-manager/FHIR/R4/DocumentReference/test-id \ - -H "Authorization: Bearer " \ -H "Content-Type: application/fhir+json" \ -H "X-Request-ID: 848b67ea-eeaa-3620-a388-e4e8594ff2e3" ``` **Headers:** -- `Authorization: Bearer ` - Authentication token is not validated and can be any string value. - `Content-Type: application/fhir+json` - Required content type. - `X-Request-ID: ` - Used for request tracking and correlation. This isn't part of the ID or response that gets returned. diff --git a/lambdas/pdm-mock-lambda/src/__tests__/authenticator.test.ts b/lambdas/pdm-mock-lambda/src/__tests__/authenticator.test.ts deleted file mode 100644 index 86db5e8c3..000000000 --- a/lambdas/pdm-mock-lambda/src/__tests__/authenticator.test.ts +++ /dev/null @@ -1,74 +0,0 @@ -import type { Logger } from 'utils'; -import { createAuthenticator } from 'authenticator'; - -const mockLogger: Logger = { - debug: jest.fn(), - info: jest.fn(), - warn: jest.fn(), - error: jest.fn(), - child: jest.fn(), -} as any; - -describe('Authenticator', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - describe('with mock token', () => { - it('should authenticate successfully with valid Bearer token', async () => { - const authenticator = createAuthenticator(mockLogger); - - const result = await authenticator({ - headers: { Authorization: 'Bearer test-token' }, - }); - - expect(result.isValid).toBe(true); - }); - - it('should reject request with missing Authorization header', async () => { - const authenticator = createAuthenticator(mockLogger); - - const result = await authenticator({ headers: {} }); - - expect(result.isValid).toBe(false); - expect(result).toHaveProperty('error'); - expect((result as { isValid: false; error: any }).error).toBeDefined(); - expect((result as { isValid: false; error: any }).error.statusCode).toBe( - 401, - ); - expect((result as { isValid: false; error: any }).error.body).toContain( - 'ACCESS_DENIED', - ); - expect((result as { isValid: false; error: any }).error.body).toContain( - 'Missing Authentication Token', - ); - }); - - it('should reject request with invalid token type', async () => { - const authenticator = createAuthenticator(mockLogger); - - const result = await authenticator({ - headers: { Authorization: 'Basic test-token' }, - }); - - expect(result.isValid).toBe(false); - expect(result).toHaveProperty('error'); - expect((result as { isValid: false; error: any }).error.statusCode).toBe( - 401, - ); - expect((result as { isValid: false; error: any }).error.body).toContain( - 'Invalid Access Token', - ); - }); - - it('should handle lowercase authorization header', async () => { - const authenticator = createAuthenticator(mockLogger); - - const result = await authenticator({ - headers: { authorization: 'Bearer test-token' }, - }); - - expect(result.isValid).toBe(true); - }); - }); -}); diff --git a/lambdas/pdm-mock-lambda/src/__tests__/container.test.ts b/lambdas/pdm-mock-lambda/src/__tests__/container.test.ts index 4cfda0ac9..f46136ecd 100644 --- a/lambdas/pdm-mock-lambda/src/__tests__/container.test.ts +++ b/lambdas/pdm-mock-lambda/src/__tests__/container.test.ts @@ -35,16 +35,11 @@ describe('Container', () => { it('should create a container with all required dependencies', () => { expect(container).toBeDefined(); - expect(container.authenticator).toBeDefined(); expect(container.getResourceHandler).toBeDefined(); expect(container.createResourceHandler).toBeDefined(); expect(container.logger).toBeDefined(); }); - it('should create an authenticator function', () => { - expect(typeof container.authenticator).toBe('function'); - }); - it('should create a getResourceHandler function', () => { expect(typeof container.getResourceHandler).toBe('function'); }); @@ -74,14 +69,4 @@ describe('Container', () => { expect(result).toBeDefined(); expect(result.statusCode).toBeDefined(); }); - - it('should create authenticator that can be called', async () => { - const mockEvent = { - headers: { Authorization: 'Bearer test-token' }, - }; - - const result = await container.authenticator(mockEvent); - expect(result).toBeDefined(); - expect(result.isValid).toBeDefined(); - }); }); diff --git a/lambdas/pdm-mock-lambda/src/__tests__/handlers.test.ts b/lambdas/pdm-mock-lambda/src/__tests__/handlers.test.ts index d70357243..3743aa4e6 100644 --- a/lambdas/pdm-mock-lambda/src/__tests__/handlers.test.ts +++ b/lambdas/pdm-mock-lambda/src/__tests__/handlers.test.ts @@ -157,37 +157,37 @@ describe('GET Resource Handler', () => { describe('error scenarios', () => { it.each([ { - id: 'error-400-invalid', + id: 'error-400-invalid-a1b2c3', expectedStatus: 400, expectedCode: 'INVALID_VALUE', }, { - id: 'error-401-unauthorized', + id: 'error-401-unauthorized-d4e5f6', expectedStatus: 401, expectedCode: 'UNAUTHORISED', }, { - id: 'error-403-forbidden', + id: 'error-403-forbidden-7g8h9i', expectedStatus: 403, expectedCode: 'FORBIDDEN', }, { - id: 'error-404-notfound', + id: 'error-404-notfound-a1b2c3', expectedStatus: 404, expectedCode: 'RESOURCE_NOT_FOUND', }, { - id: 'error-429-ratelimit', + id: 'error-429-ratelimit-j8f6l1', expectedStatus: 429, expectedCode: 'TOO_MANY_REQUESTS', }, { - id: 'error-500-internal', + id: 'error-500-internal-i9j0k1', expectedStatus: 500, expectedCode: 'INTERNAL_ERROR', }, { - id: 'error-503-unavailable', + id: 'error-503-unavailable-j1k2l3', expectedStatus: 503, expectedCode: 'SERVICE_UNAVAILABLE', }, diff --git a/lambdas/pdm-mock-lambda/src/__tests__/index.test.ts b/lambdas/pdm-mock-lambda/src/__tests__/index.test.ts index a056396bc..a00e58362 100644 --- a/lambdas/pdm-mock-lambda/src/__tests__/index.test.ts +++ b/lambdas/pdm-mock-lambda/src/__tests__/index.test.ts @@ -8,7 +8,6 @@ import { createContainer } from 'container'; import { handler } from '..'; jest.mock('container', () => { - const mockAuthenticator = jest.fn(); const mockGetResourceHandler = jest.fn(); const mockCreateResourceHandler = jest.fn(); const mockLogger = { @@ -21,7 +20,6 @@ jest.mock('container', () => { return { createContainer: jest.fn(() => ({ - authenticator: mockAuthenticator, getResourceHandler: mockGetResourceHandler, createResourceHandler: mockCreateResourceHandler, logger: mockLogger, @@ -66,7 +64,6 @@ const createMockEvent = ( }; describe('Lambda Handler Integration', () => { - let mockAuthenticator: jest.Mock; let mockGetResourceHandler: jest.Mock; let mockCreateResourceHandler: jest.Mock; @@ -74,33 +71,11 @@ describe('Lambda Handler Integration', () => { jest.clearAllMocks(); const container = createContainer(); - mockAuthenticator = container.authenticator as jest.Mock; mockGetResourceHandler = container.getResourceHandler as jest.Mock; mockCreateResourceHandler = container.createResourceHandler as jest.Mock; }); - it('should return authentication error when authentication fails', async () => { - mockAuthenticator.mockResolvedValue({ - isValid: false, - error: { - statusCode: 401, - body: JSON.stringify({ error: 'Unauthorized' }), - }, - }); - - const event = createMockEvent(); - const response = (await handler( - event, - {} as Context, - {} as Callback, - )) as APIGatewayProxyResult; - - expect(response.statusCode).toBe(401); - expect(mockGetResourceHandler).not.toHaveBeenCalled(); - }); - it('should route GET requests to getResourceHandler', async () => { - mockAuthenticator.mockResolvedValue({ isValid: true }); mockGetResourceHandler.mockResolvedValue({ statusCode: 200, body: JSON.stringify({ id: 'test-id' }), @@ -117,13 +92,11 @@ describe('Lambda Handler Integration', () => { {} as Callback, )) as APIGatewayProxyResult; - expect(mockAuthenticator).toHaveBeenCalledWith(event); expect(mockGetResourceHandler).toHaveBeenCalledWith(event); expect(response.statusCode).toBe(200); }); it('should route POST requests to createResourceHandler', async () => { - mockAuthenticator.mockResolvedValue({ isValid: true }); mockCreateResourceHandler.mockResolvedValue({ statusCode: 201, body: JSON.stringify({ id: 'new-id' }), @@ -141,14 +114,11 @@ describe('Lambda Handler Integration', () => { {} as Callback, )) as APIGatewayProxyResult; - expect(mockAuthenticator).toHaveBeenCalledWith(event); expect(mockCreateResourceHandler).toHaveBeenCalledWith(event); expect(response.statusCode).toBe(201); }); it('should return 404 for unsupported endpoints', async () => { - mockAuthenticator.mockResolvedValue({ isValid: true }); - const event = createMockEvent({ httpMethod: 'DELETE', path: '/unsupported', @@ -165,7 +135,7 @@ describe('Lambda Handler Integration', () => { }); it('should handle unexpected errors gracefully', async () => { - mockAuthenticator.mockRejectedValue(new Error('Unexpected error')); + mockGetResourceHandler.mockRejectedValue(new Error('Unexpected error')); const event = createMockEvent(); const response = (await handler( diff --git a/lambdas/pdm-mock-lambda/src/authenticator.ts b/lambdas/pdm-mock-lambda/src/authenticator.ts deleted file mode 100644 index 000de2dbe..000000000 --- a/lambdas/pdm-mock-lambda/src/authenticator.ts +++ /dev/null @@ -1,66 +0,0 @@ -import type { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda'; -import type { Logger } from 'utils'; - -export type AuthResult = - | { isValid: true } - | { isValid: false; error: APIGatewayProxyResult }; - -export const createAuthenticator = (logger: Logger) => { - return async ( - event: Pick, - ): Promise => { - const authHeader = - event.headers?.Authorization || event.headers?.authorization; - - if (!authHeader) { - logger.warn('Missing Authorization header'); - return { - isValid: false, - error: { - statusCode: 401, - body: JSON.stringify({ - resourceType: 'OperationOutcome', - issue: [ - { - severity: 'error', - code: 'forbidden', - details: { - coding: [{ code: 'ACCESS_DENIED' }], - }, - diagnostics: 'Missing Authentication Token', - }, - ], - }), - }, - }; - } - - const [tokenType] = authHeader.split(' '); - - if (tokenType !== 'Bearer') { - logger.warn(tokenType, 'Invalid token type'); - return { - isValid: false, - error: { - statusCode: 401, - body: JSON.stringify({ - resourceType: 'OperationOutcome', - issue: [ - { - severity: 'error', - code: 'forbidden', - details: { - coding: [{ code: 'ACCESS_DENIED' }], - }, - diagnostics: 'Invalid Access Token', - }, - ], - }), - }, - }; - } - - logger.debug('Authentication successful'); - return { isValid: true }; - }; -}; diff --git a/lambdas/pdm-mock-lambda/src/container.ts b/lambdas/pdm-mock-lambda/src/container.ts index 2824c4652..c8e8caea6 100644 --- a/lambdas/pdm-mock-lambda/src/container.ts +++ b/lambdas/pdm-mock-lambda/src/container.ts @@ -1,25 +1,20 @@ import { logger } from 'utils'; -import { createAuthenticator } from 'authenticator'; import { createCreateResourceHandler, createGetResourceHandler, } from 'handlers'; export interface Container { - authenticator: ReturnType; getResourceHandler: ReturnType; createResourceHandler: ReturnType; logger: typeof logger; } export const createContainer = (): Container => { - const authenticator = createAuthenticator(logger); - const getResourceHandler = createGetResourceHandler(logger); const createResourceHandler = createCreateResourceHandler(logger); return { - authenticator, getResourceHandler, createResourceHandler, logger, diff --git a/lambdas/pdm-mock-lambda/src/handlers.ts b/lambdas/pdm-mock-lambda/src/handlers.ts index a7b5ad1d2..cf3519fd6 100644 --- a/lambdas/pdm-mock-lambda/src/handlers.ts +++ b/lambdas/pdm-mock-lambda/src/handlers.ts @@ -225,7 +225,9 @@ export const createGetResourceHandler = (logger: Logger) => { ); } - const errorScenario = ERROR_SCENARIOS.find((s) => s.id === resourceId); + const errorScenario = ERROR_SCENARIOS.find((s) => + resourceId.startsWith(s.id), + ); if (errorScenario) { logger.debug('Triggering error scenario', { resourceId, @@ -293,7 +295,9 @@ export const createCreateResourceHandler = (logger: Logger) => { requestId, }); - const errorScenario = ERROR_SCENARIOS.find((s) => s.id === resourceId); + const errorScenario = ERROR_SCENARIOS.find((s) => + resourceId.startsWith(s.id), + ); if (errorScenario) { logger.debug('Triggering error scenario', { resourceId, diff --git a/lambdas/pdm-mock-lambda/src/index.ts b/lambdas/pdm-mock-lambda/src/index.ts index d1d185d1e..49b36cefb 100644 --- a/lambdas/pdm-mock-lambda/src/index.ts +++ b/lambdas/pdm-mock-lambda/src/index.ts @@ -11,8 +11,7 @@ export const handler: Handler< APIGatewayProxyEvent, APIGatewayProxyResult > = async (event: APIGatewayProxyEvent): Promise => { - const { authenticator, createResourceHandler, getResourceHandler, logger } = - container; + const { createResourceHandler, getResourceHandler, logger } = container; try { const { requestId } = event.requestContext; @@ -26,12 +25,6 @@ export const handler: Handler< hasAuth: !!event.headers?.Authorization, }); - const authResult = await authenticator(event); - if (!authResult.isValid) { - logger.warn('Authentication failed', { requestId, httpMethod, path }); - return authResult.error; - } - if ( httpMethod === 'GET' && path.includes('/patient-data-manager/FHIR/R4/DocumentReference/') diff --git a/package-lock.json b/package-lock.json index 3bc163f86..177d60c7a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6601,13 +6601,13 @@ } }, "node_modules/@aws-sdk/xml-builder": { - "version": "3.972.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.8.tgz", - "integrity": "sha512-Ql8elcUdYCha83Ol7NznBsgN5GVZnv3vUd86fEc6waU6oUdY0T1O9NODkEEOS/Uaogr87avDrUC6DSeM4oXjZg==", + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.10.tgz", + "integrity": "sha512-OnejAIVD+CxzyAUrVic7lG+3QRltyja9LoNqCE/1YVs8ichoTbJlVSaZ9iSMcnHLyzrSNtvaOGjSDRP+d/ouFA==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.13.0", - "fast-xml-parser": "5.3.6", + "fast-xml-parser": "5.4.1", "tslib": "^2.6.2" }, "engines": { @@ -13555,10 +13555,22 @@ ], "license": "BSD-3-Clause" }, + "node_modules/fast-xml-builder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.0.0.tgz", + "integrity": "sha512-fpZuDogrAgnyt9oDDz+5DBz0zgPdPZz6D4IR7iESxRXElrlGTRkHJ9eEt+SACRJwT0FNFrt71DFQIUFBJfX/uQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, "node_modules/fast-xml-parser": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.6.tgz", - "integrity": "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.4.1.tgz", + "integrity": "sha512-BQ30U1mKkvXQXXkAGcuyUA/GA26oEB7NzOtsxCDtyu62sjGw5QraKFhx2Em3WQNjPw9PG6MQ9yuIIgkSDfGu5A==", "funding": [ { "type": "github", @@ -13567,6 +13579,7 @@ ], "license": "MIT", "dependencies": { + "fast-xml-builder": "^1.0.0", "strnum": "^2.1.2" }, "bin": { @@ -13664,7 +13677,9 @@ } }, "node_modules/flatted": { - "version": "3.3.3", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.1.tgz", + "integrity": "sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==", "dev": true, "license": "ISC" }, @@ -20366,9 +20381,9 @@ } }, "node_modules/strnum": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz", - "integrity": "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.0.tgz", + "integrity": "sha512-Y7Bj8XyJxnPAORMZj/xltsfo55uOiyHcU2tnAVzHUnSJR/KsEX+9RoDeXEnsXtl/CX4fAcrt64gZ13aGaWPeBg==", "funding": [ { "type": "github", diff --git a/src/eventcatalog/package-lock.json b/src/eventcatalog/package-lock.json index d87ce17e7..6ca1bd378 100644 --- a/src/eventcatalog/package-lock.json +++ b/src/eventcatalog/package-lock.json @@ -11402,10 +11402,13 @@ } }, "node_modules/dompurify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.1.tgz", - "integrity": "sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.2.tgz", + "integrity": "sha512-6obghkliLdmKa56xdbLOpUZ43pAR6xFy1uOrxBaIDjT+yaRuuybLjGS9eVBoSR/UPU5fq3OXClEHLJNGvbxKpQ==", "license": "(MPL-2.0 OR Apache-2.0)", + "engines": { + "node": ">=20" + }, "optionalDependencies": { "@types/trusted-types": "^2.0.7" } @@ -12203,9 +12206,9 @@ "license": "Apache-2.0" }, "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.1.tgz", + "integrity": "sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==", "license": "ISC" }, "node_modules/flattie": { @@ -14490,9 +14493,9 @@ } }, "node_modules/jsonpath": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.2.1.tgz", - "integrity": "sha512-Jl6Jhk0jG+kP3yk59SSeGq7LFPR4JQz1DU0K+kXTysUhMostbhU3qh5mjTuf0PqFcXpAT7kvmMt9WxV10NyIgQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.3.0.tgz", + "integrity": "sha512-0kjkYHJBkAy50Z5QzArZ7udmvxrJzkpKYW27fiF//BrMY7TQibYLl+FYIXN2BiYmwMIVzSfD8aDRj6IzgBX2/w==", "license": "MIT", "dependencies": { "esprima": "1.2.5", @@ -23619,9 +23622,9 @@ "license": "MIT" }, "node_modules/undici": { - "version": "7.22.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.22.0.tgz", - "integrity": "sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==", + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.4.tgz", + "integrity": "sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w==", "license": "MIT", "engines": { "node": ">=20.18.1" diff --git a/src/eventcatalog/package.json b/src/eventcatalog/package.json index 4e7ad91c4..8bc324488 100644 --- a/src/eventcatalog/package.json +++ b/src/eventcatalog/package.json @@ -7,8 +7,10 @@ }, "name": "digital-letters", "overrides": { + "astro-compress": { + "svgo": "^4.0.1" + }, "minimatch": "^10.2.4", - "svgo": "^4.0.1", "underscore": "^1.13.8" }, "private": true, diff --git a/tests/playwright/digital-letters-component-tests/file-scanner.component.spec.ts b/tests/playwright/digital-letters-component-tests/file-scanner.component.spec.ts index 1a394d32e..48b277fb7 100644 --- a/tests/playwright/digital-letters-component-tests/file-scanner.component.spec.ts +++ b/tests/playwright/digital-letters-component-tests/file-scanner.component.spec.ts @@ -2,6 +2,7 @@ import { expect, test } from '@playwright/test'; import { ENV, FILE_SCANNER_DLQ_NAME, + PREFIX_DL_FILES, REGION, } from 'constants/backend-constants'; import itemDequeuedValidator from 'digital-letters-events/ItemDequeued.js'; @@ -28,7 +29,7 @@ test.describe('File Scanner', () => { test('should extract PDF from DocumentReference and store in unscanned bucket with metadata', async () => { const messageReference = uuidv4(); const senderId = 'TEST_SENDER_001'; - const documentReferenceKey = messageReference; + const documentReferenceKey = `${PREFIX_DL_FILES}${messageReference}`; const pdfContent = Buffer.from('Sample PDF content for test'); const documentReference = { @@ -80,7 +81,7 @@ test('should extract PDF from DocumentReference and store in unscanned bucket wi ); await expectToPassEventually(async () => { - const expectedKey = `${ENV}/${messageReference}.pdf`; + const expectedKey = `${PREFIX_DL_FILES}${messageReference}.pdf`; const expectedUri = `s3://${UNSCANNED_FILES_BUCKET}/${expectedKey}`; const storedPdf = await getS3ObjectBufferFromUri(expectedUri); diff --git a/tests/playwright/digital-letters-component-tests/pdm-uploader.component.spec.ts b/tests/playwright/digital-letters-component-tests/pdm-uploader.component.spec.ts index b7afdc983..e5ba36dcd 100644 --- a/tests/playwright/digital-letters-component-tests/pdm-uploader.component.spec.ts +++ b/tests/playwright/digital-letters-component-tests/pdm-uploader.component.spec.ts @@ -114,17 +114,22 @@ test.describe('Digital Letters - Upload to PDM', () => { }); test('should send a pdm.resource.submission.rejected event following an error from PDM', async () => { - // Note: I suspect this will fail once we are using the PDM Mock and will need amending. + // Two mechanisms are used to trigger errors from PDM in this test + // - the first is a specific messageReference which the mock PDM is configured to return an error for. + // - the second is an unexpected field in the PDM request which causes the real PDM to return an error. + const messageReference = `error-500-internal-${uuidv4()}`; + const unexpectedField = 'I should not be here'; + const eventId = uuidv4(); const letterId = uuidv4(); const resourceKey = `test/${letterId}`; const messageUri = `s3://${LETTERS_S3_BUCKET_NAME}/${resourceKey}`; - const messageReference = uuidv4(); const senderId = SENDER_ID_SKIPS_NOTIFY; const meshMessageId = '12345'; + const invalidPdmRequest = { ...pdmRequest, - unexpectedField: 'I should not be here', + unexpectedField, }; await putDataS3(invalidPdmRequest, {