FEATURE: require name when accepting invite if 'full name required' setting is enabled
This commit is contained in:
parent
266acbcc6c
commit
d2c2139da8
|
@ -6,9 +6,10 @@ import { emailValid } from 'discourse/lib/utilities';
|
||||||
import InputValidation from 'discourse/models/input-validation';
|
import InputValidation from 'discourse/models/input-validation';
|
||||||
import PasswordValidation from "discourse/mixins/password-validation";
|
import PasswordValidation from "discourse/mixins/password-validation";
|
||||||
import UsernameValidation from "discourse/mixins/username-validation";
|
import UsernameValidation from "discourse/mixins/username-validation";
|
||||||
|
import NameValidation from "discourse/mixins/name-validation";
|
||||||
import { userPath } from 'discourse/lib/url';
|
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(),
|
login: Ember.inject.controller(),
|
||||||
|
|
||||||
complete: false,
|
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');
|
return I18n.t(Discourse.SiteSettings.full_name_required ? 'user.name.instructions_required' : 'user.name.instructions');
|
||||||
}.property(),
|
}.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
|
// Check the email address
|
||||||
emailValidation: function() {
|
emailValidation: function() {
|
||||||
// If blank, fail without a reason
|
// If blank, fail without a reason
|
||||||
|
|
|
@ -4,9 +4,10 @@ import DiscourseURL from 'discourse/lib/url';
|
||||||
import { ajax } from 'discourse/lib/ajax';
|
import { ajax } from 'discourse/lib/ajax';
|
||||||
import PasswordValidation from "discourse/mixins/password-validation";
|
import PasswordValidation from "discourse/mixins/password-validation";
|
||||||
import UsernameValidation from "discourse/mixins/username-validation";
|
import UsernameValidation from "discourse/mixins/username-validation";
|
||||||
|
import NameValidation from "discourse/mixins/name-validation";
|
||||||
import { findAll as findLoginMethods } from 'discourse/models/login-method';
|
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'),
|
invitedBy: Ember.computed.alias('model.invited_by'),
|
||||||
email: Ember.computed.alias('model.email'),
|
email: Ember.computed.alias('model.email'),
|
||||||
accountUsername: Ember.computed.alias('model.username'),
|
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});
|
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')
|
@computed('email')
|
||||||
yourEmailMessage(email) {
|
yourEmailMessage(email) {
|
||||||
return I18n.t('invites.your_email', {email: 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;
|
return findLoginMethods(this.siteSettings, this.capabilities, this.site.isMobileDevice).length > 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('usernameValidation.failed', 'passwordValidation.failed')
|
@computed('usernameValidation.failed', 'passwordValidation.failed', 'nameValidation.failed')
|
||||||
submitDisabled(usernameFailed, passwordFailed) {
|
submitDisabled(usernameFailed, passwordFailed, nameFailed) {
|
||||||
return usernameFailed || passwordFailed;
|
return usernameFailed || passwordFailed || nameFailed;
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
@ -42,6 +48,7 @@ export default Ember.Controller.extend(PasswordValidation, UsernameValidation, {
|
||||||
type: 'PUT',
|
type: 'PUT',
|
||||||
data: {
|
data: {
|
||||||
username: this.get('accountUsername'),
|
username: this.get('accountUsername'),
|
||||||
|
name: this.get('accountName'),
|
||||||
password: this.get('accountPassword')
|
password: this.get('accountPassword')
|
||||||
}
|
}
|
||||||
}).then(result => {
|
}).then(result => {
|
||||||
|
|
|
@ -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});
|
||||||
|
}
|
||||||
|
});
|
|
@ -40,7 +40,7 @@ export default Ember.Mixin.create({
|
||||||
}
|
}
|
||||||
|
|
||||||
// If too short
|
// If too short
|
||||||
if (accountUsername.length < Discourse.SiteSettings.min_username_length) {
|
if (accountUsername.length < this.siteSettings.min_username_length) {
|
||||||
return InputValidation.create({
|
return InputValidation.create({
|
||||||
failed: true,
|
failed: true,
|
||||||
reason: I18n.t('user.username.too_short')
|
reason: I18n.t('user.username.too_short')
|
||||||
|
|
|
@ -14,9 +14,9 @@
|
||||||
|
|
||||||
{{#if successMessage}}
|
{{#if successMessage}}
|
||||||
<p>{{successMessage}}</p>
|
<p>{{successMessage}}</p>
|
||||||
{{else}}
|
{{else}}
|
||||||
|
|
||||||
<p>{{{yourEmailMessage}}}
|
<p>{{{yourEmailMessage}}}
|
||||||
{{#if externalAuthsEnabled}}
|
{{#if externalAuthsEnabled}}
|
||||||
{{i18n 'invites.social_login_available'}}
|
{{i18n 'invites.social_login_available'}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -24,14 +24,17 @@
|
||||||
|
|
||||||
<form>
|
<form>
|
||||||
<label>{{i18n 'user.username.title'}}</label>
|
<label>{{i18n 'user.username.title'}}</label>
|
||||||
|
|
||||||
<div class="input username-input">
|
<div class="input username-input">
|
||||||
{{input value=accountUsername id="new-account-username" name="username" maxlength=maxUsernameLength autocomplete="off"}}
|
{{input value=accountUsername id="new-account-username" name="username" maxlength=maxUsernameLength autocomplete="off"}}
|
||||||
{{input-tip validation=usernameValidation id="username-validation"}}
|
{{input-tip validation=usernameValidation id="username-validation"}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label>{{i18n 'invites.password_label'}}</label>
|
<label>{{nameLabel}}</label>
|
||||||
|
<div class="input name-input">
|
||||||
|
{{input value=accountName id="new-account-name" name="name"}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label>{{i18n 'invites.password_label'}}</label>
|
||||||
<div class="input password-input">
|
<div class="input password-input">
|
||||||
{{password-field value=accountPassword type="password" id="new-account-password" capsLockOn=capsLockOn}}
|
{{password-field value=accountPassword type="password" id="new-account-password" capsLockOn=capsLockOn}}
|
||||||
{{input-tip validation=passwordValidation}}
|
{{input-tip validation=passwordValidation}}
|
||||||
|
@ -39,7 +42,7 @@
|
||||||
|
|
||||||
<div class="instructions">
|
<div class="instructions">
|
||||||
<div class="caps-lock-warning {{unless capsLockOn 'invisible'}}"><i class="fa fa-exclamation-triangle"></i> {{i18n 'login.caps_lock_warning'}}</div>
|
<div class="caps-lock-warning {{unless capsLockOn 'invisible'}}"><i class="fa fa-exclamation-triangle"></i> {{i18n 'login.caps_lock_warning'}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class='btn btn-primary' {{action "submit"}} disabled={{submitDisabled}}>{{i18n 'invites.accept_invite'}}</button>
|
<button class='btn btn-primary' {{action "submit"}} disabled={{submitDisabled}}>{{i18n 'invites.accept_invite'}}</button>
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,13 @@ class InvitesController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform_accept_invitation
|
def perform_accept_invitation
|
||||||
|
params.require(:id)
|
||||||
|
params.permit(:username, :name, :password)
|
||||||
invite = Invite.find_by(invite_key: params[:id])
|
invite = Invite.find_by(invite_key: params[:id])
|
||||||
|
|
||||||
if invite.present?
|
if invite.present?
|
||||||
begin
|
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?
|
if user.present?
|
||||||
log_on_user(user)
|
log_on_user(user)
|
||||||
post_process_invite(user)
|
post_process_invite(user)
|
||||||
|
|
|
@ -1099,6 +1099,8 @@ en:
|
||||||
your_email: "Your account email address is <b>%{email}</b>."
|
your_email: "Your account email address is <b>%{email}</b>."
|
||||||
accept_invite: "Accept Invitation"
|
accept_invite: "Accept Invitation"
|
||||||
success: "Your account has been created and you're now logged in."
|
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_label: "Set Password (optional)"
|
||||||
|
|
||||||
password_reset:
|
password_reset:
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
import { acceptance } from "helpers/qunit-helpers";
|
import { acceptance } from "helpers/qunit-helpers";
|
||||||
import PreloadStore from 'preload-store';
|
import PreloadStore from 'preload-store';
|
||||||
|
|
||||||
acceptance("Invite Accept");
|
acceptance("Invite Accept", {
|
||||||
|
settings: {
|
||||||
|
full_name_required: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test("Invite Acceptance Page", () => {
|
test("Invite Acceptance Page", () => {
|
||||||
PreloadStore.store('invite_info', {
|
PreloadStore.store('invite_info', {
|
||||||
|
@ -14,7 +18,13 @@ test("Invite Acceptance Page", () => {
|
||||||
andThen(() => {
|
andThen(() => {
|
||||||
ok(exists("#new-account-username"), "shows the username input");
|
ok(exists("#new-account-username"), "shows the username input");
|
||||||
equal(find("#new-account-username").val(), "invited", "username is prefilled");
|
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("#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');
|
not(exists('.invites-show .btn-primary:disabled'), 'submit is enabled');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue