mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-26 20:34:02 +03:00
Merge pull request #3051 from jgable/loginValidation
Add validation for signin/signup
This commit is contained in:
commit
4b610f09d3
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
62
core/client/controllers/signin.js
Normal file
62
core/client/controllers/signin.js
Normal file
@ -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;
|
50
core/client/controllers/signup.js
Normal file
50
core/client/controllers/signup.js
Normal file
@ -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();
|
||||
}
|
||||
});
|
||||
|
||||
|
14
core/client/validators/forgotten.js
Normal file
14
core/client/validators/forgotten.js
Normal file
@ -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;
|
18
core/client/validators/signin.js
Normal file
18
core/client/validators/signin.js
Normal file
@ -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;
|
28
core/client/validators/signup.js
Normal file
28
core/client/validators/signup.js
Normal file
@ -0,0 +1,28 @@
|
||||
var SignupValidator = Ember.Object.create({
|
||||
validate: function (model) {
|
||||
var data = model.getProperties('name', 'email', 'password'),
|
||||
validationErrors = [];
|
||||
|
||||
if (!validator.isLength(data.name || '', 1)) {
|
||||
validationErrors.push({
|
||||
message: 'Please enter a name.'
|
||||
});
|
||||
}
|
||||
|
||||
if (!validator.isEmail(data.email)) {
|
||||
validationErrors.push({
|
||||
message: 'Invalid Email.'
|
||||
});
|
||||
}
|
||||
|
||||
if (!validator.isLength(data.password || '', 1)) {
|
||||
validationErrors.push({
|
||||
message: 'Please enter a password.'
|
||||
});
|
||||
}
|
||||
|
||||
return validationErrors;
|
||||
}
|
||||
});
|
||||
|
||||
export default SignupValidator;
|
@ -81,7 +81,7 @@ CasperTest.emberBegin("Can't spam it", 4, function suite(test) {
|
||||
|
||||
casper.captureScreenshot('login_spam_test.png');
|
||||
|
||||
casper.wait(200, function doneWait() {
|
||||
casper.waitForText('attempts remaining!', function then() {
|
||||
this.fillAndSave("#login", falseUser);
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user