Repository: zulip/zulip

Issue:
Bug: Resend button during organization verification redirects to create page
When verifying a new organization, clicking on the "resend" button to receive the verification link again redirects the user to the "create organization" page, rather than resending the email. This can lead to confusion and frustration for users who expect the verification link to be resent.

Expected behavior:
Clicking on the "resend" button should resend the verification link to the specified email address.

Actual behavior:
Clicking on the "resend" button redirects the user to the "create organization" page.


Discussion:
@sahil839 Is this potentially related to #24689?
Got it. It is related to that only. Will open a PR.

Resolving patch:
diff --git a/zerver/models.py b/zerver/models.py
--- a/zerver/models.py
+++ b/zerver/models.py
@@ -623,6 +623,8 @@ class Realm(models.Model):  # type: ignore[django-manager-missing] # django-stub
         },
     }
 
+    ORG_TYPE_IDS: List[int] = [t["id"] for t in ORG_TYPES.values()]
+
     org_type = models.PositiveSmallIntegerField(
         default=ORG_TYPES["unspecified"]["id"],
         choices=[(t["id"], t["name"]) for t in ORG_TYPES.values()],
diff --git a/zerver/views/realm.py b/zerver/views/realm.py
--- a/zerver/views/realm.py
+++ b/zerver/views/realm.py
@@ -1,4 +1,4 @@
-from typing import Any, Dict, List, Optional, Union
+from typing import Any, Dict, Optional, Union
 
 from django.core.exceptions import ValidationError
 from django.http import HttpRequest, HttpResponse
@@ -40,8 +40,6 @@
 from zerver.models import Realm, RealmReactivationStatus, RealmUserDefault, UserProfile
 from zerver.views.user_settings import check_settings_values
 
-ORG_TYPE_IDS: List[int] = [t["id"] for t in Realm.ORG_TYPES.values()]
-
 
 @require_realm_admin
 @has_request_variables
@@ -137,7 +135,7 @@ def update_realm(
         str_validator=check_capped_string(Realm.MAX_REALM_SUBDOMAIN_LENGTH),
         default=None,
     ),
-    org_type: Optional[int] = REQ(json_validator=check_int_in(ORG_TYPE_IDS), default=None),
+    org_type: Optional[int] = REQ(json_validator=check_int_in(Realm.ORG_TYPE_IDS), default=None),
     enable_spectator_access: Optional[bool] = REQ(json_validator=check_bool, default=None),
     want_advertise_in_communities_directory: Optional[bool] = REQ(
         json_validator=check_bool, default=None
diff --git a/zerver/views/registration.py b/zerver/views/registration.py
--- a/zerver/views/registration.py
+++ b/zerver/views/registration.py
@@ -58,7 +58,13 @@
 from zerver.lib.subdomains import get_subdomain
 from zerver.lib.url_encoding import append_url_query_string
 from zerver.lib.users import get_accounts_for_email
-from zerver.lib.validator import to_converted_or_fallback, to_non_negative_int, to_timezone_or_empty
+from zerver.lib.validator import (
+    check_capped_string,
+    check_int_in,
+    to_converted_or_fallback,
+    to_non_negative_int,
+    to_timezone_or_empty,
+)
 from zerver.lib.zephyr import compute_mit_user_fullname
 from zerver.models import (
     DisposableEmailError,
@@ -756,7 +762,14 @@ def create_realm(request: HttpRequest, creation_key: Optional[str] = None) -> Ht
             if key_record is not None:
                 key_record.delete()
             new_realm_send_confirm_url = reverse("new_realm_send_confirm")
-            query = urlencode({"email": email})
+            query = urlencode(
+                {
+                    "email": email,
+                    "realm_name": realm_name,
+                    "realm_type": realm_type,
+                    "realm_subdomain": realm_subdomain,
+                }
+            )
             url = append_url_query_string(new_realm_send_confirm_url, query)
             return HttpResponseRedirect(url)
     else:
@@ -787,11 +800,26 @@ def signup_send_confirm(request: HttpRequest, email: str = REQ("email")) -> Http
 
 @add_google_analytics
 @has_request_variables
-def new_realm_send_confirm(request: HttpRequest, email: str = REQ("email")) -> HttpResponse:
+def new_realm_send_confirm(
+    request: HttpRequest,
+    email: str = REQ("email"),
+    realm_name: str = REQ(str_validator=check_capped_string(Realm.MAX_REALM_NAME_LENGTH)),
+    realm_type: int = REQ(json_validator=check_int_in(Realm.ORG_TYPE_IDS)),
+    realm_subdomain: str = REQ(str_validator=check_capped_string(Realm.MAX_REALM_SUBDOMAIN_LENGTH)),
+) -> HttpResponse:
     return TemplateResponse(
         request,
         "zerver/accounts_send_confirm.html",
-        context={"email": email, "realm_creation": True},
+        context={
+            "email": email,
+            # Using "new_realm_name" key here since "realm_name" key is already present in
+            # the context provided by zulip_default_context and it is "None" during realm
+            # creation.
+            "new_realm_name": realm_name,
+            "realm_type": realm_type,
+            "realm_subdomain": realm_subdomain,
+            "realm_creation": True,
+        },
     )
 
 


Test patch:
diff --git a/zerver/tests/test_management_commands.py b/zerver/tests/test_management_commands.py
--- a/zerver/tests/test_management_commands.py
+++ b/zerver/tests/test_management_commands.py
@@ -323,20 +323,23 @@ def test_generate_link_and_create_realm(self) -> None:
     @override_settings(OPEN_REALM_CREATION=False)
     def test_generate_link_confirm_email(self) -> None:
         email = "user1@test.com"
+        realm_name = "Zulip test"
+        string_id = "zuliptest"
         generated_link = generate_realm_creation_url(by_admin=False)
 
         result = self.client_post(
             generated_link,
             {
                 "email": email,
-                "realm_name": "Zulip test",
+                "realm_name": realm_name,
                 "realm_type": Realm.ORG_TYPES["business"]["id"],
-                "realm_subdomain": "zuliptest",
+                "realm_subdomain": string_id,
             },
         )
         self.assertEqual(result.status_code, 302)
         self.assertEqual(
-            f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}", result["Location"]
+            f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(realm_name)}&realm_type=10&realm_subdomain={string_id}",
+            result["Location"],
         )
         result = self.client_get(result["Location"])
         self.assert_in_response("Check your email", result)
diff --git a/zerver/tests/test_signup.py b/zerver/tests/test_signup.py
--- a/zerver/tests/test_signup.py
+++ b/zerver/tests/test_signup.py
@@ -758,7 +758,9 @@ def test_redirect_endpoints(self) -> None:
         result = self.client_get("/accounts/send_confirm/?email=alice@example.com")
         self.assert_in_success_response(["/accounts/home/"], result)
 
-        result = self.client_get("/accounts/new/send_confirm/?email=alice@example.com")
+        result = self.client_get(
+            "/accounts/new/send_confirm/?email=alice@example.com&realm_name=Zulip+test&realm_type=10&realm_subdomain=zuliptest"
+        )
         self.assert_in_success_response(["/new/"], result)
 
     def test_password_reset_for_soft_deactivated_user(self) -> None:
@@ -1266,7 +1268,7 @@ def check_able_to_create_realm(self, email: str, password: str = "test") -> None
         self.assertEqual(result.status_code, 302)
         self.assertTrue(
             result["Location"].endswith(
-                f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}"
+                f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(org_name)}&realm_type=10&realm_subdomain={string_id}"
             )
         )
         result = self.client_get(result["Location"])
