|
@@ -13,9 +13,42 @@ export default Ember.Component.extend({
|
|
|
username: '',
|
|
|
email: '',
|
|
|
password: '',
|
|
|
- captcha: Ember.computed.alias('captcha.value'),
|
|
|
|
|
|
- validation: null,
|
|
|
+ validation: Ember.Object.create({}),
|
|
|
+
|
|
|
+ passwordScore: function() {
|
|
|
+ return this.get('zxcvbn').scorePassword(this.get('password'), [
|
|
|
+ this.get('username'), this.get('email')
|
|
|
+ ]);
|
|
|
+ }.property('password', 'username', 'email'),
|
|
|
+
|
|
|
+ passwordHelpText: function() {
|
|
|
+ if (Ember.$.trim(this.get('password')).length === 0) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ return [
|
|
|
+ gettext('Password is very weak.'),
|
|
|
+ gettext('Password is weak.'),
|
|
|
+ gettext('Password is average.'),
|
|
|
+ gettext('Password is strong.'),
|
|
|
+ gettext('Password is very strong.')
|
|
|
+ ][this.get('passwordScore')];
|
|
|
+ }.property('password', 'username', 'email', 'passwordScore'),
|
|
|
+
|
|
|
+ passwordBarWidth: function() {
|
|
|
+ this.$('.progress-bar').css('width', ((this.get('passwordScore') + 1) * 20) + '%');
|
|
|
+ }.observes('password', 'username', 'email', 'passwordScore'),
|
|
|
+
|
|
|
+ passwordBarClass: function() {
|
|
|
+ return 'progress-bar-' + [
|
|
|
+ 'danger',
|
|
|
+ 'warning',
|
|
|
+ 'warning',
|
|
|
+ 'primary',
|
|
|
+ 'success'
|
|
|
+ ][this.get('passwordScore')];
|
|
|
+ }.property('password', 'username', 'email', 'passwordScore'),
|
|
|
|
|
|
loadServices: function() {
|
|
|
var self = this;
|
|
@@ -26,6 +59,8 @@ export default Ember.Component.extend({
|
|
|
];
|
|
|
|
|
|
Ember.RSVP.allSettled(promises).then(function(array) {
|
|
|
+ if (self.isDestroyed) { return; }
|
|
|
+
|
|
|
if (array[0].state === 'rejected') {
|
|
|
self.set('isErrored', true);
|
|
|
console.log('zxcvbn service failed to load.');
|
|
@@ -37,40 +72,146 @@ export default Ember.Component.extend({
|
|
|
}
|
|
|
|
|
|
self.set('isReady', !self.get('isErrored'));
|
|
|
+ self.get('captcha').reset();
|
|
|
});
|
|
|
}.on('didInsertElement'),
|
|
|
|
|
|
+ usernameValidation: function() {
|
|
|
+ var state = true;
|
|
|
+
|
|
|
+ var value = Ember.$.trim(this.get('username'));
|
|
|
+ var valueLength = value.length;
|
|
|
+
|
|
|
+ var limit = 0;
|
|
|
+ var message = null;
|
|
|
+ if (valueLength < this.get('settings.username_length_min')) {
|
|
|
+ limit = this.get('settings.username_length_min');
|
|
|
+ message = ngettext('Username must be at least one character long.',
|
|
|
+ 'Username must be at least %(limit)s characters long.',
|
|
|
+ limit);
|
|
|
+ state = [interpolate(message, {limit: limit}, true)];
|
|
|
+ } else if (valueLength > this.get('settings.username_length_max')) {
|
|
|
+ limit = this.get('settings.username_length_max');
|
|
|
+ message = ngettext('Username cannot be longer than one characters.',
|
|
|
+ 'Username cannot be longer than %(limit)s characters.',
|
|
|
+ limit);
|
|
|
+ state = [interpolate(message, {limit: limit}, true)];
|
|
|
+ } else if (!new RegExp('^[0-9a-z]+$', 'i').test(value)) {
|
|
|
+ state = [gettext('Username can only contain latin alphabet letters and digits.')];
|
|
|
+ }
|
|
|
+
|
|
|
+ if (state === true) {
|
|
|
+ this.set('validation.username', 'ok');
|
|
|
+ } else {
|
|
|
+ this.set('validation.username', state);
|
|
|
+ }
|
|
|
+ }.observes('username'),
|
|
|
+
|
|
|
+ emailValidation: function() {
|
|
|
+ var state = true;
|
|
|
+
|
|
|
+ var value = Ember.$.trim(this.get('email'));
|
|
|
+ var valueLength = value.length;
|
|
|
+
|
|
|
+ var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
|
|
|
+
|
|
|
+ if (valueLength < 4) {
|
|
|
+ state = [gettext('Enter valid e-mail address')];
|
|
|
+ } else if (!re.test(value)) {
|
|
|
+ state = [gettext('Invalid e-mail address.')];
|
|
|
+ }
|
|
|
+
|
|
|
+ if (state === true) {
|
|
|
+ this.set('validation.email', 'ok');
|
|
|
+ } else {
|
|
|
+ this.set('validation.email', state);
|
|
|
+ }
|
|
|
+ }.observes('email'),
|
|
|
+
|
|
|
+ passwordValidation: function() {
|
|
|
+ var state = true;
|
|
|
+
|
|
|
+ var valueLength = Ember.$.trim(this.get('password')).length;
|
|
|
+
|
|
|
+ var limit = this.get('settings.password_length_min');
|
|
|
+ if (valueLength < limit) {
|
|
|
+ var message = ngettext('Valid password must be at least one character long.',
|
|
|
+ 'Valid password must be at least %(limit)s characters long.',
|
|
|
+ limit);
|
|
|
+ state = [interpolate(message, {limit: limit}, true)];
|
|
|
+ }
|
|
|
+
|
|
|
+ if (state === true) {
|
|
|
+ this.set('validation.password', 'ok');
|
|
|
+ } else {
|
|
|
+ this.set('validation.password', state);
|
|
|
+ }
|
|
|
+ }.observes('password'),
|
|
|
+
|
|
|
+ captchaValidation: function() {
|
|
|
+ this.set('validation.captcha', undefined);
|
|
|
+ }.observes('captcha.value'),
|
|
|
+
|
|
|
submit: function() {
|
|
|
if (this.get('isLoading')) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+ var data = {
|
|
|
+ username: Ember.$.trim(this.get('username')),
|
|
|
+ email: Ember.$.trim(this.get('email')),
|
|
|
+ password: Ember.$.trim(this.get('password')),
|
|
|
+ captcha: Ember.$.trim(this.get('captcha.value'))
|
|
|
+ };
|
|
|
+
|
|
|
+ var lengths = [data.username.length, data.email.length, data.password.length];
|
|
|
+ if (lengths.indexOf(0) !== -1) {
|
|
|
+ this.toast.error(gettext("Fill out all fields."));
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.$('.has-error').length) {
|
|
|
+ this.toast.error(gettext("Form contains errors."));
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
this.set('isLoading', true);
|
|
|
|
|
|
var self = this;
|
|
|
- this.rpc.ajax('users', {
|
|
|
- username: this.get('username'),
|
|
|
- email: this.get('email'),
|
|
|
- password: this.get('password'),
|
|
|
- captcha: this.get('captcha.value')
|
|
|
- }).then(function(response) {
|
|
|
+ this.rpc.ajax('users', data
|
|
|
+ ).then(function(response) {
|
|
|
+ if (self.isDestroyed) { return; }
|
|
|
self.success(response);
|
|
|
}, function(jqXHR) {
|
|
|
- self.error(jqXHR);
|
|
|
+ if (self.isDestroyed) { return; }
|
|
|
+ self.error(jqXHR);
|
|
|
}).finally(function() {
|
|
|
+ if (self.isDestroyed) { return; }
|
|
|
self.set('isLoading', false);
|
|
|
- })
|
|
|
+ });
|
|
|
|
|
|
return false;
|
|
|
},
|
|
|
|
|
|
success: function(response) {
|
|
|
console.log(response);
|
|
|
+ this.get('captcha').reset();
|
|
|
},
|
|
|
|
|
|
error: function(jqXHR) {
|
|
|
if (jqXHR.status === 400) {
|
|
|
- this.set('validation', Ember.Object.create(jqXHR.responseJSON));
|
|
|
+ this.toast.error(gettext("Form contains errors."));
|
|
|
+ this.get('validation').setProperties(jqXHR.responseJSON);
|
|
|
+
|
|
|
+ if (!this.get('validation.captcha')) {
|
|
|
+ this.get('captcha').pass();
|
|
|
+ } else {
|
|
|
+ this.get('captcha').refresh();
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
+ },
|
|
|
+
|
|
|
+ showTermsFootnote: function() {
|
|
|
+ return this.get('settings.terms_of_service') || this.get('settings.terms_of_service_link');
|
|
|
+ }.property('settings')
|
|
|
});
|