about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2019-12-30 19:20:43 +0100
committerGitHub <noreply@github.com>2019-12-30 19:20:43 +0100
commitf86ee4b59f25727d248609e0afe277a4f69f6be7 (patch)
tree8bc4518d8ec59d2f23f10a5c5a67709bee2de610 /app
parentb2f81060b75e5128279cd3f85f55de0982e8f35b (diff)
Fix IDN mentions not being processed, IDN domains not being rendered (#12715)
This changes the REST API to return unicode domains in the `acct`
attribute instead of punycode, and to render unicode instead of
punycode on public HTML pages as well.

Fix #7812, fix #12246
Diffstat (limited to 'app')
-rw-r--r--app/helpers/accounts_helper.rb2
-rw-r--r--app/models/account.rb6
-rw-r--r--app/serializers/rest/account_serializer.rb4
-rw-r--r--app/services/process_mentions_service.rb11
4 files changed, 20 insertions, 3 deletions
diff --git a/app/helpers/accounts_helper.rb b/app/helpers/accounts_helper.rb
index 99815be7b..53939adfc 100644
--- a/app/helpers/accounts_helper.rb
+++ b/app/helpers/accounts_helper.rb
@@ -13,7 +13,7 @@ module AccountsHelper
     if account.local?
       "@#{account.acct}@#{Rails.configuration.x.local_domain}"
     else
-      "@#{account.acct}"
+      "@#{account.pretty_acct}"
     end
   end
 
diff --git a/app/models/account.rb b/app/models/account.rb
index 884332e5a..feaf273c1 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -50,7 +50,7 @@
 
 class Account < ApplicationRecord
   USERNAME_RE = /[a-z0-9_]+([a-z0-9_\.-]+[a-z0-9_]+)?/i
-  MENTION_RE  = /(?<=^|[^\/[:word:]])@((#{USERNAME_RE})(?:@[a-z0-9\.\-]+[a-z0-9]+)?)/i
+  MENTION_RE  = /(?<=^|[^\/[:word:]])@((#{USERNAME_RE})(?:@[[:word:]\.\-]+[a-z0-9]+)?)/i
 
   include AccountAssociations
   include AccountAvatar
@@ -164,6 +164,10 @@ class Account < ApplicationRecord
     local? ? username : "#{username}@#{domain}"
   end
 
+  def pretty_acct
+    local? ? username : "#{username}@#{Addressable::IDNA.to_unicode(domain)}"
+  end
+
   def local_username_and_domain
     "#{username}@#{Rails.configuration.x.local_domain}"
   end
diff --git a/app/serializers/rest/account_serializer.rb b/app/serializers/rest/account_serializer.rb
index 5fec75673..fd361a34c 100644
--- a/app/serializers/rest/account_serializer.rb
+++ b/app/serializers/rest/account_serializer.rb
@@ -24,6 +24,10 @@ class REST::AccountSerializer < ActiveModel::Serializer
     object.id.to_s
   end
 
+  def acct
+    object.pretty_acct
+  end
+
   def note
     Formatter.instance.simplified_format(object)
   end
diff --git a/app/services/process_mentions_service.rb b/app/services/process_mentions_service.rb
index 2f7a9e985..b2d868165 100644
--- a/app/services/process_mentions_service.rb
+++ b/app/services/process_mentions_service.rb
@@ -14,7 +14,16 @@ class ProcessMentionsService < BaseService
     mentions = []
 
     status.text = status.text.gsub(Account::MENTION_RE) do |match|
-      username, domain  = Regexp.last_match(1).split('@')
+      username, domain = Regexp.last_match(1).split('@')
+
+      domain = begin
+        if TagManager.instance.local_domain?(domain)
+          nil
+        else
+          TagManager.instance.normalize_domain(domain)
+        end
+      end
+
       mentioned_account = Account.find_remote(username, domain)
 
       if mention_undeliverable?(mentioned_account)