diff --git a/app/assets/javascripts/discourse/controllers/invite.js.es6 b/app/assets/javascripts/discourse/controllers/invite.js.es6 index fa951677383..54edc7706ce 100644 --- a/app/assets/javascripts/discourse/controllers/invite.js.es6 +++ b/app/assets/javascripts/discourse/controllers/invite.js.es6 @@ -20,12 +20,25 @@ export default Ember.Controller.extend(ModalFunctionality, { if (!this.get('invitingToTopic') && !Discourse.Utilities.emailValid(emailOrUsername)) return true; // normal users (not admin) can't invite users to private topic via email if (!this.get('isAdmin') && this.get('isPrivateTopic') && Discourse.Utilities.emailValid(emailOrUsername)) return true; - // when invting to private topic via email, group name must be specified + // when inviting to private topic via email, group name must be specified if (this.get('isPrivateTopic') && Ember.isEmpty(this.get('model.groupNames')) && Discourse.Utilities.emailValid(emailOrUsername)) return true; if (this.get('model.details.can_invite_to')) return false; return false; }.property('isAdmin', 'emailOrUsername', 'invitingToTopic', 'isPrivateTopic', 'model.groupNames', 'model.saving'), + disabledCopyLink: function() { + if (this.get('model.saving')) return true; + if (Ember.isEmpty(this.get('emailOrUsername'))) return true; + const emailOrUsername = this.get('emailOrUsername').trim(); + // email must be valid + if (!Discourse.Utilities.emailValid(emailOrUsername)) return true; + // normal users (not admin) can't invite users to private topic via email + if (!this.get('isAdmin') && this.get('isPrivateTopic') && Discourse.Utilities.emailValid(emailOrUsername)) return true; + // when inviting to private topic via email, group name must be specified + if (this.get('isPrivateTopic') && Ember.isEmpty(this.get('model.groupNames')) && Discourse.Utilities.emailValid(emailOrUsername)) return true; + return false; + }.property('emailOrUsername', 'model.saving', 'isPrivateTopic', 'model.groupNames'), + buttonTitle: function() { return this.get('model.saving') ? 'topic.inviting' : 'topic.invite_reply.action'; }.property('model.saving'), @@ -36,9 +49,9 @@ export default Ember.Controller.extend(ModalFunctionality, { return this.get('model') !== this.currentUser; }.property('model'), - invitingToForum: function() { - return (!Discourse.SiteSettings.enable_sso && !this.get('invitingToTopic') && !this.get('isMessage')); - }.property('invitingToTopic', 'isMessage'), + showCopyInviteButton: function() { + return (!Discourse.SiteSettings.enable_sso && !this.get('isMessage')); + }.property('isMessage'), topicId: Ember.computed.alias('model.id'), @@ -163,9 +176,15 @@ export default Ember.Controller.extend(ModalFunctionality, { userInvitedController = this.get('controllers.user-invited-show'), model = this.get('model'); + if (this.get('invitingToTopic')) { + var topicId = this.get('model.id'); + } else { + var topicId = null; + } + model.setProperties({ saving: true, error: false }); - return this.get('model').generateInviteLink(this.get('emailOrUsername').trim(), groupNames).then(result => { + return this.get('model').generateInviteLink(this.get('emailOrUsername').trim(), groupNames, topicId).then(result => { model.setProperties({ saving: false, finished: true, inviteLink: result }); Invite.findInvitedBy(this.currentUser, userInvitedController.get('filter')).then(invite_model => { userInvitedController.set('model', invite_model); diff --git a/app/assets/javascripts/discourse/models/topic.js.es6 b/app/assets/javascripts/discourse/models/topic.js.es6 index 157af104dd4..3b63069ed76 100644 --- a/app/assets/javascripts/discourse/models/topic.js.es6 +++ b/app/assets/javascripts/discourse/models/topic.js.es6 @@ -263,6 +263,13 @@ const Topic = RestModel.extend({ }); }, + generateInviteLink: function(email, groupNames, topicId) { + return Discourse.ajax('/invites/link', { + type: 'POST', + data: {email: email, group_names: groupNames, topic_id: topicId} + }); + }, + // Delete this topic destroy(deleted_by) { this.setProperties({ diff --git a/app/assets/javascripts/discourse/models/user.js.es6 b/app/assets/javascripts/discourse/models/user.js.es6 index 8e3d15e2934..19cf8eace75 100644 --- a/app/assets/javascripts/discourse/models/user.js.es6 +++ b/app/assets/javascripts/discourse/models/user.js.es6 @@ -372,10 +372,10 @@ const User = RestModel.extend({ }); }, - generateInviteLink: function(email, groupNames) { + generateInviteLink: function(email, groupNames, topicId) { return Discourse.ajax('/invites/link', { type: 'POST', - data: {email: email, group_names: groupNames} + data: {email: email, group_names: groupNames, topic_id: topicId} }); }, diff --git a/app/assets/javascripts/discourse/templates/modal/invite.hbs b/app/assets/javascripts/discourse/templates/modal/invite.hbs index 0f41fb3973b..a5ccb897f10 100644 --- a/app/assets/javascripts/discourse/templates/modal/invite.hbs +++ b/app/assets/javascripts/discourse/templates/modal/invite.hbs @@ -29,8 +29,8 @@ {{d-button class="btn-primary" action="closeModal" label="close"}} {{else}} {{d-button icon="envelope" action="createInvite" class="btn-primary" disabled=disabled label=buttonTitle}} - {{#if invitingToForum}} - {{d-button icon="link" action="generateInvitelink" class="btn-primary" disabled=disabled label='user.invited.generate_link'}} + {{#if showCopyInviteButton}} + {{d-button icon="link" action="generateInvitelink" class="btn-primary" disabled=disabledCopyLink label='user.invited.generate_link'}} {{/if}} {{/if}} diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb index c8d5679e76c..eeb55b67f44 100644 --- a/app/controllers/invites_controller.rb +++ b/app/controllers/invites_controller.rb @@ -51,6 +51,7 @@ class InvitesController < ApplicationController def create_invite_link params.require(:email) group_ids = Group.lookup_group_ids(params) + topic = Topic.find_by(id: params[:topic_id]) guardian.ensure_can_invite_to_forum!(group_ids) invite_exists = Invite.where(email: params[:email], invited_by_id: current_user.id).first @@ -59,7 +60,7 @@ class InvitesController < ApplicationController end # generate invite link - invite_link = Invite.generate_invite_link(params[:email], current_user, group_ids) + invite_link = Invite.generate_invite_link(params[:email], current_user, topic, group_ids) render_json_dump(invite_link) end diff --git a/app/models/invite.rb b/app/models/invite.rb index 6bc76bfaeaa..8cf304d4567 100644 --- a/app/models/invite.rb +++ b/app/models/invite.rb @@ -72,10 +72,20 @@ class Invite < ActiveRecord::Base end end + def self.invite_by_email(email, invited_by, topic=nil, group_ids=nil) + create_invite_by_email(email, invited_by, topic, group_ids, true) + end + + # generate invite link + def self.generate_invite_link(email, invited_by, topic=nil, group_ids=nil) + invite = create_invite_by_email(email, invited_by, topic, group_ids, false) + return "#{Discourse.base_url}/invites/#{invite.invite_key}" + end + # Create an invite for a user, supplying an optional topic # # Return the previously existing invite if already exists. Returns nil if the invite can't be created. - def self.invite_by_email(email, invited_by, topic=nil, group_ids=nil) + def self.create_invite_by_email(email, invited_by, topic=nil, group_ids=nil, send_email=true) lower_email = Email.downcase(email) user = User.find_by(email: lower_email) @@ -116,40 +126,12 @@ class Invite < ActiveRecord::Base end end - Jobs.enqueue(:invite_email, invite_id: invite.id) + Jobs.enqueue(:invite_email, invite_id: invite.id) if send_email invite.reload invite end - # generate invite link - def self.generate_invite_link(email, invited_by, group_ids=nil) - lower_email = Email.downcase(email) - - invite = Invite.with_deleted - .where(email: lower_email, invited_by_id: invited_by.id) - .order('created_at DESC') - .first - - if invite && (invite.expired? || invite.deleted_at) - invite.destroy - invite = nil - end - - if !invite - invite = Invite.create!(invited_by: invited_by, email: lower_email) - end - - if group_ids.present? - group_ids = group_ids - invite.invited_groups.pluck(:group_id) - group_ids.each do |group_id| - invite.invited_groups.create!(group_id: group_id) - end - end - - return "#{Discourse.base_url}/invites/#{invite.invite_key}" - end - # generate invite tokens without email def self.generate_disposable_tokens(invited_by, quantity=nil, group_names=nil) invite_tokens = []