Ghost/core/test/unit/utils/tokens_spec.js
Katharina Irrgang 4e7779b783 🎨 remove token logic from user model (#7622)
* 🔥  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
2016-11-07 11:18:50 +00:00

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