diff --git a/client/src/components/esignature-modal/esignature-modal.container.jsx b/client/src/components/esignature-modal/esignature-modal.container.jsx index 58460d4d3..279a74551 100644 --- a/client/src/components/esignature-modal/esignature-modal.container.jsx +++ b/client/src/components/esignature-modal/esignature-modal.container.jsx @@ -67,11 +67,11 @@ export function EsignatureModalContainer({ esignatureModal, toggleModalVisible, destroyOnHidden width={"80%"} > -
+
{token ? ( diff --git a/documenso/cert/certificate.crt b/documenso/cert/certificate.crt new file mode 100644 index 000000000..b6a67ce91 --- /dev/null +++ b/documenso/cert/certificate.crt @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID9zCCAt+gAwIBAgIUTB4OhIqfXvT0mBKHwYAwDPq79ygwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAkNBMQswCQYDVQQIDAJCQzESMBAGA1UEBwwJVmFuY291 +dmVyMRowGAYDVQQKDBFJbUVYIFN5c3RlbXMgSW5jLjEXMBUGA1UEAwwOaW1leHN5 +c3RlbXMuY2ExJTAjBgkqhkiG9w0BCQEWFmNvbnRhY3RAaW1leHN5c3RlbXMuY2Ew +HhcNMjYwNDEzMjAxMDIzWhcNMzYwNDEwMjAxMDIzWjCBijELMAkGA1UEBhMCQ0Ex +CzAJBgNVBAgMAkJDMRIwEAYDVQQHDAlWYW5jb3V2ZXIxGjAYBgNVBAoMEUltRVgg +U3lzdGVtcyBJbmMuMRcwFQYDVQQDDA5pbWV4c3lzdGVtcy5jYTElMCMGCSqGSIb3 +DQEJARYWY29udGFjdEBpbWV4c3lzdGVtcy5jYTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAPE+5bcnfYsMyLzJr50bzpHHP8I+cdSkvu7lwGysPZCCxi4Z +vkIDq4Q5xDa3ZZCeNZ9feELqm9ZjWpnaZj4CMbXMDpIucZHQJC9USCGavYhzNYu2 +G3IU7D834jd8GkwGMQuXkGiuQmQssIZIKfX+MaZ0KKrh8gJbxXZOfCp3fdYOnFPq +BFCR0N/gTbeRboq36dG4vo1FanDLGroMS7FycGjyUTQv3CTWkGAOAPGQVrGZgvYM +DtFr+7M2J/KCbUMobK0uc1scAjLgetXknzVPU3qA66F3Hi7oWykoFX8m9oX/OJnK +/Gt8rIjRMOyQSK7dKT7qXCxgQVQnqHbyUCX4WUkCAwEAAaNTMFEwHQYDVR0OBBYE +FIRKLjeI+adC7yNg6cSDj72Kej11MB8GA1UdIwQYMBaAFIRKLjeI+adC7yNg6cSD +j72Kej11MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAAHCSjlG +bo5miEfisKffPyfzufBIhOLLORasuFQ3gVKBU32JytuoflABfcqy3prgZxbFLMB2 +fDcSImKuOtt79OMeMlA+ptfkWuOpFMqL2j6BilzjJ/MAlPAZlZmmuLh/fPj3lbMD +QQds/YhSmZcTdRX8seQslnYq1AT7629BDbpCjjL3pRkntnePR7u8tgb28Pm8Vl3S +uCnGS/mMxrS/7z+QnaDi1N/nyIwa2bQtGmsoMn+CzuUUjyMD4TYbdUJv+fca8/tR +zezNEHcpBCKGGgZRowhifJwEoel0M1iEo8UYy5eFPDF8CoRGRIH7QSaduCfnej06 +KLtevL/vyhUpTMA= +-----END CERTIFICATE----- diff --git a/documenso/cert/certificate.p12 b/documenso/cert/certificate.p12 new file mode 100644 index 000000000..e329b8a36 Binary files /dev/null and b/documenso/cert/certificate.p12 differ diff --git a/documenso/terraform/README.md b/documenso/terraform/README.md index a3af506a5..ff0ad0818 100644 --- a/documenso/terraform/README.md +++ b/documenso/terraform/README.md @@ -9,7 +9,7 @@ This Terraform stack deploys Documenso to AWS in `ca-central-1` using: - Route53 DNS for `esignature.imex.online` - Optional SES domain identity and DKIM management for outbound email - Secrets Manager for generated application secrets, SMTP credentials, and the optional Documenso signing certificate -- AWS WAF with a basic managed rule set and rate limiting +- AWS WAF with a basic managed rule set, rate limiting, and an allowlist for trusted IPv4 CIDRs - CloudWatch alarms for ALB, ECS, and RDS health indicators ## Why this shape @@ -47,9 +47,10 @@ This is the most practical fit for your Docker Compose workload if you want a ba 2. If you want Documenso signing enabled, add `signing_certificate_base64` and `signing_certificate_passphrase`. 3. Optionally set `upload_bucket_name` if you want a specific S3 bucket name. 4. Set `manage_ses_resources = true` only if you want this stack to own SES identity verification and DKIM records. -5. Run `terraform init`. -6. Run `terraform plan`. -7. Run `terraform apply`. +5. Set `waf_bypass_ipv4_cidrs` with any public `/32` addresses that should bypass WAF inspection. The VPC CIDR is already allowlisted automatically. +6. Run `terraform init`. +7. Run `terraform plan`. +8. Run `terraform apply`. ## Recommended first production adjustments diff --git a/documenso/terraform/main.tf b/documenso/terraform/main.tf index 0fb3a2141..bd76a4ff3 100644 --- a/documenso/terraform/main.tf +++ b/documenso/terraform/main.tf @@ -26,6 +26,10 @@ locals { smtp_host = "email-smtp.${var.aws_region}.amazonaws.com" s3_bucket_name = coalesce(var.upload_bucket_name, "${local.name_prefix}-${data.aws_caller_identity.current.account_id}-${var.aws_region}") app_secret_name = coalesce(var.app_secret_name, "${local.name_prefix}/${replace(var.domain_name, ".", "-")}/app") + waf_bypass_ipv4_cidrs = distinct(concat( + [var.vpc_cidr], + var.waf_bypass_ipv4_cidrs + )) common_tags = merge(var.tags, { Application = var.project_name ManagedBy = "Terraform" @@ -44,6 +48,7 @@ locals { NEXT_PRIVATE_ALLOWED_SIGNUP_DOMAINS = var.allowed_signup_domains NEXT_PRIVATE_UPLOAD_ACCESS_KEY_ID = aws_iam_access_key.documenso_upload.id NEXT_PRIVATE_UPLOAD_SECRET_ACCESS_KEY = aws_iam_access_key.documenso_upload.secret + NEXT_PRIVATE_DOCUMENSO_LICENSE_KEY = var.documenso_license_key }, trimspace(var.signing_certificate_base64) != "" ? { NEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTS = var.signing_certificate_base64 @@ -66,7 +71,8 @@ locals { "NEXT_PRIVATE_SMTP_FROM_ADDRESS", "NEXT_PRIVATE_ALLOWED_SIGNUP_DOMAINS", "NEXT_PRIVATE_UPLOAD_ACCESS_KEY_ID", - "NEXT_PRIVATE_UPLOAD_SECRET_ACCESS_KEY" + "NEXT_PRIVATE_UPLOAD_SECRET_ACCESS_KEY", + "NEXT_PRIVATE_DOCUMENSO_LICENSE_KEY" ] : { name = secret_name valueFrom = "${aws_secretsmanager_secret.app.arn}:${secret_name}::" @@ -634,6 +640,16 @@ resource "aws_lb_listener" "https" { depends_on = [aws_acm_certificate_validation.this] } +resource "aws_wafv2_ip_set" "trusted_ipv4" { + name = "${local.name_prefix}-trusted-ipv4" + description = "IPv4 CIDRs that bypass the Documenso WAF rules" + scope = "REGIONAL" + ip_address_version = "IPV4" + addresses = local.waf_bypass_ipv4_cidrs + + tags = local.common_tags +} + resource "aws_wafv2_web_acl" "this" { name = "${local.name_prefix}-web-acl" description = "WAF protection for Documenso" @@ -643,6 +659,27 @@ resource "aws_wafv2_web_acl" "this" { allow {} } + rule { + name = "AllowTrustedIpv4" + priority = 0 + + action { + allow {} + } + + statement { + ip_set_reference_statement { + arn = aws_wafv2_ip_set.trusted_ipv4.arn + } + } + + visibility_config { + cloudwatch_metrics_enabled = true + metric_name = "AllowTrustedIpv4" + sampled_requests_enabled = true + } + } + rule { name = "AWSManagedRulesCommonRuleSet" priority = 1 @@ -1004,4 +1041,4 @@ resource "aws_cloudwatch_metric_alarm" "rds_free_storage_low" { } tags = local.common_tags -} \ No newline at end of file +} diff --git a/documenso/terraform/terraform.tfstate b/documenso/terraform/terraform.tfstate index d4560965a..62c5c8794 100644 --- a/documenso/terraform/terraform.tfstate +++ b/documenso/terraform/terraform.tfstate @@ -1,7 +1,7 @@ { "version": 4, "terraform_version": "1.14.3", - "serial": 64, + "serial": 84, "lineage": "2b49a6da-17c7-01da-d62f-9a13def4b683", "outputs": { "application_url": { @@ -491,7 +491,7 @@ "scheduled_scaling_suspended": false } ], - "tags": null, + "tags": {}, "tags_all": {} }, "sensitive_attributes": [], @@ -715,7 +715,7 @@ "schema_version": 1, "attributes": { "actions_enabled": true, - "alarm_actions": null, + "alarm_actions": [], "alarm_description": "Documenso ECS service CPU is consistently high", "alarm_name": "documenso-ecs-cpu-high", "arn": "arn:aws:cloudwatch:ca-central-1:714144183158:alarm:documenso-ecs-cpu-high", @@ -729,11 +729,11 @@ "evaluation_periods": 2, "extended_statistic": "", "id": "documenso-ecs-cpu-high", - "insufficient_data_actions": null, + "insufficient_data_actions": [], "metric_name": "CPUUtilization", "metric_query": [], "namespace": "AWS/ECS", - "ok_actions": null, + "ok_actions": [], "period": 300, "region": "ca-central-1", "statistic": "Average", @@ -811,7 +811,7 @@ "schema_version": 1, "attributes": { "actions_enabled": true, - "alarm_actions": null, + "alarm_actions": [], "alarm_description": "Documenso ECS service memory is consistently high", "alarm_name": "documenso-ecs-memory-high", "arn": "arn:aws:cloudwatch:ca-central-1:714144183158:alarm:documenso-ecs-memory-high", @@ -825,11 +825,11 @@ "evaluation_periods": 2, "extended_statistic": "", "id": "documenso-ecs-memory-high", - "insufficient_data_actions": null, + "insufficient_data_actions": [], "metric_name": "MemoryUtilization", "metric_query": [], "namespace": "AWS/ECS", - "ok_actions": null, + "ok_actions": [], "period": 300, "region": "ca-central-1", "statistic": "Average", @@ -1096,7 +1096,7 @@ "instance_class": "db.t4g.micro", "iops": 3000, "kms_key_id": "arn:aws:kms:ca-central-1:714144183158:key/1237b672-91b3-4d23-958d-1877c5d22eb9", - "latest_restorable_time": "2026-03-26T21:33:39Z", + "latest_restorable_time": "2026-04-13T20:19:35Z", "license_model": "postgresql-license", "listener_endpoint": [], "maintenance_window": "tue:03:10-tue:03:40", @@ -1384,7 +1384,7 @@ "Application": "documenso", "ManagedBy": "Terraform" }, - "task_definition": "arn:aws:ecs:ca-central-1:714144183158:task-definition/documenso-task:3", + "task_definition": "arn:aws:ecs:ca-central-1:714144183158:task-definition/documenso-task:5", "timeouts": null, "triggers": {}, "volume_configuration": [], @@ -1451,9 +1451,9 @@ { "schema_version": 1, "attributes": { - "arn": "arn:aws:ecs:ca-central-1:714144183158:task-definition/documenso-task:3", + "arn": "arn:aws:ecs:ca-central-1:714144183158:task-definition/documenso-task:5", "arn_without_revision": "arn:aws:ecs:ca-central-1:714144183158:task-definition/documenso-task", - "container_definitions": "[{\"environment\":[{\"name\":\"NEXT_PRIVATE_INTERNAL_WEBAPP_URL\",\"value\":\"http://127.0.0.1:3000\"},{\"name\":\"NEXT_PRIVATE_SMTP_HOST\",\"value\":\"email-smtp.ca-central-1.amazonaws.com\"},{\"name\":\"NEXT_PRIVATE_SMTP_PORT\",\"value\":\"587\"},{\"name\":\"NEXT_PRIVATE_SMTP_SECURE\",\"value\":\"false\"},{\"name\":\"NEXT_PRIVATE_SMTP_TRANSPORT\",\"value\":\"smtp-auth\"},{\"name\":\"NEXT_PRIVATE_SMTP_UNSAFE_IGNORE_TLS\",\"value\":\"false\"},{\"name\":\"NEXT_PRIVATE_UPLOAD_BUCKET\",\"value\":\"documenso-714144183158-ca-central-1\"},{\"name\":\"NEXT_PRIVATE_UPLOAD_REGION\",\"value\":\"ca-central-1\"},{\"name\":\"NEXT_PUBLIC_DISABLE_SIGNUP\",\"value\":\"false\"},{\"name\":\"NEXT_PUBLIC_DOCUMENT_SIZE_UPLOAD_LIMIT\",\"value\":\"10\"},{\"name\":\"NEXT_PUBLIC_UPLOAD_TRANSPORT\",\"value\":\"s3\"},{\"name\":\"NEXT_PUBLIC_WEBAPP_URL\",\"value\":\"https://sign.imex.online\"},{\"name\":\"PORT\",\"value\":\"3000\"}],\"essential\":true,\"image\":\"documenso/documenso:latest\",\"logConfiguration\":{\"logDriver\":\"awslogs\",\"options\":{\"awslogs-group\":\"/ecs/documenso\",\"awslogs-region\":\"ca-central-1\",\"awslogs-stream-prefix\":\"documenso\"}},\"mountPoints\":[],\"name\":\"documenso\",\"portMappings\":[{\"containerPort\":3000,\"hostPort\":3000,\"protocol\":\"tcp\"}],\"secrets\":[{\"name\":\"NEXTAUTH_SECRET\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXTAUTH_SECRET::\"},{\"name\":\"NEXT_PRIVATE_ALLOWED_SIGNUP_DOMAINS\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_ALLOWED_SIGNUP_DOMAINS::\"},{\"name\":\"NEXT_PRIVATE_DATABASE_URL\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_DATABASE_URL::\"},{\"name\":\"NEXT_PRIVATE_DIRECT_DATABASE_URL\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_DIRECT_DATABASE_URL::\"},{\"name\":\"NEXT_PRIVATE_ENCRYPTION_KEY\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_ENCRYPTION_KEY::\"},{\"name\":\"NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY::\"},{\"name\":\"NEXT_PRIVATE_SMTP_FROM_ADDRESS\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_SMTP_FROM_ADDRESS::\"},{\"name\":\"NEXT_PRIVATE_SMTP_FROM_NAME\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_SMTP_FROM_NAME::\"},{\"name\":\"NEXT_PRIVATE_SMTP_PASSWORD\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_SMTP_PASSWORD::\"},{\"name\":\"NEXT_PRIVATE_SMTP_USERNAME\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_SMTP_USERNAME::\"},{\"name\":\"NEXT_PRIVATE_UPLOAD_ACCESS_KEY_ID\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_UPLOAD_ACCESS_KEY_ID::\"},{\"name\":\"NEXT_PRIVATE_UPLOAD_SECRET_ACCESS_KEY\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_UPLOAD_SECRET_ACCESS_KEY::\"}],\"systemControls\":[],\"volumesFrom\":[]}]", + "container_definitions": "[{\"environment\":[{\"name\":\"NEXT_PRIVATE_INTERNAL_WEBAPP_URL\",\"value\":\"http://127.0.0.1:3000\"},{\"name\":\"NEXT_PRIVATE_SMTP_HOST\",\"value\":\"email-smtp.ca-central-1.amazonaws.com\"},{\"name\":\"NEXT_PRIVATE_SMTP_PORT\",\"value\":\"587\"},{\"name\":\"NEXT_PRIVATE_SMTP_SECURE\",\"value\":\"false\"},{\"name\":\"NEXT_PRIVATE_SMTP_TRANSPORT\",\"value\":\"smtp-auth\"},{\"name\":\"NEXT_PRIVATE_SMTP_UNSAFE_IGNORE_TLS\",\"value\":\"false\"},{\"name\":\"NEXT_PRIVATE_UPLOAD_BUCKET\",\"value\":\"documenso-714144183158-ca-central-1\"},{\"name\":\"NEXT_PRIVATE_UPLOAD_REGION\",\"value\":\"ca-central-1\"},{\"name\":\"NEXT_PUBLIC_DISABLE_SIGNUP\",\"value\":\"false\"},{\"name\":\"NEXT_PUBLIC_DOCUMENT_SIZE_UPLOAD_LIMIT\",\"value\":\"10\"},{\"name\":\"NEXT_PUBLIC_UPLOAD_TRANSPORT\",\"value\":\"s3\"},{\"name\":\"NEXT_PUBLIC_WEBAPP_URL\",\"value\":\"https://sign.imex.online\"},{\"name\":\"PORT\",\"value\":\"3000\"}],\"essential\":true,\"image\":\"documenso/documenso:latest\",\"logConfiguration\":{\"logDriver\":\"awslogs\",\"options\":{\"awslogs-group\":\"/ecs/documenso\",\"awslogs-region\":\"ca-central-1\",\"awslogs-stream-prefix\":\"documenso\"}},\"mountPoints\":[],\"name\":\"documenso\",\"portMappings\":[{\"containerPort\":3000,\"hostPort\":3000,\"protocol\":\"tcp\"}],\"secrets\":[{\"name\":\"NEXTAUTH_SECRET\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXTAUTH_SECRET::\"},{\"name\":\"NEXT_PRIVATE_ALLOWED_SIGNUP_DOMAINS\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_ALLOWED_SIGNUP_DOMAINS::\"},{\"name\":\"NEXT_PRIVATE_DATABASE_URL\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_DATABASE_URL::\"},{\"name\":\"NEXT_PRIVATE_DIRECT_DATABASE_URL\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_DIRECT_DATABASE_URL::\"},{\"name\":\"NEXT_PRIVATE_DOCUMENSO_LICENSE_KEY\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_DOCUMENSO_LICENSE_KEY::\"},{\"name\":\"NEXT_PRIVATE_ENCRYPTION_KEY\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_ENCRYPTION_KEY::\"},{\"name\":\"NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY::\"},{\"name\":\"NEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTS\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTS::\"},{\"name\":\"NEXT_PRIVATE_SIGNING_PASSPHRASE\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_SIGNING_PASSPHRASE::\"},{\"name\":\"NEXT_PRIVATE_SMTP_FROM_ADDRESS\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_SMTP_FROM_ADDRESS::\"},{\"name\":\"NEXT_PRIVATE_SMTP_FROM_NAME\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_SMTP_FROM_NAME::\"},{\"name\":\"NEXT_PRIVATE_SMTP_PASSWORD\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_SMTP_PASSWORD::\"},{\"name\":\"NEXT_PRIVATE_SMTP_USERNAME\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_SMTP_USERNAME::\"},{\"name\":\"NEXT_PRIVATE_UPLOAD_ACCESS_KEY_ID\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_UPLOAD_ACCESS_KEY_ID::\"},{\"name\":\"NEXT_PRIVATE_UPLOAD_SECRET_ACCESS_KEY\",\"valueFrom\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE:NEXT_PRIVATE_UPLOAD_SECRET_ACCESS_KEY::\"}],\"systemControls\":[],\"volumesFrom\":[]}]", "cpu": "512", "enable_fault_injection": false, "ephemeral_storage": [], @@ -1470,7 +1470,7 @@ "requires_compatibilities": [ "FARGATE" ], - "revision": 3, + "revision": 5, "runtime_platform": [], "skip_destroy": false, "tags": { @@ -1498,7 +1498,7 @@ "account_id": "714144183158", "family": "documenso-task", "region": "ca-central-1", - "revision": 3 + "revision": 5 }, "private": "eyJzY2hlbWFfdmVyc2lvbiI6IjEifQ==", "dependencies": [ @@ -1632,7 +1632,12 @@ "description": "", "force_detach_policies": false, "id": "documenso-ecs-execution", - "inline_policy": [], + "inline_policy": [ + { + "name": "documenso-ecs-secrets", + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":[\"secretsmanager:GetSecretValue\"],\"Effect\":\"Allow\",\"Resource\":\"arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE\"}]}" + } + ], "managed_policy_arns": [ "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" ], @@ -2870,14 +2875,14 @@ "attributes": { "arn": "arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE", "has_secret_string_wo": null, - "id": "arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE|terraform-20260326213740930700000002", + "id": "arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE|terraform-20260413202325454100000001", "region": "ca-central-1", "secret_binary": "", "secret_id": "arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE", - "secret_string": "{\"NEXTAUTH_SECRET\":\"NFPjonJogt95fVLJCtzCDfwdJng5Ece07rgOjBrVF56a8wlPrbtaiIYjKDttcjbo\",\"NEXT_PRIVATE_ALLOWED_SIGNUP_DOMAINS\":\"\",\"NEXT_PRIVATE_DATABASE_URL\":\"postgresql://documenso:HsKgbmS6RxH1wAUN3eHvkAfx3iGi35JK@documenso-postgres.cfo5pnykioqq.ca-central-1.rds.amazonaws.com:5432/documenso?schema=public\",\"NEXT_PRIVATE_DIRECT_DATABASE_URL\":\"postgresql://documenso:HsKgbmS6RxH1wAUN3eHvkAfx3iGi35JK@documenso-postgres.cfo5pnykioqq.ca-central-1.rds.amazonaws.com:5432/documenso?schema=public\",\"NEXT_PRIVATE_ENCRYPTION_KEY\":\"tCRYLQ9BKjW00d5GSl8pl2whKY6ab4Gf0wa3DaaLbDJ2ihN7WwWOlflxa3NUlnPc\",\"NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY\":\"HoMkHNTYHWOleVAkZJljkY6fHaCWY3bSROQOiK1lKGccMi2PbqBP0AvqfvlKGSoO\",\"NEXT_PRIVATE_SMTP_FROM_ADDRESS\":\"no-reply@imex.online\",\"NEXT_PRIVATE_SMTP_FROM_NAME\":\"ImEX E-Signature\",\"NEXT_PRIVATE_SMTP_PASSWORD\":\"BJPF9NvYxkDn6BWkrmf6kkvVDFwC8/cB1NvHtC9Fd3j/\",\"NEXT_PRIVATE_SMTP_USERNAME\":\"AKIA2MRSPON3O6PRVUPE\",\"NEXT_PRIVATE_UPLOAD_ACCESS_KEY_ID\":\"AKIA2MRSPON3LYGF2HPA\",\"NEXT_PRIVATE_UPLOAD_SECRET_ACCESS_KEY\":\"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\"}", + "secret_string": "{\"NEXTAUTH_SECRET\":\"NFPjonJogt95fVLJCtzCDfwdJng5Ece07rgOjBrVF56a8wlPrbtaiIYjKDttcjbo\",\"NEXT_PRIVATE_ALLOWED_SIGNUP_DOMAINS\":\"\",\"NEXT_PRIVATE_DATABASE_URL\":\"postgresql://documenso:HsKgbmS6RxH1wAUN3eHvkAfx3iGi35JK@documenso-postgres.cfo5pnykioqq.ca-central-1.rds.amazonaws.com:5432/documenso?schema=public\",\"NEXT_PRIVATE_DIRECT_DATABASE_URL\":\"postgresql://documenso:HsKgbmS6RxH1wAUN3eHvkAfx3iGi35JK@documenso-postgres.cfo5pnykioqq.ca-central-1.rds.amazonaws.com:5432/documenso?schema=public\",\"NEXT_PRIVATE_DOCUMENSO_LICENSE_KEY\":\"DOCUMENSO-B3H3-LJFA-PEMZ-CBCK-THBX\",\"NEXT_PRIVATE_ENCRYPTION_KEY\":\"tCRYLQ9BKjW00d5GSl8pl2whKY6ab4Gf0wa3DaaLbDJ2ihN7WwWOlflxa3NUlnPc\",\"NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY\":\"HoMkHNTYHWOleVAkZJljkY6fHaCWY3bSROQOiK1lKGccMi2PbqBP0AvqfvlKGSoO\",\"NEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTS\":\"MIIK5wIBAzCCCpUGCSqGSIb3DQEHAaCCCoYEggqCMIIKfjCCBOoGCSqGSIb3DQEHBqCCBNswggTXAgEAMIIE0AYJKoZIhvcNAQcBMF8GCSqGSIb3DQEFDTBSMDEGCSqGSIb3DQEFDDAkBBDPGLKtlkmj6wf0D6roFLGsAgIIADAMBggqhkiG9w0CCQUAMB0GCWCGSAFlAwQBKgQQmiqrIJKxMaa52XumQ2nyxoCCBGCcOHBZRmLmTRhh/DFjKKlk4fDaF4geklv4OSs+pRJXOPVU1C3U+2OJyrHYPejCJobA4ZBtfw2Z+BDULr43bK5WS0hHywCCAhKgfIXJy9GEJ+YS6cjFxWNwJUakTRx69tzwjzKtifJ14s9gZIL+dPbbQlCM0bs6CEUZYGZtwfpfGH/DqToA6coV73efUCHTHg1KLcoimT7X8CUogD6QulDAN3Fajd2udaC1jdb2nStHFzrI6AT/v7LWjfvxN+jbPTDGyuoaGX+60NGdZwfsJob5Kr8g+btii5FELhTOU3aI22/nk5bdVMEmjW2WzFp2MmrCe7iTWa0/Tl18HY0XXlxUixnzT0ZMEgafumvNwu8pLlXk0y8Q1/zK0fmdSSPCuljWkFcdwo8gp2cbmZ0YU1zbcqN1Vecop6oPptssy/2y51zFS6pKWV9DSliACphxTHOXkP2GkjS4PdCKQgQbUdrz1IvuI25eEAQnsxEpuPTYt3Q33oMXNrgjUGqQYaO8/CtftTkC8MjEw23hBMdkvWW/MNLzj+9XueRPYpnJMxVsSLmtTp91lZBm9yuYEPxhk4BC66nyo7aFxK3Cdrd9NyntJourbVOj+RFJvIL+KCGrkD+s+e7xA+VdWFoGBQR2ZXImOYaBPVnuRXK+I39tX/geNDKox4ZY7/Jfkw5M/2UTKF9ZE3umvjBeBsIRwtkEJhmduc/DUJpE5642i1AIqF0ZK72qX9CGz6ypKnYmDJZ1JM0EU8TiGfrSpBqizB7QWvLQm/z9a55142UkwUOFVC1VyMVAeNwnOGqwxBCnV59P5QD8BBnNIsYDYWNU3OcKvAS36sZeO0QQLCL4VgUGHFFsQjfupUIKOOFFHrV4Vtd0DuealFxCf/q5ssH+ERTiYRXeZ2U8AFbzGBNmfbmHxjeldSGcKKVne2tFqWb58XAkE9g18MP40nbfxLNJQConf9mKqydAMoUFrK/C2763DPlVD4o/2n/XcJzZbZ0cfjpPyD+qCr/o5gjjZByK3pqJdbzKOnKIXSk/tmzI3AbiUMQXz5CHBFSmeu7XVTFxb55cmPN9YdtkqqMhbMRkaKlaXxlZkgiX2wTT2P+bVDcRMFJWs+VVuvHmHo5djIgFTO12KDOT+13nKoqxPoz/FZ/nmUD/i1kR/PrArTEToMna/aKTowD4sZkgBE/ksqrZAR3LZfXs6n03rT4XHqyKoVyi+2QIEPJgbK0/AXLyVIbe+k2jY3Te6G/3jm7++G8XDQKs/lgGdnnvKBr1BXp7BKLngejvjKEVQTrm8BoJ76eqZDBcZ+u9KJih8+J7F6HWDPhaWGir+Ls7vyjstq7YScmhGfabhsZXBj84mRd8ljfJLzr1tz6dXLhr+Na5SEtRrfHQrl6k02/wKtKJSN6dHhHNoiMxco/TNxc23Tq3ppjcTkVLePMN7oERDPzVetcepFa+B98b3oKmtVN9H1pBBW+gkCwhvr6GrfQyb0EJH4/hZfl9MIIFjAYJKoZIhvcNAQcBoIIFfQSCBXkwggV1MIIFcQYLKoZIhvcNAQwKAQKgggU5MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQgYOXISN7448mJKsqaU/JQwICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEAAMPn748gKY5DhpF6wcXOoEggTQ+xT8WfPAsABdOi2PvpFmTNemCgehn0y19p6fmXgCL3FHoGljZW7j+COUclum7Rkgnwa/WsFppZeIhjrhnahN6+IuLj72vy9wYaScNaBWzzzA5OB3vWee0fw4z1w0JZVOhCNr+wn+lfHRaY8dYelFxKSdNdRH3HWRvPhxUthSrDHxrVAION23Kezzqz3gtEAnNwskLQgCzr3wI0pgjuYOuiXo0Lo5hTuOTQlAqs+thlZaan/y8V2mOXl7tw72zE+2XBaPIkyREteLwv5+ejeNJl6Pf5zDcO/6TT4uIiS4HGG6coKsh5rWmZZcMQFny5TSMH0tXz2GCy9eUz1J1wwnfh76su4765d9R6KVkqhvwNvUxqAR9z1h855JKtP+QlBhOTlQDuI9gDk5q+H+h+0FFjBL3Jr01oItdgiqPsVzRId1fbOyxNmk1MzZnk/Q2d5aS1lv8B2db/srkPNLw8MT5YNnKqpsPkrcoZqLasMxAWl1R9vxazZJUTWhdSmxwvp4ILl0lcilRoXp5c36EFX6vAPLIeEQj0a1bUWDxTx0a7DtIdJcfx610bvbp6zKJH5XBWF361DXwaiBqvFfBCOOM1aypxzfoIjv+soJNasnCKEtiy0QmveHnZHcjG15v3XSgCw6/TCHIUqPtDilUBxQZ/WT4vlWPdo3ytXPkehrWxDXz7ltS8QEzaWkjDTcFmSmWdewDfC+1waJW7yzDjcITBIHfPxKaW0C2FaWj2ATOzO37ih6cwYuaCPh7D1iFOb9DNM364UxUdq4dKaScMgaTVHYotU29lrpUM6GKPAj4KEf/4PEQP/Mgpps81IC93ZXXBV6nSTYXGjI7xI5joDewMZEkfuZkVibiSDgbV0eTWOHydfdvd9E7mF2gr3QUIU5zZ6u/rvZLeWOkNxhzx4BlRjNAj/4ly7dongSQ50Qp0UzcM6mL7XnEBjVJBwwpTh/hlys+ophB+OwoAtjQ/OgQRdaUsezMGh0VnlBGvWegc3ZFera596u4Nz6kIB5Qfn86qurL6Bqcr3gEsNrbWNXr9rH8lzhTVdVidhnALATPkGVIgqDt1EujK3bzY251Zbpe7UYvpdK0/JhUb5HoWYiAQ/+eXobaXBPXQM1BTtTTg76QN+MJUF3eCc0+moH8OXuraQ+Uz55cXQ2rhXE0zCWAFEla9HkyVPZGj4qZ4bXP0Fdvtogh3VieKIbfi+6X3aL8LWNmAeQ84bBemRaLQ4yyDKKmJCL+FYTp8DZVImn+ytG9ucUvbb8t1jAq4H4YVfFw4Tl+pMCncBBMpzJlQRefi/1BOh1nvcTevGElg671S8wNw6ZyJPknLOY3PH/sFlv1zgJHaqn8WHYsFI4SctwT+QoL6MriUlJnEOfgfb+7tK0w7s6XvyNXuD0TEWM7/+txsjMzLXblcSIqQnZaK1F9jcWwU/raO8ZstTpNNTYWBR/zGbtohN+/Lg7ZPqt01ITx8yUalEHXy1ftBbwbvow39kImWf7/APBdwhqoqRn++etiTaCGe2IWJywNpB2uEJtST2OQsXfd9cb2HOhL1AD41eNrOAROXLQ7JiPxVbBGEs2ng7dBdGfpQ99rAseFDL/EFDd/leFnGolQOCwU+WqujGeCxmkgn0fJZbwWYs3q+gxJTAjBgkqhkiG9w0BCRUxFgQUeGwbF0JvtSD0DWedKPyplVIFt5wwSTAxMA0GCWCGSAFlAwQCAQUABCCeIE2+8Drr37ej+RPfASUV47sGTFxNDWk4n7lBQqWqQgQQvUfLXplDNWIv9yFoAbPGnwICCAA=\",\"NEXT_PRIVATE_SIGNING_PASSPHRASE\":\"Wl0d8k@!@!ImEXSystems\",\"NEXT_PRIVATE_SMTP_FROM_ADDRESS\":\"no-reply@imex.online\",\"NEXT_PRIVATE_SMTP_FROM_NAME\":\"ImEX Sign\",\"NEXT_PRIVATE_SMTP_PASSWORD\":\"BJPF9NvYxkDn6BWkrmf6kkvVDFwC8/cB1NvHtC9Fd3j/\",\"NEXT_PRIVATE_SMTP_USERNAME\":\"AKIA2MRSPON3O6PRVUPE\",\"NEXT_PRIVATE_UPLOAD_ACCESS_KEY_ID\":\"AKIA2MRSPON3LYGF2HPA\",\"NEXT_PRIVATE_UPLOAD_SECRET_ACCESS_KEY\":\"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\"}", "secret_string_wo": null, "secret_string_wo_version": null, - "version_id": "terraform-20260326213740930700000002", + "version_id": "terraform-20260413202325454100000001", "version_stages": [ "AWSCURRENT" ] @@ -2907,7 +2912,7 @@ "account_id": "714144183158", "region": "ca-central-1", "secret_id": "arn:aws:secretsmanager:ca-central-1:714144183158:secret:documenso/sign-imex-online/app-DNl1NE", - "version_id": "terraform-20260326213740930700000002" + "version_id": "terraform-20260413202325454100000001" }, "private": "bnVsbA==", "dependencies": [ @@ -3480,6 +3485,43 @@ } ] }, + { + "mode": "managed", + "type": "aws_wafv2_ip_set", + "name": "trusted_ipv4", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "addresses": [ + "10.42.0.0/16", + "64.46.30.40/32" + ], + "arn": "arn:aws:wafv2:ca-central-1:714144183158:regional/ipset/documenso-trusted-ipv4/c3731d62-ee0c-4cff-bfc9-199b86cde469", + "description": "IPv4 CIDRs that bypass the Documenso WAF rules", + "id": "c3731d62-ee0c-4cff-bfc9-199b86cde469", + "ip_address_version": "IPV4", + "lock_token": "2bedc1da-5039-443c-a950-9ffac7fd5f9d", + "name": "documenso-trusted-ipv4", + "name_prefix": "", + "region": "ca-central-1", + "scope": "REGIONAL", + "tags": { + "Application": "documenso", + "ManagedBy": "Terraform" + }, + "tags_all": { + "Application": "documenso", + "ManagedBy": "Terraform" + } + }, + "sensitive_attributes": [], + "identity_schema_version": 0, + "private": "bnVsbA==" + } + ] + }, { "mode": "managed", "type": "aws_wafv2_web_acl", @@ -3492,7 +3534,7 @@ "application_integration_url": "", "arn": "arn:aws:wafv2:ca-central-1:714144183158:regional/webacl/documenso-web-acl/04577153-2a1a-462c-94b8-b0a1804755bb", "association_config": [], - "capacity": 702, + "capacity": 703, "captcha_config": [], "challenge_config": [], "custom_response_body": [], @@ -3509,11 +3551,64 @@ ], "description": "WAF protection for Documenso", "id": "04577153-2a1a-462c-94b8-b0a1804755bb", - "lock_token": "a64452be-7ff7-4236-b192-0d8941153888", + "lock_token": "e71f2816-492c-4afc-acc2-3700795c2657", "name": "documenso-web-acl", "name_prefix": "", "region": "ca-central-1", "rule": [ + { + "action": [ + { + "allow": [ + { + "custom_request_handling": [] + } + ], + "block": [], + "captcha": [], + "challenge": [], + "count": [] + } + ], + "captcha_config": [], + "challenge_config": [], + "name": "AllowTrustedIpv4", + "override_action": [], + "priority": 0, + "rule_label": [], + "statement": [ + { + "and_statement": [], + "asn_match_statement": [], + "byte_match_statement": [], + "geo_match_statement": [], + "ip_set_reference_statement": [ + { + "arn": "arn:aws:wafv2:ca-central-1:714144183158:regional/ipset/documenso-trusted-ipv4/c3731d62-ee0c-4cff-bfc9-199b86cde469", + "ip_set_forwarded_ip_config": [] + } + ], + "label_match_statement": [], + "managed_rule_group_statement": [], + "not_statement": [], + "or_statement": [], + "rate_based_statement": [], + "regex_match_statement": [], + "regex_pattern_set_reference_statement": [], + "rule_group_reference_statement": [], + "size_constraint_statement": [], + "sqli_match_statement": [], + "xss_match_statement": [] + } + ], + "visibility_config": [ + { + "cloudwatch_metrics_enabled": true, + "metric_name": "AllowTrustedIpv4", + "sampled_requests_enabled": true + } + ] + }, { "action": [ { @@ -3645,7 +3740,10 @@ }, "sensitive_attributes": [], "identity_schema_version": 0, - "private": "bnVsbA==" + "private": "bnVsbA==", + "dependencies": [ + "aws_wafv2_ip_set.trusted_ipv4" + ] } ] }, @@ -3672,6 +3770,7 @@ "aws_security_group.alb", "aws_subnet.public", "aws_vpc.this", + "aws_wafv2_ip_set.trusted_ipv4", "aws_wafv2_web_acl.this", "data.aws_availability_zones.available" ] diff --git a/documenso/terraform/variables.tf b/documenso/terraform/variables.tf index 42e7c893a..34b1fd457 100644 --- a/documenso/terraform/variables.tf +++ b/documenso/terraform/variables.tf @@ -229,7 +229,7 @@ variable "smtp_password" { variable "smtp_from_name" { description = "Display name used in outbound email." type = string - default = "ImEX E-Signature" + default = "ImEX Sign" } variable "smtp_from_address" { @@ -269,6 +269,12 @@ variable "waf_rate_limit" { default = 2000 } +variable "waf_bypass_ipv4_cidrs" { + description = "Additional IPv4 CIDR blocks that bypass the WAF. The VPC CIDR is always included automatically." + type = list(string) + default = [] +} + variable "alarm_actions" { description = "Optional list of SNS topic ARNs or other alarm actions to invoke when CloudWatch alarms fire." type = list(string) @@ -303,4 +309,10 @@ variable "rds_free_storage_alarm_threshold_bytes" { description = "Alarm threshold for low RDS free storage, in bytes." type = number default = 5368709120 +} + +variable "documenso_license_key" { + description = "Documenso license key. Not required for the free community edition, but required for enterprise features and support." + type = string + default = "" } \ No newline at end of file diff --git a/hasura/metadata/cron_triggers.yaml b/hasura/metadata/cron_triggers.yaml index 2c8c4c91d..845cb60f6 100644 --- a/hasura/metadata/cron_triggers.yaml +++ b/hasura/metadata/cron_triggers.yaml @@ -24,6 +24,15 @@ - name: x-imex-auth value_from_env: DATAPUMP_AUTH comment: Project Mexico +- name: Chatter API Data Pump + webhook: '{{HASURA_API_URL}}/data/chatter-api' + schedule: 45 4 * * * + include_in_metadata: true + payload: {} + headers: + - name: x-imex-auth + value_from_env: DATAPUMP_AUTH + comment: "" - name: Chatter Data Pump webhook: '{{HASURA_API_URL}}/data/chatter' schedule: 45 5 * * * diff --git a/hasura/metadata/tables.yaml b/hasura/metadata/tables.yaml index d6f3f1c25..54973664d 100644 --- a/hasura/metadata/tables.yaml +++ b/hasura/metadata/tables.yaml @@ -1891,6 +1891,14 @@ - name: job using: foreign_key_constraint_on: jobid + array_relationships: + - name: esignature_documents + using: + foreign_key_constraint_on: + column: documentid + table: + name: esignature_documents + schema: public insert_permissions: - role: user permission: diff --git a/server/esign/esign-new.js b/server/esign/esign-new.js index a6954cc62..ebea3519d 100644 --- a/server/esign/esign-new.js +++ b/server/esign/esign-new.js @@ -3,10 +3,11 @@ const { Documenso } = require("@documenso/sdk-typescript"); const axios = require("axios"); const { jsrAuthString } = require("../utils/utils"); const logger = require("../utils/logger"); -const DOCUMENSO_API_KEY = "api_asojim0czruv13ud";//Done on a by team basis, +//Need to pull the key dynamically to send documents. +const DOCUMENSO_API_KEY = "api_io2lssosg9v4p2mb";//Done on a by team basis, const documenso = new Documenso({ apiKey: DOCUMENSO_API_KEY,//Done on a by team basis, - serverURL: "https://stg-app.documenso.com/api/v2", + serverURL: "https://sign.imex.online/api/v2", }); const JSR_SERVER = "https://reports.test.imex.online"; const jsreport = require("@jsreport/nodejs-client"); @@ -216,9 +217,9 @@ async function newEsignDocument(req, res) { catch (error) { logger.log(`esig-new-error`, "ERROR", "esig", "api", { message: error.message, stack: error.stack, - body: req.body + body: _.omit(req.body, ["bodyshop"]) // bodyshop can be large, so we omit it from the logs }); - res.status(500).json({ error: "An error occurred while creating the e-sign document." }); + res.status(500).json({ error: "An error occurred while creating the e-sign document.", message: error.message }); } } diff --git a/server/esign/webhook.js b/server/esign/webhook.js index 10a29723d..bbba8dab0 100644 --- a/server/esign/webhook.js +++ b/server/esign/webhook.js @@ -7,8 +7,8 @@ const { log } = require("node-persist"); const client = require('../graphql-client/graphql-client').client; const documenso = new Documenso({ - apiKey: "api_asojim0czruv13ud",//Done on a by team basis, - serverURL: "https://stg-app.documenso.com/api/v2", + apiKey: "api_io2lssosg9v4p2mb",// Centralize key and pull dynamically. + serverURL: "https://sign.imex.online/api/v2", }); const webhookTypeEnums = { @@ -22,7 +22,6 @@ const webhookTypeEnums = { } async function esignWebhook(req, res) { - console.log("Esign Webhook Received:", req.body); try { const message = req.body logger.log(`esig-webhook-received`, "DEBUG", "redis", "api", { @@ -30,11 +29,12 @@ async function esignWebhook(req, res) { body: message }); + const documentId = (message.payload?.id || message.payload?.payload?.id)?.toString() //TODO: Implement checks to prevent this from going backwards in status? If a request fails, it retries, which could cause a document marked as completed to be marked as rejected if the rejection event is processed after the completion event. switch (message.event) { case webhookTypeEnums.DOCUMENT_OPENED: await client.request(UPDATE_ESIGNATURE_DOCUMENT, { - external_document_id: message.payload?.payload?.id?.toString(), + external_document_id: documentId, esig_update: { status: "OPENED", opened: true, @@ -43,7 +43,7 @@ async function esignWebhook(req, res) { break; case webhookTypeEnums.DOCUMENT_REJECTED: await client.request(UPDATE_ESIGNATURE_DOCUMENT, { - external_document_id: message.payload?.payload?.id?.toString(), + external_document_id: documentId, esig_update: { status: "REJECTED", rejected: true, @@ -52,19 +52,19 @@ async function esignWebhook(req, res) { break; case webhookTypeEnums.DOCUMENT_CREATED: //This is largely a throwaway event we know it was created. - console.log("Document created event received. Document ID:", message.payload?.payload?.documentId); + console.log("Document created event received. Document ID:", documentId); // Here you can add any additional processing you want to do when a document is created break; case webhookTypeEnums.DOCUMENT_COMPLETED: - console.log("Document completed event received. Document ID:", message.payload?.payload?.documentId); + console.log("Document completed event received. Document ID:", documentId); await handleDocumentCompleted(message.payload); // Here you can add any additional processing you want to do when a document is completed break; case webhookTypeEnums.DOCUMENT_SIGNED: - console.log("Document signed event received. Document ID:", message.payload?.payload?.documentId); + console.log("Document signed event received. Document ID:", documentId); // Here you can add any additional processing you want to do when a document is signed await client.request(UPDATE_ESIGNATURE_DOCUMENT, { - external_document_id: message.payload?.payload?.id?.toString(), + external_document_id: documentId, esig_update: { status: "SIGNED", }