From 36f3d3e8a909588b06ea5efc1e78e6e1c2e4ee0a Mon Sep 17 00:00:00 2001 From: matthewswspence Date: Mon, 16 Dec 2024 10:25:25 -0600 Subject: [PATCH 01/44] add warning to domain requests when status cannot be changed --- src/registrar/admin.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 0e8e4847a..5e8148664 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -2543,6 +2543,31 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): # Further filter the queryset by the portfolio qs = qs.filter(portfolio=portfolio_id) return qs + + def change_view(self, request, object_id, form_url="", extra_context=None): + """Extend the change_view for DomainRequest objects in django admin. + Customize to display notification that statu cannot be changed from 'Approved'.""" + + # Fetch the Contact instance + domain_request: models.DomainRequest = models.DomainRequest.objects.get(pk=object_id) + if domain_request.approved_domain and domain_request.approved_domain.state == models.Domain.State.READY: + domain = domain_request.approved_domain + # get change url for domain + app_label = domain_request.approved_domain._meta.app_label + model_name = domain._meta.model_name + obj_id = domain.id + change_url = reverse("admin:%s_%s_change" % (app_label, model_name), args=[obj_id]) + + message += f"

The status of this domain request cannot be changed because it has been joined to a domain in Ready status: " # noqa + message += f"{domain}

