diff --git a/hc/front/forms.py b/hc/front/forms.py index d569bd68..a87300c5 100644 --- a/hc/front/forms.py +++ b/hc/front/forms.py @@ -284,15 +284,14 @@ class PhoneUpDownForm(PhoneNumberForm): class SignalRecipientForm(forms.Form): error_css_class = "has-error" label = forms.CharField(max_length=100, required=False) - phone = forms.CharField() + recipient = forms.CharField() - def clean_phone(self) -> str: - v = self.cleaned_data["phone"] + def clean_recipient(self) -> str: + v = self.cleaned_data["recipient"] stripped = v.encode("ascii", "ignore").decode("ascii") assert isinstance(stripped, str) stripped = stripped.replace(" ", "").replace("-", "") - if "." in stripped: # Assume it is a username if not re.match(r"^\w{3,48}\.\d{2,10}$", stripped): @@ -321,7 +320,7 @@ class SignalForm(SignalRecipientForm): def get_json(self) -> str: return json.dumps( { - "value": self.cleaned_data["phone"], + "value": self.cleaned_data["recipient"], "up": self.cleaned_data["up"], "down": self.cleaned_data["down"], } diff --git a/hc/front/tests/test_add_signal.py b/hc/front/tests/test_add_signal.py index f9e59b57..efe3aa69 100644 --- a/hc/front/tests/test_add_signal.py +++ b/hc/front/tests/test_add_signal.py @@ -22,7 +22,7 @@ class AddSignalTestCase(BaseTestCase): def test_it_creates_channel(self) -> None: form = { "label": "My Phone", - "phone": "+1234567890", + "recipient": "+1234567890", "down": "true", "up": "true", } @@ -45,7 +45,7 @@ class AddSignalTestCase(BaseTestCase): def test_it_handles_username(self) -> None: form = { "label": "My Phone", - "phone": "foobar.123", + "recipient": "foobar.123", "down": "true", "up": "true", } @@ -71,7 +71,7 @@ class AddSignalTestCase(BaseTestCase): self.assertEqual(r.status_code, 403) def test_it_handles_down_false_up_true(self) -> None: - form = {"phone": "+1234567890", "up": True} + form = {"recipient": "+1234567890", "up": True} self.client.login(username="alice@example.org", password="password") self.client.post(self.url, form) @@ -81,7 +81,7 @@ class AddSignalTestCase(BaseTestCase): self.assertTrue(c.phone.notify_up) def test_it_rejects_unchecked_up_and_down(self) -> None: - form = {"phone": "+1234567890"} + form = {"recipient": "+1234567890"} self.client.login(username="alice@example.org", password="password") r = self.client.post(self.url, form) @@ -90,17 +90,17 @@ class AddSignalTestCase(BaseTestCase): def test_it_rejects_bad_phone(self) -> None: for v in ["not a phone number", False, 15, "+123456789A"]: self.client.login(username="alice@example.org", password="password") - r = self.client.post(self.url, {"phone": v}) + r = self.client.post(self.url, {"recipient": v}) self.assertContains(r, "Invalid phone number format.") def test_it_rejects_bad_username(self) -> None: for v in ["a.123", "foobar.0"]: self.client.login(username="alice@example.org", password="password") - r = self.client.post(self.url, {"phone": v}) + r = self.client.post(self.url, {"recipient": v}) self.assertContains(r, "Invalid username format.") def test_it_strips_invisible_formatting_characters(self) -> None: - form = {"phone": "\u202c+1234567890\u202c", "down": True} + form = {"recipient": "\u202c+1234567890\u202c", "down": True} self.client.login(username="alice@example.org", password="password") r = self.client.post(self.url, form) @@ -110,7 +110,7 @@ class AddSignalTestCase(BaseTestCase): self.assertEqual(c.phone.value, "+1234567890") def test_it_strips_hyphens(self) -> None: - form = {"phone": "+123-4567890", "down": True} + form = {"recipient": "+123-4567890", "down": True} self.client.login(username="alice@example.org", password="password") r = self.client.post(self.url, form) @@ -120,7 +120,7 @@ class AddSignalTestCase(BaseTestCase): self.assertEqual(c.phone.value, "+1234567890") def test_it_strips_spaces(self) -> None: - form = {"phone": " +123 45 678 90 ", "down": True} + form = {"recipient": " +123 45 678 90 ", "down": True} self.client.login(username="alice@example.org", password="password") r = self.client.post(self.url, form) diff --git a/hc/front/tests/test_edit_signal.py b/hc/front/tests/test_edit_signal.py index 333c7282..cb1f40ea 100644 --- a/hc/front/tests/test_edit_signal.py +++ b/hc/front/tests/test_edit_signal.py @@ -32,7 +32,7 @@ class EditSignalTestCase(BaseTestCase): def test_it_updates_channel(self) -> None: form = { "label": "My Phone", - "phone": "+1234567890", + "recipient": "+1234567890", "down": "true", "up": "false", } @@ -53,7 +53,7 @@ class EditSignalTestCase(BaseTestCase): def test_it_handles_username(self) -> None: form = { "label": "My Phone", - "phone": "foobar.123", + "recipient": "foobar.123", "down": "true", "up": "false", } diff --git a/hc/front/tests/test_verify_signal_number.py b/hc/front/tests/test_verify_signal_number.py index 804f5423..ca7b6b9a 100644 --- a/hc/front/tests/test_verify_signal_number.py +++ b/hc/front/tests/test_verify_signal_number.py @@ -19,7 +19,7 @@ class VerifySignalNumberTestCase(BaseTestCase): @patch("hc.front.views.Signal") def test_it_works(self, mock_signal: Mock) -> None: self.client.login(username="alice@example.org", password="password") - r = self.client.post(self.url, {"phone": "+1234567890"}) + r = self.client.post(self.url, {"recipient": "+1234567890"}) self.assertContains(r, "All good, the message was sent") @patch("hc.front.views.Signal") @@ -27,7 +27,7 @@ class VerifySignalNumberTestCase(BaseTestCase): mock_signal.send.side_effect = TransportError("CAPTCHA proof required") self.client.login(username="alice@example.org", password="password") - r = self.client.post(self.url, {"phone": "+1234567890"}) + r = self.client.post(self.url, {"recipient": "+1234567890"}) self.assertContains(r, "We hit a Signal rate-limit") @patch("hc.front.views.Signal") @@ -35,7 +35,7 @@ class VerifySignalNumberTestCase(BaseTestCase): mock_signal.send.side_effect = TransportError("Recipient not found") self.client.login(username="alice@example.org", password="password") - r = self.client.post(self.url, {"phone": "+1234567890"}) + r = self.client.post(self.url, {"recipient": "+1234567890"}) self.assertContains(r, "Recipient not found") @patch("hc.front.views.Signal") @@ -43,13 +43,13 @@ class VerifySignalNumberTestCase(BaseTestCase): mock_signal.send.side_effect = TransportError("signal-cli call failed (123)") self.client.login(username="alice@example.org", password="password") - r = self.client.post(self.url, {"phone": "+1234567890"}) + r = self.client.post(self.url, {"recipient": "+1234567890"}) self.assertContains(r, "signal-cli call failed") @patch("hc.front.views.Signal") def test_it_handles_invalid_phone_number(self, mock_signal: Mock) -> None: self.client.login(username="alice@example.org", password="password") - r = self.client.post(self.url, {"phone": "+123"}) + r = self.client.post(self.url, {"recipient": "+123"}) self.assertContains(r, "Invalid phone number") def test_it_requires_post(self) -> None: @@ -58,14 +58,14 @@ class VerifySignalNumberTestCase(BaseTestCase): self.assertEqual(r.status_code, 405) def test_it_requires_authenticated_user(self) -> None: - r = self.client.post(self.url, {"phone": "+1234567890"}) + r = self.client.post(self.url, {"recipient": "+1234567890"}) self.assertRedirects(r, "/accounts/login/?next=" + self.url) def test_it_obeys_per_account_rate_limit(self) -> None: TokenBucket.objects.create(value=f"signal-verify-{self.alice.id}", tokens=0) self.client.login(username="alice@example.org", password="password") - r = self.client.post(self.url, {"phone": "+1234567890"}) + r = self.client.post(self.url, {"recipient": "+1234567890"}) self.assertContains(r, "Verification rate limit exceeded") @override_settings(SECRET_KEY="test-secret") @@ -76,5 +76,5 @@ class VerifySignalNumberTestCase(BaseTestCase): obj.save() self.client.login(username="alice@example.org", password="password") - r = self.client.post(self.url, {"phone": "+123456789"}) + r = self.client.post(self.url, {"recipient": "+123456789"}) self.assertContains(r, "Verification rate limit exceeded") diff --git a/hc/front/views.py b/hc/front/views.py index 4c6f77c5..dad5c458 100644 --- a/hc/front/views.py +++ b/hc/front/views.py @@ -2285,7 +2285,7 @@ def signal_form(request: HttpRequest, channel: Channel) -> HttpResponse: form = forms.SignalForm( { "label": channel.name, - "phone": channel.phone.value, + "recipient": channel.phone.value, "up": channel.phone.notify_up, "down": channel.phone.notify_down, } @@ -2697,13 +2697,13 @@ def verify_signal_number(request: AuthenticatedHttpRequest) -> HttpResponse: if not form.is_valid(): return render_result("Invalid phone number") - phone = form.cleaned_data["phone"] + recipient = form.cleaned_data["recipient"] # Enforce per-recipient rate limit (6 messages per minute) - if not TokenBucket.authorize_signal(phone): + if not TokenBucket.authorize_signal(recipient): return render_result("Verification rate limit exceeded") try: - Signal.send(phone, f"Test message from {settings.SITE_NAME}") + Signal.send(recipient, f"Test message from {settings.SITE_NAME}") except TransportError as e: return render_result(e.message) diff --git a/static/js/signal_form.js b/static/js/signal_form.js index 0f46097e..e3307de0 100644 --- a/static/js/signal_form.js +++ b/static/js/signal_form.js @@ -15,7 +15,7 @@ $(function () { url: url, type: "post", headers: { "X-CSRFToken": token }, - data: { phone: $("#id_number").val() }, + data: { recipient: $("#id_number").val() }, success: function (data) { $("#verify-result").html(data); $("#submit-btn").attr("disabled", data.indexOf("alert-success") == -1); diff --git a/templates/integrations/signal_form.html b/templates/integrations/signal_form.html index d8ebf07a..de3039fa 100644 --- a/templates/integrations/signal_form.html +++ b/templates/integrations/signal_form.html @@ -45,7 +45,7 @@ Signal Settings - {% site_name %} </div> </div> - <div class="form-group {{ form.phone.css_classes }}"> + <div class="form-group {{ form.recipient.css_classes }}"> <label for="id_number" class="col-sm-2 control-label">Phone or Username</label> <div class="col-sm-6"> <div class="input-group"> @@ -53,9 +53,9 @@ Signal Settings - {% site_name %} id="id_number" type="text" class="form-control" - name="phone" + name="recipient" placeholder="+1234567890 or xyz.123" - value="{{ form.phone.value|default:"" }}"> + value="{{ form.recipient.value|default:"" }}"> <span class="input-group-btn"> <button @@ -69,9 +69,9 @@ Signal Settings - {% site_name %} </span> </div> - {% if form.phone.errors %} + {% if form.recipient.errors %} <div class="help-block"> - {{ form.phone.errors|join:"" }} + {{ form.recipient.errors|join:"" }} </div> {% else %} <span class="help-block">