mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-28 14:03:48 +03:00
Merge pull request #5349 from acburdine/onboarding-api
Add PUT route to authentication setup
This commit is contained in:
commit
b8415e8b90
@ -9,6 +9,45 @@ var _ = require('lodash'),
|
||||
config = require('../config'),
|
||||
authentication;
|
||||
|
||||
function setupTasks(object) {
|
||||
var setupUser,
|
||||
internal = {context: {internal: true}};
|
||||
|
||||
return utils.checkObject(object, 'setup').then(function (checkedSetupData) {
|
||||
setupUser = {
|
||||
name: checkedSetupData.setup[0].name,
|
||||
email: checkedSetupData.setup[0].email,
|
||||
password: checkedSetupData.setup[0].password,
|
||||
blogTitle: checkedSetupData.setup[0].blogTitle,
|
||||
status: 'active'
|
||||
};
|
||||
|
||||
return dataProvider.User.findOne({role: 'Owner', status: 'all'});
|
||||
}).then(function (ownerUser) {
|
||||
if (ownerUser) {
|
||||
return dataProvider.User.setup(setupUser, _.extend({id: ownerUser.id}, internal));
|
||||
} else {
|
||||
return dataProvider.Role.findOne({name: 'Owner'}).then(function (ownerRole) {
|
||||
setupUser.roles = [ownerRole.id];
|
||||
return dataProvider.User.add(setupUser, internal);
|
||||
});
|
||||
}
|
||||
}).then(function (user) {
|
||||
var userSettings = [];
|
||||
|
||||
// Handles the additional values set by the setup screen.
|
||||
if (!_.isEmpty(setupUser.blogTitle)) {
|
||||
userSettings.push({key: 'title', value: setupUser.blogTitle});
|
||||
userSettings.push({key: 'description', value: 'Thoughts, stories and ideas.'});
|
||||
}
|
||||
|
||||
setupUser = user.toJSON(internal);
|
||||
return settings.edit({settings: userSettings}, {context: {user: setupUser.id}});
|
||||
}).then(function () {
|
||||
return Promise.resolve(setupUser);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* ## Authentication API Methods
|
||||
*
|
||||
@ -153,7 +192,7 @@ authentication = {
|
||||
* @param {string} options.email The email to check for an invitation on
|
||||
* @returns {Promise(Invitation}} An invitation status
|
||||
*/
|
||||
isInvitation: function (options) {
|
||||
isInvitation: function isInvitation(options) {
|
||||
return authentication.isSetup().then(function (result) {
|
||||
var setup = result.setup[0].status;
|
||||
|
||||
@ -175,7 +214,7 @@ authentication = {
|
||||
});
|
||||
},
|
||||
|
||||
isSetup: function () {
|
||||
isSetup: function isSetup() {
|
||||
return dataProvider.User.query(function (qb) {
|
||||
qb.whereIn('status', ['active', 'warn-1', 'warn-2', 'warn-3', 'warn-4', 'locked']);
|
||||
}).fetch().then(function (users) {
|
||||
@ -187,9 +226,8 @@ authentication = {
|
||||
});
|
||||
},
|
||||
|
||||
setup: function (object) {
|
||||
var setupUser,
|
||||
internal = {context: {internal: true}};
|
||||
setup: function setup(object) {
|
||||
var setupUser;
|
||||
|
||||
return authentication.isSetup().then(function (result) {
|
||||
var setup = result.setup[0].status;
|
||||
@ -198,37 +236,10 @@ authentication = {
|
||||
return Promise.reject(new errors.NoPermissionError('Setup has already been completed.'));
|
||||
}
|
||||
|
||||
return utils.checkObject(object, 'setup');
|
||||
}).then(function (checkedSetupData) {
|
||||
setupUser = {
|
||||
name: checkedSetupData.setup[0].name,
|
||||
email: checkedSetupData.setup[0].email,
|
||||
password: checkedSetupData.setup[0].password,
|
||||
blogTitle: checkedSetupData.setup[0].blogTitle,
|
||||
status: 'active'
|
||||
};
|
||||
return setupTasks(object);
|
||||
}).then(function (result) {
|
||||
setupUser = result;
|
||||
|
||||
return dataProvider.User.findOne({role: 'Owner', status: 'all'});
|
||||
}).then(function (ownerUser) {
|
||||
if (ownerUser) {
|
||||
return dataProvider.User.setup(setupUser, _.extend({id: ownerUser.id}, internal));
|
||||
} else {
|
||||
return dataProvider.Role.findOne({name: 'Owner'}).then(function (ownerRole) {
|
||||
setupUser.roles = [ownerRole.id];
|
||||
return dataProvider.User.add(setupUser, internal);
|
||||
});
|
||||
}
|
||||
}).then(function (user) {
|
||||
var userSettings = [];
|
||||
|
||||
// Handles the additional values set by the setup screen.
|
||||
if (!_.isEmpty(setupUser.blogTitle)) {
|
||||
userSettings.push({key: 'title', value: setupUser.blogTitle});
|
||||
userSettings.push({key: 'description', value: 'Thoughts, stories and ideas.'});
|
||||
}
|
||||
setupUser = user.toJSON(internal);
|
||||
return settings.edit({settings: userSettings}, {context: {user: setupUser.id}});
|
||||
}).then(function () {
|
||||
var data = {
|
||||
ownerEmail: setupUser.email
|
||||
};
|
||||
@ -260,22 +271,21 @@ authentication = {
|
||||
});
|
||||
},
|
||||
|
||||
revoke: function (object) {
|
||||
var token;
|
||||
|
||||
if (object.token_type_hint && object.token_type_hint === 'access_token') {
|
||||
token = dataProvider.Accesstoken;
|
||||
} else if (object.token_type_hint && object.token_type_hint === 'refresh_token') {
|
||||
token = dataProvider.Refreshtoken;
|
||||
} else {
|
||||
return errors.BadRequestError('Invalid token_type_hint given.');
|
||||
updateSetup: function updateSetup(object, options) {
|
||||
if (!options.context || !options.context.user) {
|
||||
return Promise.reject(new errors.NoPermissionError('You are not logged in.'));
|
||||
}
|
||||
|
||||
return token.destroyByToken({token: object.token}).then(function () {
|
||||
return Promise.resolve({token: object.token});
|
||||
}, function () {
|
||||
// On error we still want a 200. See https://tools.ietf.org/html/rfc7009#page-5
|
||||
return Promise.resolve({token: object.token, error: 'Invalid token provided'});
|
||||
return dataProvider.User.findOne({role: 'Owner', status: 'all'}).then(function (result) {
|
||||
var user = result.toJSON();
|
||||
|
||||
if (user.id !== options.context.user) {
|
||||
return Promise.reject(new errors.NoPermissionError('You are not the blog owner.'));
|
||||
}
|
||||
|
||||
return setupTasks(object);
|
||||
}).then(function (result) {
|
||||
return Promise.resolve({users: [result]});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -111,7 +111,8 @@ middleware = {
|
||||
});
|
||||
|
||||
if (subPath.indexOf('/ghost/api/') === 0
|
||||
&& path.indexOf('/ghost/api/v0.1/authentication/') !== 0) {
|
||||
&& (path.indexOf('/ghost/api/v0.1/authentication/') !== 0
|
||||
|| (path.indexOf('/ghost/api/v0.1/authentication/') === 0 && req.method === 'PUT'))) {
|
||||
return passport.authenticate('bearer', {session: false, failWithError: true},
|
||||
function authenticate(err, user, info) {
|
||||
if (err) {
|
||||
|
@ -77,6 +77,7 @@ apiRoutes = function apiRoutes(middleware) {
|
||||
router.post('/authentication/invitation', api.http(api.authentication.acceptInvitation));
|
||||
router.get('/authentication/invitation', api.http(api.authentication.isInvitation));
|
||||
router.post('/authentication/setup', api.http(api.authentication.setup));
|
||||
router.put('/authentication/setup', api.http(api.authentication.updateSetup));
|
||||
router.get('/authentication/setup', api.http(api.authentication.isSetup));
|
||||
router.post('/authentication/token',
|
||||
middleware.spamPrevention.signin,
|
||||
|
@ -7,7 +7,8 @@ var testUtils = require('../../utils'),
|
||||
|
||||
// Stuff we are testing
|
||||
mail = rewire('../../../server/api/mail'),
|
||||
AuthAPI = require('../../../server/api/authentication');
|
||||
AuthAPI = require('../../../server/api/authentication'),
|
||||
context = testUtils.context;
|
||||
|
||||
describe('Authentication API', function () {
|
||||
// Keep the DB clean
|
||||
@ -81,7 +82,7 @@ describe('Authentication API', function () {
|
||||
name: 'test user',
|
||||
email: 'test@example.com',
|
||||
password: 'areallygoodpassword',
|
||||
title: 'a test blog'
|
||||
blogTitle: 'a test blog'
|
||||
};
|
||||
|
||||
AuthAPI.setup({setup: [setupData]}).then(function () {
|
||||
@ -98,6 +99,112 @@ describe('Authentication API', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Setup Update', function () {
|
||||
describe('Setup not complete', function () {
|
||||
beforeEach(testUtils.setup('roles', 'owner:pre', 'settings', 'perms:setting', 'perms:init'));
|
||||
|
||||
it('should report that setup has not been completed', function (done) {
|
||||
AuthAPI.isSetup().then(function (result) {
|
||||
should.exist(result);
|
||||
result.setup[0].status.should.be.false;
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should not allow setup to be updated', function (done) {
|
||||
var setupData = {
|
||||
name: 'test user',
|
||||
email: 'test@example.com',
|
||||
password: 'areallygoodpassword',
|
||||
blogTitle: 'a test blog'
|
||||
};
|
||||
|
||||
AuthAPI.updateSetup({setup: [setupData]}, {}).then(function () {
|
||||
done(new Error('Update was able to be run'));
|
||||
}).catch(function (err) {
|
||||
should.exist(err);
|
||||
|
||||
err.name.should.equal('NoPermissionError');
|
||||
err.code.should.equal(403);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Not Owner', function () {
|
||||
beforeEach(testUtils.setup('roles', 'users:roles', 'settings', 'perms:setting', 'perms:init', 'perms:user'));
|
||||
|
||||
it('should report that setup has been completed', function (done) {
|
||||
AuthAPI.isSetup().then(function (result) {
|
||||
should.exist(result);
|
||||
result.setup[0].status.should.be.true;
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should not allow setup to be updated', function (done) {
|
||||
var setupData = {
|
||||
name: 'test user',
|
||||
email: 'test@example.com',
|
||||
password: 'areallygoodpassword',
|
||||
blogTitle: 'a test blog'
|
||||
};
|
||||
|
||||
AuthAPI.updateSetup({setup: [setupData]}, context.author).then(function () {
|
||||
done(new Error('Update was able to be run'));
|
||||
}).catch(function (err) {
|
||||
should.exist(err);
|
||||
|
||||
err.name.should.equal('NoPermissionError');
|
||||
err.code.should.equal(403);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Owner', function () {
|
||||
beforeEach(testUtils.setup('roles', 'users:roles', 'settings', 'perms:setting', 'perms:init'));
|
||||
|
||||
it('should report that setup has been completed', function (done) {
|
||||
AuthAPI.isSetup().then(function (result) {
|
||||
should.exist(result);
|
||||
result.setup[0].status.should.be.true;
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should allow setup to be updated', function (done) {
|
||||
var setupData = {
|
||||
name: 'test user',
|
||||
email: 'test@example.com',
|
||||
password: 'areallygoodpassword',
|
||||
blogTitle: 'a test blog'
|
||||
};
|
||||
|
||||
AuthAPI.updateSetup({setup: [setupData]}, context.owner).then(function (result) {
|
||||
should.exist(result);
|
||||
should.exist(result.users);
|
||||
should.not.exist(result.meta);
|
||||
result.users.should.have.length(1);
|
||||
testUtils.API.checkResponse(result.users[0], 'user');
|
||||
|
||||
var newUser = result.users[0];
|
||||
|
||||
newUser.id.should.equal(1);
|
||||
newUser.name.should.equal(setupData.name);
|
||||
newUser.email.should.equal(setupData.email);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// describe('Authentication', function () {
|
||||
|
||||
// describe('Setup not completed', function () {
|
||||
|
Loading…
Reference in New Issue
Block a user