07972312ed
refs https://github.com/TryGhost/Ghost/issues/11878 - To be able to identify the reason behind comparison failure on more granular level (like token expiration) had to provide additional information in return result for falsy token comparisons
200 lines
5.5 KiB
JavaScript
200 lines
5.5 KiB
JavaScript
require('./utils');
|
|
const should = require('should');
|
|
const uuid = require('uuid');
|
|
const security = require('../');
|
|
|
|
describe('Utils: tokens', function () {
|
|
it('generate', function () {
|
|
const expires = Date.now() + 60 * 1000;
|
|
const dbHash = uuid.v4();
|
|
let token;
|
|
|
|
token = security.tokens.resetToken.generateHash({
|
|
email: 'test1@ghost.org',
|
|
expires: expires,
|
|
password: 'password',
|
|
dbHash: dbHash
|
|
});
|
|
|
|
should.exist(token);
|
|
token.length.should.be.above(0);
|
|
});
|
|
|
|
it('compare: success', function () {
|
|
const expires = Date.now() + 60 * 1000;
|
|
const dbHash = uuid.v4();
|
|
let token;
|
|
let tokenIsCorrect;
|
|
|
|
token = security.tokens.resetToken.generateHash({
|
|
email: 'test1@ghost.org',
|
|
expires: expires,
|
|
password: '12345678',
|
|
dbHash: dbHash
|
|
});
|
|
|
|
tokenIsCorrect = security.tokens.resetToken.compare({
|
|
token: token,
|
|
dbHash: dbHash,
|
|
password: '12345678'
|
|
});
|
|
|
|
tokenIsCorrect.correct.should.eql(true);
|
|
should(tokenIsCorrect.reason).be.undefined;
|
|
});
|
|
|
|
it('compare: error from invalid password', function () {
|
|
const expires = Date.now() + 60 * 1000;
|
|
const dbHash = uuid.v4();
|
|
let token;
|
|
let tokenIsCorrect;
|
|
|
|
token = security.tokens.resetToken.generateHash({
|
|
email: 'test1@ghost.org',
|
|
expires: expires,
|
|
password: '12345678',
|
|
dbHash: dbHash
|
|
});
|
|
|
|
tokenIsCorrect = security.tokens.resetToken.compare({
|
|
token: token,
|
|
dbHash: dbHash,
|
|
password: '123456'
|
|
});
|
|
|
|
tokenIsCorrect.correct.should.eql(false);
|
|
tokenIsCorrect.reason.should.eql('invalid');
|
|
});
|
|
|
|
it('compare: error from invalid expires parameter', function () {
|
|
const invalidDate = 'not a date';
|
|
const dbHash = uuid.v4();
|
|
let token;
|
|
let tokenIsCorrect;
|
|
|
|
token = security.tokens.resetToken.generateHash({
|
|
email: 'test1@ghost.org',
|
|
expires: invalidDate,
|
|
password: '12345678',
|
|
dbHash: dbHash
|
|
});
|
|
|
|
tokenIsCorrect = security.tokens.resetToken.compare({
|
|
token: token,
|
|
dbHash: dbHash,
|
|
password: '123456'
|
|
});
|
|
|
|
tokenIsCorrect.correct.should.eql(false);
|
|
tokenIsCorrect.reason.should.eql('invalid_expiry');
|
|
});
|
|
|
|
it('compare: error from expired token', function () {
|
|
const dateInThePast = Date.now() - 60 * 1000;
|
|
const dbHash = uuid.v4();
|
|
let token;
|
|
let tokenIsCorrect;
|
|
|
|
token = security.tokens.resetToken.generateHash({
|
|
email: 'test1@ghost.org',
|
|
expires: dateInThePast,
|
|
password: '12345678',
|
|
dbHash: dbHash
|
|
});
|
|
|
|
tokenIsCorrect = security.tokens.resetToken.compare({
|
|
token: token,
|
|
dbHash: dbHash,
|
|
password: '123456'
|
|
});
|
|
|
|
tokenIsCorrect.correct.should.eql(false);
|
|
tokenIsCorrect.reason.should.eql('expired');
|
|
});
|
|
|
|
it('extract', function () {
|
|
const expires = Date.now() + 60 * 1000;
|
|
const dbHash = uuid.v4();
|
|
let token;
|
|
let parts;
|
|
const email = 'test1@ghost.org';
|
|
|
|
token = security.tokens.resetToken.generateHash({
|
|
email: email,
|
|
expires: expires,
|
|
password: '12345678',
|
|
dbHash: dbHash
|
|
});
|
|
|
|
parts = security.tokens.resetToken.extract({
|
|
token: token
|
|
});
|
|
|
|
parts.email.should.eql(email);
|
|
parts.expires.should.eql(expires);
|
|
should.not.exist(parts.password);
|
|
should.not.exist(parts.dbHash);
|
|
});
|
|
|
|
it('extract - hashed password', function () {
|
|
const expires = Date.now() + 60 * 1000;
|
|
const dbHash = uuid.v4();
|
|
let token;
|
|
let parts;
|
|
const email = 'test3@ghost.org';
|
|
|
|
token = security.tokens.resetToken.generateHash({
|
|
email: email,
|
|
expires: expires,
|
|
password: '$2a$10$t5dY1uRRdjvqfNlXhae3uuc0nuhi.Rd7/K/9JaHHwSkLm6UUa3NsW',
|
|
dbHash: dbHash
|
|
});
|
|
|
|
parts = security.tokens.resetToken.extract({
|
|
token: token
|
|
});
|
|
|
|
parts.email.should.eql(email);
|
|
parts.expires.should.eql(expires);
|
|
should.not.exist(parts.password);
|
|
should.not.exist(parts.dbHash);
|
|
});
|
|
|
|
it('can validate an URI encoded reset token', function () {
|
|
const expires = Date.now() + 60 * 1000;
|
|
const email = 'test1@ghost.org';
|
|
const dbHash = uuid.v4();
|
|
let token;
|
|
let tokenIsCorrect;
|
|
let parts;
|
|
|
|
token = security.tokens.resetToken.generateHash({
|
|
email: email,
|
|
expires: expires,
|
|
password: '12345678',
|
|
dbHash: dbHash
|
|
});
|
|
|
|
token = security.url.encodeBase64(token);
|
|
token = encodeURIComponent(token);
|
|
token = decodeURIComponent(token);
|
|
token = security.url.decodeBase64(token);
|
|
|
|
parts = security.tokens.resetToken.extract({
|
|
token: token
|
|
});
|
|
|
|
parts.email.should.eql(email);
|
|
parts.expires.should.eql(expires);
|
|
|
|
tokenIsCorrect = security.tokens.resetToken.compare({
|
|
token: token,
|
|
dbHash: dbHash,
|
|
password: '12345678'
|
|
});
|
|
|
|
tokenIsCorrect.correct.should.eql(true);
|
|
});
|
|
});
|
|
|