diff --git a/app/helpers/html_helper.rb b/app/helpers/html_helper.rb
index 82a18722d..8998ffcb9 100644
--- a/app/helpers/html_helper.rb
+++ b/app/helpers/html_helper.rb
@@ -9,7 +9,7 @@ module HtmlHelper
private
EXCLUDED_ELEMENTS = %w[ a figcaption pre code ]
- EMAIL_REGEXP = /\b[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\b/
+ EMAIL_AUTOLINK_REGEXP = /\b[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\b/
URL_REGEXP = URI::DEFAULT_PARSER.make_regexp(%w[http https])
def auto_link(fragment)
@@ -48,7 +48,7 @@ module HtmlHelper
end
def auto_link_emails(text)
- text.gsub!(EMAIL_REGEXP) do |match|
+ text.gsub!(EMAIL_AUTOLINK_REGEXP) do |match|
%(#{match})
end
end
diff --git a/app/models/identity.rb b/app/models/identity.rb
index 135fdaae7..ee4a323b2 100644
--- a/app/models/identity.rb
+++ b/app/models/identity.rb
@@ -10,6 +10,7 @@ class Identity < ApplicationRecord
before_destroy :deactivate_users
+ validates :email_address, format: { with: URI::MailTo::EMAIL_REGEXP }
normalizes :email_address, with: ->(value) { value.strip.downcase.presence }
def send_magic_link(**attributes)
diff --git a/test/controllers/signups_controller_test.rb b/test/controllers/signups_controller_test.rb
index 9d65c7a55..83fea8882 100644
--- a/test/controllers/signups_controller_test.rb
+++ b/test/controllers/signups_controller_test.rb
@@ -34,6 +34,18 @@ class SignupsControllerTest < ActionDispatch::IntegrationTest
end
end
+ test "create with email address containing blanks" do
+ untenanted do
+ assert_no_difference -> { Identity.count } do
+ assert_no_difference -> { MagicLink.count } do
+ post signup_path, params: { signup: { email_address: "sam smith@example.com" } }
+ end
+ end
+
+ assert_response :unprocessable_entity
+ end
+ end
+
test "create for an authenticated user" do
identity = identities(:kevin)
sign_in_as identity
diff --git a/test/models/identity_test.rb b/test/models/identity_test.rb
index 2e7687169..1c6c6b258 100644
--- a/test/models/identity_test.rb
+++ b/test/models/identity_test.rb
@@ -13,6 +13,23 @@ class IdentityTest < ActiveSupport::TestCase
end
end
+ test "email address format validation" do
+ invalid_emails = [
+ "sam smith@example.com", # space in local part
+ "@example.com", # missing local part
+ "test@", # missing domain
+ "test", # missing @ and domain
+ "