From d2c2139da809fe8dc80b54f37672a4294557527f Mon Sep 17 00:00:00 2001 From: Arpit Jalan Date: Mon, 29 May 2017 13:15:01 +0530 Subject: [PATCH] FEATURE: require name when accepting invite if 'full name required' setting is enabled --- .../discourse/controllers/create-account.js.es6 | 12 ++---------- .../discourse/controllers/invites-show.js.es6 | 15 +++++++++++---- .../discourse/mixins/name-validation.js.es6 | 15 +++++++++++++++ .../discourse/mixins/username-validation.js.es6 | 2 +- .../discourse/templates/invites/show.hbs | 13 ++++++++----- app/controllers/invites_controller.rb | 4 +++- config/locales/client.en.yml | 2 ++ .../acceptance/invite-accept-test.js.es6 | 12 +++++++++++- 8 files changed, 53 insertions(+), 22 deletions(-) create mode 100644 app/assets/javascripts/discourse/mixins/name-validation.js.es6 diff --git a/app/assets/javascripts/discourse/controllers/create-account.js.es6 b/app/assets/javascripts/discourse/controllers/create-account.js.es6 index d77a4db489e..956b9bf35b7 100644 --- a/app/assets/javascripts/discourse/controllers/create-account.js.es6 +++ b/app/assets/javascripts/discourse/controllers/create-account.js.es6 @@ -6,9 +6,10 @@ import { emailValid } from 'discourse/lib/utilities'; import InputValidation from 'discourse/models/input-validation'; import PasswordValidation from "discourse/mixins/password-validation"; import UsernameValidation from "discourse/mixins/username-validation"; +import NameValidation from "discourse/mixins/name-validation"; import { userPath } from 'discourse/lib/url'; -export default Ember.Controller.extend(ModalFunctionality, PasswordValidation, UsernameValidation, { +export default Ember.Controller.extend(ModalFunctionality, PasswordValidation, UsernameValidation, NameValidation, { login: Ember.inject.controller(), complete: false, @@ -85,15 +86,6 @@ export default Ember.Controller.extend(ModalFunctionality, PasswordValidation, U return I18n.t(Discourse.SiteSettings.full_name_required ? 'user.name.instructions_required' : 'user.name.instructions'); }.property(), - // Validate the name. - nameValidation: function() { - if (Discourse.SiteSettings.full_name_required && Ember.isEmpty(this.get('accountName'))) { - return InputValidation.create({ failed: true }); - } - - return InputValidation.create({ok: true}); - }.property('accountName'), - // Check the email address emailValidation: function() { // If blank, fail without a reason diff --git a/app/assets/javascripts/discourse/controllers/invites-show.js.es6 b/app/assets/javascripts/discourse/controllers/invites-show.js.es6 index f6f5fa8150f..d032c769852 100644 --- a/app/assets/javascripts/discourse/controllers/invites-show.js.es6 +++ b/app/assets/javascripts/discourse/controllers/invites-show.js.es6 @@ -4,9 +4,10 @@ import DiscourseURL from 'discourse/lib/url'; import { ajax } from 'discourse/lib/ajax'; import PasswordValidation from "discourse/mixins/password-validation"; import UsernameValidation from "discourse/mixins/username-validation"; +import NameValidation from "discourse/mixins/name-validation"; import { findAll as findLoginMethods } from 'discourse/models/login-method'; -export default Ember.Controller.extend(PasswordValidation, UsernameValidation, { +export default Ember.Controller.extend(PasswordValidation, UsernameValidation, NameValidation, { invitedBy: Ember.computed.alias('model.invited_by'), email: Ember.computed.alias('model.email'), accountUsername: Ember.computed.alias('model.username'), @@ -20,6 +21,11 @@ export default Ember.Controller.extend(PasswordValidation, UsernameValidation, { return I18n.t('invites.welcome_to', {site_name: this.siteSettings.title}); }, + @computed + nameLabel() { + return I18n.t(this.siteSettings.full_name_required ? 'invites.name_label' : 'invites.name_label_optional'); + }, + @computed('email') yourEmailMessage(email) { return I18n.t('invites.your_email', {email: email}); @@ -30,9 +36,9 @@ export default Ember.Controller.extend(PasswordValidation, UsernameValidation, { return findLoginMethods(this.siteSettings, this.capabilities, this.site.isMobileDevice).length > 0; }, - @computed('usernameValidation.failed', 'passwordValidation.failed') - submitDisabled(usernameFailed, passwordFailed) { - return usernameFailed || passwordFailed; + @computed('usernameValidation.failed', 'passwordValidation.failed', 'nameValidation.failed') + submitDisabled(usernameFailed, passwordFailed, nameFailed) { + return usernameFailed || passwordFailed || nameFailed; }, actions: { @@ -42,6 +48,7 @@ export default Ember.Controller.extend(PasswordValidation, UsernameValidation, { type: 'PUT', data: { username: this.get('accountUsername'), + name: this.get('accountName'), password: this.get('accountPassword') } }).then(result => { diff --git a/app/assets/javascripts/discourse/mixins/name-validation.js.es6 b/app/assets/javascripts/discourse/mixins/name-validation.js.es6 new file mode 100644 index 00000000000..8a286522dff --- /dev/null +++ b/app/assets/javascripts/discourse/mixins/name-validation.js.es6 @@ -0,0 +1,15 @@ +import InputValidation from 'discourse/models/input-validation'; +import { default as computed } from 'ember-addons/ember-computed-decorators'; + +export default Ember.Mixin.create({ + + // Validate the name. + @computed('accountName') + nameValidation() { + if (this.siteSettings.full_name_required && Ember.isEmpty(this.get('accountName'))) { + return InputValidation.create({ failed: true }); + } + + return InputValidation.create({ok: true}); + } +}); diff --git a/app/assets/javascripts/discourse/mixins/username-validation.js.es6 b/app/assets/javascripts/discourse/mixins/username-validation.js.es6 index 91e9554c9ff..515d32c3131 100644 --- a/app/assets/javascripts/discourse/mixins/username-validation.js.es6 +++ b/app/assets/javascripts/discourse/mixins/username-validation.js.es6 @@ -40,7 +40,7 @@ export default Ember.Mixin.create({ } // If too short - if (accountUsername.length < Discourse.SiteSettings.min_username_length) { + if (accountUsername.length < this.siteSettings.min_username_length) { return InputValidation.create({ failed: true, reason: I18n.t('user.username.too_short') diff --git a/app/assets/javascripts/discourse/templates/invites/show.hbs b/app/assets/javascripts/discourse/templates/invites/show.hbs index 3857017e37a..5822156abd8 100644 --- a/app/assets/javascripts/discourse/templates/invites/show.hbs +++ b/app/assets/javascripts/discourse/templates/invites/show.hbs @@ -14,9 +14,9 @@ {{#if successMessage}}

{{successMessage}}

- {{else}} + {{else}} -

{{{yourEmailMessage}}} +

{{{yourEmailMessage}}} {{#if externalAuthsEnabled}} {{i18n 'invites.social_login_available'}} {{/if}} @@ -24,14 +24,17 @@

-
{{input value=accountUsername id="new-account-username" name="username" maxlength=maxUsernameLength autocomplete="off"}}  {{input-tip validation=usernameValidation id="username-validation"}}
- + +
+ {{input value=accountName id="new-account-name" name="name"}} +
+
{{password-field value=accountPassword type="password" id="new-account-password" capsLockOn=capsLockOn}}  {{input-tip validation=passwordValidation}} @@ -39,7 +42,7 @@
{{i18n 'login.caps_lock_warning'}}
-
+
diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb index fc7230fec73..1693d1616a7 100644 --- a/app/controllers/invites_controller.rb +++ b/app/controllers/invites_controller.rb @@ -29,11 +29,13 @@ class InvitesController < ApplicationController end def perform_accept_invitation + params.require(:id) + params.permit(:username, :name, :password) invite = Invite.find_by(invite_key: params[:id]) if invite.present? begin - user = invite.redeem(username: params[:username], password: params[:password]) + user = invite.redeem(username: params[:username], name: params[:name], password: params[:password]) if user.present? log_on_user(user) post_process_invite(user) diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 0ab3ececb79..425d20e219c 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -1099,6 +1099,8 @@ en: your_email: "Your account email address is %{email}." accept_invite: "Accept Invitation" success: "Your account has been created and you're now logged in." + name_label: "Name" + name_label_optional: "Name (optional)" password_label: "Set Password (optional)" password_reset: diff --git a/test/javascripts/acceptance/invite-accept-test.js.es6 b/test/javascripts/acceptance/invite-accept-test.js.es6 index 2a58c89e9b8..f89d5329bc0 100644 --- a/test/javascripts/acceptance/invite-accept-test.js.es6 +++ b/test/javascripts/acceptance/invite-accept-test.js.es6 @@ -1,7 +1,11 @@ import { acceptance } from "helpers/qunit-helpers"; import PreloadStore from 'preload-store'; -acceptance("Invite Accept"); +acceptance("Invite Accept", { + settings: { + full_name_required: true + } +}); test("Invite Acceptance Page", () => { PreloadStore.store('invite_info', { @@ -14,7 +18,13 @@ test("Invite Acceptance Page", () => { andThen(() => { ok(exists("#new-account-username"), "shows the username input"); equal(find("#new-account-username").val(), "invited", "username is prefilled"); + ok(exists("#new-account-name"), "shows the name input"); ok(exists("#new-account-password"), "shows the password input"); + ok(exists('.invites-show .btn-primary:disabled'), 'submit is disabled because name is not filled'); + }); + + fillIn("#new-account-name", 'John Doe'); + andThen(() => { not(exists('.invites-show .btn-primary:disabled'), 'submit is enabled'); });