Fix JWT expire time going crazy. Now set to 1day

This commit is contained in:
Jamie Curnow
2020-02-19 13:01:34 +10:00
parent e09b427081
commit 0ec4f63926
2 changed files with 140 additions and 152 deletions

View File

@@ -7,158 +7,156 @@ const TokenModel = require('../models/token');
module.exports = { module.exports = {
/** /**
* @param {Object} data * @param {Object} data
* @param {String} data.identity * @param {String} data.identity
* @param {String} data.secret * @param {String} data.secret
* @param {String} [data.scope] * @param {String} [data.scope]
* @param {String} [data.expiry] * @param {String} [data.expiry]
* @param {String} [issuer] * @param {String} [issuer]
* @returns {Promise} * @returns {Promise}
*/ */
getTokenFromEmail: (data, issuer) => { getTokenFromEmail: (data, issuer) => {
let Token = new TokenModel(); let Token = new TokenModel();
data.scope = data.scope || 'user'; data.scope = data.scope || 'user';
data.expiry = data.expiry || '30d'; data.expiry = data.expiry || '1d';
return userModel return userModel
.query() .query()
.where('email', data.identity) .where('email', data.identity)
.andWhere('is_deleted', 0) .andWhere('is_deleted', 0)
.andWhere('is_disabled', 0) .andWhere('is_disabled', 0)
.first() .first()
.then(user => { .then(user => {
if (user) { if (user) {
// Get auth // Get auth
return authModel return authModel
.query() .query()
.where('user_id', '=', user.id) .where('user_id', '=', user.id)
.where('type', '=', 'password') .where('type', '=', 'password')
.first() .first()
.then(auth => { .then(auth => {
if (auth) { if (auth) {
return auth.verifyPassword(data.secret) return auth.verifyPassword(data.secret)
.then(valid => { .then(valid => {
if (valid) { if (valid) {
if (data.scope !== 'user' && _.indexOf(user.roles, data.scope) === -1) { if (data.scope !== 'user' && _.indexOf(user.roles, data.scope) === -1) {
// The scope requested doesn't exist as a role against the user, // The scope requested doesn't exist as a role against the user,
// you shall not pass. // you shall not pass.
throw new error.AuthError('Invalid scope: ' + data.scope); throw new error.AuthError('Invalid scope: ' + data.scope);
} }
// Create a moment of the expiry expression // Create a moment of the expiry expression
let expiry = helpers.parseDatePeriod(data.expiry); let expiry = helpers.parseDatePeriod(data.expiry);
if (expiry === null) { if (expiry === null) {
throw new error.AuthError('Invalid expiry time: ' + data.expiry); throw new error.AuthError('Invalid expiry time: ' + data.expiry);
} }
return Token.create({ return Token.create({
iss: issuer || 'api', iss: issuer || 'api',
attrs: { attrs: {
id: user.id id: user.id
}, },
scope: [data.scope] scope: [data.scope],
}, { expiresIn: data.expiry
expires: expiry.unix() })
}) .then(signed => {
.then(signed => { return {
return { token: signed.token,
token: signed.token, expires: expiry.toISOString()
expires: expiry.toISOString() };
}; });
}); } else {
} else { throw new error.AuthError('Invalid password');
throw new error.AuthError('Invalid password'); }
} });
}); } else {
} else { throw new error.AuthError('No password auth for user');
throw new error.AuthError('No password auth for user'); }
} });
}); } else {
} else { throw new error.AuthError('No relevant user found');
throw new error.AuthError('No relevant user found'); }
} });
}); },
},
/** /**
* @param {Access} access * @param {Access} access
* @param {Object} [data] * @param {Object} [data]
* @param {String} [data.expiry] * @param {String} [data.expiry]
* @param {String} [data.scope] Only considered if existing token scope is admin * @param {String} [data.scope] Only considered if existing token scope is admin
* @returns {Promise} * @returns {Promise}
*/ */
getFreshToken: (access, data) => { getFreshToken: (access, data) => {
let Token = new TokenModel(); let Token = new TokenModel();
data = data || {}; data = data || {};
data.expiry = data.expiry || '30d'; data.expiry = data.expiry || '1d';
if (access && access.token.getUserId(0)) { if (access && access.token.getUserId(0)) {
// Create a moment of the expiry expression // Create a moment of the expiry expression
let expiry = helpers.parseDatePeriod(data.expiry); let expiry = helpers.parseDatePeriod(data.expiry);
if (expiry === null) { if (expiry === null) {
throw new error.AuthError('Invalid expiry time: ' + data.expiry); throw new error.AuthError('Invalid expiry time: ' + data.expiry);
} }
let token_attrs = { let token_attrs = {
id: access.token.getUserId(0) id: access.token.getUserId(0)
}; };
// Only admins can request otherwise scoped tokens // Only admins can request otherwise scoped tokens
let scope = access.token.get('scope'); let scope = access.token.get('scope');
if (data.scope && access.token.hasScope('admin')) { if (data.scope && access.token.hasScope('admin')) {
scope = [data.scope]; scope = [data.scope];
if (data.scope === 'job-board' || data.scope === 'worker') { if (data.scope === 'job-board' || data.scope === 'worker') {
token_attrs.id = 0; token_attrs.id = 0;
} }
} }
return Token.create({ return Token.create({
iss: 'api', iss: 'api',
scope: scope, scope: scope,
attrs: token_attrs attrs: token_attrs,
}, { expiresIn: data.expiry
expiresIn: expiry.unix() })
}) .then(signed => {
.then(signed => { return {
return { token: signed.token,
token: signed.token, expires: expiry.toISOString()
expires: expiry.toISOString() };
}; });
}); } else {
} else { throw new error.AssertionFailedError('Existing token contained invalid user data');
throw new error.AssertionFailedError('Existing token contained invalid user data'); }
} },
},
/** /**
* @param {Object} user * @param {Object} user
* @returns {Promise} * @returns {Promise}
*/ */
getTokenFromUser: user => { getTokenFromUser: (user) => {
let Token = new TokenModel(); const expire = '1d';
let expiry = helpers.parseDatePeriod('1d'); const Token = new TokenModel();
const expiry = helpers.parseDatePeriod(expire);
return Token.create({ return Token.create({
iss: 'api', iss: 'api',
attrs: { attrs: {
id: user.id id: user.id
}, },
scope: ['user'] scope: ['user'],
}, { expiresIn: expire
expiresIn: expiry.unix() })
}) .then(signed => {
.then(signed => { return {
return { token: signed.token,
token: signed.token, expires: expiry.toISOString(),
expires: expiry.toISOString(), user: user
user: user };
}; });
}); }
}
}; };

View File

@@ -19,23 +19,15 @@ module.exports = function () {
let self = { let self = {
/** /**
* @param {Object} payload * @param {Object} payload
* @param {Object} [user_options]
* @param {Integer} [user_options.expires]
* @returns {Promise} * @returns {Promise}
*/ */
create: (payload, user_options) => { create: (payload) => {
user_options = user_options || {};
// sign with RSA SHA256 // sign with RSA SHA256
let options = { let options = {
algorithm: ALGO algorithm: ALGO,
expiresIn: payload.expiresIn || '1d'
}; };
if (typeof user_options.expires !== 'undefined' && user_options.expires) {
options.expiresIn = user_options.expires;
}
payload.jti = crypto.randomBytes(12) payload.jti = crypto.randomBytes(12)
.toString('base64') .toString('base64')
.substr(-8); .substr(-8);
@@ -51,10 +43,8 @@ module.exports = function () {
payload: payload payload: payload
}); });
} }
}); });
}); });
}, },
/** /**