From bb05f6f4657c1d6aaab06e3658b128ee86f744a8 Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Tue, 11 Feb 2025 12:50:40 -0800 Subject: [PATCH 01/10] Add logic for getting envs and adding it to email subject and body --- src/registrar/config/settings.py | 1 + .../templates/emails/domain_invitation.txt | 2 +- .../emails/domain_invitation_subject.txt | 2 +- ...n_manager_deleted_notification_subject.txt | 2 +- .../emails/domain_manager_notification.txt | 2 +- .../domain_manager_notification_subject.txt | 2 +- .../emails/domain_request_withdrawn.txt | 2 +- .../domain_request_withdrawn_subject.txt | 2 +- .../templates/emails/metadata_body.txt | 2 +- .../templates/emails/metadata_subject.txt | 2 +- .../portfolio_admin_addition_notification.txt | 2 +- ...io_admin_addition_notification_subject.txt | 2 +- .../portfolio_admin_removal_notification.txt | 2 +- ...lio_admin_removal_notification_subject.txt | 2 +- .../templates/emails/portfolio_invitation.txt | 2 +- .../emails/portfolio_invitation_subject.txt | 2 +- .../emails/status_change_approved.txt | 2 +- .../emails/status_change_approved_subject.txt | 2 +- .../emails/status_change_subject.txt | 2 +- .../emails/submission_confirmation.txt | 2 +- .../submission_confirmation_subject.txt | 2 +- .../emails/transition_domain_invitation.txt | 2 +- .../transition_domain_invitation_subject.txt | 2 +- .../emails/update_to_approved_domain.txt | 4 ++-- .../update_to_approved_domain_subject.txt | 2 +- src/registrar/utility/email.py | 19 +++++++++++++++++++ 26 files changed, 45 insertions(+), 25 deletions(-) diff --git a/src/registrar/config/settings.py b/src/registrar/config/settings.py index 78439188e..fa4c2d8dc 100644 --- a/src/registrar/config/settings.py +++ b/src/registrar/config/settings.py @@ -107,6 +107,7 @@ DEBUG = env_debug # Controls production specific feature toggles IS_PRODUCTION = env_is_production SECRET_ENCRYPT_METADATA = secret_encrypt_metadata +BASE_URL = env_base_url # Applications are modular pieces of code. # They are provided by Django, by third-parties, or by yourself. diff --git a/src/registrar/templates/emails/domain_invitation.txt b/src/registrar/templates/emails/domain_invitation.txt index a077bff26..270786a7a 100644 --- a/src/registrar/templates/emails/domain_invitation.txt +++ b/src/registrar/templates/emails/domain_invitation.txt @@ -4,7 +4,7 @@ Hi,{% if requested_user and requested_user.first_name %} {{ requested_user.first {{ requestor_email }} has invited you to manage: {% for domain in domains %}{{ domain.name }} {% endfor %} -To manage domain information, visit the .gov registrar . +To manage domain information, visit the .gov registrar <{{ manage_url }}>. ---------------------------------------------------------------- {% if not requested_user %} diff --git a/src/registrar/templates/emails/domain_invitation_subject.txt b/src/registrar/templates/emails/domain_invitation_subject.txt index 9663346d0..9f15c38b4 100644 --- a/src/registrar/templates/emails/domain_invitation_subject.txt +++ b/src/registrar/templates/emails/domain_invitation_subject.txt @@ -1 +1 @@ -You've been invited to manage {% if domains|length > 1 %}.gov domains{% else %}{{ domains.0.name }}{% endif %} \ No newline at end of file +{{ prefix }}You've been invited to manage {% if domains|length > 1 %}.gov domains{% else %}{{ domains.0.name }}{% endif %} \ No newline at end of file diff --git a/src/registrar/templates/emails/domain_manager_deleted_notification_subject.txt b/src/registrar/templates/emails/domain_manager_deleted_notification_subject.txt index c84a20f18..7376bdb86 100644 --- a/src/registrar/templates/emails/domain_manager_deleted_notification_subject.txt +++ b/src/registrar/templates/emails/domain_manager_deleted_notification_subject.txt @@ -1 +1 @@ -A domain manager was removed from {{ domain.name }} \ No newline at end of file +{{ prefix }}A domain manager was removed from {{ domain.name }} \ No newline at end of file diff --git a/src/registrar/templates/emails/domain_manager_notification.txt b/src/registrar/templates/emails/domain_manager_notification.txt index c253937e4..18e682329 100644 --- a/src/registrar/templates/emails/domain_manager_notification.txt +++ b/src/registrar/templates/emails/domain_manager_notification.txt @@ -15,7 +15,7 @@ The person who received the invitation will become a domain manager once they lo associated with the invited email address. If you need to cancel this invitation or remove the domain manager, you can do that by going to -this domain in the .gov registrar . +this domain in the .gov registrar <{{ manage_url }}. WHY DID YOU RECEIVE THIS EMAIL? diff --git a/src/registrar/templates/emails/domain_manager_notification_subject.txt b/src/registrar/templates/emails/domain_manager_notification_subject.txt index 0e9918de0..8560cb9fa 100644 --- a/src/registrar/templates/emails/domain_manager_notification_subject.txt +++ b/src/registrar/templates/emails/domain_manager_notification_subject.txt @@ -1 +1 @@ -A domain manager was invited to {{ domain.name }} \ No newline at end of file +{{ prefix }}A domain manager was invited to {{ domain.name }} \ No newline at end of file diff --git a/src/registrar/templates/emails/domain_request_withdrawn.txt b/src/registrar/templates/emails/domain_request_withdrawn.txt index fbdf5b4f1..fe026027b 100644 --- a/src/registrar/templates/emails/domain_request_withdrawn.txt +++ b/src/registrar/templates/emails/domain_request_withdrawn.txt @@ -11,7 +11,7 @@ STATUS: Withdrawn ---------------------------------------------------------------- YOU CAN EDIT YOUR WITHDRAWN REQUEST -You can edit and resubmit this request by signing in to the registrar . +You can edit and resubmit this request by signing in to the registrar <{{ manage_url }}>. SOMETHING WRONG? diff --git a/src/registrar/templates/emails/domain_request_withdrawn_subject.txt b/src/registrar/templates/emails/domain_request_withdrawn_subject.txt index 51b2c745a..cc146643a 100644 --- a/src/registrar/templates/emails/domain_request_withdrawn_subject.txt +++ b/src/registrar/templates/emails/domain_request_withdrawn_subject.txt @@ -1 +1 @@ -Update on your .gov request: {{ domain_request.requested_domain.name }} +{{ prefix }}Update on your .gov request: {{ domain_request.requested_domain.name }} diff --git a/src/registrar/templates/emails/metadata_body.txt b/src/registrar/templates/emails/metadata_body.txt index adf0a186c..a0a3682b7 100644 --- a/src/registrar/templates/emails/metadata_body.txt +++ b/src/registrar/templates/emails/metadata_body.txt @@ -1 +1 @@ -An export of all .gov metadata. +{{ prefix }}An export of all .gov metadata. diff --git a/src/registrar/templates/emails/metadata_subject.txt b/src/registrar/templates/emails/metadata_subject.txt index 5fdece7ef..c19b4c26e 100644 --- a/src/registrar/templates/emails/metadata_subject.txt +++ b/src/registrar/templates/emails/metadata_subject.txt @@ -1,2 +1,2 @@ -Domain metadata - {{current_date_str}} +{{ prefix }}Domain metadata - {{current_date_str}} diff --git a/src/registrar/templates/emails/portfolio_admin_addition_notification.txt b/src/registrar/templates/emails/portfolio_admin_addition_notification.txt index b8953aa67..9e6da3985 100644 --- a/src/registrar/templates/emails/portfolio_admin_addition_notification.txt +++ b/src/registrar/templates/emails/portfolio_admin_addition_notification.txt @@ -16,7 +16,7 @@ The person who received the invitation will become an admin once they log in to associated with the invited email address. If you need to cancel this invitation or remove the admin, you can do that by going to -the Members section for your organization . +the Members section for your organization <{{ manage_url }}>. WHY DID YOU RECEIVE THIS EMAIL? diff --git a/src/registrar/templates/emails/portfolio_admin_addition_notification_subject.txt b/src/registrar/templates/emails/portfolio_admin_addition_notification_subject.txt index 3d6b2a140..ee5987512 100644 --- a/src/registrar/templates/emails/portfolio_admin_addition_notification_subject.txt +++ b/src/registrar/templates/emails/portfolio_admin_addition_notification_subject.txt @@ -1 +1 @@ -An admin was invited to your .gov organization \ No newline at end of file +{{ prefix }}An admin was invited to your .gov organization \ No newline at end of file diff --git a/src/registrar/templates/emails/portfolio_admin_removal_notification.txt b/src/registrar/templates/emails/portfolio_admin_removal_notification.txt index 6a536aa49..bf0338c03 100644 --- a/src/registrar/templates/emails/portfolio_admin_removal_notification.txt +++ b/src/registrar/templates/emails/portfolio_admin_removal_notification.txt @@ -8,7 +8,7 @@ REMOVED BY: {{ requestor_email }} REMOVED ON: {{date}} ADMIN REMOVED: {{ removed_email_address }} -You can view this update by going to the Members section for your .gov organization . +You can view this update by going to the Members section for your .gov organization <{{ manage_url }}>. ---------------------------------------------------------------- diff --git a/src/registrar/templates/emails/portfolio_admin_removal_notification_subject.txt b/src/registrar/templates/emails/portfolio_admin_removal_notification_subject.txt index e250b17f8..030d27ae7 100644 --- a/src/registrar/templates/emails/portfolio_admin_removal_notification_subject.txt +++ b/src/registrar/templates/emails/portfolio_admin_removal_notification_subject.txt @@ -1 +1 @@ -An admin was removed from your .gov organization \ No newline at end of file +{{ prefix}}An admin was removed from your .gov organization \ No newline at end of file diff --git a/src/registrar/templates/emails/portfolio_invitation.txt b/src/registrar/templates/emails/portfolio_invitation.txt index 775b74c7c..893da153d 100644 --- a/src/registrar/templates/emails/portfolio_invitation.txt +++ b/src/registrar/templates/emails/portfolio_invitation.txt @@ -3,7 +3,7 @@ Hi. {{ requestor_email }} has invited you to {{ portfolio.organization_name }}. -You can view this organization on the .gov registrar . +You can view this organization on the .gov registrar <{{ manage_url }}>. ---------------------------------------------------------------- diff --git a/src/registrar/templates/emails/portfolio_invitation_subject.txt b/src/registrar/templates/emails/portfolio_invitation_subject.txt index 552bb2bec..de9080196 100644 --- a/src/registrar/templates/emails/portfolio_invitation_subject.txt +++ b/src/registrar/templates/emails/portfolio_invitation_subject.txt @@ -1 +1 @@ -You’ve been invited to a .gov organization \ No newline at end of file +{{ prefix }}You’ve been invited to a .gov organization \ No newline at end of file diff --git a/src/registrar/templates/emails/status_change_approved.txt b/src/registrar/templates/emails/status_change_approved.txt index 821e89e42..635b36cbd 100644 --- a/src/registrar/templates/emails/status_change_approved.txt +++ b/src/registrar/templates/emails/status_change_approved.txt @@ -8,7 +8,7 @@ REQUESTED BY: {{ domain_request.creator.email }} REQUEST RECEIVED ON: {{ domain_request.last_submitted_date|date }} STATUS: Approved -You can manage your approved domain on the .gov registrar . +You can manage your approved domain on the .gov registrar <{{ manage_url }}>. ---------------------------------------------------------------- diff --git a/src/registrar/templates/emails/status_change_approved_subject.txt b/src/registrar/templates/emails/status_change_approved_subject.txt index 51b2c745a..cc146643a 100644 --- a/src/registrar/templates/emails/status_change_approved_subject.txt +++ b/src/registrar/templates/emails/status_change_approved_subject.txt @@ -1 +1 @@ -Update on your .gov request: {{ domain_request.requested_domain.name }} +{{ prefix }}Update on your .gov request: {{ domain_request.requested_domain.name }} diff --git a/src/registrar/templates/emails/status_change_subject.txt b/src/registrar/templates/emails/status_change_subject.txt index 51b2c745a..cc146643a 100644 --- a/src/registrar/templates/emails/status_change_subject.txt +++ b/src/registrar/templates/emails/status_change_subject.txt @@ -1 +1 @@ -Update on your .gov request: {{ domain_request.requested_domain.name }} +{{ prefix }}Update on your .gov request: {{ domain_request.requested_domain.name }} diff --git a/src/registrar/templates/emails/submission_confirmation.txt b/src/registrar/templates/emails/submission_confirmation.txt index d9d01ec3e..afbde48d5 100644 --- a/src/registrar/templates/emails/submission_confirmation.txt +++ b/src/registrar/templates/emails/submission_confirmation.txt @@ -20,7 +20,7 @@ During our review, we’ll verify that: - You work at the organization and/or can make requests on its behalf - Your requested domain meets our naming requirements {% endif %} -We’ll email you if we have questions. We’ll also email you as soon as we complete our review. You can check the status of your request at any time on the registrar. . +We’ll email you if we have questions. We’ll also email you as soon as we complete our review. You can check the status of your request at any time on the registrar. <{{ manage_url }}>. NEED TO MAKE CHANGES? diff --git a/src/registrar/templates/emails/submission_confirmation_subject.txt b/src/registrar/templates/emails/submission_confirmation_subject.txt index 51b2c745a..cc146643a 100644 --- a/src/registrar/templates/emails/submission_confirmation_subject.txt +++ b/src/registrar/templates/emails/submission_confirmation_subject.txt @@ -1 +1 @@ -Update on your .gov request: {{ domain_request.requested_domain.name }} +{{ prefix }}Update on your .gov request: {{ domain_request.requested_domain.name }} diff --git a/src/registrar/templates/emails/transition_domain_invitation.txt b/src/registrar/templates/emails/transition_domain_invitation.txt index b6773d9e9..dc812edf3 100644 --- a/src/registrar/templates/emails/transition_domain_invitation.txt +++ b/src/registrar/templates/emails/transition_domain_invitation.txt @@ -31,7 +31,7 @@ CHECK YOUR .GOV DOMAIN CONTACTS This is a good time to check who has access to your .gov domain{% if domains|length > 1 %}s{% endif %}. The admin, technical, and billing contacts listed for your domain{% if domains|length > 1 %}s{% endif %} in our old system also received this email. In our new registrar, these contacts are all considered “domain managers.” We no longer have the admin, technical, and billing roles, and you aren’t limited to three domain managers like in the old system. - 1. Once you have your Login.gov account, sign in to the new registrar at . + 1. Once you have your Login.gov account, sign in to the new registrar at <{{ manage_url }}>. 2. Click the “Manage” link next to your .gov domain, then click on “Domain managers” to see who has access to your domain. 3. If any of these users should not have access to your domain, let us know in a reply to this email. diff --git a/src/registrar/templates/emails/transition_domain_invitation_subject.txt b/src/registrar/templates/emails/transition_domain_invitation_subject.txt index 526c7714b..b162341d9 100644 --- a/src/registrar/templates/emails/transition_domain_invitation_subject.txt +++ b/src/registrar/templates/emails/transition_domain_invitation_subject.txt @@ -1 +1 @@ -(Action required) Manage your .gov domain{% if domains|length > 1 %}s{% endif %} in the new registrar \ No newline at end of file +{{ prefix }}(Action required) Manage your .gov domain{% if domains|length > 1 %}s{% endif %} in the new registrar \ No newline at end of file diff --git a/src/registrar/templates/emails/update_to_approved_domain.txt b/src/registrar/templates/emails/update_to_approved_domain.txt index 99f86ea54..fb0a442cb 100644 --- a/src/registrar/templates/emails/update_to_approved_domain.txt +++ b/src/registrar/templates/emails/update_to_approved_domain.txt @@ -1,4 +1,4 @@ -{% autoescape off %}{# In a text file, we don't want to have HTML entities escaped #} + {% autoescape off %}{# In a text file, we don't want to have HTML entities escaped #} Hi, An update was made to a domain you manage. @@ -8,7 +8,7 @@ UPDATED BY: {{user}} UPDATED ON: {{date}} INFORMATION UPDATED: {{changes}} -You can view this update in the .gov registrar . +You can view this update in the .gov registrar <{{ manage_url }}>. Get help with managing your .gov domain . diff --git a/src/registrar/templates/emails/update_to_approved_domain_subject.txt b/src/registrar/templates/emails/update_to_approved_domain_subject.txt index cf4c9a14c..d952999a0 100644 --- a/src/registrar/templates/emails/update_to_approved_domain_subject.txt +++ b/src/registrar/templates/emails/update_to_approved_domain_subject.txt @@ -1 +1 @@ -An update was made to {{domain}} \ No newline at end of file +{{ prefix }}An update was made to {{domain}} \ No newline at end of file diff --git a/src/registrar/utility/email.py b/src/registrar/utility/email.py index 40601cdc7..535096b10 100644 --- a/src/registrar/utility/email.py +++ b/src/registrar/utility/email.py @@ -3,6 +3,7 @@ import boto3 import logging import textwrap +import re from datetime import datetime from django.apps import apps from django.conf import settings @@ -48,6 +49,24 @@ def send_templated_email( # noqa No valid recipient addresses are provided """ + if context is None: + context = {} + + env_base_url = settings.BASE_URL + # The regular expresstion is to get both http (localhost) and https (everything else) + env_name = re.sub(r"^https?://", "", env_base_url).split(".")[0] + # To add to subject lines ie [GETGOV-RH] + prefix = f"[{env_name.upper()}] " if not settings.IS_PRODUCTION else "" + # For email links + manage_url = env_base_url if not settings.IS_PRODUCTION else "https://manage.get.gov" + + # Adding to context + context.update( + { + "prefix": prefix, + "manage_url": manage_url, + } + ) # by default assume we can send to all addresses (prod has no whitelist) sendable_cc_addresses = cc_addresses From c540a324c7df33c7011fcef4bebe158a43bf417a Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Wed, 12 Feb 2025 10:11:25 -0800 Subject: [PATCH 02/10] Add unit tests --- src/registrar/tests/test_emails.py | 76 ++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/src/registrar/tests/test_emails.py b/src/registrar/tests/test_emails.py index f39f11517..c79038668 100644 --- a/src/registrar/tests/test_emails.py +++ b/src/registrar/tests/test_emails.py @@ -108,6 +108,82 @@ class TestEmails(TestCase): self.assertEqual(["testy2@town.com", "mayor@igorville.gov"], kwargs["Destination"]["CcAddresses"]) + @boto3_mocking.patching + @override_settings(IS_PRODUCTION=True, BASE_URL="manage.get.gov") + def test_email_production_subject_and_url_check(self): + """Test sending an email in production that: + 1. Does not have a prefix in the email subject (no [MANAGE]) + 2. Uses the production URL in the email body of manage.get.gov still""" + with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class): + send_templated_email( + "emails/update_to_approved_domain.txt", + "emails/update_to_approved_domain_subject.txt", + "doesnotexist@igorville.com", + context={"domain": "test", "user": "test", "date": 1, "changes": "test"}, + bcc_address=None, + cc_addresses=["testy2@town.com", "mayor@igorville.gov"], + ) + + # check that an email was sent + self.assertTrue(self.mock_client.send_email.called) + + # check the call sequence for the email + args, kwargs = self.mock_client.send_email.call_args + self.assertIn("Destination", kwargs) + self.assertIn("CcAddresses", kwargs["Destination"]) + + self.assertEqual(["testy2@town.com", "mayor@igorville.gov"], kwargs["Destination"]["CcAddresses"]) + + # Grab email subject + email_subject = kwargs["Content"]["Simple"]["Subject"]["Data"] + + # Check that the subject does NOT contain a prefix for production + self.assertNotIn("[MANAGE]", email_subject) + self.assertIn("An update was made to", email_subject) + + # Grab email body + email_body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"] + + # Check that manage_url is correctly set for production + self.assertIn("https://manage.get.gov", email_body) + + @boto3_mocking.patching + @override_settings(IS_PRODUCTION=False, BASE_URL="https://getgov-rh.app.cloud.gov") + def test_email_non_production_subject_and_url_check(self): + """Test sending an email in production that: + 1. Does prefix in the email subject ([GETGOV-RH]) + 2. Uses the sandbox url in the email body (ie getgov-rh.app.cloud.gov)""" + with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class): + send_templated_email( + "emails/update_to_approved_domain.txt", + "emails/update_to_approved_domain_subject.txt", + "doesnotexist@igorville.com", + context={"domain": "test", "user": "test", "date": 1, "changes": "test"}, + bcc_address=None, + cc_addresses=["testy2@town.com", "mayor@igorville.gov"], + ) + + # check that an email was sent + self.assertTrue(self.mock_client.send_email.called) + + # check the call sequence for the email + args, kwargs = self.mock_client.send_email.call_args + self.assertIn("Destination", kwargs) + self.assertIn("CcAddresses", kwargs["Destination"]) + self.assertEqual(["testy2@town.com", "mayor@igorville.gov"], kwargs["Destination"]["CcAddresses"]) + + # Grab email subject + email_subject = kwargs["Content"]["Simple"]["Subject"]["Data"] + + # Check that the subject DOES contain a prefix of the current sandbox + self.assertIn("[GETGOV-RH]", email_subject) + + # Grab email body + email_body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"] + + # Check that manage_url is correctly set of the sandbox + self.assertIn("https://getgov-rh.app.cloud.gov", email_body) + @boto3_mocking.patching @less_console_noise_decorator def test_submission_confirmation(self): From 0725ab8e59e59ac63267fe1d008998d7fd7ba26c Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Wed, 12 Feb 2025 10:31:53 -0800 Subject: [PATCH 03/10] Clean up the comments --- src/registrar/tests/test_emails.py | 2 +- src/registrar/utility/email.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/registrar/tests/test_emails.py b/src/registrar/tests/test_emails.py index c79038668..2b7f89ac9 100644 --- a/src/registrar/tests/test_emails.py +++ b/src/registrar/tests/test_emails.py @@ -151,7 +151,7 @@ class TestEmails(TestCase): @override_settings(IS_PRODUCTION=False, BASE_URL="https://getgov-rh.app.cloud.gov") def test_email_non_production_subject_and_url_check(self): """Test sending an email in production that: - 1. Does prefix in the email subject ([GETGOV-RH]) + 1. Does prefix in the email subject (ie [GETGOV-RH]) 2. Uses the sandbox url in the email body (ie getgov-rh.app.cloud.gov)""" with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class): send_templated_email( diff --git a/src/registrar/utility/email.py b/src/registrar/utility/email.py index 535096b10..9323255af 100644 --- a/src/registrar/utility/email.py +++ b/src/registrar/utility/email.py @@ -57,7 +57,7 @@ def send_templated_email( # noqa env_name = re.sub(r"^https?://", "", env_base_url).split(".")[0] # To add to subject lines ie [GETGOV-RH] prefix = f"[{env_name.upper()}] " if not settings.IS_PRODUCTION else "" - # For email links + # For email links ie getgov-rh.app.cloud.gov manage_url = env_base_url if not settings.IS_PRODUCTION else "https://manage.get.gov" # Adding to context From 00732d0a64499224cc1e7da96ec35eba54970d51 Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Wed, 12 Feb 2025 10:58:38 -0800 Subject: [PATCH 04/10] Fix carrot link --- src/registrar/templates/emails/domain_manager_notification.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/templates/emails/domain_manager_notification.txt b/src/registrar/templates/emails/domain_manager_notification.txt index 18e682329..b5096a9d8 100644 --- a/src/registrar/templates/emails/domain_manager_notification.txt +++ b/src/registrar/templates/emails/domain_manager_notification.txt @@ -15,7 +15,7 @@ The person who received the invitation will become a domain manager once they lo associated with the invited email address. If you need to cancel this invitation or remove the domain manager, you can do that by going to -this domain in the .gov registrar <{{ manage_url }}. +this domain in the .gov registrar <{{ manage_url }}>. WHY DID YOU RECEIVE THIS EMAIL? From 16f0ae6f627417f9162c29bfa7b832396e4c5951 Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Wed, 12 Feb 2025 11:00:13 -0800 Subject: [PATCH 05/10] Fix more spacing --- .../emails/portfolio_admin_removal_notification_subject.txt | 2 +- src/registrar/templates/emails/update_to_approved_domain.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/registrar/templates/emails/portfolio_admin_removal_notification_subject.txt b/src/registrar/templates/emails/portfolio_admin_removal_notification_subject.txt index 030d27ae7..9a45a8bbc 100644 --- a/src/registrar/templates/emails/portfolio_admin_removal_notification_subject.txt +++ b/src/registrar/templates/emails/portfolio_admin_removal_notification_subject.txt @@ -1 +1 @@ -{{ prefix}}An admin was removed from your .gov organization \ No newline at end of file +{{ prefix }}An admin was removed from your .gov organization \ No newline at end of file diff --git a/src/registrar/templates/emails/update_to_approved_domain.txt b/src/registrar/templates/emails/update_to_approved_domain.txt index fb0a442cb..070096f62 100644 --- a/src/registrar/templates/emails/update_to_approved_domain.txt +++ b/src/registrar/templates/emails/update_to_approved_domain.txt @@ -1,4 +1,4 @@ - {% autoescape off %}{# In a text file, we don't want to have HTML entities escaped #} +{% autoescape off %}{# In a text file, we don't want to have HTML entities escaped #} Hi, An update was made to a domain you manage. From c737daa8fd2f8d497edfb9c5499d74e66316dcd7 Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Thu, 13 Feb 2025 10:28:49 -0800 Subject: [PATCH 06/10] Add prefix and manage url to the action needed reasons templates --- .../action_needed_reasons/already_has_domains_subject.txt | 2 +- .../templates/emails/action_needed_reasons/bad_name.txt | 2 +- .../templates/emails/action_needed_reasons/bad_name_subject.txt | 2 +- .../action_needed_reasons/eligibility_unclear_subject.txt | 2 +- .../action_needed_reasons/questionable_senior_official.txt | 2 +- .../questionable_senior_official_subject.txt | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/registrar/templates/emails/action_needed_reasons/already_has_domains_subject.txt b/src/registrar/templates/emails/action_needed_reasons/already_has_domains_subject.txt index 7ca332ddd..b29b8040c 100644 --- a/src/registrar/templates/emails/action_needed_reasons/already_has_domains_subject.txt +++ b/src/registrar/templates/emails/action_needed_reasons/already_has_domains_subject.txt @@ -1 +1 @@ -Update on your .gov request: {{ domain_request.requested_domain.name }} \ No newline at end of file +{{ prefix }}Update on your .gov request: {{ domain_request.requested_domain.name }} \ No newline at end of file diff --git a/src/registrar/templates/emails/action_needed_reasons/bad_name.txt b/src/registrar/templates/emails/action_needed_reasons/bad_name.txt index ac563b549..40e5ed899 100644 --- a/src/registrar/templates/emails/action_needed_reasons/bad_name.txt +++ b/src/registrar/templates/emails/action_needed_reasons/bad_name.txt @@ -17,7 +17,7 @@ Domains should uniquely identify a government organization and be clear to the g ACTION NEEDED -First, we need you to identify a new domain name that meets our naming requirements for your type of organization. Then, log in to the registrar and update the name in your domain request. Once you submit your updated request, we’ll resume the adjudication process. +First, we need you to identify a new domain name that meets our naming requirements for your type of organization. Then, log in to the registrar and update the name in your domain request. <{{ manage_url }}> Once you submit your updated request, we’ll resume the adjudication process. If you have questions or want to discuss potential domain names, reply to this email. diff --git a/src/registrar/templates/emails/action_needed_reasons/bad_name_subject.txt b/src/registrar/templates/emails/action_needed_reasons/bad_name_subject.txt index 7ca332ddd..b29b8040c 100644 --- a/src/registrar/templates/emails/action_needed_reasons/bad_name_subject.txt +++ b/src/registrar/templates/emails/action_needed_reasons/bad_name_subject.txt @@ -1 +1 @@ -Update on your .gov request: {{ domain_request.requested_domain.name }} \ No newline at end of file +{{ prefix }}Update on your .gov request: {{ domain_request.requested_domain.name }} \ No newline at end of file diff --git a/src/registrar/templates/emails/action_needed_reasons/eligibility_unclear_subject.txt b/src/registrar/templates/emails/action_needed_reasons/eligibility_unclear_subject.txt index 7ca332ddd..b29b8040c 100644 --- a/src/registrar/templates/emails/action_needed_reasons/eligibility_unclear_subject.txt +++ b/src/registrar/templates/emails/action_needed_reasons/eligibility_unclear_subject.txt @@ -1 +1 @@ -Update on your .gov request: {{ domain_request.requested_domain.name }} \ No newline at end of file +{{ prefix }}Update on your .gov request: {{ domain_request.requested_domain.name }} \ No newline at end of file diff --git a/src/registrar/templates/emails/action_needed_reasons/questionable_senior_official.txt b/src/registrar/templates/emails/action_needed_reasons/questionable_senior_official.txt index ef05e17d7..40d068cd9 100644 --- a/src/registrar/templates/emails/action_needed_reasons/questionable_senior_official.txt +++ b/src/registrar/templates/emails/action_needed_reasons/questionable_senior_official.txt @@ -21,7 +21,7 @@ We expect a senior official to be someone in a role of significant, executive re ACTION NEEDED Reply to this email with a justification for naming {{ domain_request.senior_official.get_formatted_name }} as the senior official. If you have questions or comments, include those in your reply. -Alternatively, you can log in to the registrar and enter a different senior official for this domain request. Once you submit your updated request, we’ll resume the adjudication process. +Alternatively, you can log in to the registrar and enter a different senior official for this domain request. <{{ manage_url }}> Once you submit your updated request, we’ll resume the adjudication process. THANK YOU diff --git a/src/registrar/templates/emails/action_needed_reasons/questionable_senior_official_subject.txt b/src/registrar/templates/emails/action_needed_reasons/questionable_senior_official_subject.txt index 7ca332ddd..b29b8040c 100644 --- a/src/registrar/templates/emails/action_needed_reasons/questionable_senior_official_subject.txt +++ b/src/registrar/templates/emails/action_needed_reasons/questionable_senior_official_subject.txt @@ -1 +1 @@ -Update on your .gov request: {{ domain_request.requested_domain.name }} \ No newline at end of file +{{ prefix }}Update on your .gov request: {{ domain_request.requested_domain.name }} \ No newline at end of file From 856b71b6ce70e429a77a1342e20ac41db8a75b42 Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Thu, 13 Feb 2025 10:30:48 -0800 Subject: [PATCH 07/10] Add for transition domain inv email --- src/registrar/templates/emails/transition_domain_invitation.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/templates/emails/transition_domain_invitation.txt b/src/registrar/templates/emails/transition_domain_invitation.txt index dc812edf3..14dd626dd 100644 --- a/src/registrar/templates/emails/transition_domain_invitation.txt +++ b/src/registrar/templates/emails/transition_domain_invitation.txt @@ -57,7 +57,7 @@ THANK YOU The .gov team .Gov blog -Domain management +Domain management <{{ manage_url }}}> Get.gov The .gov registry is a part of the Cybersecurity and Infrastructure Security Agency (CISA) From 8020bd6f7461b71fa663fc5fff8c4a797eeed907 Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Fri, 14 Feb 2025 08:02:47 -0800 Subject: [PATCH 08/10] Update for prefix to be in the subject dynamically --- .../already_has_domains_subject.txt | 2 +- .../emails/action_needed_reasons/bad_name_subject.txt | 2 +- .../eligibility_unclear_subject.txt | 2 +- .../questionable_senior_official_subject.txt | 2 +- .../templates/emails/domain_invitation_subject.txt | 2 +- .../domain_manager_deleted_notification_subject.txt | 2 +- .../emails/domain_manager_notification_subject.txt | 2 +- .../emails/domain_request_withdrawn_subject.txt | 2 +- src/registrar/templates/emails/metadata_body.txt | 2 +- src/registrar/templates/emails/metadata_subject.txt | 2 +- .../portfolio_admin_addition_notification_subject.txt | 2 +- .../portfolio_admin_removal_notification_subject.txt | 2 +- .../templates/emails/portfolio_invitation_subject.txt | 2 +- .../emails/status_change_approved_subject.txt | 2 +- .../templates/emails/status_change_subject.txt | 2 +- .../emails/submission_confirmation_subject.txt | 2 +- .../emails/transition_domain_invitation_subject.txt | 2 +- .../emails/update_to_approved_domain_subject.txt | 2 +- src/registrar/utility/email.py | 11 +++++++---- 19 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/registrar/templates/emails/action_needed_reasons/already_has_domains_subject.txt b/src/registrar/templates/emails/action_needed_reasons/already_has_domains_subject.txt index b29b8040c..7ca332ddd 100644 --- a/src/registrar/templates/emails/action_needed_reasons/already_has_domains_subject.txt +++ b/src/registrar/templates/emails/action_needed_reasons/already_has_domains_subject.txt @@ -1 +1 @@ -{{ prefix }}Update on your .gov request: {{ domain_request.requested_domain.name }} \ No newline at end of file +Update on your .gov request: {{ domain_request.requested_domain.name }} \ No newline at end of file diff --git a/src/registrar/templates/emails/action_needed_reasons/bad_name_subject.txt b/src/registrar/templates/emails/action_needed_reasons/bad_name_subject.txt index b29b8040c..7ca332ddd 100644 --- a/src/registrar/templates/emails/action_needed_reasons/bad_name_subject.txt +++ b/src/registrar/templates/emails/action_needed_reasons/bad_name_subject.txt @@ -1 +1 @@ -{{ prefix }}Update on your .gov request: {{ domain_request.requested_domain.name }} \ No newline at end of file +Update on your .gov request: {{ domain_request.requested_domain.name }} \ No newline at end of file diff --git a/src/registrar/templates/emails/action_needed_reasons/eligibility_unclear_subject.txt b/src/registrar/templates/emails/action_needed_reasons/eligibility_unclear_subject.txt index b29b8040c..7ca332ddd 100644 --- a/src/registrar/templates/emails/action_needed_reasons/eligibility_unclear_subject.txt +++ b/src/registrar/templates/emails/action_needed_reasons/eligibility_unclear_subject.txt @@ -1 +1 @@ -{{ prefix }}Update on your .gov request: {{ domain_request.requested_domain.name }} \ No newline at end of file +Update on your .gov request: {{ domain_request.requested_domain.name }} \ No newline at end of file diff --git a/src/registrar/templates/emails/action_needed_reasons/questionable_senior_official_subject.txt b/src/registrar/templates/emails/action_needed_reasons/questionable_senior_official_subject.txt index b29b8040c..7ca332ddd 100644 --- a/src/registrar/templates/emails/action_needed_reasons/questionable_senior_official_subject.txt +++ b/src/registrar/templates/emails/action_needed_reasons/questionable_senior_official_subject.txt @@ -1 +1 @@ -{{ prefix }}Update on your .gov request: {{ domain_request.requested_domain.name }} \ No newline at end of file +Update on your .gov request: {{ domain_request.requested_domain.name }} \ No newline at end of file diff --git a/src/registrar/templates/emails/domain_invitation_subject.txt b/src/registrar/templates/emails/domain_invitation_subject.txt index 9f15c38b4..9663346d0 100644 --- a/src/registrar/templates/emails/domain_invitation_subject.txt +++ b/src/registrar/templates/emails/domain_invitation_subject.txt @@ -1 +1 @@ -{{ prefix }}You've been invited to manage {% if domains|length > 1 %}.gov domains{% else %}{{ domains.0.name }}{% endif %} \ No newline at end of file +You've been invited to manage {% if domains|length > 1 %}.gov domains{% else %}{{ domains.0.name }}{% endif %} \ No newline at end of file diff --git a/src/registrar/templates/emails/domain_manager_deleted_notification_subject.txt b/src/registrar/templates/emails/domain_manager_deleted_notification_subject.txt index 7376bdb86..c84a20f18 100644 --- a/src/registrar/templates/emails/domain_manager_deleted_notification_subject.txt +++ b/src/registrar/templates/emails/domain_manager_deleted_notification_subject.txt @@ -1 +1 @@ -{{ prefix }}A domain manager was removed from {{ domain.name }} \ No newline at end of file +A domain manager was removed from {{ domain.name }} \ No newline at end of file diff --git a/src/registrar/templates/emails/domain_manager_notification_subject.txt b/src/registrar/templates/emails/domain_manager_notification_subject.txt index 8560cb9fa..0e9918de0 100644 --- a/src/registrar/templates/emails/domain_manager_notification_subject.txt +++ b/src/registrar/templates/emails/domain_manager_notification_subject.txt @@ -1 +1 @@ -{{ prefix }}A domain manager was invited to {{ domain.name }} \ No newline at end of file +A domain manager was invited to {{ domain.name }} \ No newline at end of file diff --git a/src/registrar/templates/emails/domain_request_withdrawn_subject.txt b/src/registrar/templates/emails/domain_request_withdrawn_subject.txt index cc146643a..51b2c745a 100644 --- a/src/registrar/templates/emails/domain_request_withdrawn_subject.txt +++ b/src/registrar/templates/emails/domain_request_withdrawn_subject.txt @@ -1 +1 @@ -{{ prefix }}Update on your .gov request: {{ domain_request.requested_domain.name }} +Update on your .gov request: {{ domain_request.requested_domain.name }} diff --git a/src/registrar/templates/emails/metadata_body.txt b/src/registrar/templates/emails/metadata_body.txt index a0a3682b7..adf0a186c 100644 --- a/src/registrar/templates/emails/metadata_body.txt +++ b/src/registrar/templates/emails/metadata_body.txt @@ -1 +1 @@ -{{ prefix }}An export of all .gov metadata. +An export of all .gov metadata. diff --git a/src/registrar/templates/emails/metadata_subject.txt b/src/registrar/templates/emails/metadata_subject.txt index c19b4c26e..5fdece7ef 100644 --- a/src/registrar/templates/emails/metadata_subject.txt +++ b/src/registrar/templates/emails/metadata_subject.txt @@ -1,2 +1,2 @@ -{{ prefix }}Domain metadata - {{current_date_str}} +Domain metadata - {{current_date_str}} diff --git a/src/registrar/templates/emails/portfolio_admin_addition_notification_subject.txt b/src/registrar/templates/emails/portfolio_admin_addition_notification_subject.txt index ee5987512..3d6b2a140 100644 --- a/src/registrar/templates/emails/portfolio_admin_addition_notification_subject.txt +++ b/src/registrar/templates/emails/portfolio_admin_addition_notification_subject.txt @@ -1 +1 @@ -{{ prefix }}An admin was invited to your .gov organization \ No newline at end of file +An admin was invited to your .gov organization \ No newline at end of file diff --git a/src/registrar/templates/emails/portfolio_admin_removal_notification_subject.txt b/src/registrar/templates/emails/portfolio_admin_removal_notification_subject.txt index 9a45a8bbc..e250b17f8 100644 --- a/src/registrar/templates/emails/portfolio_admin_removal_notification_subject.txt +++ b/src/registrar/templates/emails/portfolio_admin_removal_notification_subject.txt @@ -1 +1 @@ -{{ prefix }}An admin was removed from your .gov organization \ No newline at end of file +An admin was removed from your .gov organization \ No newline at end of file diff --git a/src/registrar/templates/emails/portfolio_invitation_subject.txt b/src/registrar/templates/emails/portfolio_invitation_subject.txt index de9080196..552bb2bec 100644 --- a/src/registrar/templates/emails/portfolio_invitation_subject.txt +++ b/src/registrar/templates/emails/portfolio_invitation_subject.txt @@ -1 +1 @@ -{{ prefix }}You’ve been invited to a .gov organization \ No newline at end of file +You’ve been invited to a .gov organization \ No newline at end of file diff --git a/src/registrar/templates/emails/status_change_approved_subject.txt b/src/registrar/templates/emails/status_change_approved_subject.txt index cc146643a..51b2c745a 100644 --- a/src/registrar/templates/emails/status_change_approved_subject.txt +++ b/src/registrar/templates/emails/status_change_approved_subject.txt @@ -1 +1 @@ -{{ prefix }}Update on your .gov request: {{ domain_request.requested_domain.name }} +Update on your .gov request: {{ domain_request.requested_domain.name }} diff --git a/src/registrar/templates/emails/status_change_subject.txt b/src/registrar/templates/emails/status_change_subject.txt index cc146643a..51b2c745a 100644 --- a/src/registrar/templates/emails/status_change_subject.txt +++ b/src/registrar/templates/emails/status_change_subject.txt @@ -1 +1 @@ -{{ prefix }}Update on your .gov request: {{ domain_request.requested_domain.name }} +Update on your .gov request: {{ domain_request.requested_domain.name }} diff --git a/src/registrar/templates/emails/submission_confirmation_subject.txt b/src/registrar/templates/emails/submission_confirmation_subject.txt index cc146643a..51b2c745a 100644 --- a/src/registrar/templates/emails/submission_confirmation_subject.txt +++ b/src/registrar/templates/emails/submission_confirmation_subject.txt @@ -1 +1 @@ -{{ prefix }}Update on your .gov request: {{ domain_request.requested_domain.name }} +Update on your .gov request: {{ domain_request.requested_domain.name }} diff --git a/src/registrar/templates/emails/transition_domain_invitation_subject.txt b/src/registrar/templates/emails/transition_domain_invitation_subject.txt index b162341d9..526c7714b 100644 --- a/src/registrar/templates/emails/transition_domain_invitation_subject.txt +++ b/src/registrar/templates/emails/transition_domain_invitation_subject.txt @@ -1 +1 @@ -{{ prefix }}(Action required) Manage your .gov domain{% if domains|length > 1 %}s{% endif %} in the new registrar \ No newline at end of file +(Action required) Manage your .gov domain{% if domains|length > 1 %}s{% endif %} in the new registrar \ No newline at end of file diff --git a/src/registrar/templates/emails/update_to_approved_domain_subject.txt b/src/registrar/templates/emails/update_to_approved_domain_subject.txt index d952999a0..cf4c9a14c 100644 --- a/src/registrar/templates/emails/update_to_approved_domain_subject.txt +++ b/src/registrar/templates/emails/update_to_approved_domain_subject.txt @@ -1 +1 @@ -{{ prefix }}An update was made to {{domain}} \ No newline at end of file +An update was made to {{domain}} \ No newline at end of file diff --git a/src/registrar/utility/email.py b/src/registrar/utility/email.py index 9323255af..b4caf42a5 100644 --- a/src/registrar/utility/email.py +++ b/src/registrar/utility/email.py @@ -60,13 +60,19 @@ def send_templated_email( # noqa # For email links ie getgov-rh.app.cloud.gov manage_url = env_base_url if not settings.IS_PRODUCTION else "https://manage.get.gov" + # Update the subject to have prefix here versus every email + subject_template = get_template(subject_template_name) + subject = subject_template.render(context=context) + subject = f"{prefix}{subject}" + # Adding to context context.update( { - "prefix": prefix, + "subject": subject, "manage_url": manage_url, } ) + # by default assume we can send to all addresses (prod has no whitelist) sendable_cc_addresses = cc_addresses @@ -89,9 +95,6 @@ def send_templated_email( # noqa if email_body: email_body.strip().lstrip("\n") - subject_template = get_template(subject_template_name) - subject = subject_template.render(context=context) - try: ses_client = boto3.client( "sesv2", From 33bf1988f1700ca149403555e3125697199c9128 Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Fri, 14 Feb 2025 08:28:50 -0800 Subject: [PATCH 09/10] Fix placement of where email subject is edited --- src/registrar/utility/email.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/registrar/utility/email.py b/src/registrar/utility/email.py index b4caf42a5..39c7f21ac 100644 --- a/src/registrar/utility/email.py +++ b/src/registrar/utility/email.py @@ -60,18 +60,7 @@ def send_templated_email( # noqa # For email links ie getgov-rh.app.cloud.gov manage_url = env_base_url if not settings.IS_PRODUCTION else "https://manage.get.gov" - # Update the subject to have prefix here versus every email - subject_template = get_template(subject_template_name) - subject = subject_template.render(context=context) - subject = f"{prefix}{subject}" - - # Adding to context - context.update( - { - "subject": subject, - "manage_url": manage_url, - } - ) + context["manage_url"] = manage_url # by default assume we can send to all addresses (prod has no whitelist) sendable_cc_addresses = cc_addresses @@ -95,6 +84,13 @@ def send_templated_email( # noqa if email_body: email_body.strip().lstrip("\n") + # Update the subject to have prefix here versus every email + subject_template = get_template(subject_template_name) + subject = subject_template.render(context=context) + subject = f"{prefix}{subject}" + + context["subject"] = subject + try: ses_client = boto3.client( "sesv2", From 7d8249923e88a0fa4571d6290e5409d792bb42eb Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Fri, 14 Feb 2025 09:17:28 -0800 Subject: [PATCH 10/10] Update comments --- src/registrar/utility/email.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/registrar/utility/email.py b/src/registrar/utility/email.py index 39c7f21ac..797ad4aa9 100644 --- a/src/registrar/utility/email.py +++ b/src/registrar/utility/email.py @@ -53,11 +53,13 @@ def send_templated_email( # noqa context = {} env_base_url = settings.BASE_URL - # The regular expresstion is to get both http (localhost) and https (everything else) + # The regular expression is to get both http (localhost) and https (everything else) env_name = re.sub(r"^https?://", "", env_base_url).split(".")[0] - # To add to subject lines ie [GETGOV-RH] + # If NOT in prod, add env to the subject line + # IE adds [GETGOV-RH] if we are in the -RH sandbox prefix = f"[{env_name.upper()}] " if not settings.IS_PRODUCTION else "" - # For email links ie getgov-rh.app.cloud.gov + # If NOT in prod, update instances of "manage.get.gov" links to point to + # current environment, ie "getgov-rh.app.cloud.gov" manage_url = env_base_url if not settings.IS_PRODUCTION else "https://manage.get.gov" context["manage_url"] = manage_url