diff --git a/core/client/controllers/forgotten.js b/core/client/controllers/forgotten.js index a8f24aff7f..8b2013c8df 100644 --- a/core/client/controllers/forgotten.js +++ b/core/client/controllers/forgotten.js @@ -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); + }); } } }); diff --git a/core/client/controllers/signin.js b/core/client/controllers/signin.js new file mode 100644 index 0000000000..04e89e19b3 --- /dev/null +++ b/core/client/controllers/signin.js @@ -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; diff --git a/core/client/controllers/signup.js b/core/client/controllers/signup.js new file mode 100644 index 0000000000..76381de6dd --- /dev/null +++ b/core/client/controllers/signup.js @@ -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; diff --git a/core/client/mixins/validation-engine.js b/core/client/mixins/validation-engine.js index 263a77f733..f573d20909 100644 --- a/core/client/mixins/validation-engine.js +++ b/core/client/mixins/validation-engine.js @@ -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); }); }, diff --git a/core/client/routes/signin.js b/core/client/routes/signin.js index d805c1e50c..db0c94fa4b 100644 --- a/core/client/routes/signin.js +++ b/core/client/routes/signin.js @@ -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; \ No newline at end of file diff --git a/core/client/routes/signup.js b/core/client/routes/signup.js index 0ae6f2f5f1..84337a4099 100644 --- a/core/client/routes/signup.js +++ b/core/client/routes/signup.js @@ -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; diff --git a/core/client/templates/forgotten.hbs b/core/client/templates/forgotten.hbs index 4fde70da52..bb0fbad5ad 100644 --- a/core/client/templates/forgotten.hbs +++ b/core/client/templates/forgotten.hbs @@ -1,8 +1,8 @@
-
+ - +
diff --git a/core/client/templates/signin.hbs b/core/client/templates/signin.hbs index 13813a0dfb..9fc77a5079 100644 --- a/core/client/templates/signin.hbs +++ b/core/client/templates/signin.hbs @@ -6,7 +6,7 @@
{{input class="password" type="password" placeholder="Password" name="password" value=password}}
- +
{{#link-to 'forgotten' class="forgotten-password"}}Forgotten password?{{/link-to}}
diff --git a/core/client/templates/signup.hbs b/core/client/templates/signup.hbs index 37b1337967..0623d33e66 100644 --- a/core/client/templates/signup.hbs +++ b/core/client/templates/signup.hbs @@ -9,6 +9,6 @@
{{input class="password" type="password" placeholder="Password" name="password" value=password }}
- + diff --git a/core/client/utils/notifications.js b/core/client/utils/notifications.js index db7bb30ee5..43e4f8d044 100644 --- a/core/client/utils/notifications.js +++ b/core/client/utils/notifications.js @@ -48,7 +48,7 @@ var Notifications = Ember.ArrayProxy.extend({ }); }, closeAll: function () { - window.alert('@TODO implement closeALl notifications'); + this.clear(); } }); diff --git a/core/client/validators/forgotten.js b/core/client/validators/forgotten.js new file mode 100644 index 0000000000..eaf9dbcba1 --- /dev/null +++ b/core/client/validators/forgotten.js @@ -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; diff --git a/core/client/validators/signin.js b/core/client/validators/signin.js new file mode 100644 index 0000000000..800603f4f1 --- /dev/null +++ b/core/client/validators/signin.js @@ -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; diff --git a/core/client/validators/signup.js b/core/client/validators/signup.js new file mode 100644 index 0000000000..d389980eef --- /dev/null +++ b/core/client/validators/signup.js @@ -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; diff --git a/core/test/functional/client/signin_test.js b/core/test/functional/client/signin_test.js index 504a05cbba..1e6edd594c 100644 --- a/core/test/functional/client/signin_test.js +++ b/core/test/functional/client/signin_test.js @@ -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); });