mirror of
https://github.com/wassname/talk.git
synced 2026-07-25 13:30:59 +08:00
Fixes to secrets init
This commit is contained in:
@@ -130,20 +130,18 @@ if (process.env.NODE_ENV === 'test' && !CONFIG.ROOT_URL) {
|
||||
|
||||
if (CONFIG.JWT_SECRETS) {
|
||||
CONFIG.JWT_SECRETS = JSON.parse(CONFIG.JWT_SECRETS);
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === 'test' && !CONFIG.JWT_SECRET) {
|
||||
CONFIG.JWT_SECRET = 'keyboard cat';
|
||||
} else if (!CONFIG.JWT_SECRET) {
|
||||
throw new Error(
|
||||
'TALK_JWT_SECRET must be provided in the environment to sign/verify tokens'
|
||||
);
|
||||
}
|
||||
if (process.env.NODE_ENV === 'test') {
|
||||
if (!CONFIG.JWT_ALG.startsWith('HS')) {
|
||||
throw new Error('Providing a asymmetric signing/verfying algorithm without a corresponding secret is not permitted');
|
||||
}
|
||||
|
||||
// If this is not employing a HMAC based signing method, then we need to turn
|
||||
// the secret into a buffer.
|
||||
if (!CONFIG.JWT_ALG.startsWith('HS')) {
|
||||
CONFIG.JWT_SECRET = Buffer.from(CONFIG.JWT_SECRET);
|
||||
CONFIG.JWT_SECRET = 'keyboard cat';
|
||||
} else {
|
||||
throw new Error(
|
||||
'TALK_JWT_SECRET must be provided in the environment to sign/verify tokens'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+5
-1
@@ -22,6 +22,10 @@ if (JWT_SECRETS) {
|
||||
throw new Error('when multiple keys are specified, kid\'s must be specified');
|
||||
}
|
||||
|
||||
if (typeof secret.kid !== 'string' || secret.kid.length === 0) {
|
||||
throw new Error('kid must be a unique string');
|
||||
}
|
||||
|
||||
// HMAC secrets do not have public/private keys.
|
||||
if (JWT_ALG.startsWith('HS')) {
|
||||
return new jwt.SharedSecret(secret, JWT_ALG);
|
||||
@@ -34,7 +38,7 @@ if (JWT_SECRETS) {
|
||||
return new jwt.AsymmetricSecret(secret, JWT_ALG);
|
||||
}));
|
||||
|
||||
debug(`loaded ${JWT_SECRET.length} ${JWT_ALG.startsWith('HS') ? 'shared' : 'asymmetric'} secrets`);
|
||||
debug(`loaded ${JWT_SECRETS.length} ${JWT_ALG.startsWith('HS') ? 'shared' : 'asymmetric'} secrets`);
|
||||
} else if (JWT_SECRET) {
|
||||
if (JWT_ALG.startsWith('HS')) {
|
||||
module.exports.jwt = new jwt.SharedSecret({
|
||||
|
||||
+12
-1
@@ -1,4 +1,5 @@
|
||||
const jwt = require('jsonwebtoken');
|
||||
const uniq = require('lodash/uniq');
|
||||
|
||||
/**
|
||||
* MultiSecret will take many secrets and provide a unified interface for
|
||||
@@ -6,6 +7,12 @@ const jwt = require('jsonwebtoken');
|
||||
*/
|
||||
class MultiSecret {
|
||||
constructor(secrets) {
|
||||
this.kids = secrets.map(({kid}) => kid);
|
||||
|
||||
if (uniq(this.kids).length !== secrets.length) {
|
||||
throw new Error('Duplicate kid\'s cannot be used to construct a MultiSecret');
|
||||
}
|
||||
|
||||
this.secrets = secrets;
|
||||
}
|
||||
|
||||
@@ -86,7 +93,11 @@ class Secret {
|
||||
/**
|
||||
* SharedSecret is the HMAC based secret that's used for signing/verifying.
|
||||
*/
|
||||
function SharedSecret({kid = undefined, secret}, algorithm) {
|
||||
function SharedSecret({kid = undefined, secret = null}, algorithm) {
|
||||
if (secret === null || secret.length === 0) {
|
||||
throw new Error('Secret cannot have a zero length');
|
||||
}
|
||||
|
||||
return new Secret({
|
||||
kid,
|
||||
signingKey: secret,
|
||||
|
||||
+10
-5
@@ -195,7 +195,9 @@ const CheckBlacklisted = async (jwt) => {
|
||||
}
|
||||
|
||||
// It wasn't a PAT! Check to see if it is valid anyways.
|
||||
return checkGeneralTokenBlacklist(jwt);
|
||||
await checkGeneralTokenBlacklist(jwt);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const JwtStrategy = require('passport-jwt').Strategy;
|
||||
@@ -257,11 +259,14 @@ passport.use(new JwtStrategy({
|
||||
try {
|
||||
|
||||
// Check to see if the token has been revoked
|
||||
await CheckBlacklisted(jwt);
|
||||
let user = await CheckBlacklisted(jwt);
|
||||
|
||||
// Try to get the user from the database or crack it from the token and
|
||||
// plugin integrations.
|
||||
let user = await UsersService.findOrCreateByIDToken(jwt.sub, {token, jwt});
|
||||
if (user === null) {
|
||||
|
||||
// Try to get the user from the database or crack it from the token and
|
||||
// plugin integrations.
|
||||
user = await UsersService.findOrCreateByIDToken(jwt.sub, {token, jwt});
|
||||
}
|
||||
|
||||
// Attach the JWT to the request.
|
||||
req.jwt = jwt;
|
||||
|
||||
+3
-1
@@ -93,7 +93,7 @@ module.exports = class TokenService {
|
||||
// Find the user.
|
||||
let user = await UserModel.findOne({
|
||||
id: userID
|
||||
}).select('tokens');
|
||||
});
|
||||
if (!user || !user.tokens) {
|
||||
throw new errors.ErrAuthentication('user does not exist');
|
||||
}
|
||||
@@ -108,6 +108,8 @@ module.exports = class TokenService {
|
||||
if (!token.active) {
|
||||
throw new errors.ErrAuthentication('token is not active');
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user