From b058df3faa60f3996ad02362432cf7567e87f100 Mon Sep 17 00:00:00 2001
From: FloatingGhost <hannah@coffee-and-dreams.uk>
Date: Tue, 6 Dec 2022 10:57:10 +0000
Subject: [PATCH] Allow dashes in domain name search

---
 lib/pleroma/user/search.ex                    |  7 +++++-
 test/pleroma/user/user_search_test.exs        | 22 +++++++++++++++++++
 .../web/activity_pub/activity_pub_test.exs    | 10 +++++++--
 3 files changed, 36 insertions(+), 3 deletions(-)
 create mode 100644 test/pleroma/user/user_search_test.exs

diff --git a/lib/pleroma/user/search.ex b/lib/pleroma/user/search.ex
index 6b3f58999..ddce51775 100644
--- a/lib/pleroma/user/search.ex
+++ b/lib/pleroma/user/search.ex
@@ -62,6 +62,11 @@ defp maybe_add_uri_match(list, query) do
     end
   end
 
+  def sanitise_domain(domain) do
+    domain
+    |> String.replace(~r/[!-\,|@|?|<|>|[-`|{-~|\/|:|\s]+/, "")
+  end
+
   defp format_query(query_string) do
     # Strip the beginning @ off if there is a query
     query_string = String.trim_leading(query_string, "@")
@@ -69,7 +74,7 @@ defp format_query(query_string) do
     with [name, domain] <- String.split(query_string, "@") do
       encoded_domain =
         domain
-        |> String.replace(~r/[!-\-|@|[-`|{-~|\/|:|\s]+/, "")
+        |> sanitise_domain()
         |> String.to_charlist()
         |> :idna.encode()
         |> to_string()
diff --git a/test/pleroma/user/user_search_test.exs b/test/pleroma/user/user_search_test.exs
new file mode 100644
index 000000000..5ea5bf774
--- /dev/null
+++ b/test/pleroma/user/user_search_test.exs
@@ -0,0 +1,22 @@
+defmodule Pleroma.User.SearchTest do
+  use Pleroma.DataCase
+
+  describe "sanitise_domain/1" do
+    test "should remove url-reserved characters" do
+      examples = [
+        ["example.com", "example.com"],
+        ["no spaces", "nospaces"],
+        ["no@at", "noat"],
+        ["dash-is-ok", "dash-is-ok"],
+        ["underscore_not_so_much", "underscorenotsomuch"],
+        ["no!", "no"],
+        ["no?", "no"],
+        ["a$b%s^o*l(u)t'e#l<y n>o/t", "absolutelynot"]
+      ]
+
+      for [input, expected] <- examples do
+        assert Pleroma.User.Search.sanitise_domain(input) == expected
+      end
+    end
+  end
+end
diff --git a/test/pleroma/web/activity_pub/activity_pub_test.exs b/test/pleroma/web/activity_pub/activity_pub_test.exs
index 1ba1ad96a..17c52fc91 100644
--- a/test/pleroma/web/activity_pub/activity_pub_test.exs
+++ b/test/pleroma/web/activity_pub/activity_pub_test.exs
@@ -725,13 +725,19 @@ test "it should return public activities that reference a given hashtag" do
       user = insert(:user)
       other_user = insert(:user)
 
-      {:ok, normally_visible} = CommonAPI.post(other_user, %{status: "hello :)", visibility: "public"})
+      {:ok, normally_visible} =
+        CommonAPI.post(other_user, %{status: "hello :)", visibility: "public"})
+
       {:ok, public} = CommonAPI.post(user, %{status: "maji #tenshi", visibility: "public"})
       {:ok, _unrelated} = CommonAPI.post(user, %{status: "dai #tensh", visibility: "public"})
       {:ok, unlisted} = CommonAPI.post(user, %{status: "maji #tenshi", visibility: "unlisted"})
       {:ok, _private} = CommonAPI.post(user, %{status: "maji #tenshi", visibility: "private"})
 
-      activities = ActivityPub.fetch_activities([other_user.follower_address], %{followed_hashtags: [hashtag.id]})
+      activities =
+        ActivityPub.fetch_activities([other_user.follower_address], %{
+          followed_hashtags: [hashtag.id]
+        })
+
       assert length(activities) == 3
       normal_id = normally_visible.id
       public_id = public.id