@@ -1401,7 +1403,7 @@ def test_create_realm_with_subdomain(self) -> None:
         self.assertEqual(result.status_code, 302)
         self.assertTrue(
             result["Location"].endswith(
-                f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}"
+                f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(realm_name)}&realm_type=10&realm_subdomain={string_id}"
             )
         )
         result = self.client_get(result["Location"])
@@ -1447,7 +1449,7 @@ def test_create_realm_with_marketing_emails_enabled(self) -> None:
         self.assertEqual(result.status_code, 302)
         self.assertTrue(
             result["Location"].endswith(
-                f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}"
+                f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(realm_name)}&realm_type=10&realm_subdomain={string_id}"
             )
         )
         result = self.client_get(result["Location"])
@@ -1496,7 +1498,7 @@ def test_create_realm_without_prompting_for_marketing_emails(self) -> None:
         self.assertEqual(result.status_code, 302)
         self.assertTrue(
             result["Location"].endswith(
-                f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}"
+                f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(realm_name)}&realm_type=10&realm_subdomain={string_id}"
             )
         )
         result = self.client_get(result["Location"])
@@ -1543,7 +1545,7 @@ def test_create_realm_with_marketing_emails_disabled(self) -> None:
         password = "test"
         string_id = "zuliptest"
         email = "user1@test.com"
