diff --git a/app/assets/javascripts/discourse/app/lib/utilities.js b/app/assets/javascripts/discourse/app/lib/utilities.js index 0424bdbfc4d..dff0909873a 100644 --- a/app/assets/javascripts/discourse/app/lib/utilities.js +++ b/app/assets/javascripts/discourse/app/lib/utilities.js @@ -145,7 +145,7 @@ export function emailValid(email) { export function hostnameValid(hostname) { // see: https://stackoverflow.com/questions/106179/regular-expression-to-match-dns-hostname-or-ip-address - const re = /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/; + const re = /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)+([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/; return hostname && re.test(hostname); } diff --git a/app/assets/javascripts/discourse/app/templates/modal/create-invite.hbs b/app/assets/javascripts/discourse/app/templates/modal/create-invite.hbs index 0fce75b6681..689a85545ed 100644 --- a/app/assets/javascripts/discourse/app/templates/modal/create-invite.hbs +++ b/app/assets/javascripts/discourse/app/templates/modal/create-invite.hbs @@ -44,7 +44,7 @@ {{else if isDomain}} {{i18n "user.invited.invite.restrict_domain"}} {{else}} - {{i18n "user.invited.invite.restrict_email_or_domain"}} + {{i18n "user.invited.invite.restrict"}} {{/if}} </label> <div class="invite-email-container"> diff --git a/app/models/invite.rb b/app/models/invite.rb index 77cc9fc79c2..52c0a97b425 100644 --- a/app/models/invite.rb +++ b/app/models/invite.rb @@ -15,7 +15,7 @@ class Invite < ActiveRecord::Base } BULK_INVITE_EMAIL_LIMIT = 200 - HOSTNAME_REGEX = /\A(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])\z/ + DOMAIN_REGEX = /\A(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)+([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])\z/ rate_limit :limit_invites_per_day @@ -292,7 +292,7 @@ class Invite < ActiveRecord::Base self.domain.downcase! - if self.domain !~ Invite::HOSTNAME_REGEX + if self.domain !~ Invite::DOMAIN_REGEX self.errors.add(:base, I18n.t('invite.domain_not_allowed', domain: self.domain)) end end diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 05a88bd7994..cfe37659c19 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -1621,10 +1621,10 @@ en: show_advanced: "Show Advanced Options" hide_advanced: "Hide Advanced Options" - restrict_email_or_domain: "Restrict to email or domain" - email_or_domain_placeholder: "name@example.com or example.com" + restrict: "Restrict to" restrict_email: "Restrict to email" restrict_domain: "Restrict to domain" + email_or_domain_placeholder: "name@example.com or example.com" max_redemptions_allowed: "Max uses" diff --git a/spec/models/invite_spec.rb b/spec/models/invite_spec.rb index 58f32775397..dd3e6a66452 100644 --- a/spec/models/invite_spec.rb +++ b/spec/models/invite_spec.rb @@ -38,6 +38,14 @@ describe Invite do expect(invite.valid?).to eq(false) expect(invite.errors.full_messages).to include(I18n.t('invite.invalid_email', email: invite.email)) end + + it 'allows only valid domains' do + invite = Fabricate.build(:invite, domain: 'example', invited_by: user) + expect(invite).not_to be_valid + + invite = Fabricate.build(:invite, domain: 'example.com', invited_by: user) + expect(invite).to be_valid + end end context 'before_save' do