0
Fork 0
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:
kirrg001 2018-04-25 11:56:45 +02:00
parent fef94b63ed
commit 27ebc3d1ac
4 changed files with 114 additions and 13 deletions

View file

@ -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 || {};

View file

@ -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);
}

View 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();
});
});
});
});

View file

@ -23,6 +23,7 @@ class KnexMock {
'posts',
'users',
'tags',
'invites',
'permissions',
'roles',
'posts_authors',