-        realm_name = "Test"
+        realm_name = "Zulip test"
 
         # Make sure the realm does not exist
         with self.assertRaises(Realm.DoesNotExist):
@@ -1551,12 +1553,12 @@ def test_create_realm_with_marketing_emails_disabled(self) -> None:
 
         # Create new realm with the email
         result = self.submit_realm_creation_form(
-            email, realm_subdomain=string_id, realm_name="Zulip test"
+            email, realm_subdomain=string_id, realm_name=realm_name
         )
         self.assertEqual(result.status_code, 302)
         self.assertTrue(
             result["Location"].endswith(
-                f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}"
+                f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(realm_name)}&realm_type=10&realm_subdomain={string_id}"
             )
         )
         result = self.client_get(result["Location"])
@@ -1601,7 +1603,7 @@ def test_create_regular_realm_welcome_bot_pm(self) -> None:
         self.assertEqual(result.status_code, 302)
         self.assertTrue(
             result["Location"].endswith(
-                f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}"
+                f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(realm_name)}&realm_type=10&realm_subdomain={string_id}"
             )
         )
         result = self.client_get(result["Location"])
@@ -1642,7 +1644,7 @@ def test_create_demo_realm_welcome_bot_pm(self) -> None:
         self.assertEqual(result.status_code, 302)
         self.assertTrue(
             result["Location"].endswith(
-                f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}"
+                f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(realm_name)}&realm_type=10&realm_subdomain={string_id}"
             )
         )
         result = self.client_get(result["Location"])
@@ -1687,7 +1689,7 @@ def test_create_realm_during_free_trial(self) -> None:
         self.assertEqual(result.status_code, 302)
         self.assertTrue(
             result["Location"].endswith(
-                f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}"
+                f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(realm_name)}&realm_type=10&realm_subdomain={string_id}"
             )
         )
         result = self.client_get(result["Location"])
@@ -1741,7 +1743,7 @@ def test_create_two_realms(self) -> None:
         self.assertEqual(result.status_code, 302)
         self.assertTrue(
             result["Location"].endswith(
-                f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}"
+                f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(first_realm_name)}&realm_type=10&realm_subdomain={first_string_id}"
             )
         )
         result = self.client_get(result["Location"])
@@ -1755,7 +1757,7 @@ def test_create_two_realms(self) -> None:
         self.assertEqual(result.status_code, 302)
         self.assertTrue(
             result["Location"].endswith(
-                f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}"
+                f"/accounts/new/send_confirm/?email={urllib.parse.quote(email)}&realm_name={urllib.parse.quote_plus(second_realm_name)}&realm_type=10&realm_subdomain={second_string_id}"
             )
         )
         result = self.client_get(result["Location"])