diff --git a/core/client/controllers/forgotten.js b/core/client/controllers/forgotten.js index 8b2013c8df..b390d51b28 100644 --- a/core/client/controllers/forgotten.js +++ b/core/client/controllers/forgotten.js @@ -1,3 +1,5 @@ +/* jshint unused: false */ +import ajax from 'ghost/utils/ajax'; import ValidationEngine from 'ghost/mixins/validation-engine'; var ForgottenController = Ember.Controller.extend(ValidationEngine, { @@ -9,20 +11,27 @@ var ForgottenController = Ember.Controller.extend(ValidationEngine, { actions: { submit: function () { - var self = this; + var self = this, + data = self.getProperties('email'); 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.'); - }); + ajax({ + url: self.get('ghostPaths').apiUrl('authentication', 'passwordreset'), + type: 'POST', + data: { + passwordreset: [{ + email: data.email + }] + } + }).then(function (resp) { + 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/reset.js b/core/client/controllers/reset.js index 13e3ba4473..f97e4f4e16 100644 --- a/core/client/controllers/reset.js +++ b/core/client/controllers/reset.js @@ -1,28 +1,48 @@ -/*global alert, console */ -var ResetController = Ember.Controller.extend({ +/*global console*/ +/* jshint unused: false */ +import ajax from 'ghost/utils/ajax'; +import ValidationEngine from 'ghost/mixins/validation-engine'; + +var ResetController = Ember.Controller.extend(ValidationEngine, { passwords: { newPassword: '', ne2Password: '' }, token: '', submitButtonDisabled: false, + + validationType: 'reset', + actions: { submit: function () { - var self = this; - this.set('submitButtonDisabled', true); - - this.user.resetPassword(this.passwords, this.token) - .then(function () { - alert('@TODO Notification : Success'); + var self = this, + data = self.getProperties('passwords', 'token'); + + this.toggleProperty('submitting'); + this.validate({format: false}).then(function () { + ajax({ + url: self.get('ghostPaths').apiUrl('authentication', 'passwordreset'), + type: 'PUT', + data: { + passwordreset: [{ + newPassword: data.passwords.newPassword, + ne2Password: data.passwords.ne2Password, + token: data.token + }] + } + }).then(function (resp) { + self.toggleProperty('submitting'); + console.log('success'); self.transitionToRoute('signin'); - }) - .catch(function (response) { - alert('@TODO Notification : Failure'); - console.log(response); - }) - .finally(function () { - self.set('submitButtonDisabled', false); + }).catch(function (errors) { + self.toggleProperty('submitting'); + console.log('error'); }); + }).catch(function (error) { + self.toggleProperty('submitting'); + // @TODO: notifications here for validation errors + console.log('validation error', error); + }); } } }); diff --git a/core/client/mixins/validation-engine.js b/core/client/mixins/validation-engine.js index e1fbad7c78..351b9e2922 100644 --- a/core/client/mixins/validation-engine.js +++ b/core/client/mixins/validation-engine.js @@ -7,6 +7,7 @@ import SignupValidator from 'ghost/validators/signup'; import SigninValidator from 'ghost/validators/signin'; import ForgotValidator from 'ghost/validators/forgotten'; import SettingValidator from 'ghost/validators/setting'; +import ResetValidator from 'ghost/validators/reset'; ValidatorExtensions.init(); @@ -17,7 +18,8 @@ var ValidationEngine = Ember.Mixin.create({ signup: SignupValidator, signin: SigninValidator, forgotten: ForgotValidator, - setting: SettingValidator + setting: SettingValidator, + reset: ResetValidator }, validate: function (opts) { diff --git a/core/client/models/user.js b/core/client/models/user.js index 617b1e18fe..71e326a325 100644 --- a/core/client/models/user.js +++ b/core/client/models/user.js @@ -73,50 +73,9 @@ var User = DS.Model.extend({ return validationErrors; }, - fetchForgottenPasswordFor: function (email) { - var forgottenUrl = this.get('ghostPaths').apiUrl('forgotten'); - return new Ember.RSVP.Promise(function (resolve, reject) { - if (!validator.isEmail(email)) { - reject(new Error('Please enter a correct email address.')); - } else { - resolve(ic.ajax.request(forgottenUrl, { - type: 'POST', - headers: { - // @TODO Find a more proper way to do this. - 'X-CSRF-Token': $('meta[name="csrf-param"]').attr('content') - }, - data: { - email: email - } - })); - } - }); - }, - resetPassword: function (passwords, token) { - var self = this, - resetUrl = this.get('ghostPaths').apiUrl('reset'); - return new Ember.RSVP.Promise(function (resolve, reject) { - if (!self.validatePassword(passwords).get('passwordIsValid')) { - reject(new Error('Errors found! ' + JSON.stringify(self.get('passwordErrors')))); - } else { - resolve(ic.ajax.request(resetUrl, { - type: 'POST', - headers: { - // @TODO: find a more proper way to do this. - 'X-CSRF-Token': $('meta[name="csrf-param"]').attr('content') - }, - data: { - newpassword: passwords.newPassword, - ne2password: passwords.ne2Password, - token: token - } - })); - } - }); - } }); export default User; diff --git a/core/client/validators/forgotten.js b/core/client/validators/forgotten.js index eaf9dbcba1..326b2c7318 100644 --- a/core/client/validators/forgotten.js +++ b/core/client/validators/forgotten.js @@ -4,7 +4,9 @@ var ForgotValidator = Ember.Object.create({ validationErrors = []; if (!validator.isEmail(data.email)) { - validationErrors.push('Invalid Email'); + validationErrors.push({ + message: 'Invalid Email' + }); } return validationErrors; diff --git a/core/client/validators/reset.js b/core/client/validators/reset.js new file mode 100644 index 0000000000..898a5cfe65 --- /dev/null +++ b/core/client/validators/reset.js @@ -0,0 +1,24 @@ +var ResetValidator = Ember.Object.create({ + validate: function (model) { + + var data = model.getProperties('passwords'), + p1 = data.passwords.newPassword, + p2 = data.passwords.ne2Password, + validationErrors = []; + + if (!validator.equals(p1, p2)) { + validationErrors.push({ + message: 'The two new passwords don\'t match.' + }); + } + + if (!validator.isLength(p1, 8)) { + validationErrors.push({ + message: 'The password is not long enough.' + }); + } + return validationErrors; + } +}); + +export default ResetValidator; diff --git a/core/server/api/authentication.js b/core/server/api/authentication.js index 46051952e0..0ece83856a 100644 --- a/core/server/api/authentication.js +++ b/core/server/api/authentication.js @@ -31,14 +31,14 @@ authentication = { } else { return when.reject(new errors.BadRequestError('No email provided.')); } - + return settings.read({context: {internal: true}, key: 'dbHash'}).then(function (response) { var dbHash = response.settings[0].value; return dataProvider.User.generateResetToken(email, expires, dbHash).then(function (resetToken) { var baseUrl = config().forceAdminSSL ? (config().urlSSL || config().url) : config().url, siteLink = '' + baseUrl + '', - resetUrl = baseUrl.replace(/\/$/, '') + '/ghost/reset/' + resetToken + '/', + resetUrl = baseUrl.replace(/\/$/, '') + '/ghost/ember/reset/' + resetToken + '/', resetLink = '' + resetUrl + '', payload = { mail: [{