Support for auth plugins to freeze the username

This commit is contained in:
Robin Ward 2015-06-26 15:52:05 -04:00
parent b52e5d1536
commit 7dbc2590a5
4 changed files with 72 additions and 73 deletions

View file

@ -21,8 +21,7 @@ export default DiscourseController.extend(ModalFunctionality, {
maxUsernameLength: Discourse.computed.setting('max_username_length'),
minUsernameLength: Discourse.computed.setting('min_username_length'),
resetForm: function() {
resetForm() {
// We wrap the fields in a structure so we can assign a value
this.setProperties({
accountName: '',
@ -49,11 +48,11 @@ export default DiscourseController.extend(ModalFunctionality, {
if (this.get('passwordValidation.failed')) return true;
// Validate required fields
var userFields = this.get('userFields');
let userFields = this.get('userFields');
if (userFields) { userFields = userFields.filterProperty('field.required'); }
if (!Ember.isEmpty(userFields)) {
var anyEmpty = userFields.any(function(uf) {
var val = uf.get('value');
const anyEmpty = userFields.any(function(uf) {
const val = uf.get('value');
return !val || Ember.isEmpty(val);
});
if (anyEmpty) { return true; }
@ -61,6 +60,9 @@ export default DiscourseController.extend(ModalFunctionality, {
return false;
}.property('passwordRequired', 'nameValidation.failed', 'emailValidation.failed', 'usernameValidation.failed', 'passwordValidation.failed', 'formSubmitted', 'userFields.@each.value'),
usernameRequired: Ember.computed.not('authOptions.omit_username'),
passwordRequired: function() {
return this.blank('authOptions.auth_provider');
}.property('authOptions.auth_provider'),
@ -89,7 +91,7 @@ export default DiscourseController.extend(ModalFunctionality, {
// Check the email address
emailValidation: function() {
// If blank, fail without a reason
var email;
let email;
if (this.blank('accountEmail')) {
return Discourse.InputValidation.create({
failed: true
@ -149,7 +151,7 @@ export default DiscourseController.extend(ModalFunctionality, {
}.observes('emailValidation', 'accountEmail'),
fetchExistingUsername: Discourse.debounce(function() {
var self = this;
const self = this;
Discourse.User.checkUsername(null, this.get('accountEmail')).then(function(result) {
if (result.suggestion && (self.blank('accountUsername') || self.get('accountUsername') === self.get('authOptions.username'))) {
self.set('accountUsername', result.suggestion);
@ -225,7 +227,7 @@ export default DiscourseController.extend(ModalFunctionality, {
},
checkUsernameAvailability: Discourse.debounce(function() {
var _this = this;
const _this = this;
if (this.shouldCheckUsernameMatch()) {
return Discourse.User.checkUsername(this.get('accountUsername'), this.get('accountEmail')).then(function(result) {
_this.set('globalNicknameExists', false);
@ -275,30 +277,23 @@ export default DiscourseController.extend(ModalFunctionality, {
// Actually wait for the async name check before we're 100% sure we're good to go
usernameValidation: function() {
var basicValidation, uniqueUsername;
basicValidation = this.get('basicUsernameValidation');
uniqueUsername = this.get('uniqueUsernameValidation');
if (uniqueUsername) {
return uniqueUsername;
}
return basicValidation;
const basicValidation = this.get('basicUsernameValidation');
const uniqueUsername = this.get('uniqueUsernameValidation');
return uniqueUsername ? uniqueUsername : basicValidation;
}.property('uniqueUsernameValidation', 'basicUsernameValidation'),
usernameNeedsToBeValidatedWithEmail: function() {
usernameNeedsToBeValidatedWithEmail() {
return( this.get('globalNicknameExists') || false );
},
// Validate the password
passwordValidation: function() {
var password;
if (!this.get('passwordRequired')) {
return Discourse.InputValidation.create({
ok: true
});
return Discourse.InputValidation.create({ ok: true });
}
// If blank, fail without a reason
password = this.get("accountPassword");
const password = this.get("accountPassword");
if (this.blank('accountPassword')) {
return Discourse.InputValidation.create({ failed: true });
}
@ -339,8 +334,8 @@ export default DiscourseController.extend(ModalFunctionality, {
});
}.property('accountPassword', 'rejectedPasswords.@each', 'accountUsername', 'accountEmail'),
fetchConfirmationValue: function() {
var createAccountController = this;
fetchConfirmationValue() {
const createAccountController = this;
return Discourse.ajax('/users/hp.json').then(function (json) {
createAccountController.set('accountPasswordConfirm', json.value);
createAccountController.set('accountChallenge', json.challenge.split("").reverse().join(""));
@ -348,12 +343,12 @@ export default DiscourseController.extend(ModalFunctionality, {
},
actions: {
externalLogin: function(provider) {
externalLogin(provider) {
this.get('controllers.login').send('externalLogin', provider);
},
createAccount: function() {
var self = this,
createAccount() {
const self = this,
attrs = this.getProperties('accountName', 'accountEmail', 'accountPassword', 'accountUsername', 'accountPasswordConfirm', 'accountChallenge'),
userFields = this.get('userFields');
@ -369,7 +364,7 @@ export default DiscourseController.extend(ModalFunctionality, {
return Discourse.User.createAccount(attrs).then(function(result) {
if (result.success) {
// Trigger the browser's password manager using the hidden static login form:
var $hidden_login_form = $('#hidden-login-form');
const $hidden_login_form = $('#hidden-login-form');
$hidden_login_form.find('input[name=username]').val(attrs.accountUsername);
$hidden_login_form.find('input[name=password]').val(attrs.accountPassword);
$hidden_login_form.find('input[name=redirect]').val(Discourse.getURL('/users/account-created'));
@ -397,7 +392,7 @@ export default DiscourseController.extend(ModalFunctionality, {
_createUserFields: function() {
if (!this.site) { return; }
var userFields = this.site.get('user_fields');
let userFields = this.site.get('user_fields');
if (userFields) {
userFields = userFields.map(function(f) {
return Ember.Object.create({

View file

@ -47,7 +47,7 @@ export default DiscourseController.extend(ModalFunctionality, {
actions: {
login: function() {
var self = this;
const self = this;
if(this.blank('loginName') || this.blank('loginPassword')){
self.flash(I18n.t('login.blank_username_or_password'), 'error');
@ -75,9 +75,9 @@ export default DiscourseController.extend(ModalFunctionality, {
} else {
self.set('loggedIn', true);
// Trigger the browser's password manager using the hidden static login form:
var $hidden_login_form = $('#hidden-login-form');
var destinationUrl = $.cookie('destination_url');
var shouldRedirectToUrl = self.session.get("shouldRedirectToUrl");
const $hidden_login_form = $('#hidden-login-form');
const destinationUrl = $.cookie('destination_url');
const shouldRedirectToUrl = self.session.get("shouldRedirectToUrl");
$hidden_login_form.find('input[name=username]').val(self.get('loginName'));
$hidden_login_form.find('input[name=password]').val(self.get('loginPassword'));
if (self.get('loginRequired') && destinationUrl) {
@ -103,22 +103,22 @@ export default DiscourseController.extend(ModalFunctionality, {
},
externalLogin: function(loginMethod){
var name = loginMethod.get("name");
var customLogin = loginMethod.get("customLogin");
const name = loginMethod.get("name");
const customLogin = loginMethod.get("customLogin");
if(customLogin){
customLogin();
} else {
this.set('authenticate', name);
var left = this.get('lastX') - 400;
var top = this.get('lastY') - 200;
const left = this.get('lastX') - 400;
const top = this.get('lastY') - 200;
var height = loginMethod.get("frameHeight") || 400;
var width = loginMethod.get("frameWidth") || 800;
var w = window.open(Discourse.getURL("/auth/" + name), "_blank",
const height = loginMethod.get("frameHeight") || 400;
const width = loginMethod.get("frameWidth") || 800;
const w = window.open(Discourse.getURL("/auth/" + name), "_blank",
"menubar=no,status=no,height=" + height + ",width=" + width + ",left=" + left + ",top=" + top);
var self = this;
var timer = setInterval(function() {
const self = this;
const timer = setInterval(function() {
if(!w || w.closed) {
clearInterval(timer);
self.set('authenticate', null);
@ -128,10 +128,10 @@ export default DiscourseController.extend(ModalFunctionality, {
},
createAccount: function() {
var createAccountController = this.get('controllers.createAccount');
const createAccountController = this.get('controllers.createAccount');
if (createAccountController) {
createAccountController.resetForm();
var loginName = this.get('loginName');
const loginName = this.get('loginName');
if (loginName && loginName.indexOf('@') > 0) {
createAccountController.set("accountEmail", loginName);
} else {
@ -142,7 +142,7 @@ export default DiscourseController.extend(ModalFunctionality, {
},
forgotPassword: function() {
var forgotPasswordController = this.get('controllers.forgotPassword');
const forgotPasswordController = this.get('controllers.forgotPassword');
if (forgotPasswordController) { forgotPasswordController.set("accountEmailOrUsername", this.get("loginName")); }
this.send("showForgotPassword");
}
@ -150,13 +150,13 @@ export default DiscourseController.extend(ModalFunctionality, {
authMessage: (function() {
if (this.blank('authenticate')) return "";
var method = Discourse.get('LoginMethod.all').findProperty("name", this.get("authenticate"));
const method = Discourse.get('LoginMethod.all').findProperty("name", this.get("authenticate"));
if(method){
return method.get('message');
}
}).property('authenticate'),
authenticationComplete: function(options) {
authenticationComplete(options) {
const self = this;
function loginError(errorMsg, className) {
@ -188,12 +188,12 @@ export default DiscourseController.extend(ModalFunctionality, {
return;
}
var createAccountController = this.get('controllers.createAccount');
const createAccountController = this.get('controllers.createAccount');
createAccountController.setProperties({
accountEmail: options.email,
accountUsername: options.username,
accountName: options.name,
authOptions: Em.Object.create(options)
authOptions: Ember.Object.create(options)
});
showModal('createAccount');
}

View file

@ -21,17 +21,19 @@
<td><label>{{i18n 'user.email.instructions'}}</label></td>
</tr>
<tr class="input">
<td class="label"><label for='new-account-username'>{{i18n 'user.username.title'}}</label></td>
<td>
{{input value=accountUsername id="new-account-username" name="username" maxlength=maxUsernameLength}}
&nbsp;{{input-tip validation=usernameValidation id="username-validation"}}
</td>
</tr>
<tr class="instructions">
<td></td>
<td><label>{{i18n 'user.username.instructions'}}</label></td>
</tr>
{{#if usernameRequired}}
<tr class="input">
<td class="label"><label for='new-account-username'>{{i18n 'user.username.title'}}</label></td>
<td>
{{input value=accountUsername id="new-account-username" name="username" maxlength=maxUsernameLength}}
&nbsp;{{input-tip validation=usernameValidation id="username-validation"}}
</td>
</tr>
<tr class="instructions">
<td></td>
<td><label>{{i18n 'user.username.instructions'}}</label></td>
</tr>
{{/if}}
<tr class="input">
<td style="width:80px" class="label"><label for='new-account-name'>{{i18n 'user.name.title'}}</label></td>
@ -46,20 +48,20 @@
</tr>
{{#if passwordRequired}}
<tr class="input">
<td class="label"><label for='new-account-password'>{{i18n 'user.password.title'}}</label></td>
<tr class="input">
<td class="label"><label for='new-account-password'>{{i18n 'user.password.title'}}</label></td>
<td>
{{password-field value=accountPassword type="password" id="new-account-password" capsLockOn=capsLockOn}}
&nbsp;{{input-tip validation=passwordValidation}}
</td>
</tr>
<tr class="instructions">
<td></td>
<td>
{{password-field value=accountPassword type="password" id="new-account-password" capsLockOn=capsLockOn}}
&nbsp;{{input-tip validation=passwordValidation}}
<label>{{passwordInstructions}}</label>
<div {{bind-attr class=":caps-lock-warning capsLockOn::invisible"}}><i class="fa fa-exclamation-triangle"></i> {{i18n 'login.caps_lock_warning'}}</div>
</td>
</tr>
<tr class="instructions">
<td></td>
<td>
<label>{{passwordInstructions}}</label>
<div {{bind-attr class=":caps-lock-warning capsLockOn::invisible"}}><i class="fa fa-exclamation-triangle"></i> {{i18n 'login.caps_lock_warning'}}</div>
</td>
</tr>
</tr>
{{/if}}
<tr class="password-confirmation">

View file

@ -3,7 +3,7 @@ class Auth::Result
:email_valid, :extra_data, :awaiting_activation,
:awaiting_approval, :authenticated, :authenticator_name,
:requires_invite, :not_allowed_from_ip_address,
:admin_not_allowed_from_ip_address
:admin_not_allowed_from_ip_address, :omit_username
attr_accessor :failed,
:failed_reason
@ -20,6 +20,7 @@ class Auth::Result
{ email: email,
username: username,
email_valid: email_valid,
omit_username: omit_username,
name: name,
authenticator_name: authenticator_name,
extra_data: extra_data }
@ -51,7 +52,8 @@ class Auth::Result
username: UserNameSuggester.suggest(username || name || email),
# this feels a tad wrong
auth_provider: authenticator_name.capitalize,
email_valid: !!email_valid
email_valid: !!email_valid,
omit_username: !!omit_username
}
end
end