Skip to content
Permalink
Browse files

Add validation for signin/signup

Closes #2976, Closes #3017

- Move logic to signup controller
  - Add ValidationEngine mixin to signup controller
  - Add signup validator with code from clientold login view
- Add signin validator and integrate into signin controller
- Add validation to forgotten controller
  - Switch to button action to support hitting enter in text field to submit
- Clear all notifications in notifications.closeAll
- Modify ValidationEngine.validate to not format errors based on option
- Update casper test for signin to wait for notification before trying
to do another signin
  • Loading branch information...
jgable committed Jun 24, 2014
1 parent 72b3b3c commit b6a429ec35610b5b4765c66429c4c042dd625d12
@@ -1,19 +1,32 @@
/*global console, alert */
import ValidationEngine from 'ghost/mixins/validation-engine';

var ForgottenController = Ember.Controller.extend({
var ForgottenController = Ember.Controller.extend(ValidationEngine, {
email: '',
submitting: false,

// ValidationEngine settings
validationType: 'forgotten',

actions: {
submit: function () {
var self = this;
self.user.fetchForgottenPasswordFor(this.email)
.then(function () {
alert('@TODO Notification: Success');
self.transitionToRoute('signin');
})
.catch(function (response) {
alert('@TODO');
console.log(response);
});

this.toggleProperty('submitting');
this.validate({ format: false }).then(function () {
self.user.fetchForgottenPasswordFor(this.email)
.then(function () {
self.toggleProperty('submitting');
self.notifications.showSuccess('Please check your email for instructions.');
self.transitionToRoute('signin');
})
.catch(function (resp) {
self.toggleProperty('submitting');
self.notifications.showAPIError(resp, 'There was a problem logging in, please try again.');
});
}).catch(function (errors) {
self.toggleProperty('submitting');
self.notifications.showErrors(errors);
});
}
}
});
@@ -0,0 +1,62 @@
import ajax from 'ghost/utils/ajax';
import ValidationEngine from 'ghost/mixins/validation-engine';

var SigninController = Ember.ObjectController.extend(ValidationEngine, {
needs: 'application',
email: null,
password: null,
submitting: false,

// ValidationEngine settings
validationType: 'signin',

actions: {
login: function () {
var self = this,
data = this.getProperties('email', 'password'),
//Data to check if user came in somewhere besides index
appController = this.get('controllers.application'),
loginTransition = appController.get('loginTransition');

this.toggleProperty('submitting');
this.validate({ format: false }).then(function () {
ajax({
url: self.get('ghostPaths').adminUrl('signin'),
type: 'POST',
headers: {'X-CSRF-Token': self.get('csrf')},
data: data
}).then(function (response) {
// once the email and password are pulled from the controller
// they need to be cleared, or they will reappear next time the signin
// page is visited
self.setProperties({
email: '',
password: ''
});

self.store.pushPayload({users: [response.userData]});
return self.store.find('user', response.userData.id);
}).then(function (user) {
self.send('signedIn', user);
self.notifications.clear();
if (loginTransition) {
appController.set('loginTransition', null);
loginTransition.retry();
} else {
self.transitionTo('posts');
}
}).catch(function (resp) {
self.toggleProperty('submitting');
self.notifications.showAPIError(resp, 'There was a problem logging in, please try again.');
});
}).catch(function (errors) {
self.toggleProperty('submitting');
self.notifications.clear();
self.notifications.showErrors(errors);
});
}
}

});

export default SigninController;
@@ -0,0 +1,50 @@
import ajax from 'ghost/utils/ajax';
import ValidationEngine from 'ghost/mixins/validation-engine';

var SignupController = Ember.ObjectController.extend(ValidationEngine, {
name: null,
email: null,
password: null,
submitting: false,

// ValidationEngine settings
validationType: 'signup',

actions: {
signup: function () {
var self = this;

this.toggleProperty('submitting');
this.validate({ format: false }).then(function () {
ajax({
url: self.get('ghostPaths').adminUrl('signup'),
type: 'POST',
headers: {
'X-CSRF-Token': self.get('csrf')
},
data: self.getProperties('name', 'email', 'password')
}).then(function (resp) {
self.toggleProperty('submitting');
if (resp && resp.userData) {
self.store.pushPayload({ users: [resp.userData]});
self.store.find('user', resp.userData.id).then(function (user) {
self.send('signedIn', user);
self.notifications.clear();
self.transitionTo('posts');
});
} else {
self.transitionTo('signin');
}
}, function (resp) {
self.toggleProperty('submitting');
self.notifications.showAPIError(resp);
});
}, function (errors) {
self.toggleProperty('submitting');
self.notifications.showErrors(errors);
});
}
}
});

export default SignupController;
@@ -2,15 +2,23 @@ import { getRequestErrorMessage } from 'ghost/utils/ajax';

import ValidatorExtensions from 'ghost/utils/validator-extensions';
import PostValidator from 'ghost/validators/post';
import SignupValidator from 'ghost/validators/signup';
import SigninValidator from 'ghost/validators/signin';
import ForgotValidator from 'ghost/validators/forgotten';

ValidatorExtensions.init();

var ValidationEngine = Ember.Mixin.create({
validators: {
post: PostValidator
post: PostValidator,
signup: SignupValidator,
signin: SigninValidator,
forgotten: ForgotValidator
},

validate: function () {
validate: function (opts) {
opts = opts || {};

var self = this,
type = this.get('validationType'),
validator = this.get('validators.' + type);
@@ -26,7 +34,11 @@ var ValidationEngine = Ember.Mixin.create({
return resolve();
}

return reject(self.formatErrors(validationErrors));
if (opts.format !== false) {
validationErrors = self.formatErrors(validationErrors);
}

return reject(validationErrors);
});
},

@@ -1,58 +1,8 @@
import ajax from 'ghost/utils/ajax';
import styleBody from 'ghost/mixins/style-body';
import loadingIndicator from 'ghost/mixins/loading-indicator';

var isEmpty = Ember.isEmpty;

var SigninRoute = Ember.Route.extend(styleBody, loadingIndicator, {
classNames: ['ghost-login'],

actions: {
login: function () {
var self = this,
controller = this.get('controller'),
data = controller.getProperties('email', 'password'),
//Data to check if user came in somewhere besides index
appController = this.controllerFor('application'),
loginTransition = appController.get('loginTransition');

if (!isEmpty(data.email) && !isEmpty(data.password)) {

ajax({
url: this.get('ghostPaths').adminUrl('signin'),
type: 'POST',
headers: {'X-CSRF-Token': this.get('csrf')},
data: data
}).then(function (response) {
// once the email and password are pulled from the controller
// they need to be cleared, or they will reappear next time the signin
// page is visited
controller.setProperties({
email: '',
password: ''
});

self.store.pushPayload({users: [response.userData]});
return self.store.find('user', response.userData.id);
}).then(function (user) {
self.send('signedIn', user);
self.notifications.clear();
if (loginTransition) {
appController.set('loginTransition', null);
loginTransition.retry();
} else {
self.transitionTo('posts');
}
}).catch(function (resp) {
self.notifications.showAPIError(resp, 'There was a problem logging in, please try again.');
});
} else {
this.notifications.clear();

this.notifications.showError('Must enter email + password');
}
}
}
classNames: ['ghost-login']
});

export default SigninRoute;
@@ -1,49 +1,8 @@
import ajax from 'ghost/utils/ajax';
import styleBody from 'ghost/mixins/style-body';
import loadingIndicator from 'ghost/mixins/loading-indicator';

var SignupRoute = Ember.Route.extend(styleBody, loadingIndicator, {
classNames: ['ghost-signup'],

name: null,
email: null,
password: null,

actions: {
signup: function () {
var self = this,
controller = this.get('controller'),
data = controller.getProperties('name', 'email', 'password');

// TODO: Validate data

if (data.name && data.email && data.password) {
ajax({
url: '/ghost/signup/',
type: 'POST',
headers: {
'X-CSRF-Token': this.get('csrf')
},
data: data
}).then(function (resp) {
if (resp && resp.userData) {
self.store.pushPayload({ users: [resp.userData]});
self.store.find('user', resp.userData.id).then(function (user) {
self.send('signedIn', user);
self.notifications.clear();
self.transitionTo('posts');
});
} else {
self.transitionTo('signin');
}
}, function (resp) {
self.notifications.showAPIError(resp);
});
} else {
this.notifications.showError('Must provide name, email and password');
}
}
}
classNames: ['ghost-signup']
});

export default SignupRoute;
@@ -1,8 +1,8 @@
<section class="forgotten-box js-forgotten-box fade-in">
<form id="forgotten" class="forgotten-form" method="post" novalidate="novalidate" {{action "submit" on="submit"}}>
<form id="forgotten" class="forgotten-form" method="post" novalidate="novalidate">
<div class="email-wrap">
{{input value=email class="email" type="email" placeholder="Email Address" name="email" autofocus="autofocus" autocapitalize="off" autocorrect="off"}}
</div>
<button class="button-save" type="submit">Send new password</button>
<button class="button-save" type="submit" {{action "submit"}} {{bind-attr disabled=submitting}}>Send new password</button>
</form>
</section>
@@ -6,7 +6,7 @@
<div class="password-wrap">
{{input class="password" type="password" placeholder="Password" name="password" value=password}}
</div>
<button class="button-save" type="submit" {{action "login"}}>Log in</button>
<button class="button-save" type="submit" {{action "login"}} {{bind-attr disabled=submitting}}>Log in</button>
<section class="meta">
{{#link-to 'forgotten' class="forgotten-password"}}Forgotten password?{{/link-to}}
</section>
@@ -9,6 +9,6 @@
<div class="password-wrap">
{{input class="password" type="password" placeholder="Password" name="password" value=password }}
</div>
<button class="button-save" type="submit" {{action "signup"}}>Sign Up</button>
<button class="button-save" type="submit" {{action "signup"}} {{bind-attr disabled=submitting}}>Sign Up</button>
</form>
</section>
@@ -48,7 +48,7 @@ var Notifications = Ember.ArrayProxy.extend({
});
},
closeAll: function () {
window.alert('@TODO implement closeALl notifications');
this.clear();
}
});

@@ -0,0 +1,14 @@
var ForgotValidator = Ember.Object.create({
validate: function (model) {
var data = model.getProperties('email'),
validationErrors = [];

if (!validator.isEmail(data.email)) {
validationErrors.push('Invalid Email');
}

return validationErrors;
}
});

export default ForgotValidator;
@@ -0,0 +1,18 @@
var SigninValidator = Ember.Object.create({
validate: function (model) {
var data = model.getProperties('email', 'password'),
validationErrors = [];

if (!validator.isEmail(data.email)) {
validationErrors.push('Invalid Email');
}

if (!validator.isLength(data.password || '', 1)) {
validationErrors.push('Please enter a password');
}

return validationErrors;
}
});

export default SigninValidator;

0 comments on commit b6a429e

Please sign in to comment.
You can’t perform that action at this time.