mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-07 03:22:21 +03:00
4e7779b783
* 🔥 remove User model functions - validateToken - generateToken - resetPassword - all this logic will re-appear in a different way Token logic: - was already extracted as separate PR, see https://github.com/TryGhost/Ghost/pull/7554 - we will use this logic in the controller, you will see in the next commits Reset Password: Was just a wrapper for calling the token logic and change the password. We can reconsider keeping the function to call: changePassword and activate the status of the user - but i think it's fine to trigger these two actions from the controlling unit. * 🔥 remove password reset tests from User model - we already have unit tests for change password and the token logic - i will re-check at the end if any test case is missing - but for now i will just burn the tests * ✨ add token logic to controlling unit generateResetToken endpoint - the only change here is instead of calling the User model to generate a token, we generate the token via utils - we fetch the user by email, and generate a hash and return resetPassword endpoint - here we have changed a little bit more - first of all: we have added the validation check if the new passwords match - a new helper method to extract the token informations - the brute force security check, which can be handled later from the new bruteforce middleware (see TODO) - the actual reset function is doing the steps: load me the user, compare the token, change the password and activate the user - we can think of wrapping these steps into a User model function - i was not sure about it, because it is actually part of the controlling unit [ci skip] * 🎨 tidy up - jscs - jshint - naming functions - fixes * ✨ add a test for resetting the password - there was none - added a test to reset the password * 🎨 add more token tests - ensure quality - ensure logic we had * 🔥 remove compare new password check from User Model - this part of controlling unit * ✨ compare new passwords for user endpoint - we deleted the logic in User Model - we are adding the logic to controlling unit * 🐛 spam prevention forgotten can crash - no validation happend before this middleware - it just assumes that the root key is present - when we work on our API, we need to ensure that 1. pre validation happens 2. we call middlewares 3. ... * 🎨 token translation key
139 lines
3.8 KiB
JavaScript
139 lines
3.8 KiB
JavaScript
var uuid = require('node-uuid'),
|
|
should = require('should'),
|
|
utils = require('../../../server/utils');
|
|
|
|
should.equal(true, true);
|
|
|
|
describe('Utils: tokens', function () {
|
|
it('generate', function () {
|
|
var expires = Date.now() + 60 * 1000,
|
|
dbHash = uuid.v4(), token;
|
|
|
|
token = utils.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 () {
|
|
var expires = Date.now() + 60 * 1000,
|
|
dbHash = uuid.v4(), token, tokenIsCorrect;
|
|
|
|
token = utils.tokens.resetToken.generateHash({
|
|
email: 'test1@ghost.org',
|
|
expires: expires,
|
|
password: '12345678',
|
|
dbHash: dbHash
|
|
});
|
|
|
|
tokenIsCorrect = utils.tokens.resetToken.compare({
|
|
token: token,
|
|
dbHash: dbHash,
|
|
password: '12345678'
|
|
});
|
|
|
|
tokenIsCorrect.should.eql(true);
|
|
});
|
|
|
|
it('compare: error', function () {
|
|
var expires = Date.now() + 60 * 1000,
|
|
dbHash = uuid.v4(), token, tokenIsCorrect;
|
|
|
|
token = utils.tokens.resetToken.generateHash({
|
|
email: 'test1@ghost.org',
|
|
expires: expires,
|
|
password: '12345678',
|
|
dbHash: dbHash
|
|
});
|
|
|
|
tokenIsCorrect = utils.tokens.resetToken.compare({
|
|
token: token,
|
|
dbHash: dbHash,
|
|
password: '123456'
|
|
});
|
|
|
|
tokenIsCorrect.should.eql(false);
|
|
});
|
|
|
|
it('extract', function () {
|
|
var expires = Date.now() + 60 * 1000,
|
|
dbHash = uuid.v4(), token, parts, email = 'test1@ghost.org';
|
|
|
|
token = utils.tokens.resetToken.generateHash({
|
|
email: email,
|
|
expires: expires,
|
|
password: '12345678',
|
|
dbHash: dbHash
|
|
});
|
|
|
|
parts = utils.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', function () {
|
|
var expires = Date.now() + 60 * 1000,
|
|
dbHash = uuid.v4(), token, parts, email = 'test3@ghost.org';
|
|
|
|
token = utils.tokens.resetToken.generateHash({
|
|
email: email,
|
|
expires: expires,
|
|
password: '$2a$10$t5dY1uRRdjvqfNlXhae3uuc0nuhi.Rd7/K/9JaHHwSkLm6UUa3NsW',
|
|
dbHash: dbHash
|
|
});
|
|
|
|
parts = utils.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 () {
|
|
var expires = Date.now() + 60 * 1000,
|
|
email = 'test1@ghost.org',
|
|
dbHash = uuid.v4(), token, tokenIsCorrect, parts;
|
|
|
|
token = utils.tokens.resetToken.generateHash({
|
|
email: email,
|
|
expires: expires,
|
|
password: '12345678',
|
|
dbHash: dbHash
|
|
});
|
|
|
|
token = utils.encodeBase64URLsafe(token);
|
|
token = encodeURIComponent(token);
|
|
token = decodeURIComponent(token);
|
|
token = utils.decodeBase64URLsafe(token);
|
|
|
|
parts = utils.tokens.resetToken.extract({
|
|
token: token
|
|
});
|
|
|
|
parts.email.should.eql(email);
|
|
parts.expires.should.eql(expires);
|
|
|
|
tokenIsCorrect = utils.tokens.resetToken.compare({
|
|
token: token,
|
|
dbHash: dbHash,
|
|
password: '12345678'
|
|
});
|
|
|
|
tokenIsCorrect.should.eql(true);
|
|
});
|
|
});
|
|
|