" + + message_html = mark_safe(message) # nosec + messages.warning( + request, + message_html, + ) + + return super().change_view(request, object_id, form_url, extra_context=extra_context) class TransitionDomainAdmin(ListHeaderAdmin): From ead90c15411ac2f9d1cadc478bc85992642b4e7a Mon Sep 17 00:00:00 2001 From: matthewswspence Date: Mon, 16 Dec 2024 14:11:42 -0600 Subject: [PATCH 02/44] tests for approved domain warning --- src/registrar/admin.py | 50 ++++++++++------------- src/registrar/tests/test_admin_request.py | 38 ++++++++++++++++- 2 files changed, 59 insertions(+), 29 deletions(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 5e8148664..ce3b0220c 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -2429,8 +2429,28 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): return response def change_view(self, request, object_id, form_url="", extra_context=None): - """Display restricted warning, - Setup the auditlog trail and pass it in extra context.""" + """Display restricted warning, setup the auditlog trail and pass it in extra context, + display warning that status cannot be changed from 'Approved' if domain is in Ready state""" + + # Fetch the Contact instance + domain_request: models.DomainRequest = models.DomainRequest.objects.get(pk=object_id) + if domain_request.approved_domain and domain_request.approved_domain.state == models.Domain.State.READY: + domain = domain_request.approved_domain + # get change url for domain + app_label = domain_request.approved_domain._meta.app_label + model_name = domain._meta.model_name + obj_id = domain.id + change_url = reverse("admin:%s_%s_change" % (app_label, model_name), args=[obj_id]) + + message = f"
  • The status of this domain request cannot be changed because it has been joined to a domain in Ready status: " # noqa + message += f"{domain}
  • " + + message_html = mark_safe(message) # nosec + messages.warning( + request, + message_html, + ) + obj = self.get_object(request, object_id) self.display_restricted_warning(request, obj) @@ -2543,32 +2563,6 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): # Further filter the queryset by the portfolio qs = qs.filter(portfolio=portfolio_id) return qs - - def change_view(self, request, object_id, form_url="", extra_context=None): - """Extend the change_view for DomainRequest objects in django admin. - Customize to display notification that statu cannot be changed from 'Approved'.""" - - # Fetch the Contact instance - domain_request: models.DomainRequest = models.DomainRequest.objects.get(pk=object_id) - if domain_request.approved_domain and domain_request.approved_domain.state == models.Domain.State.READY: - domain = domain_request.approved_domain - # get change url for domain - app_label = domain_request.approved_domain._meta.app_label - model_name = domain._meta.model_name - obj_id = domain.id - change_url = reverse("admin:%s_%s_change" % (app_label, model_name), args=[obj_id]) - - message += f"

    The status of this domain request cannot be changed because it has been joined to a domain in Ready status: " # noqa - message += f"{domain}

    " - - message_html = mark_safe(message) # nosec - messages.warning( - request, - message_html, - ) - - return super().change_view(request, object_id, form_url, extra_context=extra_context) - class TransitionDomainAdmin(ListHeaderAdmin): """Custom transition domain admin class.""" diff --git a/src/registrar/tests/test_admin_request.py b/src/registrar/tests/test_admin_request.py index df0902719..d744dd00a 100644 --- a/src/registrar/tests/test_admin_request.py +++ b/src/registrar/tests/test_admin_request.py @@ -25,6 +25,8 @@ from registrar.models import ( Portfolio, AllowedEmail, ) +from registrar.models.host import Host +from registrar.models.public_contact import PublicContact from .common import ( MockSESClient, completed_domain_request, @@ -36,7 +38,7 @@ from .common import ( MockEppLib, GenericTestHelper, ) -from unittest.mock import patch +from unittest.mock import ANY, patch from django.conf import settings import boto3_mocking # type: ignore @@ -76,6 +78,8 @@ class TestDomainRequestAdmin(MockEppLib): def tearDown(self): super().tearDown() + Host.objects.all().delete() + PublicContact.objects.all().delete() Domain.objects.all().delete() DomainInformation.objects.all().delete() DomainRequest.objects.all().delete() @@ -91,6 +95,7 @@ class TestDomainRequestAdmin(MockEppLib): User.objects.all().delete() AllowedEmail.objects.all().delete() + @less_console_noise_decorator def test_domain_request_senior_official_is_alphabetically_sorted(self): """Tests if the senior offical dropdown is alphanetically sorted in the django admin display""" @@ -1810,6 +1815,37 @@ class TestDomainRequestAdmin(MockEppLib): request, "Cannot edit a domain request with a restricted creator.", ) + + # @less_console_noise_decorator + def test_approved_domain_request_with_ready_domain_has_warning_message(self): + """Tests if the domain request has a warning message when the approved domain is in Ready state""" + # Create an instance of the model + domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW) + # Approve the domain request + domain_request.approve() + domain_request.save() + + # Add nameservers to get to Ready state + domain_request.approved_domain.nameservers = [ + ("ns1.city.gov", ["1.1.1.1"]), + ("ns2.city.gov", ["1.1.1.2"]), + ] + domain_request.approved_domain.save() + + with boto3_mocking.clients.handler_for("sesv2", self.mock_client): + with patch("django.contrib.messages.warning") as mock_warning: + # Create a request object + self.client.force_login(self.superuser) + self.client.get( + "/admin/registrar/domainrequest/{}/change/".format(domain_request.pk), + follow=True, + ) + + # Assert that the error message was called with the correct argument + mock_warning.assert_called_once_with( + ANY, # don't care about the request argument + "
  • The status of this domain request cannot be changed because it has been joined to a domain in Ready status: city.gov
  • " # care about this message + ) def trigger_saving_approved_to_another_state(self, domain_is_active, another_state, rejection_reason=None): """Helper method that triggers domain request state changes from approved to another state, From ec39b159ecfffb7786b2530ce127037084edee68 Mon Sep 17 00:00:00 2001 From: matthewswspence Date: Mon, 16 Dec 2024 14:19:12 -0600 Subject: [PATCH 03/44] make test less brittle --- src/registrar/tests/test_admin_request.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/tests/test_admin_request.py b/src/registrar/tests/test_admin_request.py index d744dd00a..bbf6c1923 100644 --- a/src/registrar/tests/test_admin_request.py +++ b/src/registrar/tests/test_admin_request.py @@ -1844,7 +1844,7 @@ class TestDomainRequestAdmin(MockEppLib): # Assert that the error message was called with the correct argument mock_warning.assert_called_once_with( ANY, # don't care about the request argument - "
  • The status of this domain request cannot be changed because it has been joined to a domain in Ready status: city.gov
  • " # care about this message + f"
  • The status of this domain request cannot be changed because it has been joined to a domain in Ready status: {domain_request.approved_domain.name}
  • ", # noqa ) def trigger_saving_approved_to_another_state(self, domain_is_active, another_state, rejection_reason=None): From 79077cce31efa1e469ba426507e9e7d44c263890 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Mon, 16 Dec 2024 13:23:14 -0700 Subject: [PATCH 04/44] basic logic --- .../js/getgov-admin/domain-request-form.js | 5 +++ ...0_alter_suborganization_unique_together.py | 17 +++++++++ src/registrar/models/domain.py | 1 + src/registrar/models/domain_request.py | 37 ++++++++++++++++++- src/registrar/models/suborganization.py | 3 ++ 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 src/registrar/migrations/0140_alter_suborganization_unique_together.py diff --git a/src/registrar/assets/src/js/getgov-admin/domain-request-form.js b/src/registrar/assets/src/js/getgov-admin/domain-request-form.js index a815a59a1..6b79a2419 100644 --- a/src/registrar/assets/src/js/getgov-admin/domain-request-form.js +++ b/src/registrar/assets/src/js/getgov-admin/domain-request-form.js @@ -629,6 +629,10 @@ export function initRejectedEmail() { }); } +function handleSuborganizationSelection() { + console.log("cats are cool") +} + /** * A function for dynamic DomainRequest fields */ @@ -636,5 +640,6 @@ export function initDynamicDomainRequestFields(){ const domainRequestPage = document.getElementById("domainrequest_form"); if (domainRequestPage) { handlePortfolioSelection(); + handleSuborganizationSelection(); } } diff --git a/src/registrar/migrations/0140_alter_suborganization_unique_together.py b/src/registrar/migrations/0140_alter_suborganization_unique_together.py new file mode 100644 index 000000000..e59ecdf2b --- /dev/null +++ b/src/registrar/migrations/0140_alter_suborganization_unique_together.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.10 on 2024-12-16 17:02 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("registrar", "0139_alter_domainrequest_action_needed_reason"), + ] + + operations = [ + migrations.AlterUniqueTogether( + name="suborganization", + unique_together={("name", "portfolio")}, + ), + ] diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index cc600e1ce..2ea78ff10 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -237,6 +237,7 @@ class Domain(TimeStampedModel, DomainHelper): is called in the validate function on the request/domain page throws- RegistryError or InvalidDomainError""" + return True if not cls.string_could_be_domain(domain): logger.warning("Not a valid domain: %s" % str(domain)) # throw invalid domain error so that it can be caught in diff --git a/src/registrar/models/domain_request.py b/src/registrar/models/domain_request.py index 44d8511b0..46e188a0a 100644 --- a/src/registrar/models/domain_request.py +++ b/src/registrar/models/domain_request.py @@ -690,6 +690,18 @@ class DomainRequest(TimeStampedModel): # Update the cached values after saving self._cache_status_and_status_reasons() + def create_requested_suborganization(self): + """Creates the requested suborganization. + Adds the name, portfolio, city, and state_territory fields. + Returns the created suborganization.""" + Suborganization = apps.get_model("registrar.Suborganization") + return Suborganization.objects.create( + name=self.requested_suborganization, + portfolio=self.portfolio, + city=self.suborganization_city, + state_territory=self.suborganization_state_territory, + ) + def send_custom_status_update_email(self, status): """Helper function to send out a second status email when the status remains the same, but the reason has changed.""" @@ -785,6 +797,7 @@ class DomainRequest(TimeStampedModel): def delete_and_clean_up_domain(self, called_from): try: + # Clean up the approved domain domain_state = self.approved_domain.state # Only reject if it exists on EPP if domain_state != Domain.State.UNKNOWN: @@ -796,6 +809,19 @@ class DomainRequest(TimeStampedModel): logger.error(err) logger.error(f"Can't query an approved domain while attempting {called_from}") + # Clean up any created suborgs, assuming its for this record only + if self.sub_organization is not None: + request_suborg_count = self.request_sub_organization.count() + domain_suborgs = self.DomainRequest_info.filter( + sub_organization=self.sub_organization + ).count() + if request_suborg_count == 1 and domain_suborgs.count() <= 1: + # if domain_suborgs.count() == 1: + # domain_info = domain_suborgs.first() + # domain_info.sub_organization = None + # domain_info.save() + self.sub_organization.delete() + def _send_status_update_email( self, new_status, @@ -984,6 +1010,7 @@ class DomainRequest(TimeStampedModel): if self.status == self.DomainRequestStatus.APPROVED: self.delete_and_clean_up_domain("action_needed") + elif self.status == self.DomainRequestStatus.REJECTED: self.rejection_reason = None @@ -1014,8 +1041,16 @@ class DomainRequest(TimeStampedModel): domain request into an admin on that domain. It also triggers an email notification.""" + should_save = False if self.federal_agency is None: self.federal_agency = FederalAgency.objects.filter(agency="Non-Federal Agency").first() + should_save = True + + if self.is_requesting_new_suborganization(): + self.sub_organization = self.create_requested_suborganization() + should_save = True + + if should_save: self.save() # create the domain @@ -1148,7 +1183,7 @@ class DomainRequest(TimeStampedModel): def is_requesting_new_suborganization(self) -> bool: """Determines if a user is trying to request a new suborganization using the domain request form, rather than one that already exists. - Used for the RequestingEntity page. + Used for the RequestingEntity page and on DomainInformation.create_from_da(). Returns True if a sub_organization does not exist and if requested_suborganization, suborganization_city, and suborganization_state_territory all exist. diff --git a/src/registrar/models/suborganization.py b/src/registrar/models/suborganization.py index 087490244..fb32ad48a 100644 --- a/src/registrar/models/suborganization.py +++ b/src/registrar/models/suborganization.py @@ -9,6 +9,9 @@ class Suborganization(TimeStampedModel): Suborganization under an organization (portfolio) """ + class Meta: + unique_together = ["name", "portfolio"] + name = models.CharField( unique=True, max_length=1000, From 4572b52aad52154d000e0d9399d0987dbcfd48e9 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Tue, 17 Dec 2024 08:34:58 -0700 Subject: [PATCH 05/44] Removal logic --- src/registrar/forms/domain_request_wizard.py | 17 ++++++- ...0_alter_suborganization_unique_together.py | 17 ------- src/registrar/models/domain_request.py | 46 ++++++++++++++----- src/registrar/models/suborganization.py | 3 -- 4 files changed, 50 insertions(+), 33 deletions(-) delete mode 100644 src/registrar/migrations/0140_alter_suborganization_unique_together.py diff --git a/src/registrar/forms/domain_request_wizard.py b/src/registrar/forms/domain_request_wizard.py index 572ef6399..eed0866f3 100644 --- a/src/registrar/forms/domain_request_wizard.py +++ b/src/registrar/forms/domain_request_wizard.py @@ -17,6 +17,7 @@ from registrar.models import Contact, DomainRequest, DraftDomain, Domain, Federa from registrar.templatetags.url_helpers import public_site_url from registrar.utility.enums import ValidationReturnType from registrar.utility.constants import BranchChoices +from django.core.exceptions import ValidationError logger = logging.getLogger(__name__) @@ -78,6 +79,20 @@ class RequestingEntityForm(RegistrarForm): # Otherwise just return the suborg as normal return self.cleaned_data.get("sub_organization") + def clean_requested_suborganization(self): + name = self.cleaned_data.get('requested_suborganization') + if name and Suborganization.objects.filter( + name__iexact=name, + portfolio=self.domain_request.portfolio, + name__isnull=False, + portfolio__isnull=False + ).exists(): + raise ValidationError( + "This suborganization already exists. " + "Choose a new name, or select it directly if you would like to use it." + ) + return name + def full_clean(self): """Validation logic to remove the custom suborganization value before clean is triggered. Without this override, the form will throw an 'invalid option' error.""" @@ -114,7 +129,7 @@ class RequestingEntityForm(RegistrarForm): if requesting_entity_is_suborganization == "True": if is_requesting_new_suborganization: # Validate custom suborganization fields - if not cleaned_data.get("requested_suborganization"): + if not cleaned_data.get("requested_suborganization") and "requested_suborganization" not in self.errors: self.add_error("requested_suborganization", "Enter the name of your suborganization.") if not cleaned_data.get("suborganization_city"): self.add_error("suborganization_city", "Enter the city where your suborganization is located.") diff --git a/src/registrar/migrations/0140_alter_suborganization_unique_together.py b/src/registrar/migrations/0140_alter_suborganization_unique_together.py deleted file mode 100644 index e59ecdf2b..000000000 --- a/src/registrar/migrations/0140_alter_suborganization_unique_together.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 4.2.10 on 2024-12-16 17:02 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("registrar", "0139_alter_domainrequest_action_needed_reason"), - ] - - operations = [ - migrations.AlterUniqueTogether( - name="suborganization", - unique_together={("name", "portfolio")}, - ), - ] diff --git a/src/registrar/models/domain_request.py b/src/registrar/models/domain_request.py index 46e188a0a..d78cd587f 100644 --- a/src/registrar/models/domain_request.py +++ b/src/registrar/models/domain_request.py @@ -12,6 +12,7 @@ from registrar.models.utility.generic_helper import CreateOrUpdateOrganizationTy from registrar.utility.errors import FSMDomainRequestError, FSMErrorCodes from registrar.utility.constants import BranchChoices from auditlog.models import LogEntry +from django.core.exceptions import ValidationError from registrar.utility.waffle import flag_is_active_for_user @@ -796,6 +797,7 @@ class DomainRequest(TimeStampedModel): return True def delete_and_clean_up_domain(self, called_from): + # Delete the approved domain try: # Clean up the approved domain domain_state = self.approved_domain.state @@ -808,19 +810,39 @@ class DomainRequest(TimeStampedModel): except Exception as err: logger.error(err) logger.error(f"Can't query an approved domain while attempting {called_from}") + + # Delete the suborg as long as this is the only place it is used + self._cleanup_dangling_suborg() - # Clean up any created suborgs, assuming its for this record only - if self.sub_organization is not None: - request_suborg_count = self.request_sub_organization.count() - domain_suborgs = self.DomainRequest_info.filter( - sub_organization=self.sub_organization - ).count() - if request_suborg_count == 1 and domain_suborgs.count() <= 1: - # if domain_suborgs.count() == 1: - # domain_info = domain_suborgs.first() - # domain_info.sub_organization = None - # domain_info.save() - self.sub_organization.delete() + def _cleanup_dangling_suborg(self): + """Deletes the existing suborg if its only being used by the deleted record""" + # Nothing to delete, so we just smile and walk away + if self.sub_organization is None: + return + + Suborganization = apps.get_model("registrar.Suborganization") + + # Stored as so because we need to set the reference to none first, + # so we can't just use the self.sub_organization property + suborg = Suborganization.objects.get(id=self.sub_organization.id) + requests = suborg.request_sub_organization + domain_infos = suborg.information_sub_organization + + # Check if this is the only reference to the suborganization + if requests.count() != 1 or domain_infos.count() > 1: + return + + # Remove the suborganization reference from request. + self.sub_organization = None + self.save() + + # Remove the suborganization reference from domain if it exists. + if domain_infos.count() == 1: + domain_infos.update(sub_organization=None) + + # Delete the now-orphaned suborganization + logger.info(f"_cleanup_dangling_suborg() -> Deleting orphan suborganization: {suborg}") + suborg.delete() def _send_status_update_email( self, diff --git a/src/registrar/models/suborganization.py b/src/registrar/models/suborganization.py index fb32ad48a..087490244 100644 --- a/src/registrar/models/suborganization.py +++ b/src/registrar/models/suborganization.py @@ -9,9 +9,6 @@ class Suborganization(TimeStampedModel): Suborganization under an organization (portfolio) """ - class Meta: - unique_together = ["name", "portfolio"] - name = models.CharField( unique=True, max_length=1000, From 24354fd7f12ee89db24c73162c3f979c31f653d3 Mon Sep 17 00:00:00 2001 From: matthewswspence Date: Tue, 17 Dec 2024 13:03:22 -0600 Subject: [PATCH 06/44] linter fixes --- src/registrar/admin.py | 5 +++-- src/registrar/tests/test_admin_request.py | 5 ++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index ce3b0220c..c04975cb9 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -2442,7 +2442,7 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): obj_id = domain.id change_url = reverse("admin:%s_%s_change" % (app_label, model_name), args=[obj_id]) - message = f"
  • The status of this domain request cannot be changed because it has been joined to a domain in Ready status: " # noqa + message = f"
  • The status of this domain request cannot be changed because it has been joined to a domain in Ready status: " # noqa message += f"{domain}
  • " message_html = mark_safe(message) # nosec @@ -2450,7 +2450,7 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): request, message_html, ) - + obj = self.get_object(request, object_id) self.display_restricted_warning(request, obj) @@ -2564,6 +2564,7 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): qs = qs.filter(portfolio=portfolio_id) return qs + class TransitionDomainAdmin(ListHeaderAdmin): """Custom transition domain admin class.""" diff --git a/src/registrar/tests/test_admin_request.py b/src/registrar/tests/test_admin_request.py index bbf6c1923..e109d3f96 100644 --- a/src/registrar/tests/test_admin_request.py +++ b/src/registrar/tests/test_admin_request.py @@ -95,7 +95,6 @@ class TestDomainRequestAdmin(MockEppLib): User.objects.all().delete() AllowedEmail.objects.all().delete() - @less_console_noise_decorator def test_domain_request_senior_official_is_alphabetically_sorted(self): """Tests if the senior offical dropdown is alphanetically sorted in the django admin display""" @@ -1815,7 +1814,7 @@ class TestDomainRequestAdmin(MockEppLib): request, "Cannot edit a domain request with a restricted creator.", ) - + # @less_console_noise_decorator def test_approved_domain_request_with_ready_domain_has_warning_message(self): """Tests if the domain request has a warning message when the approved domain is in Ready state""" @@ -1834,7 +1833,7 @@ class TestDomainRequestAdmin(MockEppLib): with boto3_mocking.clients.handler_for("sesv2", self.mock_client): with patch("django.contrib.messages.warning") as mock_warning: - # Create a request object + # Create a request object self.client.force_login(self.superuser) self.client.get( "/admin/registrar/domainrequest/{}/change/".format(domain_request.pk), From 682594263cb9ce6d2832e728a554fa38f47f867a Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 19 Dec 2024 13:00:15 -0700 Subject: [PATCH 07/44] Clear button --- src/registrar/admin.py | 7 ++++ .../js/getgov-admin/domain-request-form.js | 39 ++++++++++++++++++- .../helpers-portfolio-dynamic-fields.js | 17 +++++++- .../admin/domain_request_change_form.html | 11 +----- .../includes/domain_request_fieldset.html | 14 +++++++ 5 files changed, 76 insertions(+), 12 deletions(-) create mode 100644 src/registrar/templates/django/admin/includes/domain_request_fieldset.html diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 0e8e4847a..6cbdd4878 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -1817,6 +1817,11 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): if self.value() == "0": return queryset.filter(Q(is_election_board=False) | Q(is_election_board=None)) + @admin.display(description="Suborganization options") + def reject_suborganization_button(self, obj): + """Custom field to display the reject suborganization button""" + return "" + @admin.display(description=_("Generic Org Type")) def converted_generic_org_type(self, obj): return obj.converted_generic_org_type_display @@ -1985,6 +1990,7 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): "requested_suborganization", "suborganization_city", "suborganization_state_territory", + "reject_suborganization_button", "creator", ] }, @@ -2106,6 +2112,7 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): "alternative_domains", "is_election_board", "status_history", + "reject_suborganization_button", ) # Read only that we'll leverage for CISA Analysts diff --git a/src/registrar/assets/src/js/getgov-admin/domain-request-form.js b/src/registrar/assets/src/js/getgov-admin/domain-request-form.js index 6b79a2419..2f98684f5 100644 --- a/src/registrar/assets/src/js/getgov-admin/domain-request-form.js +++ b/src/registrar/assets/src/js/getgov-admin/domain-request-form.js @@ -630,7 +630,44 @@ export function initRejectedEmail() { } function handleSuborganizationSelection() { - console.log("cats are cool") + const requestedSuborganizationField = document.getElementById("id_requested_suborganization"); + const suborganizationCity = document.getElementById("id_suborganization_city"); + const suborganizationStateTerritory = document.getElementById("id_suborganization_state_territory"); + // The reject button is wrapped in a fieldset with a label + const rejectButtonFieldset = document.querySelector(".field-reject_suborganization_button"); + const rejectButton = document.querySelector("#clear-requested-suborganization"); + + // Ensure that every variable is present before proceeding + if (!requestedSuborganizationField || !suborganizationCity || !suborganizationStateTerritory || !rejectButtonFieldset || !rejectButton) { + console.warn("handleSuborganizationSelection() => Could not find required fields.") + return; + } + console.log("Test") + function updateRejectButtonFieldset() { + if (requestedSuborganizationField.value || suborganizationCity.value || suborganizationStateTerritory.value) { + showElement(rejectButtonFieldset); + }else { + console.log("Hiding") + console.log(requestedSuborganizationField) + console.log(requestedSuborganizationField.value) + console.log(suborganizationCity.value) + console.log(suborganizationStateTerritory.value) + hideElement(rejectButtonFieldset) + } + } + + function handleRejectButton() { + // Clear the text fields + requestedSuborganizationField.value = ""; + suborganizationCity.value = ""; + suborganizationStateTerritory.value = ""; + // Update button visibility after clearing + updateRejectButtonFieldset(); + } + rejectButton.addEventListener("click", handleRejectButton) + requestedSuborganizationField.addEventListener("blur", updateRejectButtonFieldset); + suborganizationCity.addEventListener("blur", updateRejectButtonFieldset); + suborganizationStateTerritory.addEventListener("change", updateRejectButtonFieldset); } /** diff --git a/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js b/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js index 39f30b87f..924176c31 100644 --- a/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js +++ b/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js @@ -87,6 +87,7 @@ export function handlePortfolioSelection() { const portfolioUrbanizationField = document.querySelector(".field-portfolio_urbanization"); const portfolioUrbanization = portfolioUrbanizationField.querySelector(".readonly"); const portfolioJsonUrl = document.getElementById("portfolio_json_url")?.value || null; + const rejectRequestedSuborganizationButtonFieldset = document.querySelector(".field-reject_suborganization_button"); let isPageLoading = true; /** @@ -507,11 +508,25 @@ export function handlePortfolioSelection() { showElement(requestedSuborganizationField); showElement(suborganizationCity); showElement(suborganizationStateTerritory); + + let requestedSuborganizationField = document.getElementById("id_requested_suborganization"); + let suborganizationCity = document.getElementById("id_suborganization_city"); + let suborganizationStateTerritory = document.getElementById("id_suborganization_state_territory"); + if (!requestedSuborganizationField || !suborganizationCity || !suborganizationStateTerritory) { + return; + } + + if (requestedSuborganizationField.value || suborganizationCity.value || suborganizationStateTerritory.value) { + showElement(rejectRequestedSuborganizationButtonFieldset); + }else { + hideElement(rejectRequestedSuborganizationButtonFieldset); + } } else { // Hide suborganization request fields if suborganization is selected hideElement(requestedSuborganizationField); hideElement(suborganizationCity); - hideElement(suborganizationStateTerritory); + hideElement(suborganizationStateTerritory); + hideElement(rejectRequestedSuborganizationButtonFieldset); } } diff --git a/src/registrar/templates/django/admin/domain_request_change_form.html b/src/registrar/templates/django/admin/domain_request_change_form.html index 46965f236..ee79aaeef 100644 --- a/src/registrar/templates/django/admin/domain_request_change_form.html +++ b/src/registrar/templates/django/admin/domain_request_change_form.html @@ -20,16 +20,7 @@ {% url 'get-rejection-email-for-user-json' as url_2 %} {% for fieldset in adminform %} - {% comment %} - TODO: this will eventually need to be changed to something like this - if we ever want to customize this file: - {% include "django/admin/includes/domain_information_fieldset.html" %} - - Use detail_table_fieldset as an example, or just extend it. - - original_object is just a variable name for "DomainInformation" or "DomainRequest" - {% endcomment %} - {% include "django/admin/includes/detail_table_fieldset.html" with original_object=original %} + {% include "django/admin/includes/domain_request_fieldset.html" with original_object=original %} {% endfor %} {% endblock %} diff --git a/src/registrar/templates/django/admin/includes/domain_request_fieldset.html b/src/registrar/templates/django/admin/includes/domain_request_fieldset.html new file mode 100644 index 000000000..3186fff1d --- /dev/null +++ b/src/registrar/templates/django/admin/includes/domain_request_fieldset.html @@ -0,0 +1,14 @@ +{% extends "django/admin/includes/email_clipboard_fieldset.html" %} +{% load custom_filters %} +{% load static url_helpers %} +{% load i18n static %} + + +{% block field_readonly %} + {{ block.super }} + {% if field.field.name == "reject_suborganization_button" %} + + {% endif %} +{% endblock field_readonly %} \ No newline at end of file From 9e339c2cd9a29cfb91615f3aaa77356d84d070ac Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 19 Dec 2024 13:19:37 -0700 Subject: [PATCH 08/44] cleanup --- .../assets/src/js/getgov-admin/domain-request-form.js | 7 +------ .../getgov-admin/helpers-portfolio-dynamic-fields.js | 11 ++++++----- src/registrar/models/domain.py | 1 - 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/registrar/assets/src/js/getgov-admin/domain-request-form.js b/src/registrar/assets/src/js/getgov-admin/domain-request-form.js index 2f98684f5..242ae25c8 100644 --- a/src/registrar/assets/src/js/getgov-admin/domain-request-form.js +++ b/src/registrar/assets/src/js/getgov-admin/domain-request-form.js @@ -642,16 +642,11 @@ function handleSuborganizationSelection() { console.warn("handleSuborganizationSelection() => Could not find required fields.") return; } - console.log("Test") + function updateRejectButtonFieldset() { if (requestedSuborganizationField.value || suborganizationCity.value || suborganizationStateTerritory.value) { showElement(rejectButtonFieldset); }else { - console.log("Hiding") - console.log(requestedSuborganizationField) - console.log(requestedSuborganizationField.value) - console.log(suborganizationCity.value) - console.log(suborganizationStateTerritory.value) hideElement(rejectButtonFieldset) } } diff --git a/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js b/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js index 924176c31..5b67f8fad 100644 --- a/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js +++ b/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js @@ -87,7 +87,7 @@ export function handlePortfolioSelection() { const portfolioUrbanizationField = document.querySelector(".field-portfolio_urbanization"); const portfolioUrbanization = portfolioUrbanizationField.querySelector(".readonly"); const portfolioJsonUrl = document.getElementById("portfolio_json_url")?.value || null; - const rejectRequestedSuborganizationButtonFieldset = document.querySelector(".field-reject_suborganization_button"); + const rejectSuborganizationButtonFieldset = document.querySelector(".field-reject_suborganization_button"); let isPageLoading = true; /** @@ -508,7 +508,8 @@ export function handlePortfolioSelection() { showElement(requestedSuborganizationField); showElement(suborganizationCity); showElement(suborganizationStateTerritory); - + + // Initially show / hide the clear button only if there is data to clear let requestedSuborganizationField = document.getElementById("id_requested_suborganization"); let suborganizationCity = document.getElementById("id_suborganization_city"); let suborganizationStateTerritory = document.getElementById("id_suborganization_state_territory"); @@ -517,16 +518,16 @@ export function handlePortfolioSelection() { } if (requestedSuborganizationField.value || suborganizationCity.value || suborganizationStateTerritory.value) { - showElement(rejectRequestedSuborganizationButtonFieldset); + showElement(rejectSuborganizationButtonFieldset); }else { - hideElement(rejectRequestedSuborganizationButtonFieldset); + hideElement(rejectSuborganizationButtonFieldset); } } else { // Hide suborganization request fields if suborganization is selected hideElement(requestedSuborganizationField); hideElement(suborganizationCity); hideElement(suborganizationStateTerritory); - hideElement(rejectRequestedSuborganizationButtonFieldset); + hideElement(rejectSuborganizationButtonFieldset); } } diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index 2ea78ff10..cc600e1ce 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -237,7 +237,6 @@ class Domain(TimeStampedModel, DomainHelper): is called in the validate function on the request/domain page throws- RegistryError or InvalidDomainError""" - return True if not cls.string_could_be_domain(domain): logger.warning("Not a valid domain: %s" % str(domain)) # throw invalid domain error so that it can be caught in From de8d252136abd911dd3d4439f0f086dacc0a9660 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 19 Dec 2024 14:05:06 -0700 Subject: [PATCH 09/44] unit tests --- src/registrar/models/domain_request.py | 2 +- src/registrar/tests/common.py | 16 +++ src/registrar/tests/test_models_requests.py | 142 ++++++++++++++++++++ 3 files changed, 159 insertions(+), 1 deletion(-) diff --git a/src/registrar/models/domain_request.py b/src/registrar/models/domain_request.py index d78cd587f..c0d4c7e57 100644 --- a/src/registrar/models/domain_request.py +++ b/src/registrar/models/domain_request.py @@ -810,7 +810,7 @@ class DomainRequest(TimeStampedModel): except Exception as err: logger.error(err) logger.error(f"Can't query an approved domain while attempting {called_from}") - + # Delete the suborg as long as this is the only place it is used self._cleanup_dangling_suborg() diff --git a/src/registrar/tests/common.py b/src/registrar/tests/common.py index e1f4f5a27..1c345b83b 100644 --- a/src/registrar/tests/common.py +++ b/src/registrar/tests/common.py @@ -1034,6 +1034,10 @@ def completed_domain_request( # noqa action_needed_reason=None, portfolio=None, organization_name=None, + sub_organization=None, + requested_suborganization=None, + suborganization_city=None, + suborganization_state_territory=None, ): """A completed domain request.""" if not user: @@ -1098,6 +1102,18 @@ def completed_domain_request( # noqa if portfolio: domain_request_kwargs["portfolio"] = portfolio + if sub_organization: + domain_request_kwargs["sub_organization"] = sub_organization + + if requested_suborganization: + domain_request_kwargs["requested_suborganization"] = requested_suborganization + + if suborganization_city: + domain_request_kwargs["suborganization_city"] = suborganization_city + + if suborganization_state_territory: + domain_request_kwargs["suborganization_state_territory"] = suborganization_state_territory + domain_request, _ = DomainRequest.objects.get_or_create(**domain_request_kwargs) if has_other_contacts: diff --git a/src/registrar/tests/test_models_requests.py b/src/registrar/tests/test_models_requests.py index da474224c..983a12b3c 100644 --- a/src/registrar/tests/test_models_requests.py +++ b/src/registrar/tests/test_models_requests.py @@ -15,6 +15,7 @@ from registrar.models import ( FederalAgency, AllowedEmail, Portfolio, + Suborganization, ) import boto3_mocking @@ -23,6 +24,8 @@ from registrar.utility.errors import FSMDomainRequestError from .common import ( MockSESClient, + create_user, + create_superuser, less_console_noise, completed_domain_request, set_domain_request_investigators, @@ -1070,3 +1073,142 @@ class TestDomainRequest(TestCase): ) self.assertEqual(domain_request2.generic_org_type, domain_request2.converted_generic_org_type) self.assertEqual(domain_request2.federal_agency, domain_request2.converted_federal_agency) + + +class TestDomainRequestSuborganization(TestCase): + """Tests for the suborganization fields on domain requests""" + + def setUp(self): + super().setUp() + self.user = create_user() + self.superuser = create_superuser() + + def tearDown(self): + super().tearDown() + DomainInformation.objects.all().delete() + DomainRequest.objects.all().delete() + Domain.objects.all().delete() + Suborganization.objects.all().delete() + Portfolio.objects.all().delete() + + @less_console_noise_decorator + def test_approve_creates_requested_suborganization(self): + """Test that approving a domain request with a requested suborganization creates it""" + portfolio = Portfolio.objects.create(organization_name="Test Org", creator=self.user) + + domain_request = completed_domain_request( + name="test.gov", + portfolio=portfolio, + status=DomainRequest.DomainRequestStatus.IN_REVIEW, + requested_suborganization="Boom", + suborganization_city="Explody town", + suborganization_state_territory=DomainRequest.StateTerritoryChoices.OHIO, + ) + domain_request.investigator = self.superuser + domain_request.save() + + domain_request.approve() + + created_suborg = Suborganization.objects.filter( + name="Boom", + city="Explody town", + state_territory=DomainRequest.StateTerritoryChoices.OHIO, + portfolio=portfolio, + ).first() + + self.assertIsNotNone(created_suborg) + self.assertEqual(domain_request.sub_organization, created_suborg) + + @less_console_noise_decorator + def test_approve_without_requested_suborganization_makes_no_changes(self): + """Test that approving without a requested suborganization doesn't create one""" + portfolio = Portfolio.objects.create(organization_name="Test Org", creator=self.user) + + domain_request = completed_domain_request( + name="test.gov", + portfolio=portfolio, + status=DomainRequest.DomainRequestStatus.IN_REVIEW, + ) + domain_request.investigator = self.superuser + domain_request.save() + + initial_suborg_count = Suborganization.objects.count() + domain_request.approve() + + self.assertEqual(Suborganization.objects.count(), initial_suborg_count) + self.assertIsNone(domain_request.sub_organization) + + @less_console_noise_decorator + def test_approve_with_existing_suborganization_makes_no_changes(self): + """Test that approving with an existing suborganization doesn't create a new one""" + portfolio = Portfolio.objects.create(organization_name="Test Org", creator=self.user) + existing_suborg = Suborganization.objects.create(name="Existing Division", portfolio=portfolio) + + domain_request = completed_domain_request( + name="test.gov", + portfolio=portfolio, + status=DomainRequest.DomainRequestStatus.IN_REVIEW, + sub_organization=existing_suborg, + ) + domain_request.investigator = self.superuser + domain_request.save() + + initial_suborg_count = Suborganization.objects.count() + domain_request.approve() + + self.assertEqual(Suborganization.objects.count(), initial_suborg_count) + self.assertEqual(domain_request.sub_organization, existing_suborg) + + @less_console_noise_decorator + def test_cleanup_dangling_suborg_with_single_reference(self): + """Test that a suborganization is deleted when it's only referenced once""" + portfolio = Portfolio.objects.create(organization_name="Test Org", creator=self.user) + suborg = Suborganization.objects.create(name="Test Division", portfolio=portfolio) + + domain_request = completed_domain_request( + name="test.gov", + portfolio=portfolio, + status=DomainRequest.DomainRequestStatus.IN_REVIEW, + sub_organization=suborg, + ) + domain_request.approve() + + # set it back to in review + domain_request.in_review() + domain_request.refresh_from_db() + + # Verify the suborganization was deleted + self.assertFalse(Suborganization.objects.filter(id=suborg.id).exists()) + self.assertIsNone(domain_request.sub_organization) + + @less_console_noise_decorator + def test_cleanup_dangling_suborg_with_multiple_references(self): + """Test that a suborganization is preserved when it has multiple references""" + portfolio = Portfolio.objects.create(organization_name="Test Org", creator=self.user) + suborg = Suborganization.objects.create(name="Test Division", portfolio=portfolio) + + # Create two domain requests using the same suborganization + domain_request1 = completed_domain_request( + name="test1.gov", + portfolio=portfolio, + status=DomainRequest.DomainRequestStatus.IN_REVIEW, + sub_organization=suborg, + ) + domain_request2 = completed_domain_request( + name="test2.gov", + portfolio=portfolio, + status=DomainRequest.DomainRequestStatus.IN_REVIEW, + sub_organization=suborg, + ) + + domain_request1.approve() + domain_request2.approve() + + # set one back to in review + domain_request1.in_review() + domain_request1.refresh_from_db() + + # Verify the suborganization still exists + self.assertTrue(Suborganization.objects.filter(id=suborg.id).exists()) + self.assertEqual(domain_request1.sub_organization, suborg) + self.assertEqual(domain_request2.sub_organization, suborg) From e1ad261e9c7eb939827254f7a068f18fa705c4ef Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:23:49 -0700 Subject: [PATCH 10/44] Validation logic for /admin --- src/registrar/forms/domain_request_wizard.py | 2 +- src/registrar/models/domain_request.py | 40 ++++++++++++++++++++ src/registrar/models/suborganization.py | 1 - 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/registrar/forms/domain_request_wizard.py b/src/registrar/forms/domain_request_wizard.py index eed0866f3..d84ceeb15 100644 --- a/src/registrar/forms/domain_request_wizard.py +++ b/src/registrar/forms/domain_request_wizard.py @@ -90,7 +90,7 @@ class RequestingEntityForm(RegistrarForm): raise ValidationError( "This suborganization already exists. " "Choose a new name, or select it directly if you would like to use it." - ) + ) return name def full_clean(self): diff --git a/src/registrar/models/domain_request.py b/src/registrar/models/domain_request.py index c0d4c7e57..ff3af829b 100644 --- a/src/registrar/models/domain_request.py +++ b/src/registrar/models/domain_request.py @@ -672,6 +672,46 @@ class DomainRequest(TimeStampedModel): # Store original values for caching purposes. Used to compare them on save. self._cache_status_and_status_reasons() + def clean(self): + super().clean() + # Validation logic for a suborganization request + if self.is_requesting_new_suborganization(): + # Raise an error if this suborganization already exists + Suborganization = apps.get_model("registrar.Suborganization") + if ( + self.requested_suborganization + and Suborganization.objects.filter( + name__iexact=self.requested_suborganization, + portfolio=self.portfolio, + name__isnull=False, + portfolio__isnull=False, + ).exists() + ): + raise ValidationError( + "This suborganization already exists. " + "Choose a new name, or select it directly if you would like to use it." + ) + elif self.portfolio and not self.sub_organization: + # You cannot create a new suborganization without these fields + required_suborg_fields = { + "requested_suborganization": self.requested_suborganization, + "suborganization_city": self.suborganization_city, + "suborganization_state_territory": self.suborganization_state_territory, + } + + if any(bool(value) for value in required_suborg_fields.values()): + # Find which fields are empty + errors_dict = { + field_name: [f"This field is required when creating a new suborganization."] + for field_name, value in required_suborg_fields.items() + if not value + } + # Adds a validation error to each missing field + raise ValidationError({ + k: ValidationError(v, code='required') + for k, v in errors_dict.items() + }) + def save(self, *args, **kwargs): """Save override for custom properties""" self.sync_organization_type() diff --git a/src/registrar/models/suborganization.py b/src/registrar/models/suborganization.py index 087490244..78689799c 100644 --- a/src/registrar/models/suborganization.py +++ b/src/registrar/models/suborganization.py @@ -1,5 +1,4 @@ from django.db import models - from registrar.models.domain_request import DomainRequest from .utility.time_stamped_model import TimeStampedModel From 9cb3ecebf4952c9779bc444ce9fb2e742d3cbf2e Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 20 Dec 2024 10:08:00 -0700 Subject: [PATCH 11/44] Cleanup js after merge --- .../src/js/getgov-admin/domain-request-form.js | 15 +++++++++++++-- .../helpers-portfolio-dynamic-fields.js | 12 +++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/registrar/assets/src/js/getgov-admin/domain-request-form.js b/src/registrar/assets/src/js/getgov-admin/domain-request-form.js index 242ae25c8..928495cb6 100644 --- a/src/registrar/assets/src/js/getgov-admin/domain-request-form.js +++ b/src/registrar/assets/src/js/getgov-admin/domain-request-form.js @@ -629,7 +629,18 @@ export function initRejectedEmail() { }); } -function handleSuborganizationSelection() { + +/** + * A function that handles the suborganzation and requested suborganization fields and buttons. + * - Fieldwise: Hooks to the sub_organization, suborganization_city, and suborganization_state_territory fields. + * On change, this function checks if any of these fields are not empty: + * sub_organization, suborganization_city, and suborganization_state_territory. + * If they aren't, then we show the "clear" button. If they are, then we hide it because we don't need it. + * + * - Buttonwise: Hooks to the #clear-requested-suborganization button. + * On click, this will clear the input value of sub_organization, suborganization_city, and suborganization_state_territory. +*/ +function handleSuborgFieldsAndButtons() { const requestedSuborganizationField = document.getElementById("id_requested_suborganization"); const suborganizationCity = document.getElementById("id_suborganization_city"); const suborganizationStateTerritory = document.getElementById("id_suborganization_state_territory"); @@ -672,6 +683,6 @@ export function initDynamicDomainRequestFields(){ const domainRequestPage = document.getElementById("domainrequest_form"); if (domainRequestPage) { handlePortfolioSelection(); - handleSuborganizationSelection(); + handleSuborgFieldsAndButtons(); } } diff --git a/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js b/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js index 91fd2b6e3..ce5db34c1 100644 --- a/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js +++ b/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js @@ -471,6 +471,16 @@ export function handlePortfolioSelection( if (suborganizationCity) showElement(suborganizationCity); if (suborganizationStateTerritory) showElement(suborganizationStateTerritory); + // Handle rejectSuborganizationButtonFieldset (display of the clear requested suborg button). + // Basically, this button should only be visible when we have data for suborg, city, and state_territory. + // The function handleSuborgFieldsAndButtons() in domain-request-form.js handles doing this same logic + // but on field input for city, state_territory, and the suborg field. + // If it doesn't exist, don't do anything. + if (!rejectSuborganizationButtonFieldset){ + console.warn("updateSuborganizationFieldsDisplay() => Could not update rejectSuborganizationButtonFieldset") + return; + } + // Initially show / hide the clear button only if there is data to clear let requestedSuborganizationField = document.getElementById("id_requested_suborganization"); let suborganizationCity = document.getElementById("id_suborganization_city"); @@ -489,7 +499,7 @@ export function handlePortfolioSelection( if (requestedSuborganizationField) hideElement(requestedSuborganizationField); if (suborganizationCity) hideElement(suborganizationCity); if (suborganizationStateTerritory) hideElement(suborganizationStateTerritory); - hideElement(rejectSuborganizationButtonFieldset); + if (rejectSuborganizationButtonFieldset) hideElement(rejectSuborganizationButtonFieldset); } } From 3d6d9b0d2fd2672a44293be9f40316b0b64b5d16 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 20 Dec 2024 10:28:10 -0700 Subject: [PATCH 12/44] Update domain_request.py --- src/registrar/models/domain_request.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/registrar/models/domain_request.py b/src/registrar/models/domain_request.py index ff3af829b..381d28703 100644 --- a/src/registrar/models/domain_request.py +++ b/src/registrar/models/domain_request.py @@ -673,6 +673,16 @@ class DomainRequest(TimeStampedModel): self._cache_status_and_status_reasons() def clean(self): + """ + Validates suborganization-related fields in two scenarios: + 1. New suborganization request: Prevents duplicate names within same portfolio + 2. Partial suborganization data: Enforces a all-or-nothing rule for city/state/name fields + when portfolio exists without selected suborganization + + Add new domain request validation rules here to ensure they're + enforced during both model save and form submission. + Not presently used on the domain request wizard, though. + """ super().clean() # Validation logic for a suborganization request if self.is_requesting_new_suborganization(): From 19a1d60c13034052293467636a56ee41ccb0d089 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 20 Dec 2024 10:43:20 -0700 Subject: [PATCH 13/44] Update test_admin_request.py --- src/registrar/tests/test_admin_request.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/registrar/tests/test_admin_request.py b/src/registrar/tests/test_admin_request.py index df0902719..9bdc1fbb4 100644 --- a/src/registrar/tests/test_admin_request.py +++ b/src/registrar/tests/test_admin_request.py @@ -1644,6 +1644,7 @@ class TestDomainRequestAdmin(MockEppLib): "alternative_domains", "is_election_board", "status_history", + "reject_suborganization_button", "id", "created_at", "updated_at", @@ -1718,6 +1719,7 @@ class TestDomainRequestAdmin(MockEppLib): "alternative_domains", "is_election_board", "status_history", + "reject_suborganization_button", "federal_agency", "creator", "about_your_organization", @@ -1761,6 +1763,7 @@ class TestDomainRequestAdmin(MockEppLib): "alternative_domains", "is_election_board", "status_history", + "reject_suborganization_button", ] self.assertEqual(readonly_fields, expected_fields) From 5d601d69913143a78399c545c1ad669ace385454 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 20 Dec 2024 11:30:21 -0700 Subject: [PATCH 14/44] linting --- src/registrar/forms/domain_request_wizard.py | 16 ++++++++-------- src/registrar/models/domain_request.py | 9 +++------ src/registrar/tests/test_reports.py | 1 + src/registrar/utility/csv_export.py | 2 +- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/registrar/forms/domain_request_wizard.py b/src/registrar/forms/domain_request_wizard.py index d84ceeb15..5eea13ed8 100644 --- a/src/registrar/forms/domain_request_wizard.py +++ b/src/registrar/forms/domain_request_wizard.py @@ -80,17 +80,17 @@ class RequestingEntityForm(RegistrarForm): return self.cleaned_data.get("sub_organization") def clean_requested_suborganization(self): - name = self.cleaned_data.get('requested_suborganization') - if name and Suborganization.objects.filter( - name__iexact=name, - portfolio=self.domain_request.portfolio, - name__isnull=False, - portfolio__isnull=False - ).exists(): + name = self.cleaned_data.get("requested_suborganization") + if ( + name + and Suborganization.objects.filter( + name__iexact=name, portfolio=self.domain_request.portfolio, name__isnull=False, portfolio__isnull=False + ).exists() + ): raise ValidationError( "This suborganization already exists. " "Choose a new name, or select it directly if you would like to use it." - ) + ) return name def full_clean(self): diff --git a/src/registrar/models/domain_request.py b/src/registrar/models/domain_request.py index 381d28703..f4e2a35a1 100644 --- a/src/registrar/models/domain_request.py +++ b/src/registrar/models/domain_request.py @@ -679,9 +679,9 @@ class DomainRequest(TimeStampedModel): 2. Partial suborganization data: Enforces a all-or-nothing rule for city/state/name fields when portfolio exists without selected suborganization - Add new domain request validation rules here to ensure they're + Add new domain request validation rules here to ensure they're enforced during both model save and form submission. - Not presently used on the domain request wizard, though. + Not presently used on the domain request wizard, though. """ super().clean() # Validation logic for a suborganization request @@ -717,10 +717,7 @@ class DomainRequest(TimeStampedModel): if not value } # Adds a validation error to each missing field - raise ValidationError({ - k: ValidationError(v, code='required') - for k, v in errors_dict.items() - }) + raise ValidationError({k: ValidationError(v, code="required") for k, v in errors_dict.items()}) def save(self, *args, **kwargs): """Save override for custom properties""" diff --git a/src/registrar/tests/test_reports.py b/src/registrar/tests/test_reports.py index 995782eea..64cfa95b0 100644 --- a/src/registrar/tests/test_reports.py +++ b/src/registrar/tests/test_reports.py @@ -869,6 +869,7 @@ class MemberExportTest(MockDbForIndividualTests, MockEppLib): csv_file.seek(0) # Read the content into a variable csv_content = csv_file.read() + self.maxDiff = None expected_content = ( # Header "Email,Organization admin,Invited by,Joined date,Last active,Domain requests," diff --git a/src/registrar/utility/csv_export.py b/src/registrar/utility/csv_export.py index 66809777b..f05f14d99 100644 --- a/src/registrar/utility/csv_export.py +++ b/src/registrar/utility/csv_export.py @@ -417,7 +417,7 @@ class MemberExport(BaseExport): # Adding a order_by increases output predictability. # Doesn't matter as much for normal use, but makes tests easier. # We should also just be ordering by default anyway. - members = permissions.union(invitations).order_by("email_display") + members = permissions.union(invitations).order_by("email_display", "member_display", "first_name", "last_name") return convert_queryset_to_dict(members, is_model=False) @classmethod From f277efc6c43adf072ebe26091c50e66ffbcaf8c3 Mon Sep 17 00:00:00 2001 From: Matt-Spence Date: Mon, 23 Dec 2024 14:57:37 -0600 Subject: [PATCH 15/44] Update src/registrar/admin.py Co-authored-by: zandercymatics <141044360+zandercymatics@users.noreply.github.com> --- src/registrar/admin.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index c04975cb9..117f689f8 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -2442,10 +2442,12 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): obj_id = domain.id change_url = reverse("admin:%s_%s_change" % (app_label, model_name), args=[obj_id]) - message = f"
  • The status of this domain request cannot be changed because it has been joined to a domain in Ready status: " # noqa - message += f"{domain}
  • " - - message_html = mark_safe(message) # nosec +message = format_html( + "
  • The status of this domain request cannot be changed because it has been joined to a domain in Ready status:" + "{}
  • ", + mark_safe(change_url), + escape(str(domain)) +) messages.warning( request, message_html, From ee2bff6492d87ccccc0e1ddbb1f0948f7a885108 Mon Sep 17 00:00:00 2001 From: Matthew Spence Date: Mon, 23 Dec 2024 15:31:04 -0600 Subject: [PATCH 16/44] fix warning html --- src/registrar/admin.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 117f689f8..c5aae7d2d 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -2442,16 +2442,16 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): obj_id = domain.id change_url = reverse("admin:%s_%s_change" % (app_label, model_name), args=[obj_id]) -message = format_html( - "
  • The status of this domain request cannot be changed because it has been joined to a domain in Ready status:" - "{}
  • ", - mark_safe(change_url), - escape(str(domain)) -) - messages.warning( - request, - message_html, - ) + message = format_html( + "The status of this domain request cannot be changed because it has been joined to a domain in Ready status:" + "{}", + mark_safe(change_url), + escape(str(domain)) + ) + messages.warning( + request, + message, + ) obj = self.get_object(request, object_id) self.display_restricted_warning(request, obj) From c0684539fa74b334de02a5e77b75968de0eded99 Mon Sep 17 00:00:00 2001 From: CocoByte Date: Wed, 25 Dec 2024 20:35:18 -0700 Subject: [PATCH 17/44] fix bug in domain request link --- src/registrar/admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index f43261885..874512fdc 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -1995,7 +1995,7 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): @admin.display(description=_("Requested Domain")) def custom_requested_domain(self, obj): # Example: Show different icons based on `status` - url = reverse("admin:registrar_domainrequest_changelist") + f"?portfolio={obj.id}" + url = reverse("admin:registrar_domainrequest_changelist") + f"{obj.id}" text = obj.requested_domain if obj.portfolio: return format_html(' {}', url, text) From e978297569cedc34e7fe95ddbb261a7cfbd21795 Mon Sep 17 00:00:00 2001 From: CocoByte Date: Thu, 26 Dec 2024 15:05:38 -0700 Subject: [PATCH 18/44] Fix suborg dropdown behavior --- .../getgov-admin/helpers-portfolio-dynamic-fields.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js b/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js index ce5db34c1..f045fca47 100644 --- a/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js +++ b/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js @@ -482,14 +482,14 @@ export function handlePortfolioSelection( } // Initially show / hide the clear button only if there is data to clear - let requestedSuborganizationField = document.getElementById("id_requested_suborganization"); - let suborganizationCity = document.getElementById("id_suborganization_city"); - let suborganizationStateTerritory = document.getElementById("id_suborganization_state_territory"); - if (!requestedSuborganizationField || !suborganizationCity || !suborganizationStateTerritory) { + let requestedSuborganizationFieldInput = document.getElementById("id_requested_suborganization"); + let suborganizationCityInput = document.getElementById("id_suborganization_city"); + let suborganizationStateTerritoryInput = document.getElementById("id_suborganization_state_territory"); + if (!requestedSuborganizationFieldInput || !suborganizationCityInput || !suborganizationStateTerritoryInput) { return; } - if (requestedSuborganizationField.value || suborganizationCity.value || suborganizationStateTerritory.value) { + if (requestedSuborganizationFieldInput.value || suborganizationCityInput.value || suborganizationStateTerritoryInput.value) { showElement(rejectSuborganizationButtonFieldset); }else { hideElement(rejectSuborganizationButtonFieldset); From 887a9dfc3318a037b01520cbf474893b66548ab0 Mon Sep 17 00:00:00 2001 From: matthewswspence Date: Mon, 30 Dec 2024 10:18:08 -0600 Subject: [PATCH 19/44] linter changes --- src/registrar/admin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 2b58cb5fc..bbebbdb80 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -2632,10 +2632,10 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): change_url = reverse("admin:%s_%s_change" % (app_label, model_name), args=[obj_id]) message = format_html( - "The status of this domain request cannot be changed because it has been joined to a domain in Ready status:" + "The status of this domain request cannot be changed because it has been joined to a domain in Ready status:" # noqa: E501 "{}", - mark_safe(change_url), - escape(str(domain)) + mark_safe(change_url), # nosec + escape(str(domain)), ) messages.warning( request, From 4a97525129dc331f4775404906afb8f29e5121d5 Mon Sep 17 00:00:00 2001 From: Erin Song <121973038+erinysong@users.noreply.github.com> Date: Mon, 30 Dec 2024 10:44:12 -0800 Subject: [PATCH 20/44] Remove tagging devs requirement to code review --- docs/dev-practices/code_review.md | 1 - src/package-lock.json | 53 +++------------------- src/registrar/fixtures/fixtures_domains.py | 3 +- 3 files changed, 7 insertions(+), 50 deletions(-) diff --git a/docs/dev-practices/code_review.md b/docs/dev-practices/code_review.md index 7b054cad5..c14e91d52 100644 --- a/docs/dev-practices/code_review.md +++ b/docs/dev-practices/code_review.md @@ -4,7 +4,6 @@ Pull requests should be titled in the format of `#issue_number: Descriptive name Pull requests including a migration should be suffixed with ` - MIGRATION` After creating a pull request, pull request submitters should: -- Add at least 2 developers as PR reviewers (only 1 will need to approve). - Message on Slack or in standup to notify the team that a PR is ready for review. - If any model was updated to modify/add/delete columns, run makemigrations and commit the associated migrations file. diff --git a/src/package-lock.json b/src/package-lock.json index 22fb31857..d78b5132f 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -6921,16 +6921,6 @@ "validate-npm-package-license": "^3.0.1" } }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -7307,39 +7297,6 @@ "node": ">= 12" } }, - "node_modules/pa11y/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/pa11y/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/pa11y/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, "node_modules/parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", @@ -8888,13 +8845,15 @@ } }, "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "license": "ISC", "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/semver-greatest-satisfied-range": { diff --git a/src/registrar/fixtures/fixtures_domains.py b/src/registrar/fixtures/fixtures_domains.py index 4606024d0..2b79f6963 100644 --- a/src/registrar/fixtures/fixtures_domains.py +++ b/src/registrar/fixtures/fixtures_domains.py @@ -39,12 +39,11 @@ class DomainFixture(DomainRequestFixture): except Exception as e: logger.warning(e) return - # Approve each user associated with `in review` status domains cls._approve_domain_requests(users) @staticmethod - def _generate_fake_expiration_date(days_in_future=365): + def _generate_fake_expiration_date(days_in_future=100): """Generates a fake expiration date between 1 and 365 days in the future.""" current_date = timezone.now().date() # nosec return current_date + timedelta(days=random.randint(1, days_in_future)) # nosec From f30292221492ec9d339b302e43c153c8179c5904 Mon Sep 17 00:00:00 2001 From: Erin Song <121973038+erinysong@users.noreply.github.com> Date: Mon, 30 Dec 2024 10:58:17 -0800 Subject: [PATCH 21/44] Revert changes --- src/registrar/fixtures/fixtures_domains.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/registrar/fixtures/fixtures_domains.py b/src/registrar/fixtures/fixtures_domains.py index 2b79f6963..4606024d0 100644 --- a/src/registrar/fixtures/fixtures_domains.py +++ b/src/registrar/fixtures/fixtures_domains.py @@ -39,11 +39,12 @@ class DomainFixture(DomainRequestFixture): except Exception as e: logger.warning(e) return + # Approve each user associated with `in review` status domains cls._approve_domain_requests(users) @staticmethod - def _generate_fake_expiration_date(days_in_future=100): + def _generate_fake_expiration_date(days_in_future=365): """Generates a fake expiration date between 1 and 365 days in the future.""" current_date = timezone.now().date() # nosec return current_date + timedelta(days=random.randint(1, days_in_future)) # nosec From a1c5a78aeea7742f7e98caa81d26ad122deb92e0 Mon Sep 17 00:00:00 2001 From: Erin Song <121973038+erinysong@users.noreply.github.com> Date: Mon, 30 Dec 2024 11:02:12 -0800 Subject: [PATCH 22/44] Revert package-lock.json --- src/package-lock.json | 55 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/src/package-lock.json b/src/package-lock.json index d78b5132f..e93413312 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -6921,6 +6921,16 @@ "validate-npm-package-license": "^3.0.1" } }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -7297,6 +7307,39 @@ "node": ">= 12" } }, + "node_modules/pa11y/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pa11y/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pa11y/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, "node_modules/parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", @@ -8845,15 +8888,13 @@ } }, "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" } }, "node_modules/semver-greatest-satisfied-range": { @@ -10623,4 +10664,4 @@ } } } -} +} \ No newline at end of file From cba218fe2e019855cf9b777a6b1f6a007b900e54 Mon Sep 17 00:00:00 2001 From: Erin Song <121973038+erinysong@users.noreply.github.com> Date: Mon, 30 Dec 2024 11:03:06 -0800 Subject: [PATCH 23/44] Revert package-lock.json --- src/package-lock.json | 55 ++++++------------------------------------- 1 file changed, 7 insertions(+), 48 deletions(-) diff --git a/src/package-lock.json b/src/package-lock.json index e93413312..d78b5132f 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -6921,16 +6921,6 @@ "validate-npm-package-license": "^3.0.1" } }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -7307,39 +7297,6 @@ "node": ">= 12" } }, - "node_modules/pa11y/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/pa11y/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/pa11y/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, "node_modules/parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", @@ -8888,13 +8845,15 @@ } }, "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "license": "ISC", "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/semver-greatest-satisfied-range": { @@ -10664,4 +10623,4 @@ } } } -} \ No newline at end of file +} From b8d85429021493229c668397b1974076a7f5f9f2 Mon Sep 17 00:00:00 2001 From: Erin Song <121973038+erinysong@users.noreply.github.com> Date: Mon, 30 Dec 2024 11:05:09 -0800 Subject: [PATCH 24/44] Revert package-lock --- src/package-lock.json | 55 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/src/package-lock.json b/src/package-lock.json index d78b5132f..e93413312 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -6921,6 +6921,16 @@ "validate-npm-package-license": "^3.0.1" } }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -7297,6 +7307,39 @@ "node": ">= 12" } }, + "node_modules/pa11y/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pa11y/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pa11y/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, "node_modules/parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", @@ -8845,15 +8888,13 @@ } }, "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" } }, "node_modules/semver-greatest-satisfied-range": { @@ -10623,4 +10664,4 @@ } } } -} +} \ No newline at end of file From 7fd5bacb0394322c86bc9d3c7b283fb648f03c1e Mon Sep 17 00:00:00 2001 From: matthewswspence Date: Tue, 31 Dec 2024 11:11:24 -0600 Subject: [PATCH 25/44] fix broken test --- src/registrar/admin.py | 2 +- src/registrar/tests/test_admin_request.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index bbebbdb80..e319daac0 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -2632,7 +2632,7 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): change_url = reverse("admin:%s_%s_change" % (app_label, model_name), args=[obj_id]) message = format_html( - "The status of this domain request cannot be changed because it has been joined to a domain in Ready status:" # noqa: E501 + "The status of this domain request cannot be changed because it has been joined to a domain in Ready status: " # noqa: E501 "{}", mark_safe(change_url), # nosec escape(str(domain)), diff --git a/src/registrar/tests/test_admin_request.py b/src/registrar/tests/test_admin_request.py index 8ec63b9d9..6c7d898c7 100644 --- a/src/registrar/tests/test_admin_request.py +++ b/src/registrar/tests/test_admin_request.py @@ -1812,7 +1812,7 @@ class TestDomainRequestAdmin(MockEppLib): "Cannot edit a domain request with a restricted creator.", ) - # @less_console_noise_decorator + @less_console_noise_decorator def test_approved_domain_request_with_ready_domain_has_warning_message(self): """Tests if the domain request has a warning message when the approved domain is in Ready state""" # Create an instance of the model @@ -1840,7 +1840,7 @@ class TestDomainRequestAdmin(MockEppLib): # Assert that the error message was called with the correct argument mock_warning.assert_called_once_with( ANY, # don't care about the request argument - f"
  • The status of this domain request cannot be changed because it has been joined to a domain in Ready status: {domain_request.approved_domain.name}
  • ", # noqa + f"The status of this domain request cannot be changed because it has been joined to a domain in Ready status: {domain_request.approved_domain.name}", # noqa ) def trigger_saving_approved_to_another_state(self, domain_is_active, another_state, rejection_reason=None): From 227236a049b31387d905509e8cb472e0663a35f8 Mon Sep 17 00:00:00 2001 From: Erin Song <121973038+erinysong@users.noreply.github.com> Date: Tue, 31 Dec 2024 10:08:20 -0800 Subject: [PATCH 26/44] Readd newline to package lock --- src/package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/package-lock.json b/src/package-lock.json index e93413312..22fb31857 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -10664,4 +10664,4 @@ } } } -} \ No newline at end of file +} From 465e41abc57fa55c05a21b6352635ff561debe55 Mon Sep 17 00:00:00 2001 From: matthewswspence Date: Tue, 31 Dec 2024 14:30:28 -0600 Subject: [PATCH 27/44] fix spacing causing admin bug --- src/registrar/admin.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index e319daac0..7b04f3e9d 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -2631,16 +2631,16 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): obj_id = domain.id change_url = reverse("admin:%s_%s_change" % (app_label, model_name), args=[obj_id]) - message = format_html( - "The status of this domain request cannot be changed because it has been joined to a domain in Ready status: " # noqa: E501 - "{}", - mark_safe(change_url), # nosec - escape(str(domain)), - ) - messages.warning( - request, - message, - ) + message = format_html( + "The status of this domain request cannot be changed because it has been joined to a domain in Ready status: " # noqa: E501 + "{}", + mark_safe(change_url), # nosec + escape(str(domain)), + ) + messages.warning( + request, + message, + ) obj = self.get_object(request, object_id) self.display_restricted_warning(request, obj) From 6119b39a599da9fea2564ad64eeedf016d4bff56 Mon Sep 17 00:00:00 2001 From: Matthew Spence Date: Tue, 31 Dec 2024 15:26:30 -0600 Subject: [PATCH 28/44] fix comment --- src/registrar/admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 8afc2d97f..808d1b557 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -2621,7 +2621,7 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): """Display restricted warning, setup the auditlog trail and pass it in extra context, display warning that status cannot be changed from 'Approved' if domain is in Ready state""" - # Fetch the Contact instance + # Fetch the domain request instance domain_request: models.DomainRequest = models.DomainRequest.objects.get(pk=object_id) if domain_request.approved_domain and domain_request.approved_domain.state == models.Domain.State.READY: domain = domain_request.approved_domain From 6ffe8b709d57e7db075ed48538ccd15ccb0dd15e Mon Sep 17 00:00:00 2001 From: CocoByte Date: Tue, 31 Dec 2024 16:18:59 -0700 Subject: [PATCH 29/44] fixed domain request view --- src/registrar/templates/base.html | 4 ++++ src/registrar/templates/includes/request_status_manage.html | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/registrar/templates/base.html b/src/registrar/templates/base.html index dd6417ccb..bb34dcd7e 100644 --- a/src/registrar/templates/base.html +++ b/src/registrar/templates/base.html @@ -113,7 +113,11 @@ +<<<<<<< Updated upstream
    +======= +
    +>>>>>>> Stashed changes
    -
    +
    {% block breadcrumb %} {% if portfolio %} @@ -140,7 +140,7 @@ {% endblock modify_request %}
    -
    +
    {% block request_summary_header %}

    Summary of your domain request

    {% endblock request_summary_header%} From 705ed34ea482110200ca1bfbe97279c0478b31a9 Mon Sep 17 00:00:00 2001 From: CocoByte Date: Tue, 31 Dec 2024 16:35:42 -0700 Subject: [PATCH 30/44] merge resolution --- src/registrar/templates/base.html | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/registrar/templates/base.html b/src/registrar/templates/base.html index bb34dcd7e..dd6417ccb 100644 --- a/src/registrar/templates/base.html +++ b/src/registrar/templates/base.html @@ -113,11 +113,7 @@
    -<<<<<<< Updated upstream
    -======= -
    ->>>>>>> Stashed changes
    Date: Tue, 31 Dec 2024 16:43:41 -0700 Subject: [PATCH 31/44] cherry-pick old PR changes (before revert) --- .../assets/src/sass/_theme/_admin.scss | 9 + .../assets/src/sass/_theme/_alerts.scss | 42 +- .../assets/src/sass/_theme/_base.scss | 15 + .../assets/src/sass/_theme/_containers.scss | 18 + .../assets/src/sass/_theme/_header.scss | 4 +- src/registrar/config/settings.py | 2 +- src/registrar/context_processors.py | 26 +- src/registrar/templates/401.html | 4 +- src/registrar/templates/403.html | 4 +- src/registrar/templates/404.html | 4 +- src/registrar/templates/500.html | 4 +- src/registrar/templates/admin/app_list.html | 2 +- src/registrar/templates/admin/fieldset.html | 2 +- .../templates/admin/transfer_user.html | 2 +- src/registrar/templates/base.html | 8 +- src/registrar/templates/dashboard_base.html | 2 +- .../django/admin/includes/details_button.html | 2 +- .../admin/includes/domain_fieldset.html | 2 +- .../admin/multiple_choice_list_filter.html | 4 +- src/registrar/templates/domain_base.html | 6 +- .../templates/domain_request_form.html | 6 +- .../templates/domain_request_intro.html | 63 +-- .../domain_request_withdraw_confirmation.html | 18 +- src/registrar/templates/domain_sidebar.html | 2 +- src/registrar/templates/home.html | 4 +- .../templates/includes/banner-error.html | 2 +- .../templates/includes/banner-info.html | 2 +- .../includes/banner-non-production-alert.html | 2 +- .../includes/banner-service-disruption.html | 2 +- .../templates/includes/banner-site-alert.html | 2 +- .../includes/banner-system-outage.html | 2 +- .../templates/includes/banner-warning.html | 2 +- .../domain_request_status_manage.html | 432 ++++++++--------- .../includes/domain_requests_table.html | 6 +- .../templates/includes/domains_table.html | 6 +- src/registrar/templates/includes/footer.html | 10 +- .../templates/includes/header_basic.html | 2 +- .../templates/includes/header_extended.html | 4 +- .../templates/includes/members_table.html | 2 +- .../includes/request_status_manage.html | 448 +++++++++--------- .../templates/includes/required_fields.html | 2 +- src/registrar/templates/portfolio_base.html | 25 +- src/registrar/templates/profile.html | 160 ++++--- 43 files changed, 712 insertions(+), 654 deletions(-) diff --git a/src/registrar/assets/src/sass/_theme/_admin.scss b/src/registrar/assets/src/sass/_theme/_admin.scss index 58ce1e4df..5bb523cac 100644 --- a/src/registrar/assets/src/sass/_theme/_admin.scss +++ b/src/registrar/assets/src/sass/_theme/_admin.scss @@ -176,7 +176,16 @@ html[data-theme="dark"] { color: var(--primary-fg); } +// Reset the USWDS styles for alerts +@include at-media(desktop) { + .dashboard .usa-alert__body--widescreen { + padding-left: 4rem !important; + } + .dashboard .usa-alert__body--widescreen::before { + left: 1.5rem !important; + } +} #branding h1, h1, h2, h3, diff --git a/src/registrar/assets/src/sass/_theme/_alerts.scss b/src/registrar/assets/src/sass/_theme/_alerts.scss index 9579cc057..b27fa8806 100644 --- a/src/registrar/assets/src/sass/_theme/_alerts.scss +++ b/src/registrar/assets/src/sass/_theme/_alerts.scss @@ -1,21 +1,18 @@ @use "uswds-core" as *; @use "base" as *; -// Fixes some font size disparities with the Figma -// for usa-alert alert elements -.usa-alert { - .usa-alert__heading.larger-font-sizing { - font-size: units(3); - } -} -.usa-alert__text.measure-none { - max-width: measure(none); -} +/*---------------- + Alert Layout +-----------------*/ // The icon was off center for some reason // Fixes that issue -@media (min-width: 64em){ +@include at-media(desktop) { + // NOTE: !important is used because _font.scss overrides this + .usa-alert__body--widescreen { + max-width: $widescreen-max-width !important; + } .usa-alert--warning{ .usa-alert__body::before { left: 1rem !important; @@ -24,13 +21,29 @@ .usa-alert__body.margin-left-1 { margin-left: 0.5rem!important; } + + .usa-alert__body--widescreen::before { + left: 4rem !important; + } + .usa-alert__body--widescreen { + padding-left: 7rem!important; + } } -// NOTE: !important is used because _font.scss overrides this -.usa-alert__body--widescreen { - max-width: $widescreen-max-width !important; +/*---------------- + Alert Fonts +-----------------*/ +// Fixes some font size disparities with the Figma +// for usa-alert alert elements +.usa-alert { + .usa-alert__heading.larger-font-sizing { + font-size: 1.5rem; + } } +/*---------------- + Alert Coloring +-----------------*/ .usa-site-alert--hot-pink { .usa-alert { background-color: $hot-pink; @@ -47,3 +60,4 @@ background-color: color('base-darkest'); } } + diff --git a/src/registrar/assets/src/sass/_theme/_base.scss b/src/registrar/assets/src/sass/_theme/_base.scss index 62f9f436e..23f6b6978 100644 --- a/src/registrar/assets/src/sass/_theme/_base.scss +++ b/src/registrar/assets/src/sass/_theme/_base.scss @@ -2,6 +2,8 @@ @use "cisa_colors" as *; $widescreen-max-width: 1920px; +$widescreen-x-padding: 4.5rem; + $hot-pink: #FFC3F9; /* Styles for making visible to screen reader / AT users only. */ @@ -252,6 +254,15 @@ abbr[title] { max-width: $widescreen-max-width; } +// This is used in cases where we want to align content to widescreen margins +// but we don't want the content itself to have widescreen widths +@include at-media(desktop) { + .padding-x--widescreen { + padding-left: $widescreen-x-padding !important; + padding-right: $widescreen-x-padding !important; + } +} + .margin-right-neg-4px { margin-right: -4px; } @@ -265,4 +276,8 @@ abbr[title] { margin: 0; height: 1.5em; width: 1.5em; +} + +.maxw-fit-content { + max-width: fit-content; } \ No newline at end of file diff --git a/src/registrar/assets/src/sass/_theme/_containers.scss b/src/registrar/assets/src/sass/_theme/_containers.scss index 7473615ad..24ad480f2 100644 --- a/src/registrar/assets/src/sass/_theme/_containers.scss +++ b/src/registrar/assets/src/sass/_theme/_containers.scss @@ -6,3 +6,21 @@ .usa-identifier__container--widescreen { max-width: $widescreen-max-width !important; } + + +// NOTE: !important is used because we are overriding default +// USWDS paddings in a few locations +@include at-media(desktop) { + .grid-container--widescreen { + padding-left: $widescreen-x-padding !important; + padding-right: $widescreen-x-padding !important; + } +} + +// matches max-width to equal the max-width of .grid-container +// used to trick the eye into thinking we have left-aligned a +// regular grid-container within a widescreen (see instances +// where is_widescreen_centered is used in the html). +.max-width--grid-container { + max-width: 960px; +} \ No newline at end of file diff --git a/src/registrar/assets/src/sass/_theme/_header.scss b/src/registrar/assets/src/sass/_theme/_header.scss index 53eab90d8..ffb880a7b 100644 --- a/src/registrar/assets/src/sass/_theme/_header.scss +++ b/src/registrar/assets/src/sass/_theme/_header.scss @@ -110,8 +110,8 @@ } } .usa-nav__secondary { - // I don't know why USWDS has this at 2 rem, which puts it out of alignment - right: 3rem; + right: 1rem; + padding-right: $widescreen-x-padding; color: color('white'); bottom: 4.3rem; .usa-nav-link, diff --git a/src/registrar/config/settings.py b/src/registrar/config/settings.py index 050950c9b..0111245a1 100644 --- a/src/registrar/config/settings.py +++ b/src/registrar/config/settings.py @@ -251,7 +251,7 @@ TEMPLATES = [ "registrar.context_processors.org_user_status", "registrar.context_processors.add_path_to_context", "registrar.context_processors.portfolio_permissions", - "registrar.context_processors.is_widescreen_mode", + "registrar.context_processors.is_widescreen_centered", ], }, }, diff --git a/src/registrar/context_processors.py b/src/registrar/context_processors.py index 7230b04c6..b3d9c3727 100644 --- a/src/registrar/context_processors.py +++ b/src/registrar/context_processors.py @@ -109,31 +109,21 @@ def portfolio_permissions(request): return portfolio_context -def is_widescreen_mode(request): - widescreen_paths = [] # If this list is meant to include specific paths, populate it. - portfolio_widescreen_paths = [ +def is_widescreen_centered(request): + include_paths = [ "/domains/", "/requests/", - "/request/", - "/no-organization-requests/", - "/no-organization-domains/", - "/domain-request/", + "/members/", ] - # widescreen_paths can be a bear as it trickles down sub-urls. exclude_paths gives us a way out. exclude_paths = [ "/domains/edit", + "members/new-member/", ] - # Check if the current path matches a widescreen path or the root path. - is_widescreen = any(path in request.path for path in widescreen_paths) or request.path == "/" + is_excluded = any(exclude_path in request.path for exclude_path in exclude_paths) - # Check if the user is an organization user and the path matches portfolio paths. - is_portfolio_widescreen = ( - hasattr(request.user, "is_org_user") - and request.user.is_org_user(request) - and any(path in request.path for path in portfolio_widescreen_paths) - and not any(exclude_path in request.path for exclude_path in exclude_paths) - ) + # Check if the current path matches a path in included_paths or the root path. + is_widescreen_centered = any(path in request.path for path in include_paths) or request.path == "/" # Return a dictionary with the widescreen mode status. - return {"is_widescreen_mode": is_widescreen or is_portfolio_widescreen} + return {"is_widescreen_centered": is_widescreen_centered and not is_excluded} diff --git a/src/registrar/templates/401.html b/src/registrar/templates/401.html index d7c7f83ae..7698c4f82 100644 --- a/src/registrar/templates/401.html +++ b/src/registrar/templates/401.html @@ -5,8 +5,8 @@ {% block title %}{% translate "Unauthorized | " %}{% endblock %} {% block content %} -
    -
    +
    +

    {% translate "You are not authorized to view this page" %} diff --git a/src/registrar/templates/403.html b/src/registrar/templates/403.html index 999d5f98e..a04453fe9 100644 --- a/src/registrar/templates/403.html +++ b/src/registrar/templates/403.html @@ -5,8 +5,8 @@ {% block title %}{% translate "Forbidden | " %}{% endblock %} {% block content %} -
    -
    +
    +

    {% translate "You're not authorized to view this page." %} diff --git a/src/registrar/templates/404.html b/src/registrar/templates/404.html index 471575558..2bf9ecf02 100644 --- a/src/registrar/templates/404.html +++ b/src/registrar/templates/404.html @@ -5,8 +5,8 @@ {% block title %}{% translate "Page not found | " %}{% endblock %} {% block content %} -
    -
    +
    +

    {% translate "We couldn’t find that page" %} diff --git a/src/registrar/templates/500.html b/src/registrar/templates/500.html index a0663816b..fad909ddb 100644 --- a/src/registrar/templates/500.html +++ b/src/registrar/templates/500.html @@ -5,8 +5,8 @@ {% block title %}{% translate "Server error | " %}{% endblock %} {% block content %} -
    -
    +
    +

    {% translate "We're having some trouble." %} diff --git a/src/registrar/templates/admin/app_list.html b/src/registrar/templates/admin/app_list.html index 49fb59e79..aaf3dc423 100644 --- a/src/registrar/templates/admin/app_list.html +++ b/src/registrar/templates/admin/app_list.html @@ -39,7 +39,7 @@ {% for model in app.models %} {% if model.admin_url %} - {{ model.name }} + {{ model.name }} {% else %} {{ model.name }} {% endif %} diff --git a/src/registrar/templates/admin/fieldset.html b/src/registrar/templates/admin/fieldset.html index 40cd98ca8..20b76217b 100644 --- a/src/registrar/templates/admin/fieldset.html +++ b/src/registrar/templates/admin/fieldset.html @@ -61,7 +61,7 @@ https://github.com/django/django/blob/main/django/contrib/admin/templates/admin/ {% if field.field.help_text %} {# .gov override #} {% block help_text %} -
    +
    {{ field.field.help_text|safe }}
    {% endblock help_text %} diff --git a/src/registrar/templates/admin/transfer_user.html b/src/registrar/templates/admin/transfer_user.html index 3ba136b93..61444b173 100644 --- a/src/registrar/templates/admin/transfer_user.html +++ b/src/registrar/templates/admin/transfer_user.html @@ -43,7 +43,7 @@ {% if steps.current == steps.first %} {% if portfolio %} diff --git a/src/registrar/templates/domain_request_intro.html b/src/registrar/templates/domain_request_intro.html index dd5b7ec6e..d66d019e6 100644 --- a/src/registrar/templates/domain_request_intro.html +++ b/src/registrar/templates/domain_request_intro.html @@ -4,41 +4,42 @@ {% block title %} Start a request | {% endblock %} {% block content %} -
    -
    +
    +
    +
    -
    - {% csrf_token %} + + {% csrf_token %} -

    You’re about to start your .gov domain request.

    -

    You don’t have to complete the process in one session. You can save what you enter and come back to it when you’re ready.

    - {% if portfolio %} -

    We’ll use the information you provide to verify your domain request meets our guidelines.

    - {% else %} -

    We’ll use the information you provide to verify your organization’s eligibility for a .gov domain. We’ll also verify that the domain you request meets our guidelines.

    - {% endif %} -

    Time to complete the form

    -

    If you have all the information you need, - completing your domain request might take around 15 minutes.

    -

    How we’ll reach you

    -

    While reviewing your domain request, we may need to reach out with questions. We’ll also email you when we complete our review. If the contact information below is not correct, visit your profile to make updates.

    - {% include "includes/profile_information.html" with user=user%} - +

    You’re about to start your .gov domain request.

    +

    You don’t have to complete the process in one session. You can save what you enter and come back to it when you’re ready.

    + {% if portfolio %} +

    We’ll use the information you provide to verify your domain request meets our guidelines.

    + {% else %} +

    We’ll use the information you provide to verify your organization’s eligibility for a .gov domain. We’ll also verify that the domain you request meets our guidelines.

    + {% endif %} +

    Time to complete the form

    +

    If you have all the information you need, + completing your domain request might take around 15 minutes.

    +

    How we’ll reach you

    +

    While reviewing your domain request, we may need to reach out with questions. We’ll also email you when we complete our review. If the contact information below is not correct, visit your profile to make updates.

    + {% include "includes/profile_information.html" with user=user%} + -{% block form_buttons %} -
    - -
    -{% endblock %} + {% block form_buttons %} +
    + +
    + {% endblock %} -
    + -
    Paperwork Reduction Act statement (OMB control number: 1670-0049; expiration date: 10/31/2026)
    -
    +
    Paperwork Reduction Act statement (OMB control number: 1670-0049; expiration date: 10/31/2026)
    +
    {% endblock %} diff --git a/src/registrar/templates/domain_request_withdraw_confirmation.html b/src/registrar/templates/domain_request_withdraw_confirmation.html index e1a5f0c2a..cc426eeaf 100644 --- a/src/registrar/templates/domain_request_withdraw_confirmation.html +++ b/src/registrar/templates/domain_request_withdraw_confirmation.html @@ -8,18 +8,20 @@ {% endblock wrapperdiv %} {% block content %} -
    -
    - +
    +
    +
    + -

    Withdraw request for {{ DomainRequest.requested_domain.name }}?

    +

    Withdraw request for {{ DomainRequest.requested_domain.name }}?

    -

    If you withdraw your request, we won't review it. Once you withdraw your request, you can edit it and submit it again.

    +

    If you withdraw your request, we won't review it. Once you withdraw your request, you can edit it and submit it again.

    -

    Withdraw request - Cancel

    +

    Withdraw request + Cancel

    -
    +
    +
    {% endblock %} diff --git a/src/registrar/templates/domain_sidebar.html b/src/registrar/templates/domain_sidebar.html index 289f544ce..99ca1bfb7 100644 --- a/src/registrar/templates/domain_sidebar.html +++ b/src/registrar/templates/domain_sidebar.html @@ -18,7 +18,7 @@
  • {% url 'domain-dns' pk=domain.id as url %} - + DNS {% if request.path|startswith:url %} diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index b1c3775df..de4d9e712 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -5,12 +5,12 @@ {% block title %} Home | {% endblock %} {% block content %} -
    +
    {% if user.is_authenticated %} {# the entire logged in page goes here #} {% block homepage_content %} -
    +
    {% block messages %} {% include "includes/form_messages.html" %} {% endblock %} diff --git a/src/registrar/templates/includes/banner-error.html b/src/registrar/templates/includes/banner-error.html index 7b5c32ed1..10582e268 100644 --- a/src/registrar/templates/includes/banner-error.html +++ b/src/registrar/templates/includes/banner-error.html @@ -1,6 +1,6 @@
    -
    +

    Header

    diff --git a/src/registrar/templates/includes/banner-info.html b/src/registrar/templates/includes/banner-info.html index e5d54e483..cf379c50d 100644 --- a/src/registrar/templates/includes/banner-info.html +++ b/src/registrar/templates/includes/banner-info.html @@ -1,6 +1,6 @@
    -
    +

    Header

    diff --git a/src/registrar/templates/includes/banner-non-production-alert.html b/src/registrar/templates/includes/banner-non-production-alert.html index 61d4eed51..7b66d543b 100644 --- a/src/registrar/templates/includes/banner-non-production-alert.html +++ b/src/registrar/templates/includes/banner-non-production-alert.html @@ -1,6 +1,6 @@
    -
    +

    Attention: You are on a test site.

    diff --git a/src/registrar/templates/includes/banner-service-disruption.html b/src/registrar/templates/includes/banner-service-disruption.html index fc89ee65d..6ee4b976b 100644 --- a/src/registrar/templates/includes/banner-service-disruption.html +++ b/src/registrar/templates/includes/banner-service-disruption.html @@ -1,6 +1,6 @@
    -
    +

    Service disruption

    diff --git a/src/registrar/templates/includes/banner-site-alert.html b/src/registrar/templates/includes/banner-site-alert.html index 52256f46b..8dd657267 100644 --- a/src/registrar/templates/includes/banner-site-alert.html +++ b/src/registrar/templates/includes/banner-site-alert.html @@ -1,6 +1,6 @@
    -
    +

    Header here

    diff --git a/src/registrar/templates/includes/banner-system-outage.html b/src/registrar/templates/includes/banner-system-outage.html index 911fa4487..60fc4eb03 100644 --- a/src/registrar/templates/includes/banner-system-outage.html +++ b/src/registrar/templates/includes/banner-system-outage.html @@ -1,6 +1,6 @@
    -
    +

    System outage

    diff --git a/src/registrar/templates/includes/banner-warning.html b/src/registrar/templates/includes/banner-warning.html index 6838aef7b..762d0b47c 100644 --- a/src/registrar/templates/includes/banner-warning.html +++ b/src/registrar/templates/includes/banner-warning.html @@ -1,6 +1,6 @@
    -
    +

    Header

    diff --git a/src/registrar/templates/includes/domain_request_status_manage.html b/src/registrar/templates/includes/domain_request_status_manage.html index 2a254df4b..1c6ca081e 100644 --- a/src/registrar/templates/includes/domain_request_status_manage.html +++ b/src/registrar/templates/includes/domain_request_status_manage.html @@ -1,236 +1,238 @@ {% load custom_filters %} {% load static url_helpers %} -
    -
    - {% block breadcrumb %} - {% if portfolio %} - {% url 'domain-requests' as url %} - {% else %} - {% url 'home' as url %} - {% endif %} - - {% endblock breadcrumb %} - {% block header %} - {% if not DomainRequest.requested_domain and DomainRequest.status == DomainRequest.DomainRequestStatus.STARTED %} -

    New domain request

    - {% else %} -

    Domain request for {{ DomainRequest.requested_domain.name }}

    - {% endif %} - {% endblock header %} - - {% block status_summary %} -
    -
    -

    - - Status: - - {{ DomainRequest.get_status_display|default:"ERROR Please contact technical support/dev" }} -

    -
    -
    -
    - {% endblock status_summary %} - - {% block status_metadata %} - - {% if portfolio %} - {% if DomainRequest.creator %} -

    - Created by: {{DomainRequest.creator.email|default:DomainRequest.creator.get_formatted_name }} -

    - {% else %} -

    - No creator found: this is an error, please email help@get.gov. -

    - {% endif %} - {% endif %} - - {% with statuses=DomainRequest.DomainRequestStatus last_submitted=DomainRequest.last_submitted_date|date:"F j, Y" first_submitted=DomainRequest.first_submitted_date|date:"F j, Y" last_status_update=DomainRequest.last_status_update|date:"F j, Y" %} - {% comment %} - These are intentionally seperated this way. - There is some code repetition, but it gives us more flexibility rather than a dense reduction. - Leave it this way until we've solidified our requirements. - {% endcomment %} - {% if DomainRequest.status == statuses.STARTED %} - {% with first_started_date=DomainRequest.get_first_status_started_date|date:"F j, Y" %} -

    + {% with statuses=DomainRequest.DomainRequestStatus last_submitted=DomainRequest.last_submitted_date|date:"F j, Y" first_submitted=DomainRequest.first_submitted_date|date:"F j, Y" last_status_update=DomainRequest.last_status_update|date:"F j, Y" %} {% comment %} - A newly created domain request will not have a value for last_status update. - This is because the status never really updated. - However, if this somehow goes back to started we can default to displaying that new date. + These are intentionally seperated this way. + There is some code repetition, but it gives us more flexibility rather than a dense reduction. + Leave it this way until we've solidified our requirements. {% endcomment %} - Started on: {{last_status_update|default:first_started_date}} -

    - {% endwith %} - {% elif DomainRequest.status == statuses.SUBMITTED %} -

    - Submitted on: {{last_submitted|default:first_submitted }} -

    -

    - Last updated on: {{DomainRequest.updated_at|date:"F j, Y"}} -

    - {% elif DomainRequest.status == statuses.ACTION_NEEDED %} -

    - Submitted on: {{last_submitted|default:first_submitted }} -

    -

    - Last updated on: {{DomainRequest.updated_at|date:"F j, Y"}} -

    - {% elif DomainRequest.status == statuses.REJECTED %} -

    - Submitted on: {{last_submitted|default:first_submitted }} -

    -

    - Rejected on: {{last_status_update}} -

    - {% elif DomainRequest.status == statuses.WITHDRAWN %} -

    - Submitted on: {{last_submitted|default:first_submitted }} -

    -

    - Withdrawn on: {{last_status_update}} -

    - {% else %} - {% comment %} Shown for in_review, approved, ineligible {% endcomment %} -

    - Last updated on: {{DomainRequest.updated_at|date:"F j, Y"}} -

    - {% endif %} - {% endwith %} - {% endblock status_metadata %} - - {% block status_blurb %} - {% if DomainRequest.is_awaiting_review %} -

    {% include "includes/domain_request_awaiting_review.html" with show_withdraw_text=DomainRequest.is_withdrawable %}

    - {% endif %} - {% endblock status_blurb %} - - {% block modify_request %} - {% if DomainRequest.is_withdrawable %} -

    - Withdraw request + {% if DomainRequest.status == statuses.STARTED %} + {% with first_started_date=DomainRequest.get_first_status_started_date|date:"F j, Y" %} +

    + {% comment %} + A newly created domain request will not have a value for last_status update. + This is because the status never really updated. + However, if this somehow goes back to started we can default to displaying that new date. + {% endcomment %} + Started on: {{last_status_update|default:first_started_date}}

    - {% endif %} - {% endblock modify_request %} -
    - -
    - {% block request_summary_header %} -

    Summary of your domain request

    - {% endblock request_summary_header%} - - {% block request_summary %} - {% with heading_level='h3' %} - {% with org_type=DomainRequest.get_generic_org_type_display %} - {% include "includes/summary_item.html" with title='Type of organization' value=org_type heading_level=heading_level %} - {% endwith %} - - {% if DomainRequest.tribe_name %} - {% include "includes/summary_item.html" with title='Tribal government' value=DomainRequest.tribe_name heading_level=heading_level %} - - {% if DomainRequest.federally_recognized_tribe %} -

    Federally-recognized tribe

    - {% endif %} - - {% if DomainRequest.state_recognized_tribe %} -

    State-recognized tribe

    - {% endif %} - - {% endif %} - - {% if DomainRequest.get_federal_type_display %} - {% include "includes/summary_item.html" with title='Federal government branch' value=DomainRequest.get_federal_type_display heading_level=heading_level %} - {% endif %} - - {% if DomainRequest.is_election_board %} - {% with value=DomainRequest.is_election_board|yesno:"Yes,No,Incomplete" %} - {% include "includes/summary_item.html" with title='Election office' value=value heading_level=heading_level %} {% endwith %} - {% endif %} + {% elif DomainRequest.status == statuses.SUBMITTED %} +

    + Submitted on: {{last_submitted|default:first_submitted }} +

    +

    + Last updated on: {{DomainRequest.updated_at|date:"F j, Y"}} +

    + {% elif DomainRequest.status == statuses.ACTION_NEEDED %} +

    + Submitted on: {{last_submitted|default:first_submitted }} +

    +

    + Last updated on: {{DomainRequest.updated_at|date:"F j, Y"}} +

    + {% elif DomainRequest.status == statuses.REJECTED %} +

    + Submitted on: {{last_submitted|default:first_submitted }} +

    +

    + Rejected on: {{last_status_update}} +

    + {% elif DomainRequest.status == statuses.WITHDRAWN %} +

    + Submitted on: {{last_submitted|default:first_submitted }} +

    +

    + Withdrawn on: {{last_status_update}} +

    + {% else %} + {% comment %} Shown for in_review, approved, ineligible {% endcomment %} +

    + Last updated on: {{DomainRequest.updated_at|date:"F j, Y"}} +

    + {% endif %} + {% endwith %} + {% endblock status_metadata %} - {% if DomainRequest.organization_name %} - {% include "includes/summary_item.html" with title='Organization' value=DomainRequest address='true' heading_level=heading_level %} - {% endif %} + {% block status_blurb %} + {% if DomainRequest.is_awaiting_review %} +

    {% include "includes/domain_request_awaiting_review.html" with show_withdraw_text=DomainRequest.is_withdrawable %}

    + {% endif %} + {% endblock status_blurb %} - {% if DomainRequest.about_your_organization %} - {% include "includes/summary_item.html" with title='About your organization' value=DomainRequest.about_your_organization heading_level=heading_level %} - {% endif %} + {% block modify_request %} + {% if DomainRequest.is_withdrawable %} +

    + Withdraw request +

    + {% endif %} + {% endblock modify_request %} +
    - {% if DomainRequest.senior_official %} - {% include "includes/summary_item.html" with title='Senior official' value=DomainRequest.senior_official contact='true' heading_level=heading_level %} - {% endif %} +
    + {% block request_summary_header %} +

    Summary of your domain request

    + {% endblock request_summary_header%} - {% if DomainRequest.current_websites.all %} - {% include "includes/summary_item.html" with title='Current websites' value=DomainRequest.current_websites.all list='true' heading_level=heading_level %} - {% endif %} + {% block request_summary %} + {% with heading_level='h3' %} + {% with org_type=DomainRequest.get_generic_org_type_display %} + {% include "includes/summary_item.html" with title='Type of organization' value=org_type heading_level=heading_level %} + {% endwith %} - {% if DomainRequest.requested_domain %} - {% include "includes/summary_item.html" with title='.gov domain' value=DomainRequest.requested_domain heading_level=heading_level %} - {% endif %} + {% if DomainRequest.tribe_name %} + {% include "includes/summary_item.html" with title='Tribal government' value=DomainRequest.tribe_name heading_level=heading_level %} - {% if DomainRequest.alternative_domains.all %} - {% include "includes/summary_item.html" with title='Alternative domains' value=DomainRequest.alternative_domains.all list='true' heading_level=heading_level %} - {% endif %} - - {% if DomainRequest.purpose %} - {% include "includes/summary_item.html" with title='Purpose of your domain' value=DomainRequest.purpose heading_level=heading_level %} - {% endif %} - - {% if DomainRequest.creator %} - {% include "includes/summary_item.html" with title='Your contact information' value=DomainRequest.creator contact='true' heading_level=heading_level %} - {% endif %} - - {% if DomainRequest.other_contacts.all %} - {% include "includes/summary_item.html" with title='Other employees from your organization' value=DomainRequest.other_contacts.all contact='true' list='true' heading_level=heading_level %} - {% else %} - {% include "includes/summary_item.html" with title='Other employees from your organization' value=DomainRequest.no_other_contacts_rationale heading_level=heading_level %} - {% endif %} - - {# We always show this field even if None #} - {% if DomainRequest %} -

    CISA Regional Representative

    -
      - {% if DomainRequest.cisa_representative_first_name %} - {{ DomainRequest.get_formatted_cisa_rep_name }} - {% else %} - No + {% if DomainRequest.federally_recognized_tribe %} +

      Federally-recognized tribe

      {% endif %} -
    -

    Anything else

    -
      - {% if DomainRequest.anything_else %} - {{DomainRequest.anything_else}} - {% else %} - No + + {% if DomainRequest.state_recognized_tribe %} +

      State-recognized tribe

      {% endif %} -
    - {% endif %} - {% endwith %} - {% endblock request_summary%} + + {% endif %} + + {% if DomainRequest.get_federal_type_display %} + {% include "includes/summary_item.html" with title='Federal government branch' value=DomainRequest.get_federal_type_display heading_level=heading_level %} + {% endif %} + + {% if DomainRequest.is_election_board %} + {% with value=DomainRequest.is_election_board|yesno:"Yes,No,Incomplete" %} + {% include "includes/summary_item.html" with title='Election office' value=value heading_level=heading_level %} + {% endwith %} + {% endif %} + + {% if DomainRequest.organization_name %} + {% include "includes/summary_item.html" with title='Organization' value=DomainRequest address='true' heading_level=heading_level %} + {% endif %} + + {% if DomainRequest.about_your_organization %} + {% include "includes/summary_item.html" with title='About your organization' value=DomainRequest.about_your_organization heading_level=heading_level %} + {% endif %} + + {% if DomainRequest.senior_official %} + {% include "includes/summary_item.html" with title='Senior official' value=DomainRequest.senior_official contact='true' heading_level=heading_level %} + {% endif %} + + {% if DomainRequest.current_websites.all %} + {% include "includes/summary_item.html" with title='Current websites' value=DomainRequest.current_websites.all list='true' heading_level=heading_level %} + {% endif %} + + {% if DomainRequest.requested_domain %} + {% include "includes/summary_item.html" with title='.gov domain' value=DomainRequest.requested_domain heading_level=heading_level %} + {% endif %} + + {% if DomainRequest.alternative_domains.all %} + {% include "includes/summary_item.html" with title='Alternative domains' value=DomainRequest.alternative_domains.all list='true' heading_level=heading_level %} + {% endif %} + + {% if DomainRequest.purpose %} + {% include "includes/summary_item.html" with title='Purpose of your domain' value=DomainRequest.purpose heading_level=heading_level %} + {% endif %} + + {% if DomainRequest.creator %} + {% include "includes/summary_item.html" with title='Your contact information' value=DomainRequest.creator contact='true' heading_level=heading_level %} + {% endif %} + + {% if DomainRequest.other_contacts.all %} + {% include "includes/summary_item.html" with title='Other employees from your organization' value=DomainRequest.other_contacts.all contact='true' list='true' heading_level=heading_level %} + {% else %} + {% include "includes/summary_item.html" with title='Other employees from your organization' value=DomainRequest.no_other_contacts_rationale heading_level=heading_level %} + {% endif %} + + {# We always show this field even if None #} + {% if DomainRequest %} +

    CISA Regional Representative

    +
      + {% if DomainRequest.cisa_representative_first_name %} + {{ DomainRequest.get_formatted_cisa_rep_name }} + {% else %} + No + {% endif %} +
    +

    Anything else

    +
      + {% if DomainRequest.anything_else %} + {{DomainRequest.anything_else}} + {% else %} + No + {% endif %} +
    + {% endif %} + {% endwith %} + {% endblock request_summary%} +
    \ No newline at end of file diff --git a/src/registrar/templates/includes/domain_requests_table.html b/src/registrar/templates/includes/domain_requests_table.html index 56cdc2cec..c48e2c9a6 100644 --- a/src/registrar/templates/includes/domain_requests_table.html +++ b/src/registrar/templates/includes/domain_requests_table.html @@ -4,8 +4,8 @@ {% url 'get_domain_requests_json' as url %} -
    -
    +
    +
    {% if not portfolio %}

    Domain requests

    {% else %} @@ -13,7 +13,7 @@ {% endif %} -
    \ No newline at end of file diff --git a/src/registrar/templates/includes/required_fields.html b/src/registrar/templates/includes/required_fields.html index be0395979..a9d860f24 100644 --- a/src/registrar/templates/includes/required_fields.html +++ b/src/registrar/templates/includes/required_fields.html @@ -1,3 +1,3 @@ -

    +

    Required fields are marked with an asterisk (*).

    diff --git a/src/registrar/templates/portfolio_base.html b/src/registrar/templates/portfolio_base.html index c2a60b7ba..4cafd3f84 100644 --- a/src/registrar/templates/portfolio_base.html +++ b/src/registrar/templates/portfolio_base.html @@ -4,26 +4,29 @@
    {% block content %} -
    +
    {% if user.is_authenticated %} {# the entire logged in page goes here #} -
    +
    +
    {% block messages %} {% include "includes/form_messages.html" %} {% endblock %} {% block portfolio_content %}{% endblock %} -
    - {% else %} {# not user.is_authenticated #} - {# the entire logged out page goes here #} - -

    - Sign in -

    - - {% endif %} +
    + {% else %} {# not user.is_authenticated #} + {# the entire logged out page goes here #} + +

    + Sign in +

    + + {% endif %} +
    +
    {% endblock content%} diff --git a/src/registrar/templates/profile.html b/src/registrar/templates/profile.html index 7d365d9c1..cbd2811d1 100644 --- a/src/registrar/templates/profile.html +++ b/src/registrar/templates/profile.html @@ -11,90 +11,92 @@ Edit your User Profile | {% endblock %} {% block content %} -
    -
    - {% if messages %} - {% for message in messages %} -
    -
    - {{ message }} -
    -
    - {% endfor %} - {% endif %} - {% include "includes/form_errors.html" with form=form %} +
    +
    +
    + {% if messages %} + {% for message in messages %} +
    +
    + {{ message }} +
    +
    + {% endfor %} + {% endif %} + {% include "includes/form_errors.html" with form=form %} - {% if show_back_button %} - - -

    - {{ profile_back_button_text }} -

    -
    - {% endif %} - - {% if show_confirmation_modal %} - -
    -
    -
    -

    - Add contact information -

    -
    -

    - .Gov domain registrants must maintain accurate contact information in the .gov registrar. - Before you can manage your domain, we need you to add your contact information. -

    -
    -
  • +
    +

    + .Gov domain registrants must maintain accurate contact information in the .gov registrar. + Before you can manage your domain, we need you to add your contact information. +

    +
    + +
    +
    - -

    + {% endif %} + + + + {% endblock content %} + + {% block content_bottom %} + {% include "includes/profile_form.html" with form=form %}
    - {% endif %} - - - -{% endblock content %} - -{% block content_bottom %} - {% include "includes/profile_form.html" with form=form %} -
    +

    {% endblock content_bottom %} From 4faf3df646de6b5af5543bbfcd1e99653d0434da Mon Sep 17 00:00:00 2001 From: CocoByte Date: Tue, 31 Dec 2024 16:46:06 -0700 Subject: [PATCH 32/44] delete duplicate (unused) file --- .../domain_request_status_manage.html | 238 ------------------ 1 file changed, 238 deletions(-) delete mode 100644 src/registrar/templates/includes/domain_request_status_manage.html diff --git a/src/registrar/templates/includes/domain_request_status_manage.html b/src/registrar/templates/includes/domain_request_status_manage.html deleted file mode 100644 index 1c6ca081e..000000000 --- a/src/registrar/templates/includes/domain_request_status_manage.html +++ /dev/null @@ -1,238 +0,0 @@ -{% load custom_filters %} -{% load static url_helpers %} -
    -
    -
    - {% block breadcrumb %} - {% if portfolio %} - {% url 'domain-requests' as url %} - {% else %} - {% url 'home' as url %} - {% endif %} - - {% endblock breadcrumb %} - - {% block header %} - {% if not DomainRequest.requested_domain and DomainRequest.status == DomainRequest.DomainRequestStatus.STARTED %} -

    New domain request

    - {% else %} -

    Domain request for {{ DomainRequest.requested_domain.name }}

    - {% endif %} - {% endblock header %} - - {% block status_summary %} -
    -
    -

    - - Status: - - {{ DomainRequest.get_status_display|default:"ERROR Please contact technical support/dev" }} -

    -
    -
    -
    - {% endblock status_summary %} - - {% block status_metadata %} - - {% if portfolio %} - {% if DomainRequest.creator %} -

    - Created by: {{DomainRequest.creator.email|default:DomainRequest.creator.get_formatted_name }} -

    - {% else %} -

    - No creator found: this is an error, please email help@get.gov. -

    - {% endif %} - {% endif %} - - {% with statuses=DomainRequest.DomainRequestStatus last_submitted=DomainRequest.last_submitted_date|date:"F j, Y" first_submitted=DomainRequest.first_submitted_date|date:"F j, Y" last_status_update=DomainRequest.last_status_update|date:"F j, Y" %} - {% comment %} - These are intentionally seperated this way. - There is some code repetition, but it gives us more flexibility rather than a dense reduction. - Leave it this way until we've solidified our requirements. - {% endcomment %} - {% if DomainRequest.status == statuses.STARTED %} - {% with first_started_date=DomainRequest.get_first_status_started_date|date:"F j, Y" %} -

    - {% comment %} - A newly created domain request will not have a value for last_status update. - This is because the status never really updated. - However, if this somehow goes back to started we can default to displaying that new date. - {% endcomment %} - Started on: {{last_status_update|default:first_started_date}} -

    - {% endwith %} - {% elif DomainRequest.status == statuses.SUBMITTED %} -

    - Submitted on: {{last_submitted|default:first_submitted }} -

    -

    - Last updated on: {{DomainRequest.updated_at|date:"F j, Y"}} -

    - {% elif DomainRequest.status == statuses.ACTION_NEEDED %} -

    - Submitted on: {{last_submitted|default:first_submitted }} -

    -

    - Last updated on: {{DomainRequest.updated_at|date:"F j, Y"}} -

    - {% elif DomainRequest.status == statuses.REJECTED %} -

    - Submitted on: {{last_submitted|default:first_submitted }} -

    -

    - Rejected on: {{last_status_update}} -

    - {% elif DomainRequest.status == statuses.WITHDRAWN %} -

    - Submitted on: {{last_submitted|default:first_submitted }} -

    -

    - Withdrawn on: {{last_status_update}} -

    - {% else %} - {% comment %} Shown for in_review, approved, ineligible {% endcomment %} -

    - Last updated on: {{DomainRequest.updated_at|date:"F j, Y"}} -

    - {% endif %} - {% endwith %} - {% endblock status_metadata %} - - {% block status_blurb %} - {% if DomainRequest.is_awaiting_review %} -

    {% include "includes/domain_request_awaiting_review.html" with show_withdraw_text=DomainRequest.is_withdrawable %}

    - {% endif %} - {% endblock status_blurb %} - - {% block modify_request %} - {% if DomainRequest.is_withdrawable %} -

    - Withdraw request -

    - {% endif %} - {% endblock modify_request %} -
    - -
    - {% block request_summary_header %} -

    Summary of your domain request

    - {% endblock request_summary_header%} - - {% block request_summary %} - {% with heading_level='h3' %} - {% with org_type=DomainRequest.get_generic_org_type_display %} - {% include "includes/summary_item.html" with title='Type of organization' value=org_type heading_level=heading_level %} - {% endwith %} - - {% if DomainRequest.tribe_name %} - {% include "includes/summary_item.html" with title='Tribal government' value=DomainRequest.tribe_name heading_level=heading_level %} - - {% if DomainRequest.federally_recognized_tribe %} -

    Federally-recognized tribe

    - {% endif %} - - {% if DomainRequest.state_recognized_tribe %} -

    State-recognized tribe

    - {% endif %} - - {% endif %} - - {% if DomainRequest.get_federal_type_display %} - {% include "includes/summary_item.html" with title='Federal government branch' value=DomainRequest.get_federal_type_display heading_level=heading_level %} - {% endif %} - - {% if DomainRequest.is_election_board %} - {% with value=DomainRequest.is_election_board|yesno:"Yes,No,Incomplete" %} - {% include "includes/summary_item.html" with title='Election office' value=value heading_level=heading_level %} - {% endwith %} - {% endif %} - - {% if DomainRequest.organization_name %} - {% include "includes/summary_item.html" with title='Organization' value=DomainRequest address='true' heading_level=heading_level %} - {% endif %} - - {% if DomainRequest.about_your_organization %} - {% include "includes/summary_item.html" with title='About your organization' value=DomainRequest.about_your_organization heading_level=heading_level %} - {% endif %} - - {% if DomainRequest.senior_official %} - {% include "includes/summary_item.html" with title='Senior official' value=DomainRequest.senior_official contact='true' heading_level=heading_level %} - {% endif %} - - {% if DomainRequest.current_websites.all %} - {% include "includes/summary_item.html" with title='Current websites' value=DomainRequest.current_websites.all list='true' heading_level=heading_level %} - {% endif %} - - {% if DomainRequest.requested_domain %} - {% include "includes/summary_item.html" with title='.gov domain' value=DomainRequest.requested_domain heading_level=heading_level %} - {% endif %} - - {% if DomainRequest.alternative_domains.all %} - {% include "includes/summary_item.html" with title='Alternative domains' value=DomainRequest.alternative_domains.all list='true' heading_level=heading_level %} - {% endif %} - - {% if DomainRequest.purpose %} - {% include "includes/summary_item.html" with title='Purpose of your domain' value=DomainRequest.purpose heading_level=heading_level %} - {% endif %} - - {% if DomainRequest.creator %} - {% include "includes/summary_item.html" with title='Your contact information' value=DomainRequest.creator contact='true' heading_level=heading_level %} - {% endif %} - - {% if DomainRequest.other_contacts.all %} - {% include "includes/summary_item.html" with title='Other employees from your organization' value=DomainRequest.other_contacts.all contact='true' list='true' heading_level=heading_level %} - {% else %} - {% include "includes/summary_item.html" with title='Other employees from your organization' value=DomainRequest.no_other_contacts_rationale heading_level=heading_level %} - {% endif %} - - {# We always show this field even if None #} - {% if DomainRequest %} -

    CISA Regional Representative

    -
      - {% if DomainRequest.cisa_representative_first_name %} - {{ DomainRequest.get_formatted_cisa_rep_name }} - {% else %} - No - {% endif %} -
    -

    Anything else

    -
      - {% if DomainRequest.anything_else %} - {{DomainRequest.anything_else}} - {% else %} - No - {% endif %} -
    - {% endif %} - {% endwith %} - {% endblock request_summary%} -
    -
    -
    \ No newline at end of file From 6f6e2dbc8b3a567e2c3cbfea5d354a6261ee103d Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 2 Jan 2025 09:27:42 -0700 Subject: [PATCH 33/44] Add clear button --- src/package-lock.json | 53 +++---------------- src/registrar/admin.py | 10 ---- .../js/getgov-admin/domain-request-form.js | 19 ++++--- .../helpers-portfolio-dynamic-fields.js | 37 ++++++------- src/registrar/models/domain.py | 1 + .../admin/domain_request_change_form.html | 11 +++- .../admin/includes/detail_table_fieldset.html | 19 +++++++ .../includes/domain_request_fieldset.html | 14 ----- src/registrar/tests/test_admin_request.py | 3 -- 9 files changed, 62 insertions(+), 105 deletions(-) delete mode 100644 src/registrar/templates/django/admin/includes/domain_request_fieldset.html diff --git a/src/package-lock.json b/src/package-lock.json index 22fb31857..d78b5132f 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -6921,16 +6921,6 @@ "validate-npm-package-license": "^3.0.1" } }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -7307,39 +7297,6 @@ "node": ">= 12" } }, - "node_modules/pa11y/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/pa11y/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/pa11y/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, "node_modules/parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", @@ -8888,13 +8845,15 @@ } }, "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "license": "ISC", "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/semver-greatest-satisfied-range": { diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 874512fdc..1476cee7e 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -2003,14 +2003,6 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): custom_requested_domain.admin_order_field = "requested_domain__name" # type: ignore - # ------ Converted fields ------ - # These fields map to @Property methods and - # require these custom definitions to work properly - @admin.display(description="Suborganization options") - def reject_suborganization_button(self, obj): - """Custom field to display the reject suborganization button""" - return "" - @admin.display(description=_("Generic Org Type")) def converted_generic_org_type(self, obj): return obj.converted_generic_org_type_display @@ -2182,7 +2174,6 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): "requested_suborganization", "suborganization_city", "suborganization_state_territory", - "reject_suborganization_button", "creator", ] }, @@ -2304,7 +2295,6 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): "alternative_domains", "is_election_board", "status_history", - "reject_suborganization_button", ) # Read only that we'll leverage for CISA Analysts diff --git a/src/registrar/assets/src/js/getgov-admin/domain-request-form.js b/src/registrar/assets/src/js/getgov-admin/domain-request-form.js index 928495cb6..d82b2de8b 100644 --- a/src/registrar/assets/src/js/getgov-admin/domain-request-form.js +++ b/src/registrar/assets/src/js/getgov-admin/domain-request-form.js @@ -644,21 +644,20 @@ function handleSuborgFieldsAndButtons() { const requestedSuborganizationField = document.getElementById("id_requested_suborganization"); const suborganizationCity = document.getElementById("id_suborganization_city"); const suborganizationStateTerritory = document.getElementById("id_suborganization_state_territory"); - // The reject button is wrapped in a fieldset with a label - const rejectButtonFieldset = document.querySelector(".field-reject_suborganization_button"); const rejectButton = document.querySelector("#clear-requested-suborganization"); + console.log("test12345678") // Ensure that every variable is present before proceeding - if (!requestedSuborganizationField || !suborganizationCity || !suborganizationStateTerritory || !rejectButtonFieldset || !rejectButton) { + if (!requestedSuborganizationField || !suborganizationCity || !suborganizationStateTerritory || !rejectButton) { console.warn("handleSuborganizationSelection() => Could not find required fields.") return; } - function updateRejectButtonFieldset() { + function handleRejectButtonVisibility() { if (requestedSuborganizationField.value || suborganizationCity.value || suborganizationStateTerritory.value) { - showElement(rejectButtonFieldset); + showElement(rejectButton); }else { - hideElement(rejectButtonFieldset) + hideElement(rejectButton) } } @@ -668,12 +667,12 @@ function handleSuborgFieldsAndButtons() { suborganizationCity.value = ""; suborganizationStateTerritory.value = ""; // Update button visibility after clearing - updateRejectButtonFieldset(); + handleRejectButtonVisibility(); } rejectButton.addEventListener("click", handleRejectButton) - requestedSuborganizationField.addEventListener("blur", updateRejectButtonFieldset); - suborganizationCity.addEventListener("blur", updateRejectButtonFieldset); - suborganizationStateTerritory.addEventListener("change", updateRejectButtonFieldset); + requestedSuborganizationField.addEventListener("blur", handleRejectButtonVisibility); + suborganizationCity.addEventListener("blur", handleRejectButtonVisibility); + suborganizationStateTerritory.addEventListener("change", handleRejectButtonVisibility); } /** diff --git a/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js b/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js index f045fca47..55b42d10d 100644 --- a/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js +++ b/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js @@ -49,7 +49,13 @@ export function handlePortfolioSelection( const portfolioUrbanizationField = document.querySelector(".field-portfolio_urbanization"); const portfolioUrbanization = portfolioUrbanizationField.querySelector(".readonly"); const portfolioJsonUrl = document.getElementById("portfolio_json_url")?.value || null; - const rejectSuborganizationButtonFieldset = document.querySelector(".field-reject_suborganization_button"); + // These requested suborganization fields only exist on the domain request page + const rejectSuborganizationButton = document.querySelector("#clear-requested-suborganization"); + const requestedSuborganizationFieldInput = document.getElementById("id_requested_suborganization"); + const suborganizationCityInput = document.getElementById("id_suborganization_city"); + const suborganizationStateTerritoryInput = document.getElementById("id_suborganization_state_territory"); + + // Global var to track page load let isPageLoading = true; /** @@ -471,35 +477,26 @@ export function handlePortfolioSelection( if (suborganizationCity) showElement(suborganizationCity); if (suborganizationStateTerritory) showElement(suborganizationStateTerritory); - // Handle rejectSuborganizationButtonFieldset (display of the clear requested suborg button). + // == LOGIC FOR THE DOMAIN REQUEST PAGE == // + // Handle rejectSuborganizationButton (display of the clear requested suborg button). // Basically, this button should only be visible when we have data for suborg, city, and state_territory. // The function handleSuborgFieldsAndButtons() in domain-request-form.js handles doing this same logic // but on field input for city, state_territory, and the suborg field. // If it doesn't exist, don't do anything. - if (!rejectSuborganizationButtonFieldset){ - console.warn("updateSuborganizationFieldsDisplay() => Could not update rejectSuborganizationButtonFieldset") - return; - } - - // Initially show / hide the clear button only if there is data to clear - let requestedSuborganizationFieldInput = document.getElementById("id_requested_suborganization"); - let suborganizationCityInput = document.getElementById("id_suborganization_city"); - let suborganizationStateTerritoryInput = document.getElementById("id_suborganization_state_territory"); - if (!requestedSuborganizationFieldInput || !suborganizationCityInput || !suborganizationStateTerritoryInput) { - return; - } - - if (requestedSuborganizationFieldInput.value || suborganizationCityInput.value || suborganizationStateTerritoryInput.value) { - showElement(rejectSuborganizationButtonFieldset); - }else { - hideElement(rejectSuborganizationButtonFieldset); + if (rejectSuborganizationButton){ + if (requestedSuborganizationFieldInput?.value || suborganizationCityInput?.value || suborganizationStateTerritoryInput?.value) { + showElement(rejectSuborganizationButton); + }else { + hideElement(rejectSuborganizationButton); + } } } else { // Hide suborganization request fields if suborganization is selected if (requestedSuborganizationField) hideElement(requestedSuborganizationField); if (suborganizationCity) hideElement(suborganizationCity); if (suborganizationStateTerritory) hideElement(suborganizationStateTerritory); - if (rejectSuborganizationButtonFieldset) hideElement(rejectSuborganizationButtonFieldset); + // == LOGIC FOR THE DOMAIN REQUEST PAGE == // + if (rejectSuborganizationButton) hideElement(rejectSuborganizationButton); } } diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index 6eb2fac07..003714dfb 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -244,6 +244,7 @@ class Domain(TimeStampedModel, DomainHelper): is called in the validate function on the request/domain page throws- RegistryError or InvalidDomainError""" + return True if not cls.string_could_be_domain(domain): logger.warning("Not a valid domain: %s" % str(domain)) # throw invalid domain error so that it can be caught in diff --git a/src/registrar/templates/django/admin/domain_request_change_form.html b/src/registrar/templates/django/admin/domain_request_change_form.html index ee79aaeef..46965f236 100644 --- a/src/registrar/templates/django/admin/domain_request_change_form.html +++ b/src/registrar/templates/django/admin/domain_request_change_form.html @@ -20,7 +20,16 @@ {% url 'get-rejection-email-for-user-json' as url_2 %} {% for fieldset in adminform %} - {% include "django/admin/includes/domain_request_fieldset.html" with original_object=original %} + {% comment %} + TODO: this will eventually need to be changed to something like this + if we ever want to customize this file: + {% include "django/admin/includes/domain_information_fieldset.html" %} + + Use detail_table_fieldset as an example, or just extend it. + + original_object is just a variable name for "DomainInformation" or "DomainRequest" + {% endcomment %} + {% include "django/admin/includes/detail_table_fieldset.html" with original_object=original %} {% endfor %} {% endblock %} diff --git a/src/registrar/templates/django/admin/includes/detail_table_fieldset.html b/src/registrar/templates/django/admin/includes/detail_table_fieldset.html index d5b1130ab..0641c47c6 100644 --- a/src/registrar/templates/django/admin/includes/detail_table_fieldset.html +++ b/src/registrar/templates/django/admin/includes/detail_table_fieldset.html @@ -321,6 +321,25 @@ This is using a custom implementation fieldset.html (see admin/fieldset.html) {% else %} {% endif %} + {% elif field.field.name == "requested_suborganization" %} + {{ field.field }} +
    + +
    {% else %} {{ field.field }} {% endif %} diff --git a/src/registrar/templates/django/admin/includes/domain_request_fieldset.html b/src/registrar/templates/django/admin/includes/domain_request_fieldset.html deleted file mode 100644 index 3186fff1d..000000000 --- a/src/registrar/templates/django/admin/includes/domain_request_fieldset.html +++ /dev/null @@ -1,14 +0,0 @@ -{% extends "django/admin/includes/email_clipboard_fieldset.html" %} -{% load custom_filters %} -{% load static url_helpers %} -{% load i18n static %} - - -{% block field_readonly %} - {{ block.super }} - {% if field.field.name == "reject_suborganization_button" %} - - {% endif %} -{% endblock field_readonly %} \ No newline at end of file diff --git a/src/registrar/tests/test_admin_request.py b/src/registrar/tests/test_admin_request.py index b464eb538..439f4fab0 100644 --- a/src/registrar/tests/test_admin_request.py +++ b/src/registrar/tests/test_admin_request.py @@ -1644,7 +1644,6 @@ class TestDomainRequestAdmin(MockEppLib): "alternative_domains", "is_election_board", "status_history", - "reject_suborganization_button", "id", "created_at", "updated_at", @@ -1719,7 +1718,6 @@ class TestDomainRequestAdmin(MockEppLib): "alternative_domains", "is_election_board", "status_history", - "reject_suborganization_button", "federal_agency", "creator", "about_your_organization", @@ -1760,7 +1758,6 @@ class TestDomainRequestAdmin(MockEppLib): "alternative_domains", "is_election_board", "status_history", - "reject_suborganization_button", ] self.assertEqual(readonly_fields, expected_fields) From c59cb24f51ff5849c2af1076a1779fce95dccfcc Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 2 Jan 2025 09:34:38 -0700 Subject: [PATCH 34/44] Cleanup --- .../admin/includes/detail_table_fieldset.html | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/registrar/templates/django/admin/includes/detail_table_fieldset.html b/src/registrar/templates/django/admin/includes/detail_table_fieldset.html index 0641c47c6..bebdd6ea2 100644 --- a/src/registrar/templates/django/admin/includes/detail_table_fieldset.html +++ b/src/registrar/templates/django/admin/includes/detail_table_fieldset.html @@ -326,18 +326,15 @@ This is using a custom implementation fieldset.html (see admin/fieldset.html)
    {% else %} From 610d00b7a01080b85869dea1207c8b00c7858aa5 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 2 Jan 2025 10:55:06 -0700 Subject: [PATCH 35/44] Add unit tests --- src/registrar/admin.py | 3 + .../js/getgov-admin/domain-request-form.js | 1 - .../helpers-portfolio-dynamic-fields.js | 1 + src/registrar/models/domain.py | 1 - src/registrar/models/domain_request.py | 28 ++++-- src/registrar/tests/test_admin_request.py | 97 +++++++++++++++++++ 6 files changed, 119 insertions(+), 12 deletions(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 1476cee7e..52e214bb9 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -2003,6 +2003,9 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): custom_requested_domain.admin_order_field = "requested_domain__name" # type: ignore + # ------ Converted fields ------ + # These fields map to @Property methods and + # require these custom definitions to work properly @admin.display(description=_("Generic Org Type")) def converted_generic_org_type(self, obj): return obj.converted_generic_org_type_display diff --git a/src/registrar/assets/src/js/getgov-admin/domain-request-form.js b/src/registrar/assets/src/js/getgov-admin/domain-request-form.js index d82b2de8b..b3d14839e 100644 --- a/src/registrar/assets/src/js/getgov-admin/domain-request-form.js +++ b/src/registrar/assets/src/js/getgov-admin/domain-request-form.js @@ -645,7 +645,6 @@ function handleSuborgFieldsAndButtons() { const suborganizationCity = document.getElementById("id_suborganization_city"); const suborganizationStateTerritory = document.getElementById("id_suborganization_state_territory"); const rejectButton = document.querySelector("#clear-requested-suborganization"); - console.log("test12345678") // Ensure that every variable is present before proceeding if (!requestedSuborganizationField || !suborganizationCity || !suborganizationStateTerritory || !rejectButton) { diff --git a/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js b/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js index 55b42d10d..9a60e1684 100644 --- a/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js +++ b/src/registrar/assets/src/js/getgov-admin/helpers-portfolio-dynamic-fields.js @@ -495,6 +495,7 @@ export function handlePortfolioSelection( if (requestedSuborganizationField) hideElement(requestedSuborganizationField); if (suborganizationCity) hideElement(suborganizationCity); if (suborganizationStateTerritory) hideElement(suborganizationStateTerritory); + // == LOGIC FOR THE DOMAIN REQUEST PAGE == // if (rejectSuborganizationButton) hideElement(rejectSuborganizationButton); } diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index 003714dfb..6eb2fac07 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -244,7 +244,6 @@ class Domain(TimeStampedModel, DomainHelper): is called in the validate function on the request/domain page throws- RegistryError or InvalidDomainError""" - return True if not cls.string_could_be_domain(domain): logger.warning("Not a valid domain: %s" % str(domain)) # throw invalid domain error so that it can be caught in diff --git a/src/registrar/models/domain_request.py b/src/registrar/models/domain_request.py index f4e2a35a1..533a22ced 100644 --- a/src/registrar/models/domain_request.py +++ b/src/registrar/models/domain_request.py @@ -697,10 +697,18 @@ class DomainRequest(TimeStampedModel): portfolio__isnull=False, ).exists() ): - raise ValidationError( + # Add a field-level error to requested_suborganization. + # To pass in field-specific errors, we need to embed a dict of + # field: validationerror then pass that into a validation error itself. + # This is slightly confusing, but it just adds it at that level. + msg = ( "This suborganization already exists. " "Choose a new name, or select it directly if you would like to use it." ) + errors = { + "requested_suborganization": ValidationError(msg) + } + raise ValidationError(errors) elif self.portfolio and not self.sub_organization: # You cannot create a new suborganization without these fields required_suborg_fields = { @@ -708,16 +716,16 @@ class DomainRequest(TimeStampedModel): "suborganization_city": self.suborganization_city, "suborganization_state_territory": self.suborganization_state_territory, } - + # If at least one value is populated, enforce a all-or-nothing rule if any(bool(value) for value in required_suborg_fields.values()): - # Find which fields are empty - errors_dict = { - field_name: [f"This field is required when creating a new suborganization."] - for field_name, value in required_suborg_fields.items() - if not value - } - # Adds a validation error to each missing field - raise ValidationError({k: ValidationError(v, code="required") for k, v in errors_dict.items()}) + # Find which fields are empty and throw an error on the field + errors = {} + for field_name, value in required_suborg_fields.items(): + if not value: + errors[field_name] = ValidationError( + "This field is required when creating a new suborganization.", + ) + raise ValidationError(errors) def save(self, *args, **kwargs): """Save override for custom properties""" diff --git a/src/registrar/tests/test_admin_request.py b/src/registrar/tests/test_admin_request.py index 439f4fab0..a294c127f 100644 --- a/src/registrar/tests/test_admin_request.py +++ b/src/registrar/tests/test_admin_request.py @@ -1,5 +1,7 @@ from datetime import datetime +from django.forms import ValidationError from django.utils import timezone +from waffle.testutils import override_flag import re from django.test import RequestFactory, Client, TestCase, override_settings from django.contrib.admin.sites import AdminSite @@ -25,6 +27,7 @@ from registrar.models import ( Portfolio, AllowedEmail, ) +from registrar.models.suborganization import Suborganization from .common import ( MockSESClient, completed_domain_request, @@ -82,6 +85,7 @@ class TestDomainRequestAdmin(MockEppLib): Contact.objects.all().delete() Website.objects.all().delete() SeniorOfficial.objects.all().delete() + Suborganization.objects.all().delete() Portfolio.objects.all().delete() self.mock_client.EMAILS_SENT.clear() @@ -91,6 +95,99 @@ class TestDomainRequestAdmin(MockEppLib): User.objects.all().delete() AllowedEmail.objects.all().delete() + @override_flag("organization_feature", active=True) + @less_console_noise_decorator + def test_clean_validates_duplicate_suborganization(self): + """Tests that clean() prevents duplicate suborganization names within the same portfolio""" + # Create a portfolio and existing suborganization + portfolio = Portfolio.objects.create( + organization_name="Test Portfolio", + creator=self.superuser + ) + + # Create an existing suborganization + Suborganization.objects.create( + name="Existing Suborg", + portfolio=portfolio + ) + + # Create a domain request trying to use the same suborganization name + # (intentionally lowercase) + domain_request = completed_domain_request( + name="test1234.gov", + portfolio=portfolio, + requested_suborganization="existing suborg", + suborganization_city="Rome", + suborganization_state_territory=DomainRequest.StateTerritoryChoices.OHIO, + ) + + # Assert that the validation error is raised + with self.assertRaises(ValidationError) as err: + domain_request.clean() + + self.assertIn( + "This suborganization already exists", + str(err.exception) + ) + + # Test that a different name is allowed. Should not raise a error. + domain_request.requested_suborganization = "New Suborg" + domain_request.clean() + + @less_console_noise_decorator + @override_flag("organization_feature", active=True) + def test_clean_validates_partial_suborganization_fields(self): + """Tests that clean() enforces all-or-nothing rule for suborganization fields""" + portfolio = Portfolio.objects.create( + organization_name="Test Portfolio", + creator=self.superuser + ) + + # Create domain request with only city filled out + domain_request = completed_domain_request( + name="test1234.gov", + portfolio=portfolio, + suborganization_city="Test City", + ) + + # Assert validation error is raised with correct missing fields + with self.assertRaises(ValidationError) as err: + domain_request.clean() + + error_dict = err.exception.error_dict + expected_missing = ["requested_suborganization", "suborganization_state_territory"] + + # Verify correct fields are flagged as required + self.assertEqual( + sorted(error_dict.keys()), + sorted(expected_missing) + ) + + # Verify error message + for field in expected_missing: + self.assertEqual( + str(error_dict[field][0].message), + "This field is required when creating a new suborganization." + ) + + # When all data is passed in, this should validate correctly + domain_request.requested_suborganization = "Complete Suborg" + domain_request.suborganization_state_territory = DomainRequest.StateTerritoryChoices.OHIO + # Assert that no ValidationError is raised + try: + domain_request.clean() + except ValidationError as e: + self.fail(f"ValidationError was raised unexpectedly: {e}") + + # Also ensure that no validation error is raised if nothing is passed in at all + domain_request.suborganization_city = None + domain_request.requested_suborganization = None + domain_request.suborganization_state_territory = None + try: + domain_request.clean() + except ValidationError as e: + self.fail(f"ValidationError was raised unexpectedly: {e}") + @less_console_noise_decorator def test_domain_request_senior_official_is_alphabetically_sorted(self): """Tests if the senior offical dropdown is alphanetically sorted in the django admin display""" From ef8d8f17bf29a83ed3a18e2fa1c8b710be4d9836 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 2 Jan 2025 11:51:05 -0700 Subject: [PATCH 36/44] Add unit test for requesting entity page --- src/package-lock.json | 55 ++++++++++++++++++--- src/registrar/models/domain_request.py | 4 +- src/registrar/tests/test_admin_request.py | 44 ++++++----------- src/registrar/tests/test_views_portfolio.py | 40 +++++++++++++++ 4 files changed, 103 insertions(+), 40 deletions(-) diff --git a/src/package-lock.json b/src/package-lock.json index d78b5132f..e93413312 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -6921,6 +6921,16 @@ "validate-npm-package-license": "^3.0.1" } }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -7297,6 +7307,39 @@ "node": ">= 12" } }, + "node_modules/pa11y/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pa11y/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pa11y/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, "node_modules/parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", @@ -8845,15 +8888,13 @@ } }, "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" } }, "node_modules/semver-greatest-satisfied-range": { @@ -10623,4 +10664,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/registrar/models/domain_request.py b/src/registrar/models/domain_request.py index 533a22ced..3d3aac769 100644 --- a/src/registrar/models/domain_request.py +++ b/src/registrar/models/domain_request.py @@ -705,9 +705,7 @@ class DomainRequest(TimeStampedModel): "This suborganization already exists. " "Choose a new name, or select it directly if you would like to use it." ) - errors = { - "requested_suborganization": ValidationError(msg) - } + errors = {"requested_suborganization": ValidationError(msg)} raise ValidationError(errors) elif self.portfolio and not self.sub_organization: # You cannot create a new suborganization without these fields diff --git a/src/registrar/tests/test_admin_request.py b/src/registrar/tests/test_admin_request.py index a294c127f..8a2f49ee7 100644 --- a/src/registrar/tests/test_admin_request.py +++ b/src/registrar/tests/test_admin_request.py @@ -100,17 +100,11 @@ class TestDomainRequestAdmin(MockEppLib): def test_clean_validates_duplicate_suborganization(self): """Tests that clean() prevents duplicate suborganization names within the same portfolio""" # Create a portfolio and existing suborganization - portfolio = Portfolio.objects.create( - organization_name="Test Portfolio", - creator=self.superuser - ) - + portfolio = Portfolio.objects.create(organization_name="Test Portfolio", creator=self.superuser) + # Create an existing suborganization - Suborganization.objects.create( - name="Existing Suborg", - portfolio=portfolio - ) - + Suborganization.objects.create(name="Existing Suborg", portfolio=portfolio) + # Create a domain request trying to use the same suborganization name # (intentionally lowercase) domain_request = completed_domain_request( @@ -124,11 +118,8 @@ class TestDomainRequestAdmin(MockEppLib): # Assert that the validation error is raised with self.assertRaises(ValidationError) as err: domain_request.clean() - - self.assertIn( - "This suborganization already exists", - str(err.exception) - ) + + self.assertIn("This suborganization already exists", str(err.exception)) # Test that a different name is allowed. Should not raise a error. domain_request.requested_suborganization = "New Suborg" @@ -138,11 +129,8 @@ class TestDomainRequestAdmin(MockEppLib): @override_flag("organization_feature", active=True) def test_clean_validates_partial_suborganization_fields(self): """Tests that clean() enforces all-or-nothing rule for suborganization fields""" - portfolio = Portfolio.objects.create( - organization_name="Test Portfolio", - creator=self.superuser - ) - + portfolio = Portfolio.objects.create(organization_name="Test Portfolio", creator=self.superuser) + # Create domain request with only city filled out domain_request = completed_domain_request( name="test1234.gov", @@ -153,21 +141,17 @@ class TestDomainRequestAdmin(MockEppLib): # Assert validation error is raised with correct missing fields with self.assertRaises(ValidationError) as err: domain_request.clean() - + error_dict = err.exception.error_dict expected_missing = ["requested_suborganization", "suborganization_state_territory"] - + # Verify correct fields are flagged as required - self.assertEqual( - sorted(error_dict.keys()), - sorted(expected_missing) - ) - + self.assertEqual(sorted(error_dict.keys()), sorted(expected_missing)) + # Verify error message for field in expected_missing: self.assertEqual( - str(error_dict[field][0].message), - "This field is required when creating a new suborganization." + str(error_dict[field][0].message), "This field is required when creating a new suborganization." ) # When all data is passed in, this should validate correctly @@ -178,7 +162,7 @@ class TestDomainRequestAdmin(MockEppLib): domain_request.clean() except ValidationError as e: self.fail(f"ValidationError was raised unexpectedly: {e}") - + # Also ensure that no validation error is raised if nothing is passed in at all domain_request.suborganization_city = None domain_request.requested_suborganization = None diff --git a/src/registrar/tests/test_views_portfolio.py b/src/registrar/tests/test_views_portfolio.py index 01383ae77..2f02f9ed9 100644 --- a/src/registrar/tests/test_views_portfolio.py +++ b/src/registrar/tests/test_views_portfolio.py @@ -2268,6 +2268,46 @@ class TestRequestingEntity(WebTest): User.objects.all().delete() super().tearDown() + @less_console_noise_decorator + @override_flag("organization_feature", active=True) + @override_flag("organization_requests", active=True) + def test_form_validates_duplicate_suborganization(self): + """Tests that form validation prevents duplicate suborganization names within the same portfolio""" + # Create an existing suborganization + suborganization = Suborganization.objects.create(name="Existing Suborg", portfolio=self.portfolio) + + # Start the domain request process + response = self.app.get(reverse("domain-request:start")) + session_id = self.app.cookies[settings.SESSION_COOKIE_NAME] + + # Navigate past the intro page + self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) + form = response.forms[0] + response = form.submit().follow() + + # Fill out the requesting entity form + form = response.forms[0] + form["portfolio_requesting_entity-requesting_entity_is_suborganization"] = "True" + form["portfolio_requesting_entity-is_requesting_new_suborganization"] = "True" + form["portfolio_requesting_entity-requested_suborganization"] = suborganization.name.lower() + form["portfolio_requesting_entity-suborganization_city"] = "Eggnog" + form["portfolio_requesting_entity-suborganization_state_territory"] = DomainRequest.StateTerritoryChoices.OHIO + + # Submit form and verify error + session_id = self.app.cookies[settings.SESSION_COOKIE_NAME] + self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) + response = form.submit() + self.assertContains(response, "This suborganization already exists") + + # Test that a different name is allowed + form["portfolio_requesting_entity-requested_suborganization"] = "New Suborg" + session_id = self.app.cookies[settings.SESSION_COOKIE_NAME] + self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) + response = form.submit().follow() + + # Verify successful submission by checking we're on the next page + self.assertContains(response, "Current websites") + @override_flag("organization_feature", active=True) @override_flag("organization_requests", active=True) @less_console_noise_decorator From 3b7746a409db5ba14ecfdc1b2010eb59db8d755b Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 2 Jan 2025 11:51:42 -0700 Subject: [PATCH 37/44] Update package-lock.json --- src/package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/package-lock.json b/src/package-lock.json index e93413312..22fb31857 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -10664,4 +10664,4 @@ } } } -} \ No newline at end of file +} From 419179f69d3ea9135104cb3b2e4d801a07834df4 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 2 Jan 2025 12:05:03 -0700 Subject: [PATCH 38/44] Remove junk --- src/registrar/models/suborganization.py | 1 + src/registrar/tests/test_admin_request.py | 2 +- src/registrar/tests/test_reports.py | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/registrar/models/suborganization.py b/src/registrar/models/suborganization.py index 78689799c..087490244 100644 --- a/src/registrar/models/suborganization.py +++ b/src/registrar/models/suborganization.py @@ -1,4 +1,5 @@ from django.db import models + from registrar.models.domain_request import DomainRequest from .utility.time_stamped_model import TimeStampedModel diff --git a/src/registrar/tests/test_admin_request.py b/src/registrar/tests/test_admin_request.py index 8a2f49ee7..efb1331df 100644 --- a/src/registrar/tests/test_admin_request.py +++ b/src/registrar/tests/test_admin_request.py @@ -26,8 +26,8 @@ from registrar.models import ( SeniorOfficial, Portfolio, AllowedEmail, + Suborganization, ) -from registrar.models.suborganization import Suborganization from .common import ( MockSESClient, completed_domain_request, diff --git a/src/registrar/tests/test_reports.py b/src/registrar/tests/test_reports.py index 88e408ed2..4a41238c7 100644 --- a/src/registrar/tests/test_reports.py +++ b/src/registrar/tests/test_reports.py @@ -870,7 +870,6 @@ class MemberExportTest(MockDbForIndividualTests, MockEppLib): csv_file.seek(0) # Read the content into a variable csv_content = csv_file.read() - self.maxDiff = None expected_content = ( # Header "Email,Organization admin,Invited by,Joined date,Last active,Domain requests," From 54e5b7f20c7f30fafeba2342f3084605ba6b273c Mon Sep 17 00:00:00 2001 From: Erin Song <121973038+erinysong@users.noreply.github.com> Date: Thu, 2 Jan 2025 12:34:17 -0800 Subject: [PATCH 39/44] Add whitespace to prompt security check workflow --- src/package-lock.json | 53 +++++-------------------------------------- 1 file changed, 6 insertions(+), 47 deletions(-) diff --git a/src/package-lock.json b/src/package-lock.json index 22fb31857..d78b5132f 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -6921,16 +6921,6 @@ "validate-npm-package-license": "^3.0.1" } }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -7307,39 +7297,6 @@ "node": ">= 12" } }, - "node_modules/pa11y/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/pa11y/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/pa11y/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, "node_modules/parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", @@ -8888,13 +8845,15 @@ } }, "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "license": "ISC", "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/semver-greatest-satisfied-range": { From 8f0fa1fcd88b89503d4240da73ac2e493d7fed20 Mon Sep 17 00:00:00 2001 From: Erin Song <121973038+erinysong@users.noreply.github.com> Date: Thu, 2 Jan 2025 12:37:44 -0800 Subject: [PATCH 40/44] Update python dependencies --- src/Pipfile.lock | 1317 +++++++++++++++++++++--------------------- src/requirements.txt | 68 +-- 2 files changed, 703 insertions(+), 682 deletions(-) diff --git a/src/Pipfile.lock b/src/Pipfile.lock index 56daf5db5..76f2c914d 100644 --- a/src/Pipfile.lock +++ b/src/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "2799ab9e493352740c6946e604ccc075c5c16359c809753296091bbe2b9fd837" + "sha256": "07f7bc9bda4099f96b18f8f063b487b121b82ae01de06a7f2e9013d56098a421" }, "pipfile-spec": 6, "requires": {}, @@ -32,20 +32,20 @@ }, "boto3": { "hashes": [ - "sha256:2bf7e7f376aee52155fc4ae4487f29333a6bcdf3a05c3bc4fede10b972d951a6", - "sha256:e74bc6d69c04ca611b7f58afe08e2ded6cb6504a4a80557b656abeefee395f88" + "sha256:ba391982f6cada136c5bba99e85d7fe1bc4e157c53a22a78e4aca35d1b39152e", + "sha256:eecef248f8743ab30036cd9c916808a0892fc9036e1a35434d8222060c08bbd2" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.35.41" + "version": "==1.35.91" }, "botocore": { "hashes": [ - "sha256:8a09a32136df8768190a6c92f0240cd59c30deb99c89026563efadbbed41fa00", - "sha256:915c4d81e3a0be3b793c1e2efdf19af1d0a9cd4a2d8de08ee18216c14d67764b" + "sha256:7b0b9c5954701fff4d2c516918f45641b04ff4ca92bbd9f5b37c0b80f8c14220", + "sha256:93de9d0f52f7e36a2c190d55520d3b2654f32c5a628fdd484bffa00bc7865e1d" ], "markers": "python_version >= '3.8'", - "version": "==1.35.41" + "version": "==1.35.91" }, "cachetools": { "hashes": [ @@ -58,11 +58,11 @@ }, "certifi": { "hashes": [ - "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", - "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9" + "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", + "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db" ], "markers": "python_version >= '3.6'", - "version": "==2024.8.30" + "version": "==2024.12.14" }, "cfenv": { "hashes": [ @@ -142,152 +142,139 @@ "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87", "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b" ], - "markers": "platform_python_implementation != 'PyPy'", + "markers": "python_version >= '3.8'", "version": "==1.17.1" }, "charset-normalizer": { "hashes": [ - "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621", - "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", - "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", - "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", - "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", - "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", - "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", - "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d", - "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", - "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", - "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", - "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", - "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab", - "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be", - "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", - "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", - "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0", - "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2", - "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62", - "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62", - "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", - "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", - "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", - "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", - "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455", - "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858", - "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", - "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", - "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", - "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", - "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", - "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea", - "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", - "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", - "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", - "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", - "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd", - "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", - "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242", - "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee", - "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", - "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", - "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51", - "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", - "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8", - "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", - "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613", - "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742", - "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", - "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", - "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", - "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", - "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", - "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", - "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", - "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", - "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417", - "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", - "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", - "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca", - "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa", - "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", - "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149", - "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41", - "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574", - "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0", - "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f", - "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", - "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654", - "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3", - "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19", - "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", - "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578", - "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", - "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", - "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51", - "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", - "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", - "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a", - "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", - "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade", - "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", - "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", - "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6", - "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", - "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", - "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6", - "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2", - "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12", - "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf", - "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", - "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7", - "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", - "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", - "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b", - "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", - "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", - "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4", - "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", - "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", - "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a", - "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748", - "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", - "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", - "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482" + "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537", + "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa", + "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a", + "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294", + "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b", + "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", + "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", + "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", + "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4", + "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", + "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2", + "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", + "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", + "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", + "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", + "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", + "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", + "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496", + "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", + "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", + "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e", + "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a", + "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4", + "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca", + "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78", + "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", + "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5", + "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", + "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", + "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", + "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765", + "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6", + "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", + "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", + "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", + "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd", + "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c", + "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", + "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", + "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", + "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770", + "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824", + "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f", + "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf", + "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487", + "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d", + "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd", + "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", + "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534", + "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", + "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", + "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", + "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd", + "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", + "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9", + "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", + "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", + "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d", + "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", + "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", + "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", + "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7", + "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", + "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", + "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8", + "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41", + "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", + "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", + "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", + "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", + "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", + "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", + "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", + "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", + "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", + "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", + "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", + "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e", + "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6", + "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", + "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", + "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e", + "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", + "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", + "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c", + "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", + "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", + "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089", + "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", + "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e", + "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", + "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616" ], - "markers": "python_full_version >= '3.7.0'", - "version": "==3.4.0" + "markers": "python_version >= '3.7'", + "version": "==3.4.1" }, "cryptography": { "hashes": [ - "sha256:014f58110f53237ace6a408b5beb6c427b64e084eb451ef25a28308270086494", - "sha256:1bbcce1a551e262dfbafb6e6252f1ae36a248e615ca44ba302df077a846a8806", - "sha256:203e92a75716d8cfb491dc47c79e17d0d9207ccffcbcb35f598fbe463ae3444d", - "sha256:27e613d7077ac613e399270253259d9d53872aaf657471473ebfc9a52935c062", - "sha256:2bd51274dcd59f09dd952afb696bf9c61a7a49dfc764c04dd33ef7a6b502a1e2", - "sha256:38926c50cff6f533f8a2dae3d7f19541432610d114a70808f0926d5aaa7121e4", - "sha256:511f4273808ab590912a93ddb4e3914dfd8a388fed883361b02dea3791f292e1", - "sha256:58d4e9129985185a06d849aa6df265bdd5a74ca6e1b736a77959b498e0505b85", - "sha256:5b43d1ea6b378b54a1dc99dd8a2b5be47658fe9a7ce0a58ff0b55f4b43ef2b84", - "sha256:61ec41068b7b74268fa86e3e9e12b9f0c21fcf65434571dbb13d954bceb08042", - "sha256:666ae11966643886c2987b3b721899d250855718d6d9ce41b521252a17985f4d", - "sha256:68aaecc4178e90719e95298515979814bda0cbada1256a4485414860bd7ab962", - "sha256:7c05650fe8023c5ed0d46793d4b7d7e6cd9c04e68eabe5b0aeea836e37bdcec2", - "sha256:80eda8b3e173f0f247f711eef62be51b599b5d425c429b5d4ca6a05e9e856baa", - "sha256:8385d98f6a3bf8bb2d65a73e17ed87a3ba84f6991c155691c51112075f9ffc5d", - "sha256:88cce104c36870d70c49c7c8fd22885875d950d9ee6ab54df2745f83ba0dc365", - "sha256:9d3cdb25fa98afdd3d0892d132b8d7139e2c087da1712041f6b762e4f807cc96", - "sha256:a575913fb06e05e6b4b814d7f7468c2c660e8bb16d8d5a1faf9b33ccc569dd47", - "sha256:ac119bb76b9faa00f48128b7f5679e1d8d437365c5d26f1c2c3f0da4ce1b553d", - "sha256:c1332724be35d23a854994ff0b66530119500b6053d0bd3363265f7e5e77288d", - "sha256:d03a475165f3134f773d1388aeb19c2d25ba88b6a9733c5c590b9ff7bbfa2e0c", - "sha256:d75601ad10b059ec832e78823b348bfa1a59f6b8d545db3a24fd44362a1564cb", - "sha256:de41fd81a41e53267cb020bb3a7212861da53a7d39f863585d13ea11049cf277", - "sha256:e710bf40870f4db63c3d7d929aa9e09e4e7ee219e703f949ec4073b4294f6172", - "sha256:ea25acb556320250756e53f9e20a4177515f012c9eaea17eb7587a8c4d8ae034", - "sha256:f98bf604c82c416bc829e490c700ca1553eafdf2912a91e23a79d97d9801372a", - "sha256:fba1007b3ef89946dbbb515aeeb41e30203b004f0b4b00e5e16078b518563289" + "sha256:1923cb251c04be85eec9fda837661c67c1049063305d6be5721643c22dd4e2b7", + "sha256:37d76e6863da3774cd9db5b409a9ecfd2c71c981c38788d3fcfaf177f447b731", + "sha256:3c672a53c0fb4725a29c303be906d3c1fa99c32f58abe008a82705f9ee96f40b", + "sha256:404fdc66ee5f83a1388be54300ae978b2efd538018de18556dde92575e05defc", + "sha256:4ac4c9f37eba52cb6fbeaf5b59c152ea976726b865bd4cf87883a7e7006cc543", + "sha256:62901fb618f74d7d81bf408c8719e9ec14d863086efe4185afd07c352aee1d2c", + "sha256:660cb7312a08bc38be15b696462fa7cc7cd85c3ed9c576e81f4dc4d8b2b31591", + "sha256:708ee5f1bafe76d041b53a4f95eb28cdeb8d18da17e597d46d7833ee59b97ede", + "sha256:761817a3377ef15ac23cd7834715081791d4ec77f9297ee694ca1ee9c2c7e5eb", + "sha256:831c3c4d0774e488fdc83a1923b49b9957d33287de923d58ebd3cec47a0ae43f", + "sha256:84111ad4ff3f6253820e6d3e58be2cc2a00adb29335d4cacb5ab4d4d34f2a123", + "sha256:8b3e6eae66cf54701ee7d9c83c30ac0a1e3fa17be486033000f2a73a12ab507c", + "sha256:9e6fc8a08e116fb7c7dd1f040074c9d7b51d74a8ea40d4df2fc7aa08b76b9e6c", + "sha256:a01956ddfa0a6790d594f5b34fc1bfa6098aca434696a03cfdbe469b8ed79285", + "sha256:abc998e0c0eee3c8a1904221d3f67dcfa76422b23620173e28c11d3e626c21bd", + "sha256:b15492a11f9e1b62ba9d73c210e2416724633167de94607ec6069ef724fad092", + "sha256:be4ce505894d15d5c5037167ffb7f0ae90b7be6f2a98f9a5c3442395501c32fa", + "sha256:c5eb858beed7835e5ad1faba59e865109f3e52b3783b9ac21e7e47dc5554e289", + "sha256:cd4e834f340b4293430701e772ec543b0fbe6c2dea510a5286fe0acabe153a02", + "sha256:d2436114e46b36d00f8b72ff57e598978b37399d2786fd39793c36c6d5cb1c64", + "sha256:eb33480f1bad5b78233b0ad3e1b0be21e8ef1da745d8d2aecbb20671658b9053", + "sha256:eca27345e1214d1b9f9490d200f9db5a874479be914199194e746c893788d417", + "sha256:ed3534eb1090483c96178fcb0f8893719d96d5274dfde98aa6add34614e97c8e", + "sha256:f3f6fdfa89ee2d9d496e2c087cebef9d4fcbb0ad63c40e821b39f74bf48d9c5e", + "sha256:f53c2c87e0fb4b0c00fa9571082a057e37690a8f12233306161c8f4b819960b7", + "sha256:f5e7cb1e5e56ca0933b4873c0220a78b773b24d40d186b6738080b73d3d0a756", + "sha256:f677e1268c4e23420c3acade68fac427fffcb8d19d7df95ed7ad17cdef8404f4" ], - "markers": "python_version >= '3.7'", - "version": "==43.0.1" + "markers": "python_version >= '3.7' and python_full_version not in '3.9.0, 3.9.1'", + "version": "==44.0.0" }, "defusedxml": { "hashes": [ @@ -299,18 +286,18 @@ }, "diff-match-patch": { "hashes": [ - "sha256:953019cdb9c9d2c9e47b5b12bcff3cf4746fc4598eb406076fa1fc27e6a1f15c", - "sha256:dce43505fb7b1b317de7195579388df0746d90db07015ed47a85e5e44930ef93" + "sha256:93cea333fb8b2bc0d181b0de5e16df50dd344ce64828226bda07728818936782", + "sha256:beae57a99fa48084532935ee2968b8661db861862ec82c6f21f4acdd6d835073" ], "markers": "python_version >= '3.7'", - "version": "==20230430" + "version": "==20241021" }, "dj-database-url": { "hashes": [ - "sha256:3e792567b0aa9a4884860af05fe2aa4968071ad351e033b6db632f97ac6db9de", - "sha256:9f9b05058ddf888f1e6f840048b8d705ff9395e3b52a07165daa3d8b9360551b" + "sha256:ae52e8e634186b57e5a45e445da5dc407a819c2ceed8a53d1fac004cc5288787", + "sha256:bb0d414ba0ac5cd62773ec7f86f8cc378a9dbb00a80884c2fc08cc570452521e" ], - "version": "==2.2.0" + "version": "==2.3.0" }, "dj-email-url": { "hashes": [ @@ -321,12 +308,12 @@ }, "django": { "hashes": [ - "sha256:a2d4c4d4ea0b6f0895acde632071aff6400bfc331228fc978b05452a0ff3e9f1", - "sha256:b1260ed381b10a11753c73444408e19869f3241fc45c985cd55a30177c789d13" + "sha256:3a93350214ba25f178d4045c0786c61573e7dbfa3c509b3551374f1e11ba8de0", + "sha256:6b56d834cc94c8b21a8f4e775064896be3b4a4ca387f2612d4406a5927cd2fdc" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==4.2.10" + "version": "==4.2.17" }, "django-admin-multiple-choice-list-filter": { "hashes": [ @@ -362,12 +349,12 @@ }, "django-cors-headers": { "hashes": [ - "sha256:28c1ded847aa70208798de3e42422a782f427b8b720e8d7319d34b654b5978e6", - "sha256:6c01a85cf1ec779a7bde621db853aa3ce5c065a5ba8e27df7a9f9e8dac310f4f" + "sha256:14d76b4b4c8d39375baeddd89e4f08899051eeaf177cb02a29bd6eae8cf63aa8", + "sha256:8edbc0497e611c24d5150e0055d3b178c6534b8ed826fb6f53b21c63f5d48ba3" ], "index": "pypi", "markers": "python_version >= '3.9'", - "version": "==4.5.0" + "version": "==4.6.0" }, "django-csp": { "hashes": [ @@ -387,12 +374,12 @@ }, "django-import-export": { "hashes": [ - "sha256:16ecc5a9f0df46bde6eb278a3e65ebda0ee1db55656f36440e9fb83f40ab85a3", - "sha256:730ae2443a02b1ba27d8dba078a27ae9123adfcabb78161b4f130843607b3df9" + "sha256:91b47c9a2701a5b039667df5c46ee682a41bb224ac215a0e66b177a459e35983", + "sha256:b261f44aedf572a69f975655afba15bff1e354eddd91d9c1bbd32d3cee44168d" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==4.1.1" + "markers": "python_version >= '3.9'", + "version": "==4.3.3" }, "django-login-required-middleware": { "hashes": [ @@ -414,12 +401,12 @@ }, "django-waffle": { "hashes": [ - "sha256:5979a2f3dd674ef7086480525b39651fc2045427f6d8e6a614192656d3402c5b", - "sha256:e49d7d461d89f3bd8e53f20efe39310acca8f275c9888495e68e195345bf18b1" + "sha256:774f45b929627c9d303620c85419ce1da54066f2082d741af014f5bbd747e372", + "sha256:97709550f4e75ce2a20b13e29f39777e1439a968569f2ee89398ca368afd586c" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==4.1.0" + "version": "==4.2.0" }, "django-widget-tweaks": { "hashes": [ @@ -435,20 +422,20 @@ "django" ], "hashes": [ - "sha256:069727a8f73d8ba8d033d3cd95c0da231d44f38f1da773bf076cef168d312ee8", - "sha256:e0bcfd41c718c07a7db422f9109e490746450da38793fe4ee197f397b9343435" + "sha256:9d2080cf25807a26fc0d4301e2d7b62c64fbf547540f21e3a30cc02bc5fbe948", + "sha256:e068ae3174cef52ba4b95ead22e639056a02465f616e62323e04ae08e86a75a4" ], "markers": "python_version >= '3.8'", - "version": "==11.0.0" + "version": "==11.2.1" }, "faker": { "hashes": [ - "sha256:8760fbb34564fbb2f394345eef24aec5b8f6506b6cfcefe8195ed66dd1032bdb", - "sha256:e8a15fd1b0f72992b008f5ea94c70d3baa0cb51b0d5a0e899c17b1d1b23d2771" + "sha256:1c925fc0e86a51fc46648b504078c88d0cd48da1da2595c4e712841cab43a1e4", + "sha256:d30c5f0e2796b8970de68978365247657486eb0311c5abe88d0b895b68dff05d" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==30.3.0" + "version": "==33.1.0" }, "fred-epplib": { "git": "https://github.com/cisagov/epplib.git", @@ -466,53 +453,53 @@ "sha256:929292d34f5872e70396626ef385ec22355a1fae8ad29e1a734c3e43f9fbc216", "sha256:bd2968309307861edae1458a4f8a4f3598c03be43b97521076aebf5d94c07b05" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.0.0" }, "gevent": { "hashes": [ - "sha256:013150cc0f00f0a06dd898463ad9ebc43bd9c70c7fe35555c77d83fe6f758225", - "sha256:0814a5a7084e0bd357392e44e2a8bd72fc56fbdc3da0ff492ebb310c10fc95e6", - "sha256:103097b39764a0a02f1a051225ea6b4c64a53dd37603424ca8a1e09be63a460b", - "sha256:16bf432b274795b360d88b38cbffe0a6410450c94bfa172548bf1f512cf448c2", - "sha256:1a5012b7d047b16470063f0b8d003530e77362809f38cd7e601efb625c7ca71e", - "sha256:22bc6efb0f9fbb1c2e005ef1b94374568945c711bfb92f85916f66a819a5e6d0", - "sha256:377c02d0ddae3ebf843d6f453943602102bb186b09f1c78a2247e5dbf0e07b1c", - "sha256:421cfeacae2555b11318c6ee11f34bc0a9517657068d8911c916d55a85362ce2", - "sha256:44174aa4dae4db158e6f11a4ea696f1991d43ccc1634aa0c189daf03a9ced5d7", - "sha256:44dd79cfefea24f9bb630844a25047c3807e02722436e826ef2aed3d646190c1", - "sha256:4e3fbaf484ee68437f0ec589bdb1dd6f1dccc01fd6b72eac707e858b407521fa", - "sha256:4f0e6c49aac1c182be15a43d94e3b58c253d830c5b54dc93d6130e6987278611", - "sha256:539af6b66c6b9faca2cdd903f0a7564c85053f1faf95e9a37702df578ac37085", - "sha256:562b66d8b061b9cfae1bc704b0cd5d2b255628d86c3639ddc16e4ffa3ebf6e7a", - "sha256:5bb80c88f572a11156f258333c0e7b1f80d0746a03784600017901a2f1aa584a", - "sha256:5d1db7bc758455e6f6406d66e8b276b80dda5645877392a100d1ed7dda6aa7ad", - "sha256:618c4869e8140fd955b4620b10bc5a92ef1d62ae20aef38c1af7d892ee1bd996", - "sha256:6a93f249a40bda8c42cbeefff9582b22bb1dd769da56b4cbb824038366c4202c", - "sha256:6b9da562d7d7707d5561ecf4a27a361fd9f4856f39b8491a0753c89d8f39674c", - "sha256:73b65ee9a73a35fb68d96899895162beef19d86c1bcbe6f8f92eb0bd18c1d891", - "sha256:7b5f10ac866d3432a829a3a4446489be1fa3648f3140f9373fe99440a2e05682", - "sha256:81b4915081d148a31b64ad0314d2f609920b8ae6a24d9a7e4ddaab7c1fe998e7", - "sha256:90f9bc542f76efc56e5e76b420abaff42baf585db48a9fc0ac8edd6a16d9e60f", - "sha256:96e7bab9de56e0aca3858b8bc9c71f4eb0c0e12b7cf3cbfd170b62ce68cf71d7", - "sha256:975699ac5701d7ec1c633f2067deecea8711dc2a8683530aed260dd641274791", - "sha256:9f74faefea1acb398f057ed31ee9333e100bdae978b1e4c3b6a27d05df66e588", - "sha256:a11db551555c58606ed3dfe359a9a502e44350ed3ecbd59cbe7b0093bd020418", - "sha256:a6a04df4732bb7fdf9969ddee9a16a829e7971692fefdcb5baca760976d23e04", - "sha256:a72a7cb67764adafbac7ddeeffe539a738309068e2b2ac89cbd2f498383ce537", - "sha256:aabffb8b86fb95cb1ee5dffa315c9bd68fe20a7fe7260c0328679723b0257b7c", - "sha256:bc181db59d53e407650ebf44e63ff429c7bc25f9c346edddce1bdff1af436617", - "sha256:dd9c966e5fd8d7b0a54a130c5ad38ef581fd93ff4c44b6e73767519860da6ebe", - "sha256:ec800c25f09a7e031f2fbc3b17b4a4a0b54085c7532ac51b4c7ecef6d3ff8fc3", - "sha256:f0d6cfff74be4efcafecd374e094a8fed9e0d68efe90109d374ef5d8f18aa21a", - "sha256:f57b7a02e83d6e4a205cace6dd63e16b61a641a1da9366d9ec4f2b849430700f", - "sha256:fa190663f964583c8dbbab06bc863966e6f7eceaac8aa67c3ac0fae0a0a73b80", - "sha256:fa4cba4a8acbb71dd4215be8517879e4217c0746f7af2637330e7269694f53f2", - "sha256:fd9b670da1b7160e660cbba7f52e206892b97f61d8ff1872ce99dfaa9b475420" + "sha256:1c3443b0ed23dcb7c36a748d42587168672953d368f2956b17fad36d43b58836", + "sha256:1d4fadc319b13ef0a3c44d2792f7918cf1bca27cacd4d41431c22e6b46668026", + "sha256:1ea50009ecb7f1327347c37e9eb6561bdbc7de290769ee1404107b9a9cba7cf1", + "sha256:2142704c2adce9cd92f6600f371afb2860a446bfd0be5bd86cca5b3e12130766", + "sha256:351d1c0e4ef2b618ace74c91b9b28b3eaa0dd45141878a964e03c7873af09f62", + "sha256:356b73d52a227d3313f8f828025b665deada57a43d02b1cf54e5d39028dbcf8d", + "sha256:3d882faa24f347f761f934786dde6c73aa6c9187ee710189f12dcc3a63ed4a50", + "sha256:58851f23c4bdb70390f10fc020c973ffcf409eb1664086792c8b1e20f25eef43", + "sha256:68bee86b6e1c041a187347ef84cf03a792f0b6c7238378bf6ba4118af11feaae", + "sha256:7398c629d43b1b6fd785db8ebd46c0a353880a6fab03d1cf9b6788e7240ee32e", + "sha256:816b3883fa6842c1cf9d2786722014a0fd31b6312cca1f749890b9803000bad6", + "sha256:81d918e952954675f93fb39001da02113ec4d5f4921bf5a0cc29719af6824e5d", + "sha256:85329d556aaedced90a993226d7d1186a539c843100d393f2349b28c55131c85", + "sha256:8619d5c888cb7aebf9aec6703e410620ef5ad48cdc2d813dd606f8aa7ace675f", + "sha256:8bd1419114e9e4a3ed33a5bad766afff9a3cf765cb440a582a1b3a9bc80c1aca", + "sha256:92e0d7759de2450a501effd99374256b26359e801b2d8bf3eedd3751973e87f5", + "sha256:92fe5dfee4e671c74ffaa431fd7ffd0ebb4b339363d24d0d944de532409b935e", + "sha256:97e2f3999a5c0656f42065d02939d64fffaf55861f7d62b0107a08f52c984897", + "sha256:9d3b249e4e1f40c598ab8393fc01ae6a3b4d51fc1adae56d9ba5b315f6b2d758", + "sha256:a3d75fa387b69c751a3d7c5c3ce7092a171555126e136c1d21ecd8b50c7a6e46", + "sha256:a5f1701ce0f7832f333dd2faf624484cbac99e60656bfbb72504decd42970f0f", + "sha256:b24d800328c39456534e3bc3e1684a28747729082684634789c2f5a8febe7671", + "sha256:b5efe72e99b7243e222ba0c2c2ce9618d7d36644c166d63373af239da1036bab", + "sha256:b7bfcfe08d038e1fa6de458891bca65c1ada6d145474274285822896a858c870", + "sha256:beede1d1cff0c6fafae3ab58a0c470d7526196ef4cd6cc18e7769f207f2ea4eb", + "sha256:c6b775381f805ff5faf250e3a07c0819529571d19bb2a9d474bee8c3f90d66af", + "sha256:c9c935b83d40c748b6421625465b7308d87c7b3717275acd587eef2bd1c39546", + "sha256:ca845138965c8c56d1550499d6b923eb1a2331acfa9e13b817ad8305dde83d11", + "sha256:d618e118fdb7af1d6c1a96597a5cd6ac84a9f3732b5be8515c6a66e098d498b6", + "sha256:d6c0a065e31ef04658f799215dddae8752d636de2bed61365c358f9c91e7af61", + "sha256:d740206e69dfdfdcd34510c20adcb9777ce2cc18973b3441ab9767cd8948ca8a", + "sha256:d7886b63ebfb865178ab28784accd32f287d5349b3ed71094c86e4d3ca738af5", + "sha256:d9347690f4e53de2c4af74e62d6fabc940b6d4a6cad555b5a379f61e7d3f2a8e", + "sha256:d9ca80711e6553880974898d99357fb649e062f9058418a92120ca06c18c3c59", + "sha256:e24181d172f50097ac8fc272c8c5b030149b630df02d1c639ee9f878a470ba2b", + "sha256:ec68e270543ecd532c4c1d70fca020f90aa5486ad49c4f3b8b2e64a66f5c9274", + "sha256:f43f47e702d0c8e1b8b997c00f1601486f9f976f84ab704f8f11536e3fa144c9", + "sha256:ff96c5739834c9a594db0e12bf59cb3fa0e5102fc7b893972118a3166733d61c" ], "index": "pypi", "markers": "python_version >= '3.9'", - "version": "==24.10.2" + "version": "==24.11.1" }, "greenlet": { "hashes": [ @@ -765,86 +752,86 @@ }, "mako": { "hashes": [ - "sha256:260f1dbc3a519453a9c856dedfe4beb4e50bd5a26d96386cb6c80856556bb91a", - "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc" + "sha256:42f48953c7eb91332040ff567eb7eea69b22e7a4affbc5ba8e845e8f730f6627", + "sha256:577b97e414580d3e088d47c2dbbe9594aa7a5146ed2875d4dfa9075af2dd3cc8" ], "markers": "python_version >= '3.8'", - "version": "==1.3.5" + "version": "==1.3.8" }, "markupsafe": { "hashes": [ - "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396", - "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38", - "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a", - "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8", - "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b", - "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad", - "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a", - "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a", - "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da", - "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6", - "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8", - "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344", - "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a", - "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8", - "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5", - "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7", - "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170", - "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132", - "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9", - "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd", - "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9", - "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346", - "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc", - "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589", - "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5", - "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915", - "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295", - "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453", - "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea", - "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b", - "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d", - "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b", - "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4", - "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b", - "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7", - "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf", - "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f", - "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91", - "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd", - "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50", - "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b", - "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583", - "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a", - "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984", - "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c", - "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c", - "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25", - "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa", - "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4", - "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3", - "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97", - "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1", - "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd", - "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772", - "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a", - "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729", - "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca", - "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6", - "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635", - "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b", - "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f" + "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", + "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", + "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0", + "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", + "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", + "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13", + "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", + "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", + "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", + "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", + "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0", + "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", + "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", + "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", + "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", + "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff", + "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", + "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", + "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", + "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", + "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", + "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", + "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", + "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", + "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a", + "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", + "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", + "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", + "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", + "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144", + "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f", + "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", + "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", + "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", + "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", + "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", + "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", + "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", + "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", + "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", + "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", + "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", + "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", + "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", + "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", + "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", + "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", + "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", + "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29", + "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", + "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", + "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", + "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", + "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", + "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", + "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a", + "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178", + "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", + "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", + "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", + "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50" ], "markers": "python_version >= '3.9'", - "version": "==3.0.1" + "version": "==3.0.2" }, "marshmallow": { "hashes": [ - "sha256:4972f529104a220bb8637d595aa4c9762afbe7f7a77d82dc58c1615d70c5823e", - "sha256:71a2dce49ef901c3f97ed296ae5051135fd3febd2bf43afe0ae9a82143a494d9" + "sha256:bcaf2d6fd74fb1459f8450e85d994997ad3e70036452cbfa4ab685acb19479b3", + "sha256:c448ac6455ca4d794773f00bae22c2f351d62d739929f761dce5eacb5c468d7f" ], - "markers": "python_version >= '3.8'", - "version": "==3.22.0" + "markers": "python_version >= '3.9'", + "version": "==3.23.2" }, "oic": { "hashes": [ @@ -864,97 +851,92 @@ }, "packaging": { "hashes": [ - "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", - "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124" + "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", + "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f" ], "markers": "python_version >= '3.8'", - "version": "==24.1" + "version": "==24.2" }, "phonenumberslite": { "hashes": [ - "sha256:9a4d040f4ef9ea5cbbd907f6fe9a52313d46191051e3a9994102c05082a9db67", - "sha256:baf770804c056a122c76f0d29d3a85bd3111c511c5350548e1c3355449b824e9" + "sha256:02da5e78c67b213bae95afd6289f40486c93e302e518769911dfa5e7287ddeee", + "sha256:dfa44a4bae2e46d737ae5301cb96b14cdcbf45063236c74c6ddb08f5fd471b0d" ], - "version": "==8.13.47" + "version": "==8.13.52" }, "psycopg2-binary": { "hashes": [ - "sha256:03ef7df18daf2c4c07e2695e8cfd5ee7f748a1d54d802330985a78d2a5a6dca9", - "sha256:0a602ea5aff39bb9fac6308e9c9d82b9a35c2bf288e184a816002c9fae930b77", - "sha256:0c009475ee389757e6e34611d75f6e4f05f0cf5ebb76c6037508318e1a1e0d7e", - "sha256:0ef4854e82c09e84cc63084a9e4ccd6d9b154f1dbdd283efb92ecd0b5e2b8c84", - "sha256:1236ed0952fbd919c100bc839eaa4a39ebc397ed1c08a97fc45fee2a595aa1b3", - "sha256:143072318f793f53819048fdfe30c321890af0c3ec7cb1dfc9cc87aa88241de2", - "sha256:15208be1c50b99203fe88d15695f22a5bed95ab3f84354c494bcb1d08557df67", - "sha256:1873aade94b74715be2246321c8650cabf5a0d098a95bab81145ffffa4c13876", - "sha256:18d0ef97766055fec15b5de2c06dd8e7654705ce3e5e5eed3b6651a1d2a9a152", - "sha256:1ea665f8ce695bcc37a90ee52de7a7980be5161375d42a0b6c6abedbf0d81f0f", - "sha256:2293b001e319ab0d869d660a704942c9e2cce19745262a8aba2115ef41a0a42a", - "sha256:246b123cc54bb5361588acc54218c8c9fb73068bf227a4a531d8ed56fa3ca7d6", - "sha256:275ff571376626195ab95a746e6a04c7df8ea34638b99fc11160de91f2fef503", - "sha256:281309265596e388ef483250db3640e5f414168c5a67e9c665cafce9492eda2f", - "sha256:2d423c8d8a3c82d08fe8af900ad5b613ce3632a1249fd6a223941d0735fce493", - "sha256:2e5afae772c00980525f6d6ecf7cbca55676296b580c0e6abb407f15f3706996", - "sha256:30dcc86377618a4c8f3b72418df92e77be4254d8f89f14b8e8f57d6d43603c0f", - "sha256:31a34c508c003a4347d389a9e6fcc2307cc2150eb516462a7a17512130de109e", - "sha256:323ba25b92454adb36fa425dc5cf6f8f19f78948cbad2e7bc6cdf7b0d7982e59", - "sha256:34eccd14566f8fe14b2b95bb13b11572f7c7d5c36da61caf414d23b91fcc5d94", - "sha256:3a58c98a7e9c021f357348867f537017057c2ed7f77337fd914d0bedb35dace7", - "sha256:3f78fd71c4f43a13d342be74ebbc0666fe1f555b8837eb113cb7416856c79682", - "sha256:4154ad09dac630a0f13f37b583eae260c6aa885d67dfbccb5b02c33f31a6d420", - "sha256:420f9bbf47a02616e8554e825208cb947969451978dceb77f95ad09c37791dae", - "sha256:4686818798f9194d03c9129a4d9a702d9e113a89cb03bffe08c6cf799e053291", - "sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe", - "sha256:60989127da422b74a04345096c10d416c2b41bd7bf2a380eb541059e4e999980", - "sha256:64cf30263844fa208851ebb13b0732ce674d8ec6a0c86a4e160495d299ba3c93", - "sha256:68fc1f1ba168724771e38bee37d940d2865cb0f562380a1fb1ffb428b75cb692", - "sha256:6e6f98446430fdf41bd36d4faa6cb409f5140c1c2cf58ce0bbdaf16af7d3f119", - "sha256:729177eaf0aefca0994ce4cffe96ad3c75e377c7b6f4efa59ebf003b6d398716", - "sha256:72dffbd8b4194858d0941062a9766f8297e8868e1dd07a7b36212aaa90f49472", - "sha256:75723c3c0fbbf34350b46a3199eb50638ab22a0228f93fb472ef4d9becc2382b", - "sha256:77853062a2c45be16fd6b8d6de2a99278ee1d985a7bd8b103e97e41c034006d2", - "sha256:78151aa3ec21dccd5cdef6c74c3e73386dcdfaf19bced944169697d7ac7482fc", - "sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c", - "sha256:804d99b24ad523a1fe18cc707bf741670332f7c7412e9d49cb5eab67e886b9b5", - "sha256:81ff62668af011f9a48787564ab7eded4e9fb17a4a6a74af5ffa6a457400d2ab", - "sha256:8359bf4791968c5a78c56103702000105501adb557f3cf772b2c207284273984", - "sha256:83791a65b51ad6ee6cf0845634859d69a038ea9b03d7b26e703f94c7e93dbcf9", - "sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf", - "sha256:876801744b0dee379e4e3c38b76fc89f88834bb15bf92ee07d94acd06ec890a0", - "sha256:8dbf6d1bc73f1d04ec1734bae3b4fb0ee3cb2a493d35ede9badbeb901fb40f6f", - "sha256:8f8544b092a29a6ddd72f3556a9fcf249ec412e10ad28be6a0c0d948924f2212", - "sha256:911dda9c487075abd54e644ccdf5e5c16773470a6a5d3826fda76699410066fb", - "sha256:977646e05232579d2e7b9c59e21dbe5261f403a88417f6a6512e70d3f8a046be", - "sha256:9dba73be7305b399924709b91682299794887cbbd88e38226ed9f6712eabee90", - "sha256:a148c5d507bb9b4f2030a2025c545fccb0e1ef317393eaba42e7eabd28eb6041", - "sha256:a6cdcc3ede532f4a4b96000b6362099591ab4a3e913d70bcbac2b56c872446f7", - "sha256:ac05fb791acf5e1a3e39402641827780fe44d27e72567a000412c648a85ba860", - "sha256:b0605eaed3eb239e87df0d5e3c6489daae3f7388d455d0c0b4df899519c6a38d", - "sha256:b58b4710c7f4161b5e9dcbe73bb7c62d65670a87df7bcce9e1faaad43e715245", - "sha256:b6356793b84728d9d50ead16ab43c187673831e9d4019013f1402c41b1db9b27", - "sha256:b76bedd166805480ab069612119ea636f5ab8f8771e640ae103e05a4aae3e417", - "sha256:bc7bb56d04601d443f24094e9e31ae6deec9ccb23581f75343feebaf30423359", - "sha256:c2470da5418b76232f02a2fcd2229537bb2d5a7096674ce61859c3229f2eb202", - "sha256:c332c8d69fb64979ebf76613c66b985414927a40f8defa16cf1bc028b7b0a7b0", - "sha256:c6af2a6d4b7ee9615cbb162b0738f6e1fd1f5c3eda7e5da17861eacf4c717ea7", - "sha256:c77e3d1862452565875eb31bdb45ac62502feabbd53429fdc39a1cc341d681ba", - "sha256:ca08decd2697fdea0aea364b370b1249d47336aec935f87b8bbfd7da5b2ee9c1", - "sha256:ca49a8119c6cbd77375ae303b0cfd8c11f011abbbd64601167ecca18a87e7cdd", - "sha256:cb16c65dcb648d0a43a2521f2f0a2300f40639f6f8c1ecbc662141e4e3e1ee07", - "sha256:d2997c458c690ec2bc6b0b7ecbafd02b029b7b4283078d3b32a852a7ce3ddd98", - "sha256:d3f82c171b4ccd83bbaf35aa05e44e690113bd4f3b7b6cc54d2219b132f3ae55", - "sha256:dc4926288b2a3e9fd7b50dc6a1909a13bbdadfc67d93f3374d984e56f885579d", - "sha256:ead20f7913a9c1e894aebe47cccf9dc834e1618b7aa96155d2091a626e59c972", - "sha256:ebdc36bea43063116f0486869652cb2ed7032dbc59fbcb4445c4862b5c1ecf7f", - "sha256:ed1184ab8f113e8d660ce49a56390ca181f2981066acc27cf637d5c1e10ce46e", - "sha256:ee825e70b1a209475622f7f7b776785bd68f34af6e7a46e2e42f27b659b5bc26", - "sha256:f7ae5d65ccfbebdfa761585228eb4d0df3a8b15cfb53bd953e713e09fbb12957", - "sha256:f7fc5a5acafb7d6ccca13bfa8c90f8c51f13d8fb87d95656d3950f0158d3ce53", - "sha256:f9b5571d33660d5009a8b3c25dc1db560206e2d2f89d3df1cb32d72c0d117d52" + "sha256:04392983d0bb89a8717772a193cfaac58871321e3ec69514e1c4e0d4957b5aff", + "sha256:056470c3dc57904bbf63d6f534988bafc4e970ffd50f6271fc4ee7daad9498a5", + "sha256:0ea8e3d0ae83564f2fc554955d327fa081d065c8ca5cc6d2abb643e2c9c1200f", + "sha256:155e69561d54d02b3c3209545fb08938e27889ff5a10c19de8d23eb5a41be8a5", + "sha256:18c5ee682b9c6dd3696dad6e54cc7ff3a1a9020df6a5c0f861ef8bfd338c3ca0", + "sha256:19721ac03892001ee8fdd11507e6a2e01f4e37014def96379411ca99d78aeb2c", + "sha256:1a6784f0ce3fec4edc64e985865c17778514325074adf5ad8f80636cd029ef7c", + "sha256:2286791ececda3a723d1910441c793be44625d86d1a4e79942751197f4d30341", + "sha256:230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f", + "sha256:245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7", + "sha256:26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d", + "sha256:270934a475a0e4b6925b5f804e3809dd5f90f8613621d062848dd82f9cd62007", + "sha256:2ad26b467a405c798aaa1458ba09d7e2b6e5f96b1ce0ac15d82fd9f95dc38a92", + "sha256:2b3d2491d4d78b6b14f76881905c7a8a8abcf974aad4a8a0b065273a0ed7a2cb", + "sha256:2ce3e21dc3437b1d960521eca599d57408a695a0d3c26797ea0f72e834c7ffe5", + "sha256:30e34c4e97964805f715206c7b789d54a78b70f3ff19fbe590104b71c45600e5", + "sha256:3216ccf953b3f267691c90c6fe742e45d890d8272326b4a8b20850a03d05b7b8", + "sha256:32581b3020c72d7a421009ee1c6bf4a131ef5f0a968fab2e2de0c9d2bb4577f1", + "sha256:35958ec9e46432d9076286dda67942ed6d968b9c3a6a2fd62b48939d1d78bf68", + "sha256:3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73", + "sha256:3c18f74eb4386bf35e92ab2354a12c17e5eb4d9798e4c0ad3a00783eae7cd9f1", + "sha256:3c4745a90b78e51d9ba06e2088a2fe0c693ae19cc8cb051ccda44e8df8a6eb53", + "sha256:3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d", + "sha256:3e9c76f0ac6f92ecfc79516a8034a544926430f7b080ec5a0537bca389ee0906", + "sha256:48b338f08d93e7be4ab2b5f1dbe69dc5e9ef07170fe1f86514422076d9c010d0", + "sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2", + "sha256:512d29bb12608891e349af6a0cccedce51677725a921c07dba6342beaf576f9a", + "sha256:5a507320c58903967ef7384355a4da7ff3f28132d679aeb23572753cbf2ec10b", + "sha256:5c370b1e4975df846b0277b4deba86419ca77dbc25047f535b0bb03d1a544d44", + "sha256:6b269105e59ac96aba877c1707c600ae55711d9dcd3fc4b5012e4af68e30c648", + "sha256:6d4fa1079cab9018f4d0bd2db307beaa612b0d13ba73b5c6304b9fe2fb441ff7", + "sha256:6dc08420625b5a20b53551c50deae6e231e6371194fa0651dbe0fb206452ae1f", + "sha256:73aa0e31fa4bb82578f3a6c74a73c273367727de397a7a0f07bd83cbea696baa", + "sha256:7559bce4b505762d737172556a4e6ea8a9998ecac1e39b5233465093e8cee697", + "sha256:79625966e176dc97ddabc142351e0409e28acf4660b88d1cf6adb876d20c490d", + "sha256:7a813c8bdbaaaab1f078014b9b0b13f5de757e2b5d9be6403639b298a04d218b", + "sha256:7b2c956c028ea5de47ff3a8d6b3cc3330ab45cf0b7c3da35a2d6ff8420896526", + "sha256:7f4152f8f76d2023aac16285576a9ecd2b11a9895373a1f10fd9db54b3ff06b4", + "sha256:7f5d859928e635fa3ce3477704acee0f667b3a3d3e4bb109f2b18d4005f38287", + "sha256:851485a42dbb0bdc1edcdabdb8557c09c9655dfa2ca0460ff210522e073e319e", + "sha256:8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673", + "sha256:880845dfe1f85d9d5f7c412efea7a08946a46894537e4e5d091732eb1d34d9a0", + "sha256:8aabf1c1a04584c168984ac678a668094d831f152859d06e055288fa515e4d30", + "sha256:8aecc5e80c63f7459a1a2ab2c64df952051df196294d9f739933a9f6687e86b3", + "sha256:8cd9b4f2cfab88ed4a9106192de509464b75a906462fb846b936eabe45c2063e", + "sha256:8de718c0e1c4b982a54b41779667242bc630b2197948405b7bd8ce16bcecac92", + "sha256:9440fa522a79356aaa482aa4ba500b65f28e5d0e63b801abf6aa152a29bd842a", + "sha256:b5f86c56eeb91dc3135b3fd8a95dc7ae14c538a2f3ad77a19645cf55bab1799c", + "sha256:b73d6d7f0ccdad7bc43e6d34273f70d587ef62f824d7261c4ae9b8b1b6af90e8", + "sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909", + "sha256:c3cc28a6fd5a4a26224007712e79b81dbaee2ffb90ff406256158ec4d7b52b47", + "sha256:ce5ab4bf46a211a8e924d307c1b1fcda82368586a19d0a24f8ae166f5c784864", + "sha256:d00924255d7fc916ef66e4bf22f354a940c67179ad3fd7067d7a0a9c84d2fbfc", + "sha256:d7cd730dfa7c36dbe8724426bf5612798734bff2d3c3857f36f2733f5bfc7c00", + "sha256:e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb", + "sha256:e3923c1d9870c49a2d44f795df0c889a22380d36ef92440ff618ec315757e539", + "sha256:e5720a5d25e3b99cd0dc5c8a440570469ff82659bb09431c1439b92caf184d3b", + "sha256:e8b58f0a96e7a1e341fc894f62c1177a7c83febebb5ff9123b579418fdc8a481", + "sha256:e984839e75e0b60cfe75e351db53d6db750b00de45644c5d1f7ee5d1f34a1ce5", + "sha256:eb09aa7f9cecb45027683bb55aebaaf45a0df8bf6de68801a6afdc7947bb09d4", + "sha256:ec8a77f521a17506a24a5f626cb2aee7850f9b69a0afe704586f63a464f3cd64", + "sha256:ecced182e935529727401b24d76634a357c71c9275b356efafd8a2a91ec07392", + "sha256:ee0e8c683a7ff25d23b55b11161c2663d4b099770f6085ff0a20d4505778d6b4", + "sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1", + "sha256:f758ed67cab30b9a8d2833609513ce4d3bd027641673d4ebc9c067e4d208eec1", + "sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567", + "sha256:ffe8ed017e4ed70f68b7b371d84b7d4a790368db9203dfc2d222febd3a9c8863" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==2.9.9" + "markers": "python_version >= '3.8'", + "version": "==2.9.10" }, "pycparser": { "hashes": [ @@ -1005,114 +987,125 @@ }, "pydantic": { "hashes": [ - "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f", - "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12" + "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d", + "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06" ], "markers": "python_version >= '3.8'", - "version": "==2.9.2" + "version": "==2.10.4" }, "pydantic-core": { "hashes": [ - "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36", - "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05", - "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071", - "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327", - "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c", - "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36", - "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29", - "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744", - "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d", - "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec", - "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e", - "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e", - "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577", - "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232", - "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863", - "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6", - "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368", - "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480", - "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2", - "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2", - "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6", - "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769", - "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d", - "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2", - "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84", - "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166", - "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271", - "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5", - "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb", - "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13", - "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323", - "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556", - "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665", - "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef", - "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb", - "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119", - "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126", - "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510", - "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b", - "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87", - "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f", - "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc", - "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8", - "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21", - "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f", - "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6", - "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658", - "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b", - "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3", - "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb", - "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59", - "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24", - "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9", - "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3", - "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd", - "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753", - "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55", - "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad", - "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a", - "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605", - "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e", - "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b", - "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433", - "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8", - "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07", - "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728", - "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0", - "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327", - "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555", - "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64", - "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6", - "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea", - "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b", - "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df", - "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e", - "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd", - "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068", - "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3", - "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040", - "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12", - "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916", - "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f", - "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f", - "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801", - "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231", - "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5", - "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8", - "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee", - "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607" + "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278", + "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50", + "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9", + "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f", + "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", + "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc", + "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54", + "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630", + "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9", + "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236", + "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", + "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", + "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b", + "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048", + "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", + "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", + "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", + "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd", + "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4", + "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7", + "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7", + "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", + "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e", + "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa", + "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6", + "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962", + "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", + "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f", + "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474", + "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5", + "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459", + "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf", + "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a", + "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c", + "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76", + "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362", + "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4", + "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", + "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320", + "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118", + "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96", + "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306", + "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046", + "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3", + "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", + "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af", + "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", + "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67", + "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a", + "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", + "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35", + "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", + "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151", + "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b", + "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", + "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133", + "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", + "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145", + "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15", + "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", + "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc", + "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", + "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", + "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", + "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5", + "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", + "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", + "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8", + "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", + "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da", + "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", + "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc", + "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993", + "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656", + "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4", + "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c", + "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb", + "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d", + "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", + "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e", + "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", + "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc", + "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a", + "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9", + "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506", + "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b", + "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1", + "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d", + "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99", + "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", + "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31", + "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c", + "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", + "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", + "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308", + "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2", + "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228", + "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b", + "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", + "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad" ], "markers": "python_version >= '3.8'", - "version": "==2.23.4" + "version": "==2.27.2" }, "pydantic-settings": { "hashes": [ - "sha256:2c912e55fd5794a59bf8c832b9de832dcfdf4778d79ff79b708744eed499a907", - "sha256:f90b139682bee4d2065273d5185d71d37ea46cfe57e1b5ae184fc6a0b2484ca0" + "sha256:10c9caad35e64bfb3c2fbf70a078c0e25cc92499782e5200747f942a065dec93", + "sha256:590be9e6e24d06db33a4262829edef682500ef008565a969c73d39d5f8bfb3fd" ], "markers": "python_version >= '3.8'", - "version": "==2.5.2" + "version": "==2.7.1" }, "pyjwkest": { "hashes": [ @@ -1126,7 +1119,7 @@ "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==2.9.0.post0" }, "python-dotenv": { @@ -1157,50 +1150,43 @@ }, "s3transfer": { "hashes": [ - "sha256:263ed587a5803c6c708d3ce44dc4dfedaab4c1a32e8329bab818933d79ddcf5d", - "sha256:4f50ed74ab84d474ce614475e0b8d5047ff080810aac5d01ea25231cfc944b0c" + "sha256:244a76a24355363a68164241438de1b72f8781664920260c48465896b712a41e", + "sha256:29edc09801743c21eb5ecbc617a152df41d3c287f67b615f73e5f750583666a7" ], "markers": "python_version >= '3.8'", - "version": "==0.10.3" + "version": "==0.10.4" }, "setuptools": { "hashes": [ - "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2", - "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538" + "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6", + "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d" ], - "markers": "python_version >= '3.8'", - "version": "==75.1.0" + "markers": "python_version >= '3.9'", + "version": "==75.6.0" }, "six": { "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", + "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "version": "==1.17.0" }, "sqlparse": { "hashes": [ - "sha256:773dcbf9a5ab44a090f3441e2180efe2560220203dc2f8c0b0fa141e18b505e4", - "sha256:bb6b4df465655ef332548e24f08e205afc81b9ab86cb1c45657a7ff173a3a00e" + "sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272", + "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca" ], "markers": "python_version >= '3.8'", - "version": "==0.5.1" + "version": "==0.5.3" }, "tablib": { - "extras": [ - "html", - "ods", - "xls", - "xlsx", - "yaml" - ], "hashes": [ - "sha256:9821caa9eca6062ff7299fa645e737aecff982e6b2b42046928a6413c8dabfd9", - "sha256:f6661dfc45e1d4f51fa8a6239f9c8349380859a5bfaa73280645f046d6c96e33" + "sha256:9a6930037cfe0f782377963ca3f2b1dae3fd4cdbf0883848f22f1447e7bb718b", + "sha256:f9db84ed398df5109bd69c11d46613d16cc572fb9ad3213f10d95e2b5f12c18e" ], - "markers": "python_version >= '3.8'", - "version": "==3.5.0" + "markers": "python_version >= '3.9'", + "version": "==3.7.0" }, "tblib": { "hashes": [ @@ -1222,20 +1208,20 @@ }, "urllib3": { "hashes": [ - "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", - "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9" + "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", + "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d" ], - "markers": "python_version >= '3.8'", - "version": "==2.2.3" + "markers": "python_version >= '3.9'", + "version": "==2.3.0" }, "whitenoise": { "hashes": [ - "sha256:58c7a6cd811e275a6c91af22e96e87da0b1109e9a53bb7464116ef4c963bf636", - "sha256:a1ae85e01fdc9815d12fa33f17765bc132ed2c54fa76daf9e39e879dd93566f6" + "sha256:486bd7267a375fa9650b136daaec156ac572971acc8bf99add90817a530dd1d4", + "sha256:df12dce147a043d1956d81d288c6f0044147c6d2ab9726e5772ac50fb45d2280" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==6.7.0" + "markers": "python_version >= '3.9'", + "version": "==6.8.2" }, "zope.event": { "hashes": [ @@ -1247,46 +1233,46 @@ }, "zope.interface": { "hashes": [ - "sha256:07add15de0cc7e69917f7d286b64d54125c950aeb43efed7a5ea7172f000fbc1", - "sha256:0ac20581fc6cd7c754f6dff0ae06fedb060fa0e9ea6309d8be8b2701d9ea51c4", - "sha256:124149e2d42067b9c6597f4dafdc7a0983d0163868f897b7bb5dc850b14f9a87", - "sha256:27cfb5205d68b12682b6e55ab8424662d96e8ead19550aad0796b08dd2c9a45e", - "sha256:2a29ac607e970b5576547f0e3589ec156e04de17af42839eedcf478450687317", - "sha256:2b6a4924f5bad9fe21d99f66a07da60d75696a136162427951ec3cb223a5570d", - "sha256:2bd9e9f366a5df08ebbdc159f8224904c1c5ce63893984abb76954e6fbe4381a", - "sha256:3bcff5c09d0215f42ba64b49205a278e44413d9bf9fa688fd9e42bfe472b5f4f", - "sha256:3f005869a1a05e368965adb2075f97f8ee9a26c61898a9e52a9764d93774f237", - "sha256:4a00ead2e24c76436e1b457a5132d87f83858330f6c923640b7ef82d668525d1", - "sha256:4af4a12b459a273b0b34679a5c3dc5e34c1847c3dd14a628aa0668e19e638ea2", - "sha256:5501e772aff595e3c54266bc1bfc5858e8f38974ce413a8f1044aae0f32a83a3", - "sha256:5e28ea0bc4b084fc93a483877653a033062435317082cdc6388dec3438309faf", - "sha256:5e956b1fd7f3448dd5e00f273072e73e50dfafcb35e4227e6d5af208075593c9", - "sha256:5fcf379b875c610b5a41bc8a891841533f98de0520287d7f85e25386cd10d3e9", - "sha256:6159e767d224d8f18deff634a1d3722e68d27488c357f62ebeb5f3e2f5288b1f", - "sha256:661d5df403cd3c5b8699ac480fa7f58047a3253b029db690efa0c3cf209993ef", - "sha256:711eebc77f2092c6a8b304bad0b81a6ce3cf5490b25574e7309fbc07d881e3af", - "sha256:80a3c00b35f6170be5454b45abe2719ea65919a2f09e8a6e7b1362312a872cd3", - "sha256:848b6fa92d7c8143646e64124ed46818a0049a24ecc517958c520081fd147685", - "sha256:91b6c30689cfd87c8f264acb2fc16ad6b3c72caba2aec1bf189314cf1a84ca33", - "sha256:9733a9a0f94ef53d7aa64661811b20875b5bc6039034c6e42fb9732170130573", - "sha256:9940d5bc441f887c5f375ec62bcf7e7e495a2d5b1da97de1184a88fb567f06af", - "sha256:9e3e48f3dea21c147e1b10c132016cb79af1159facca9736d231694ef5a740a8", - "sha256:a14c9decf0eb61e0892631271d500c1e306c7b6901c998c7035e194d9150fdd1", - "sha256:a735f82d2e3ed47ca01a20dfc4c779b966b16352650a8036ab3955aad151ed8a", - "sha256:a99240b1d02dc469f6afbe7da1bf617645e60290c272968f4e53feec18d7dce8", - "sha256:b7b25db127db3e6b597c5f74af60309c4ad65acd826f89609662f0dc33a54728", - "sha256:b936d61dbe29572fd2cfe13e30b925e5383bed1aba867692670f5a2a2eb7b4e9", - "sha256:bec001798ab62c3fc5447162bf48496ae9fba02edc295a9e10a0b0c639a6452e", - "sha256:cc8a318162123eddbdf22fcc7b751288ce52e4ad096d3766ff1799244352449d", - "sha256:d0a45b5af9f72c805ee668d1479480ca85169312211bed6ed18c343e39307d5f", - "sha256:e53c291debef523b09e1fe3dffe5f35dde164f1c603d77f770b88a1da34b7ed6", - "sha256:ec1ef1fdb6f014d5886b97e52b16d0f852364f447d2ab0f0c6027765777b6667", - "sha256:ec59fe53db7d32abb96c6d4efeed84aab4a7c38c62d7a901a9b20c09dd936e7a", - "sha256:f245d039f72e6f802902375755846f5de1ee1e14c3e8736c078565599bcab621", - "sha256:ff115ef91c0eeac69cd92daeba36a9d8e14daee445b504eeea2b1c0b55821984" + "sha256:033b3923b63474800b04cba480b70f6e6243a62208071fc148354f3f89cc01b7", + "sha256:05b910a5afe03256b58ab2ba6288960a2892dfeef01336dc4be6f1b9ed02ab0a", + "sha256:086ee2f51eaef1e4a52bd7d3111a0404081dadae87f84c0ad4ce2649d4f708b7", + "sha256:0ef9e2f865721553c6f22a9ff97da0f0216c074bd02b25cf0d3af60ea4d6931d", + "sha256:1090c60116b3da3bfdd0c03406e2f14a1ff53e5771aebe33fec1edc0a350175d", + "sha256:144964649eba4c5e4410bb0ee290d338e78f179cdbfd15813de1a664e7649b3b", + "sha256:15398c000c094b8855d7d74f4fdc9e73aa02d4d0d5c775acdef98cdb1119768d", + "sha256:1909f52a00c8c3dcab6c4fad5d13de2285a4b3c7be063b239b8dc15ddfb73bd2", + "sha256:21328fcc9d5b80768bf051faa35ab98fb979080c18e6f84ab3f27ce703bce465", + "sha256:224b7b0314f919e751f2bca17d15aad00ddbb1eadf1cb0190fa8175edb7ede62", + "sha256:25e6a61dcb184453bb00eafa733169ab6d903e46f5c2ace4ad275386f9ab327a", + "sha256:27f926f0dcb058211a3bb3e0e501c69759613b17a553788b2caeb991bed3b61d", + "sha256:29caad142a2355ce7cfea48725aa8bcf0067e2b5cc63fcf5cd9f97ad12d6afb5", + "sha256:2ad9913fd858274db8dd867012ebe544ef18d218f6f7d1e3c3e6d98000f14b75", + "sha256:31d06db13a30303c08d61d5fb32154be51dfcbdb8438d2374ae27b4e069aac40", + "sha256:3e0350b51e88658d5ad126c6a57502b19d5f559f6cb0a628e3dc90442b53dd98", + "sha256:3f6771d1647b1fc543d37640b45c06b34832a943c80d1db214a37c31161a93f1", + "sha256:4893395d5dd2ba655c38ceb13014fd65667740f09fa5bb01caa1e6284e48c0cd", + "sha256:52e446f9955195440e787596dccd1411f543743c359eeb26e9b2c02b077b0519", + "sha256:550f1c6588ecc368c9ce13c44a49b8d6b6f3ca7588873c679bd8fd88a1b557b6", + "sha256:72cd1790b48c16db85d51fbbd12d20949d7339ad84fd971427cf00d990c1f137", + "sha256:7bd449c306ba006c65799ea7912adbbfed071089461a19091a228998b82b1fdb", + "sha256:7dc5016e0133c1a1ec212fc87a4f7e7e562054549a99c73c8896fa3a9e80cbc7", + "sha256:802176a9f99bd8cc276dcd3b8512808716492f6f557c11196d42e26c01a69a4c", + "sha256:80ecf2451596f19fd607bb09953f426588fc1e79e93f5968ecf3367550396b22", + "sha256:8b49f1a3d1ee4cdaf5b32d2e738362c7f5e40ac8b46dd7d1a65e82a4872728fe", + "sha256:8e7da17f53e25d1a3bde5da4601e026adc9e8071f9f6f936d0fe3fe84ace6d54", + "sha256:a102424e28c6b47c67923a1f337ede4a4c2bba3965b01cf707978a801fc7442c", + "sha256:a19a6cc9c6ce4b1e7e3d319a473cf0ee989cbbe2b39201d7c19e214d2dfb80c7", + "sha256:a71a5b541078d0ebe373a81a3b7e71432c61d12e660f1d67896ca62d9628045b", + "sha256:baf95683cde5bc7d0e12d8e7588a3eb754d7c4fa714548adcd96bdf90169f021", + "sha256:cab15ff4832580aa440dc9790b8a6128abd0b88b7ee4dd56abacbc52f212209d", + "sha256:ce290e62229964715f1011c3dbeab7a4a1e4971fd6f31324c4519464473ef9f2", + "sha256:d3a8ffec2a50d8ec470143ea3d15c0c52d73df882eef92de7537e8ce13475e8a", + "sha256:e204937f67b28d2dca73ca936d3039a144a081fc47a07598d44854ea2a106239", + "sha256:eb23f58a446a7f09db85eda09521a498e109f137b85fb278edb2e34841055398", + "sha256:f6dd02ec01f4468da0f234da9d9c8545c5412fef80bc590cc51d8dd084138a89" ], "markers": "python_version >= '3.8'", - "version": "==7.1.0" + "version": "==7.2" } }, "develop": { @@ -1300,12 +1286,12 @@ }, "bandit": { "hashes": [ - "sha256:59ed5caf5d92b6ada4bf65bc6437feea4a9da1093384445fed4d472acc6cff7b", - "sha256:665721d7bebbb4485a339c55161ac0eedde27d51e638000d91c8c2d68343ad02" + "sha256:b1a61d829c0968aed625381e426aa378904b996529d048f8d908fa28f6b13e38", + "sha256:b5bfe55a095abd9fe20099178a7c6c060f844bfd4fe4c76d28e35e4c52b9d31e" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==1.7.10" + "markers": "python_version >= '3.9'", + "version": "==1.8.0" }, "beautifulsoup4": { "hashes": [ @@ -1346,20 +1332,20 @@ }, "blinker": { "hashes": [ - "sha256:1779309f71bf239144b9399d06ae925637cf6634cf6bd131104184531bf67c01", - "sha256:8f77b09d3bf7c795e969e9486f39c2c5e9c39d4ee07424be2bc594ece9642d83" + "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf", + "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc" ], - "markers": "python_version >= '3.8'", - "version": "==1.8.2" + "markers": "python_version >= '3.9'", + "version": "==1.9.0" }, "boto3": { "hashes": [ - "sha256:2bf7e7f376aee52155fc4ae4487f29333a6bcdf3a05c3bc4fede10b972d951a6", - "sha256:e74bc6d69c04ca611b7f58afe08e2ded6cb6504a4a80557b656abeefee395f88" + "sha256:ba391982f6cada136c5bba99e85d7fe1bc4e157c53a22a78e4aca35d1b39152e", + "sha256:eecef248f8743ab30036cd9c916808a0892fc9036e1a35434d8222060c08bbd2" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.35.41" + "version": "==1.35.91" }, "boto3-mocking": { "hashes": [ @@ -1372,45 +1358,45 @@ }, "boto3-stubs": { "hashes": [ - "sha256:5884048edf0581479ecc3726c0b4b6d83640b5590d4646cbd229bae8f5a5666b", - "sha256:724c5999390eed5ed84832dcd003d1dcd1b12c941e50f6a6f63378c407d8fa0a" + "sha256:780f71406147b78f9860d78907b5c015874537d821364588ec837c4cd1eecf91", + "sha256:e4301b9d05b31fbfea382d0d1d950c2178f7fca03058b31373fac9a4cdf89438" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.35.41" + "version": "==1.35.91" }, "botocore": { "hashes": [ - "sha256:8a09a32136df8768190a6c92f0240cd59c30deb99c89026563efadbbed41fa00", - "sha256:915c4d81e3a0be3b793c1e2efdf19af1d0a9cd4a2d8de08ee18216c14d67764b" + "sha256:7b0b9c5954701fff4d2c516918f45641b04ff4ca92bbd9f5b37c0b80f8c14220", + "sha256:93de9d0f52f7e36a2c190d55520d3b2654f32c5a628fdd484bffa00bc7865e1d" ], "markers": "python_version >= '3.8'", - "version": "==1.35.41" + "version": "==1.35.91" }, "botocore-stubs": { "hashes": [ - "sha256:62e369aed694471eaf72305cd2f33c356337d49637a5fcc17fc2ef237e8f517f", - "sha256:99e8f0e20266b2abc0e095ef19e8e628a926c25c4a0edbfd25978f484677bac6" + "sha256:c6b294cae436eaaf87dcb717e4348c250ea1fc170336579da114b693663d8e42", + "sha256:f7fd78d84f49d28692662b9bdeb4c92f1bf8a5707d0c28c8544399005b02823b" ], "markers": "python_version >= '3.8'", - "version": "==1.35.41" + "version": "==1.35.90" }, "click": { "hashes": [ - "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", - "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" + "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", + "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a" ], "markers": "python_version >= '3.7'", - "version": "==8.1.7" + "version": "==8.1.8" }, "django": { "hashes": [ - "sha256:a2d4c4d4ea0b6f0895acde632071aff6400bfc331228fc978b05452a0ff3e9f1", - "sha256:b1260ed381b10a11753c73444408e19869f3241fc45c985cd55a30177c789d13" + "sha256:3a93350214ba25f178d4045c0786c61573e7dbfa3c509b3551374f1e11ba8de0", + "sha256:6b56d834cc94c8b21a8f4e775064896be3b4a4ca387f2612d4406a5927cd2fdc" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==4.2.10" + "version": "==4.2.17" }, "django-debug-toolbar": { "hashes": [ @@ -1423,27 +1409,27 @@ }, "django-model2puml": { "hashes": [ - "sha256:f7ef57efbf261e8e0f90043c2be379e9457b30603ccc01fe7a01c233d0dfa27c" + "sha256:c823366d5ddc7cc52d855b62ce3b2b0acaa54dcaa0f372b9c5f2679d9a341f54" ], "index": "pypi", - "version": "==0.5.1" + "version": "==0.6.0" }, "django-stubs": { "hashes": [ - "sha256:86128c228b65e6c9a85e5dc56eb1c6f41125917dae0e21e6cfecdf1b27e630c5", - "sha256:b98d49a80aa4adf1433a97407102d068de26c739c405431d93faad96dd282c40" + "sha256:126d354bbdff4906c4e93e6361197f6fbfb6231c3df6def85a291dae6f9f577b", + "sha256:c4dc64260bd72e6d32b9e536e8dd0d9247922f0271f82d1d5132a18f24b388ac" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==5.1.0" + "version": "==5.1.1" }, "django-stubs-ext": { "hashes": [ - "sha256:a455fc222c90b30b29ad8c53319559f5b54a99b4197205ddbb385aede03b395d", - "sha256:ed7d51c0b731651879fc75f331fb0806d98b67bfab464e96e2724db6b46ef926" + "sha256:3907f99e178c93323e2ce908aef8352adb8c047605161f8d9e5e7b4efb5a6a9c", + "sha256:db7364e4f50ae7e5360993dbd58a3a57ea4b2e7e5bab0fbd525ccdb3e7975d1c" ], "markers": "python_version >= '3.8'", - "version": "==5.1.0" + "version": "==5.1.1" }, "django-webtest": { "hashes": [ @@ -1496,42 +1482,48 @@ }, "mypy": { "hashes": [ - "sha256:060a07b10e999ac9e7fa249ce2bdcfa9183ca2b70756f3bce9df7a92f78a3c0a", - "sha256:06de0498798527451ffb60f68db0d368bd2bae2bbfb5237eae616d4330cc87aa", - "sha256:0eff042d7257f39ba4ca06641d110ca7d2ad98c9c1fb52200fe6b1c865d360ff", - "sha256:1ebf9e796521f99d61864ed89d1fb2926d9ab6a5fab421e457cd9c7e4dd65aa9", - "sha256:20c7c5ce0c1be0b0aea628374e6cf68b420bcc772d85c3c974f675b88e3e6e57", - "sha256:233e11b3f73ee1f10efada2e6da0f555b2f3a5316e9d8a4a1224acc10e7181d3", - "sha256:2c40658d4fa1ab27cb53d9e2f1066345596af2f8fe4827defc398a09c7c9519b", - "sha256:2f106db5ccb60681b622ac768455743ee0e6a857724d648c9629a9bd2ac3f721", - "sha256:4397081e620dc4dc18e2f124d5e1d2c288194c2c08df6bdb1db31c38cd1fe1ed", - "sha256:48d3e37dd7d9403e38fa86c46191de72705166d40b8c9f91a3de77350daa0893", - "sha256:4ae8959c21abcf9d73aa6c74a313c45c0b5a188752bf37dace564e29f06e9c1b", - "sha256:4b86de37a0da945f6d48cf110d5206c5ed514b1ca2614d7ad652d4bf099c7de7", - "sha256:52b9e1492e47e1790360a43755fa04101a7ac72287b1a53ce817f35899ba0521", - "sha256:5bc81701d52cc8767005fdd2a08c19980de9ec61a25dbd2a937dfb1338a826f9", - "sha256:5feee5c74eb9749e91b77f60b30771563327329e29218d95bedbe1257e2fe4b0", - "sha256:65a22d87e757ccd95cbbf6f7e181e6caa87128255eb2b6be901bb71b26d8a99d", - "sha256:684a9c508a283f324804fea3f0effeb7858eb03f85c4402a967d187f64562469", - "sha256:6b5df6c8a8224f6b86746bda716bbe4dbe0ce89fd67b1fa4661e11bfe38e8ec8", - "sha256:6cabe4cda2fa5eca7ac94854c6c37039324baaa428ecbf4de4567279e9810f9e", - "sha256:77278e8c6ffe2abfba6db4125de55f1024de9a323be13d20e4f73b8ed3402bd1", - "sha256:8462655b6694feb1c99e433ea905d46c478041a8b8f0c33f1dab00ae881b2164", - "sha256:923ea66d282d8af9e0f9c21ffc6653643abb95b658c3a8a32dca1eff09c06475", - "sha256:9b9ce1ad8daeb049c0b55fdb753d7414260bad8952645367e70ac91aec90e07e", - "sha256:a64ee25f05fc2d3d8474985c58042b6759100a475f8237da1f4faf7fcd7e6309", - "sha256:bfe012b50e1491d439172c43ccb50db66d23fab714d500b57ed52526a1020bb7", - "sha256:c72861b7139a4f738344faa0e150834467521a3fba42dc98264e5aa9507dd601", - "sha256:dcfb754dea911039ac12434d1950d69a2f05acd4d56f7935ed402be09fad145e", - "sha256:dee78a8b9746c30c1e617ccb1307b351ded57f0de0d287ca6276378d770006c0", - "sha256:e478601cc3e3fa9d6734d255a59c7a2e5c2934da4378f3dd1e3411ea8a248642", - "sha256:eafc1b7319b40ddabdc3db8d7d48e76cfc65bbeeafaa525a4e0fa6b76175467f", - "sha256:faca7ab947c9f457a08dcb8d9a8664fd438080e002b0fa3e41b0535335edcf7f", - "sha256:fd313226af375d52e1e36c383f39bf3836e1f192801116b31b090dfcd3ec5266" + "sha256:07ba89fdcc9451f2ebb02853deb6aaaa3d2239a236669a63ab3801bbf923ef5c", + "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd", + "sha256:183cf0a45457d28ff9d758730cd0210419ac27d4d3f285beda038c9083363b1f", + "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0", + "sha256:27fc248022907e72abfd8e22ab1f10e903915ff69961174784a3900a8cba9ad9", + "sha256:2ae753f5c9fef278bcf12e1a564351764f2a6da579d4a81347e1d5a15819997b", + "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14", + "sha256:3888a1816d69f7ab92092f785a462944b3ca16d7c470d564165fe703b0970c35", + "sha256:44bf464499f0e3a2d14d58b54674dee25c031703b2ffc35064bd0df2e0fac319", + "sha256:46c756a444117c43ee984bd055db99e498bc613a70bbbc120272bd13ca579fbc", + "sha256:499d6a72fb7e5de92218db961f1a66d5f11783f9ae549d214617edab5d4dbdbb", + "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb", + "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e", + "sha256:57961db9795eb566dc1d1b4e9139ebc4c6b0cb6e7254ecde69d1552bf7613f60", + "sha256:7084fb8f1128c76cd9cf68fe5971b37072598e7c31b2f9f95586b65c741a9d31", + "sha256:7d54bd85b925e501c555a3227f3ec0cfc54ee8b6930bd6141ec872d1c572f81f", + "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6", + "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107", + "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11", + "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a", + "sha256:8edc07eeade7ebc771ff9cf6b211b9a7d93687ff892150cb5692e4f4272b0837", + "sha256:8f845a00b4f420f693f870eaee5f3e2692fa84cc8514496114649cfa8fd5e2c6", + "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b", + "sha256:90716d8b2d1f4cd503309788e51366f07c56635a3309b0f6a32547eaaa36a64d", + "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255", + "sha256:ad3301ebebec9e8ee7135d8e3109ca76c23752bac1e717bc84cd3836b4bf3eae", + "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1", + "sha256:ba24549de7b89b6381b91fbc068d798192b1b5201987070319889e93038967a8", + "sha256:bce23c7377b43602baa0bd22ea3265c49b9ff0b76eb315d6c34721af4cdf1d9b", + "sha256:c99f27732c0b7dc847adb21c9d47ce57eb48fa33a17bc6d7d5c5e9f9e7ae5bac", + "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9", + "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9", + "sha256:d64169ec3b8461311f8ce2fd2eb5d33e2d0f2c7b49116259c51d0d96edee48d1", + "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34", + "sha256:e0fe0f5feaafcb04505bcf439e991c6d8f1bf8b15f12b05feeed96e9e7bf1427", + "sha256:f2a0ecc86378f45347f586e4163d1769dd81c5a223d577fe351f26b179e148b1", + "sha256:f995e511de847791c3b11ed90084a7a0aafdc074ab88c5a9711622fe4751138c", + "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.12.0" + "version": "==1.14.1" }, "mypy-extensions": { "hashes": [ @@ -1551,11 +1543,11 @@ }, "packaging": { "hashes": [ - "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", - "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124" + "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", + "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f" ], "markers": "python_version >= '3.8'", - "version": "==24.1" + "version": "==24.2" }, "pathspec": { "hashes": [ @@ -1610,7 +1602,7 @@ "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==2.9.0.post0" }, "pyyaml": { @@ -1674,27 +1666,27 @@ }, "rich": { "hashes": [ - "sha256:51a2c62057461aaf7152b4d611168f93a9fc73068f8ded2790f29fe2b5366d0c", - "sha256:8c82a3d3f8dcfe9e734771313e606b39d8247bb6b826e196f4914b333b743cf1" + "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098", + "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90" ], "markers": "python_full_version >= '3.8.0'", - "version": "==13.9.2" + "version": "==13.9.4" }, "s3transfer": { "hashes": [ - "sha256:263ed587a5803c6c708d3ce44dc4dfedaab4c1a32e8329bab818933d79ddcf5d", - "sha256:4f50ed74ab84d474ce614475e0b8d5047ff080810aac5d01ea25231cfc944b0c" + "sha256:244a76a24355363a68164241438de1b72f8781664920260c48465896b712a41e", + "sha256:29edc09801743c21eb5ecbc617a152df41d3c287f67b615f73e5f750583666a7" ], "markers": "python_version >= '3.8'", - "version": "==0.10.3" + "version": "==0.10.4" }, "six": { "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", + "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "version": "==1.17.0" }, "soupsieve": { "hashes": [ @@ -1706,35 +1698,65 @@ }, "sqlparse": { "hashes": [ - "sha256:773dcbf9a5ab44a090f3441e2180efe2560220203dc2f8c0b0fa141e18b505e4", - "sha256:bb6b4df465655ef332548e24f08e205afc81b9ab86cb1c45657a7ff173a3a00e" + "sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272", + "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca" ], "markers": "python_version >= '3.8'", - "version": "==0.5.1" + "version": "==0.5.3" }, "stevedore": { "hashes": [ - "sha256:1efd34ca08f474dad08d9b19e934a22c68bb6fe416926479ba29e5013bcc8f78", - "sha256:9a64265f4060312828151c204efbe9b7a9852a0d9228756344dbc7e4023e375a" + "sha256:79e92235ecb828fe952b6b8b0c6c87863248631922c8e8e0fa5b17b232c4514d", + "sha256:b0be3c4748b3ea7b854b265dcb4caa891015e442416422be16f8b31756107857" ], - "markers": "python_version >= '3.8'", - "version": "==5.3.0" + "markers": "python_version >= '3.9'", + "version": "==5.4.0" }, "tomli": { "hashes": [ - "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38", - "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed" + "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", + "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", + "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", + "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", + "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", + "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", + "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", + "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", + "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", + "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", + "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", + "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", + "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", + "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", + "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", + "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", + "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", + "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", + "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", + "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", + "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", + "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", + "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", + "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", + "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", + "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", + "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", + "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", + "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", + "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", + "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", + "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7" ], - "markers": "python_version < '3.11'", - "version": "==2.0.2" + "markers": "python_version >= '3.8'", + "version": "==2.2.1" }, "types-awscrt": { "hashes": [ - "sha256:67a660c90bad360c339f6a79310cc17094d12472042c7ca5a41450aaf5fc9a54", - "sha256:b2c196bbd3226bab42d80fae13c34548de9ddc195f5a366d79c15d18e5897aa9" + "sha256:405bce8c281f9e7c6c92a229225cc0bf10d30729a6a601123213389bd524b8b1", + "sha256:fbf9c221af5607b24bf17f8431217ce8b9a27917139edbc984891eb63fd5a593" ], "markers": "python_version >= '3.8'", - "version": "==0.22.0" + "version": "==0.23.6" }, "types-cachetools": { "hashes": [ @@ -1747,28 +1769,28 @@ }, "types-pyyaml": { "hashes": [ - "sha256:392b267f1c0fe6022952462bf5d6523f31e37f6cea49b14cee7ad634b6301570", - "sha256:d1405a86f9576682234ef83bcb4e6fff7c9305c8b1fbad5e0bcd4f7dbdc9c587" + "sha256:7f07622dbd34bb9c8b264fe860a17e0efcad00d50b5f27e93984909d9363498c", + "sha256:fa4d32565219b68e6dee5f67534c722e53c00d1cfc09c435ef04d7353e1e96e6" ], "markers": "python_version >= '3.8'", - "version": "==6.0.12.20240917" + "version": "==6.0.12.20241230" }, "types-requests": { "hashes": [ - "sha256:2850e178db3919d9bf809e434eef65ba49d0e7e33ac92d588f4a5e295fffd405", - "sha256:59c2f673eb55f32a99b2894faf6020e1a9f4a402ad0f192bfee0b64469054310" + "sha256:0d9cad2f27515d0e3e3da7134a1b6f28fb97129d86b867f24d9c726452634d95", + "sha256:4195d62d6d3e043a4eaaf08ff8a62184584d2e8684e9d2aa178c7915a7da3747" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==2.32.0.20240914" + "version": "==2.32.0.20241016" }, "types-s3transfer": { "hashes": [ - "sha256:d34c5a82f531af95bb550927136ff5b737a1ed3087f90a59d545591dfde5b4cc", - "sha256:f761b2876ac4c208e6c6b75cdf5f6939009768be9950c545b11b0225e7703ee7" + "sha256:03123477e3064c81efe712bf9d372c7c72f2790711431f9baa59cf96ea607267", + "sha256:22ac1aabc98f9d7f2928eb3fb4d5c02bf7435687f0913345a97dd3b84d0c217d" ], "markers": "python_version >= '3.8'", - "version": "==0.10.3" + "version": "==0.10.4" }, "typing-extensions": { "hashes": [ @@ -1781,36 +1803,35 @@ }, "urllib3": { "hashes": [ - "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", - "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9" + "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", + "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d" ], - "markers": "python_version >= '3.8'", - "version": "==2.2.3" + "markers": "python_version >= '3.9'", + "version": "==2.3.0" }, "waitress": { "hashes": [ - "sha256:26cdbc593093a15119351690752c99adc13cbc6786d75f7b6341d1234a3730ac", - "sha256:ef0c1f020d9f12a515c4ec65c07920a702613afcad1dbfdc3bcec256b6c072b3" + "sha256:682aaaf2af0c44ada4abfb70ded36393f0e307f4ab9456a215ce0020baefc31f", + "sha256:c56d67fd6e87c2ee598b76abdd4e96cfad1f24cacdea5078d382b1f9d7b5ed2e" ], - "index": "pypi", "markers": "python_full_version >= '3.9.0'", - "version": "==3.0.1" + "version": "==3.0.2" }, "webob": { "hashes": [ - "sha256:2abc1555e118fc251e705fc6dc66c7f5353bb9fbfab6d20e22f1c02b4b71bcee", - "sha256:b60ba63f05c0cf61e086a10c3781a41fcfe30027753a8ae6d819c77592ce83ea" + "sha256:45e34c58ed0c7e2ecd238ffd34432487ff13d9ad459ddfd77895e67abba7c1f9", + "sha256:ad6078e2edb6766d1334ec3dee072ac6a7f95b1e32ce10def8ff7f0f02d56589" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.8.8" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "version": "==1.8.9" }, "webtest": { "hashes": [ - "sha256:493b5c802f8948a65b5e3a1ad5b2524ee5e1ab60cd713d9a3da3b8da082c06fe", - "sha256:b3bc75d020d0576ee93a5f149666045e58fe2400ea5f0c214d7430d7d213d0d0" + "sha256:0b2de681c16f57b31da5cce6e94ff03cdc77bd86c37a57ba0ee27fed8e065ceb", + "sha256:799846e169d15e0c1233ab4ab00ee4de59a5d964407d6f2945d89249328dbbdb" ], "markers": "python_version >= '3.7'", - "version": "==3.0.1" + "version": "==3.0.2" } } } diff --git a/src/requirements.txt b/src/requirements.txt index 1a9282591..c3ed17604 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -1,68 +1,68 @@ -i https://pypi.python.org/simple annotated-types==0.7.0; python_version >= '3.8' asgiref==3.8.1; python_version >= '3.8' -boto3==1.35.41; python_version >= '3.8' -botocore==1.35.41; python_version >= '3.8' +boto3==1.35.91; python_version >= '3.8' +botocore==1.35.91; python_version >= '3.8' cachetools==5.5.0; python_version >= '3.7' -certifi==2024.8.30; python_version >= '3.6' +certifi==2024.12.14; python_version >= '3.6' cfenv==0.5.3 -cffi==1.17.1; platform_python_implementation != 'PyPy' -charset-normalizer==3.4.0; python_full_version >= '3.7.0' -cryptography==43.0.1; python_version >= '3.7' +cffi==1.17.1; python_version >= '3.8' +charset-normalizer==3.4.1; python_version >= '3.7' +cryptography==44.0.0; python_version >= '3.7' and python_full_version not in '3.9.0, 3.9.1' defusedxml==0.7.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' -diff-match-patch==20230430; python_version >= '3.7' -dj-database-url==2.2.0 +diff-match-patch==20241021; python_version >= '3.7' +dj-database-url==2.3.0 dj-email-url==1.0.6 django==4.2.17; python_version >= '3.8' django-admin-multiple-choice-list-filter==0.1.1 django-allow-cidr==0.7.1 django-auditlog==3.0.0; python_version >= '3.8' django-cache-url==3.4.5 -django-cors-headers==4.5.0; python_version >= '3.9' +django-cors-headers==4.6.0; python_version >= '3.9' django-csp==3.8 django-fsm==2.8.1 -django-import-export==4.1.1; python_version >= '3.8' +django-import-export==4.3.3; python_version >= '3.9' django-login-required-middleware==0.9.0 django-phonenumber-field[phonenumberslite]==8.0.0; python_version >= '3.8' -django-waffle==4.1.0; python_version >= '3.8' +django-waffle==4.2.0; python_version >= '3.8' django-widget-tweaks==1.5.0; python_version >= '3.8' -environs[django]==11.0.0; python_version >= '3.8' -faker==30.3.0; python_version >= '3.8' -fred-epplib@ git+https://github.com/cisagov/epplib.git@d56d183f1664f34c40ca9716a3a9a345f0ef561c +environs[django]==11.2.1; python_version >= '3.8' +faker==33.1.0; python_version >= '3.8' +fred-epplib @ git+https://github.com/cisagov/epplib.git@d56d183f1664f34c40ca9716a3a9a345f0ef561c furl==2.1.3 -future==1.0.0; python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3' -gevent==24.10.2; python_version >= '3.9' +future==1.0.0; python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2' +gevent==24.11.1; python_version >= '3.9' greenlet==3.1.1; python_version >= '3.7' gunicorn==23.0.0; python_version >= '3.7' idna==3.10; python_version >= '3.6' jmespath==1.0.1; python_version >= '3.7' lxml==5.3.0; python_version >= '3.6' -mako==1.3.5; python_version >= '3.8' -markupsafe==3.0.1; python_version >= '3.9' -marshmallow==3.22.0; python_version >= '3.8' +mako==1.3.8; python_version >= '3.8' +markupsafe==3.0.2; python_version >= '3.9' +marshmallow==3.23.2; python_version >= '3.9' oic==1.7.0; python_version ~= '3.8' orderedmultidict==1.0.1 -packaging==24.1; python_version >= '3.8' -phonenumberslite==8.13.47 -psycopg2-binary==2.9.9; python_version >= '3.7' +packaging==24.2; python_version >= '3.8' +phonenumberslite==8.13.52 +psycopg2-binary==2.9.10; python_version >= '3.8' pycparser==2.22; python_version >= '3.8' pycryptodomex==3.21.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' -pydantic==2.9.2; python_version >= '3.8' -pydantic-core==2.23.4; python_version >= '3.8' -pydantic-settings==2.5.2; python_version >= '3.8' +pydantic==2.10.4; python_version >= '3.8' +pydantic-core==2.27.2; python_version >= '3.8' +pydantic-settings==2.7.1; python_version >= '3.8' pyjwkest==1.4.2 -python-dateutil==2.9.0.post0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' +python-dateutil==2.9.0.post0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2' python-dotenv==1.0.1; python_version >= '3.8' pyzipper==0.3.6; python_version >= '3.4' requests==2.32.3; python_version >= '3.8' -s3transfer==0.10.3; python_version >= '3.8' -setuptools==75.1.0; python_version >= '3.8' -six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -sqlparse==0.5.1; python_version >= '3.8' -tablib[html,ods,xls,xlsx,yaml]==3.5.0; python_version >= '3.8' +s3transfer==0.10.4; python_version >= '3.8' +setuptools==75.6.0; python_version >= '3.9' +six==1.17.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2' +sqlparse==0.5.3; python_version >= '3.8' +tablib==3.7.0; python_version >= '3.9' tblib==3.0.0; python_version >= '3.8' typing-extensions==4.12.2; python_version >= '3.8' -urllib3==2.2.3; python_version >= '3.8' -whitenoise==6.7.0; python_version >= '3.8' +urllib3==2.3.0; python_version >= '3.9' +whitenoise==6.8.2; python_version >= '3.9' zope.event==5.0; python_version >= '3.7' -zope.interface==7.1.0; python_version >= '3.8' +zope.interface==7.2; python_version >= '3.8' From 16f44584b59ed26f5c4bbb9771ea93dea3b9f2e0 Mon Sep 17 00:00:00 2001 From: CocoByte Date: Thu, 2 Jan 2025 14:34:00 -0700 Subject: [PATCH 41/44] UPDATE TO AC -- add left margin for all single-page views --- src/registrar/templates/domain_request_intro.html | 2 +- .../templates/domain_request_withdraw_confirmation.html | 2 +- src/registrar/templates/includes/request_status_manage.html | 6 +++--- src/registrar/templates/portfolio_base.html | 2 +- src/registrar/templates/profile.html | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/registrar/templates/domain_request_intro.html b/src/registrar/templates/domain_request_intro.html index d66d019e6..263201393 100644 --- a/src/registrar/templates/domain_request_intro.html +++ b/src/registrar/templates/domain_request_intro.html @@ -6,7 +6,7 @@ {% block content %}
    -
    +
    {% csrf_token %} diff --git a/src/registrar/templates/domain_request_withdraw_confirmation.html b/src/registrar/templates/domain_request_withdraw_confirmation.html index cc426eeaf..525c6784a 100644 --- a/src/registrar/templates/domain_request_withdraw_confirmation.html +++ b/src/registrar/templates/domain_request_withdraw_confirmation.html @@ -10,7 +10,7 @@ {% block content %}
    -
    +

    Withdraw request for {{ DomainRequest.requested_domain.name }}?

    diff --git a/src/registrar/templates/includes/request_status_manage.html b/src/registrar/templates/includes/request_status_manage.html index 502ac0569..811574f91 100644 --- a/src/registrar/templates/includes/request_status_manage.html +++ b/src/registrar/templates/includes/request_status_manage.html @@ -1,8 +1,8 @@ {% load custom_filters %} {% load static url_helpers %}
    -
    -
    +
    +
    {% block breadcrumb %} {% if portfolio %} {% url 'domain-requests' as url %} @@ -140,7 +140,7 @@ {% endblock modify_request %}
    -
    +
    {% block request_summary_header %}

    Summary of your domain request

    {% endblock request_summary_header%} diff --git a/src/registrar/templates/portfolio_base.html b/src/registrar/templates/portfolio_base.html index 4cafd3f84..4d77cea04 100644 --- a/src/registrar/templates/portfolio_base.html +++ b/src/registrar/templates/portfolio_base.html @@ -9,7 +9,7 @@ {# the entire logged in page goes here #}
    -
    +
    {% block messages %} {% include "includes/form_messages.html" %} {% endblock %} diff --git a/src/registrar/templates/profile.html b/src/registrar/templates/profile.html index cbd2811d1..1d91a2597 100644 --- a/src/registrar/templates/profile.html +++ b/src/registrar/templates/profile.html @@ -12,8 +12,8 @@ Edit your User Profile | {% block content %}
    -
    -
    +
    +
    {% if messages %} {% for message in messages %}
    From 23eb3ebe96dcf563b56518792b92bd22b926b0ef Mon Sep 17 00:00:00 2001 From: CocoByte Date: Thu, 2 Jan 2025 15:31:18 -0700 Subject: [PATCH 42/44] fixed grid gap --- src/registrar/templates/domain_request_form.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/templates/domain_request_form.html b/src/registrar/templates/domain_request_form.html index 59a2474b8..d8b020cc1 100644 --- a/src/registrar/templates/domain_request_form.html +++ b/src/registrar/templates/domain_request_form.html @@ -9,7 +9,7 @@ {% include 'domain_request_sidebar.html' %}
    -
    +
    {% if steps.current == steps.first %} {% if portfolio %} From ce5e6b7d7cc3e1e4c3d0a4d763288b7b7d52d568 Mon Sep 17 00:00:00 2001 From: CocoByte Date: Thu, 2 Jan 2025 17:17:43 -0700 Subject: [PATCH 43/44] Refactored margin on portfolio_ pages so that only single-page layouts have left margin --- src/registrar/templates/portfolio_base.html | 2 +- src/registrar/templates/portfolio_member.html | 2 +- .../templates/portfolio_member_domains.html | 2 +- .../portfolio_member_domains_edit.html | 2 +- .../portfolio_member_permissions.html | 214 +++++------ .../templates/portfolio_members_add_new.html | 340 +++++++++--------- 6 files changed, 283 insertions(+), 279 deletions(-) diff --git a/src/registrar/templates/portfolio_base.html b/src/registrar/templates/portfolio_base.html index 4d77cea04..4cafd3f84 100644 --- a/src/registrar/templates/portfolio_base.html +++ b/src/registrar/templates/portfolio_base.html @@ -9,7 +9,7 @@ {# the entire logged in page goes here #}
    -
    +
    {% block messages %} {% include "includes/form_messages.html" %} {% endblock %} diff --git a/src/registrar/templates/portfolio_member.html b/src/registrar/templates/portfolio_member.html index f492dbd2f..071dba843 100644 --- a/src/registrar/templates/portfolio_member.html +++ b/src/registrar/templates/portfolio_member.html @@ -8,7 +8,7 @@ Organization member {% load static %} {% block portfolio_content %} -
    +
    {% url 'members' as url %}