mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-04-08 02:52:39 -05:00
Added unit tests for models.Invite.add
no issue - replaced token creation by `lib.common.security` - added unit tests for adding invites - allow a different invite status for internal access
This commit is contained in:
parent
fef94b63ed
commit
27ebc3d1ac
4 changed files with 114 additions and 13 deletions
|
@ -2,7 +2,25 @@
|
|||
|
||||
const crypto = require('crypto');
|
||||
|
||||
exports.resetToken = {
|
||||
module.exports.generateHash = function generateHash(options) {
|
||||
options = options || {};
|
||||
|
||||
const hash = crypto.createHash('sha256'),
|
||||
expires = options.expires,
|
||||
email = options.email,
|
||||
secret = options.secret;
|
||||
|
||||
let text = '';
|
||||
|
||||
hash.update(String(expires));
|
||||
hash.update(email.toLocaleLowerCase());
|
||||
hash.update(String(secret));
|
||||
|
||||
text += [expires, email, hash.digest('base64')].join('|');
|
||||
return new Buffer(text).toString('base64');
|
||||
};
|
||||
|
||||
module.exports.resetToken = {
|
||||
generateHash: function generateHash(options) {
|
||||
options = options || {};
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
'use strict';
|
||||
|
||||
const crypto = require('crypto'),
|
||||
constants = require('../lib/constants'),
|
||||
const constants = require('../lib/constants'),
|
||||
security = require('../lib/security'),
|
||||
settingsCache = require('../services/settings/cache'),
|
||||
ghostBookshelf = require('./base');
|
||||
|
||||
let Invite,
|
||||
|
@ -26,18 +27,20 @@ Invite = ghostBookshelf.Model.extend({
|
|||
return options;
|
||||
},
|
||||
|
||||
add: function add(data, options) {
|
||||
var hash = crypto.createHash('sha256'),
|
||||
text = '';
|
||||
add: function add(data, unfilteredOptions) {
|
||||
const options = Invite.filterOptions(unfilteredOptions, 'add');
|
||||
data = data || {};
|
||||
|
||||
if (!options.context || !options.context.internal) {
|
||||
data.status = 'pending';
|
||||
}
|
||||
|
||||
data.expires = Date.now() + constants.ONE_WEEK_MS;
|
||||
data.status = 'pending';
|
||||
|
||||
// @TODO: call a util fn?
|
||||
hash.update(String(data.expires));
|
||||
hash.update(data.email.toLocaleLowerCase());
|
||||
text += [data.expires, data.email, hash.digest('base64')].join('|');
|
||||
data.token = new Buffer(text).toString('base64');
|
||||
data.token = security.tokens.generateHash({
|
||||
email: data.email,
|
||||
expires: data.expires,
|
||||
secret: settingsCache.get('db_hash')
|
||||
});
|
||||
|
||||
return ghostBookshelf.Model.add.call(this, data, options);
|
||||
}
|
||||
|
|
79
core/test/unit/models/invite_spec.js
Normal file
79
core/test/unit/models/invite_spec.js
Normal file
|
@ -0,0 +1,79 @@
|
|||
'use strict';
|
||||
|
||||
const should = require('should'),
|
||||
sinon = require('sinon'),
|
||||
common = require('../../../server/lib/common'),
|
||||
models = require('../../../server/models'),
|
||||
settingsCache = require('../../../server/services/settings/cache'),
|
||||
testUtils = require('../../utils'),
|
||||
sandbox = sinon.sandbox.create();
|
||||
|
||||
describe('Unit: models/invite', function () {
|
||||
before(function () {
|
||||
models.init();
|
||||
sandbox.stub(settingsCache, 'get').withArgs('db_hash').returns('12345678');
|
||||
});
|
||||
|
||||
after(function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
describe('add', function () {
|
||||
let knexMock;
|
||||
|
||||
before(function () {
|
||||
knexMock = new testUtils.mocks.knex();
|
||||
knexMock.mock();
|
||||
});
|
||||
|
||||
after(function () {
|
||||
knexMock.unmock();
|
||||
});
|
||||
|
||||
it('default', function () {
|
||||
return models.Invite.add({email: 'invited@test.org', role_id: testUtils.DataGenerator.forKnex.roles[1].id})
|
||||
.then(function (invite) {
|
||||
invite.get('status').should.eql('pending');
|
||||
invite.get('email').should.eql('invited@test.org');
|
||||
should.exist(invite.get('token'));
|
||||
should.exist(invite.get('expires'));
|
||||
});
|
||||
});
|
||||
|
||||
it('set status with none internal context', function () {
|
||||
return models.Invite.add({
|
||||
email: 'invited@test.org',
|
||||
role_id: testUtils.DataGenerator.forKnex.roles[1].id,
|
||||
status: 'sent'
|
||||
}).then(function (invite) {
|
||||
invite.get('status').should.eql('pending');
|
||||
invite.get('email').should.eql('invited@test.org');
|
||||
should.exist(invite.get('token'));
|
||||
should.exist(invite.get('expires'));
|
||||
});
|
||||
});
|
||||
|
||||
it('set status with internal context', function () {
|
||||
return models.Invite.add({
|
||||
email: 'invited@test.org',
|
||||
role_id: testUtils.DataGenerator.forKnex.roles[1].id,
|
||||
status: 'sent'
|
||||
}, testUtils.context.internal).then(function (invite) {
|
||||
invite.get('status').should.eql('sent');
|
||||
invite.get('email').should.eql('invited@test.org');
|
||||
should.exist(invite.get('token'));
|
||||
should.exist(invite.get('expires'));
|
||||
});
|
||||
});
|
||||
|
||||
it('[error] no role passed', function () {
|
||||
return models.Invite.add({email: 'invited@test.org'})
|
||||
.then(function () {
|
||||
'Should fail'.should.be.true();
|
||||
})
|
||||
.catch(function (err) {
|
||||
(err[0] instanceof common.errors.ValidationError).should.be.true();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -23,6 +23,7 @@ class KnexMock {
|
|||
'posts',
|
||||
'users',
|
||||
'tags',
|
||||
'invites',
|
||||
'permissions',
|
||||
'roles',
|
||||
'posts_authors',
|
||||
|
|
Loading…
Add table
Reference in a new issue