mirror of
https://github.com/wassname/talk.git
synced 2026-08-01 13:00:55 +08:00
refactored secret parsing
This commit is contained in:
@@ -7,8 +7,6 @@
|
||||
// entrypoint for the entire applications configuration.
|
||||
require('env-rewrite').rewrite();
|
||||
|
||||
const debug = require('debug')('talk:config');
|
||||
|
||||
//==============================================================================
|
||||
// CONFIG INITIALIZATION
|
||||
//==============================================================================
|
||||
@@ -106,53 +104,12 @@ const CONFIG = {
|
||||
// JWT based configuration
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const jwt = require('./services/jwt');
|
||||
|
||||
if (CONFIG.JWT_SECRETS) {
|
||||
CONFIG.JWT_SECRETS = JSON.parse(CONFIG.JWT_SECRETS);
|
||||
if (!Array.isArray(CONFIG.JWT_SECRETS)) {
|
||||
throw new Error('TALK_JWT_SECRETS must be a JSON array in the form [{"kid": kid, ["secret": secret | "private": private, "public": public]}, ...]');
|
||||
}
|
||||
|
||||
if (CONFIG.JWT_SECRETS.length === 0) {
|
||||
throw new Error('TALK_JWT_SECRETS must be a JSON array with non zero length');
|
||||
}
|
||||
|
||||
// Wrap a multi-secret around the available secrets.
|
||||
CONFIG.JWT_SECRET = new jwt.MultiSecret(CONFIG.JWT_SECRETS.map((secret) => {
|
||||
if (!('kid' in secret)) {
|
||||
throw new Error('when multiple keys are specified, kid\'s must be specified');
|
||||
}
|
||||
|
||||
// HMAC secrets do not have public/private keys.
|
||||
if (CONFIG.JWT_ALG.startsWith('HS')) {
|
||||
return new jwt.SharedSecret(secret, CONFIG.JWT_ALG);
|
||||
}
|
||||
|
||||
if (!('public' in secret)) {
|
||||
throw new Error('all symetric keys must provide a PEM encoded public key');
|
||||
}
|
||||
|
||||
return new jwt.AsymmetricSecret(secret, CONFIG.JWT_ALG);
|
||||
}));
|
||||
|
||||
debug(`loaded ${CONFIG.JWT_SECRET.length} secrets`);
|
||||
} else if (CONFIG.JWT_SECRET) {
|
||||
if (CONFIG.JWT_ALG.startsWith('HS')) {
|
||||
CONFIG.JWT_SECRET = new jwt.SharedSecret({
|
||||
secret: CONFIG.JWT_SECRET
|
||||
}, CONFIG.JWT_ALG);
|
||||
} else {
|
||||
CONFIG.JWT_SECRET = new jwt.AsymmetricSecret(JSON.parse(CONFIG.JWT_SECRET), CONFIG.JWT_ALG);
|
||||
}
|
||||
|
||||
debug('loaded 1 secret');
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === 'test' && !CONFIG.JWT_SECRET) {
|
||||
CONFIG.JWT_SECRET = new jwt.SharedSecret({
|
||||
secret: 'keyboard cat'
|
||||
}, CONFIG.JWT_ALG);
|
||||
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'
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
const {
|
||||
JWT_SECRETS,
|
||||
JWT_SECRET,
|
||||
JWT_ALG
|
||||
} = require('./config');
|
||||
|
||||
const debug = require('debug')('talk:secrets');
|
||||
const jwt = require('./services/jwt');
|
||||
|
||||
if (JWT_SECRETS) {
|
||||
if (!Array.isArray(JWT_SECRETS)) {
|
||||
throw new Error('TALK_JWT_SECRETS must be a JSON array in the form [{"kid": kid, ["secret": secret | "private": private, "public": public]}, ...]');
|
||||
}
|
||||
|
||||
if (JWT_SECRETS.length === 0) {
|
||||
throw new Error('TALK_JWT_SECRETS must be a JSON array with non zero length');
|
||||
}
|
||||
|
||||
// Wrap a multi-secret around the available secrets.
|
||||
module.exports.jwt = new jwt.MultiSecret(JWT_SECRETS.map((secret) => {
|
||||
if (!('kid' in secret)) {
|
||||
throw new Error('when multiple keys are specified, kid\'s must be specified');
|
||||
}
|
||||
|
||||
// HMAC secrets do not have public/private keys.
|
||||
if (JWT_ALG.startsWith('HS')) {
|
||||
return new jwt.SharedSecret(secret, JWT_ALG);
|
||||
}
|
||||
|
||||
if (!('public' in secret)) {
|
||||
throw new Error('all symetric keys must provide a PEM encoded public key');
|
||||
}
|
||||
|
||||
return new jwt.AsymmetricSecret(secret, JWT_ALG);
|
||||
}));
|
||||
|
||||
debug(`loaded ${JWT_SECRET.length} secrets`);
|
||||
} else if (JWT_SECRET) {
|
||||
if (JWT_ALG.startsWith('HS')) {
|
||||
module.exports.jwt = new jwt.SharedSecret({
|
||||
secret: JWT_SECRET
|
||||
}, JWT_ALG);
|
||||
} else {
|
||||
module.exports.jwt = new jwt.AsymmetricSecret(JSON.parse(JWT_SECRET), JWT_ALG);
|
||||
}
|
||||
|
||||
debug('loaded 1 secret');
|
||||
}
|
||||
@@ -16,7 +16,6 @@ const {createClientFactory} = require('./redis');
|
||||
const client = createClientFactory();
|
||||
|
||||
const {
|
||||
JWT_SECRET,
|
||||
JWT_ISSUER,
|
||||
JWT_EXPIRY,
|
||||
JWT_AUDIENCE,
|
||||
@@ -25,6 +24,10 @@ const {
|
||||
RECAPTCHA_ENABLED
|
||||
} = require('../config');
|
||||
|
||||
const {
|
||||
jwt: JWT_SECRET
|
||||
} = require('../secrets');
|
||||
|
||||
// GenerateToken will sign a token to include all the authorization information
|
||||
// needed for the front end.
|
||||
const GenerateToken = (user) => {
|
||||
|
||||
+4
-1
@@ -3,11 +3,14 @@ const UserModel = require('../models/user');
|
||||
const uuid = require('uuid');
|
||||
|
||||
const {
|
||||
JWT_SECRET,
|
||||
JWT_ISSUER,
|
||||
JWT_AUDIENCE
|
||||
} = require('../config');
|
||||
|
||||
const {
|
||||
jwt: JWT_SECRET
|
||||
} = require('../secrets');
|
||||
|
||||
/**
|
||||
* TokenService manages Personal Access Tokens for users. These tokens are
|
||||
* persisted in the database and attached to the user.
|
||||
|
||||
+6
-1
@@ -4,10 +4,15 @@ const bcrypt = require('bcryptjs');
|
||||
const url = require('url');
|
||||
const Wordlist = require('./wordlist');
|
||||
const errors = require('../errors');
|
||||
|
||||
const {
|
||||
JWT_SECRET,
|
||||
ROOT_URL
|
||||
} = require('../config');
|
||||
|
||||
const {
|
||||
jwt: JWT_SECRET
|
||||
} = require('../secrets');
|
||||
|
||||
const debug = require('debug')('talk:services:users');
|
||||
|
||||
const UserModel = require('../models/user');
|
||||
|
||||
Reference in New Issue
Block a user