mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-20 22:42:53 -05:00
Allow user to accept invitation
closes #3081 - added route `/ghost/api/v0.1/authentication/invitation` - added accept invitation - added signup with token - removed check() from users api - fixed promise in resetPassword()
This commit is contained in:
parent
f114f4f2f6
commit
84cfd529ed
8 changed files with 66 additions and 16 deletions
|
@ -5,6 +5,7 @@ var SignupController = Ember.ObjectController.extend(ValidationEngine, {
|
|||
name: null,
|
||||
email: null,
|
||||
password: null,
|
||||
token: null,
|
||||
submitting: false,
|
||||
|
||||
// ValidationEngine settings
|
||||
|
@ -12,16 +13,25 @@ var SignupController = Ember.ObjectController.extend(ValidationEngine, {
|
|||
|
||||
actions: {
|
||||
signup: function () {
|
||||
var self = this;
|
||||
var self = this,
|
||||
data = self.getProperties('name', 'email', 'password', 'token');
|
||||
|
||||
self.notifications.closePassive();
|
||||
|
||||
this.toggleProperty('submitting');
|
||||
this.validate({ format: false }).then(function () {
|
||||
ajax({
|
||||
url: self.get('ghostPaths').adminUrl('signup'),
|
||||
url: self.get('ghostPaths').apiUrl('authentication', 'invitation'),
|
||||
type: 'POST',
|
||||
data: self.getProperties('name', 'email', 'password')
|
||||
dataType: 'json',
|
||||
data: {
|
||||
invitation: [{
|
||||
name: data.name,
|
||||
email: data.email,
|
||||
password: data.password,
|
||||
token: data.token
|
||||
}]
|
||||
}
|
||||
}).then(function () {
|
||||
self.get('session').authenticate('ember-simple-auth-authenticator:oauth2-password-grant', {
|
||||
identification: self.get('email'),
|
||||
|
|
|
@ -18,7 +18,7 @@ Router.map(function () {
|
|||
this.route('setup');
|
||||
this.route('signin');
|
||||
this.route('signout');
|
||||
this.route('signup');
|
||||
this.route('signup', { path: '/signup/:token' });
|
||||
this.route('forgotten');
|
||||
this.route('reset', { path: '/reset/:token' });
|
||||
this.resource('posts', { path: '/' }, function () {
|
||||
|
|
|
@ -2,7 +2,19 @@ import styleBody from 'ghost/mixins/style-body';
|
|||
import loadingIndicator from 'ghost/mixins/loading-indicator';
|
||||
|
||||
var SignupRoute = Ember.Route.extend(styleBody, loadingIndicator, {
|
||||
classNames: ['ghost-signup']
|
||||
classNames: ['ghost-signup'],
|
||||
beforeModel: function () {
|
||||
if (this.get('session').isAuthenticated) {
|
||||
this.transitionTo(Ember.SimpleAuth.routeAfterAuthentication);
|
||||
}
|
||||
},
|
||||
setupController: function (controller, params) {
|
||||
var tokenText = atob(params.token),
|
||||
email = tokenText.split('|')[1];
|
||||
controller.token = params.token;
|
||||
controller.email = email;
|
||||
controller.name = email.substring(0, email.indexOf('@'));
|
||||
}
|
||||
});
|
||||
|
||||
export default SignupRoute;
|
||||
|
|
|
@ -91,6 +91,38 @@ authentication = {
|
|||
return when.reject(new errors.UnauthorizedError(error.message));
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* ### Accept Invitation
|
||||
* @param {User} object the user to create
|
||||
* @returns {Promise(User}} Newly created user
|
||||
*/
|
||||
acceptInvitation: function acceptInvitation(object) {
|
||||
var resetToken,
|
||||
newPassword,
|
||||
ne2Password,
|
||||
name,
|
||||
email;
|
||||
|
||||
return utils.checkObject(object, 'invitation').then(function (checkedInvitation) {
|
||||
resetToken = checkedInvitation.invitation[0].token;
|
||||
newPassword = checkedInvitation.invitation[0].password;
|
||||
ne2Password = checkedInvitation.invitation[0].password;
|
||||
email = checkedInvitation.invitation[0].email;
|
||||
name = checkedInvitation.invitation[0].name;
|
||||
|
||||
return settings.read({context: {internal: true}, key: 'dbHash'}).then(function (response) {
|
||||
var dbHash = response.settings[0].value;
|
||||
return dataProvider.User.resetPassword(resetToken, newPassword, ne2Password, dbHash);
|
||||
}).then(function (user) {
|
||||
return dataProvider.User.edit({name: name, email: email}, {id: user.id});
|
||||
}).then(function () {
|
||||
return when.resolve({invitation: [{message: 'Invitation accepted.'}]});
|
||||
}).otherwise(function (error) {
|
||||
return when.reject(new errors.UnauthorizedError(error.message));
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -96,6 +96,7 @@ users = {
|
|||
* @param {{context}} options
|
||||
* @returns {Promise(User}} Newly created user
|
||||
*/
|
||||
// TODO: remove and rename invite to add when setup is implemented
|
||||
add: function add(object, options) {
|
||||
options = options || {};
|
||||
|
||||
|
@ -213,16 +214,12 @@ users = {
|
|||
* @param {User} object the user to create
|
||||
* @returns {Promise(User}} Newly created user
|
||||
*/
|
||||
// TODO: create a proper API end point and use JSON API format
|
||||
// TODO: remove when setup is implemented
|
||||
register: function register(object) {
|
||||
// TODO: if we want to prevent users from being created with the signup form this is the right place to do it
|
||||
return users.add(object, {context: {internal: true}});
|
||||
},
|
||||
|
||||
check: function check(object) {
|
||||
return dataProvider.User.check(object);
|
||||
},
|
||||
|
||||
/**
|
||||
* ### Change Password
|
||||
* @param {password} object
|
||||
|
|
|
@ -50,8 +50,7 @@ var middleware = {
|
|||
|
||||
if (res.isAdmin) {
|
||||
if (subPath.indexOf('/ghost/api/') === 0
|
||||
&& path.indexOf('/ghost/api/v0.1/authentication/token') !== 0
|
||||
&& path.indexOf('/ghost/api/v0.1/authentication/passwordreset/') !== 0) {
|
||||
&& path.indexOf('/ghost/api/v0.1/authentication/') !== 0) {
|
||||
|
||||
return passport.authenticate('bearer', { session: false, failWithError: true },
|
||||
function (err, user, info) {
|
||||
|
|
|
@ -216,7 +216,6 @@ User = ghostBookshelf.Model.extend({
|
|||
if (!user || user.get('status') === 'invited') {
|
||||
return when.reject(new Error('NotFound'));
|
||||
}
|
||||
|
||||
if (user.get('status') !== 'locked') {
|
||||
return nodefn.call(bcrypt.compare, object.password, user.get('password')).then(function (matched) {
|
||||
if (!matched) {
|
||||
|
@ -376,9 +375,7 @@ User = ghostBookshelf.Model.extend({
|
|||
var foundUser = results[0],
|
||||
passwordHash = results[1];
|
||||
|
||||
foundUser.save({password: passwordHash, status: 'active'});
|
||||
|
||||
return foundUser;
|
||||
return foundUser.save({password: passwordHash, status: 'active'});
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -56,6 +56,9 @@ apiRoutes = function (middleware) {
|
|||
// ## Authentication
|
||||
router.post('/ghost/api/v0.1/authentication/passwordreset', api.http(api.authentication.generateResetToken));
|
||||
router.put('/ghost/api/v0.1/authentication/passwordreset', api.http(api.authentication.resetPassword));
|
||||
|
||||
router.post('/ghost/api/v0.1/authentication/invitation', api.http(api.authentication.acceptInvitation));
|
||||
|
||||
router.post('/ghost/api/v0.1/authentication/token',
|
||||
middleware.addClientSecret,
|
||||
middleware.authenticateClient,
|
||||
|
|
Loading…
Add table
Reference in a new issue