Getting error: FATAL ERROR: jwtPrivateKey is not defined.'
I'm still having some exception errors about JSON web token Private Key. It says it's not defined but I think I already put the JSON web token private key and still throwing an error. I'm not sure where the problem is maybe in the user module or auth module or on the config. Please see the below code and any help would be appreciated.
//default.json
{
"jwtPrivateKey": "",
"db": "mongodb://localhost/vidly"
}
// test.json
{
"jwtPrivateKey": "1234",
"db": "mongodb://localhost/vidly_tests"
}
// config.js
const config = require('config');
module.exports = function() {
if (!config.get('jwtPrivateKey')) {
throw new Error('FATAL ERROR: jwtPrivateKey is not defined.');
}
}
// users.js
const auth = require('../middleware/auth');
const jwt = require('jsonwebtoken');
const config = require('config');
const bcrypt = require('bcrypt');
const _ = require('lodash');
const {User, validate} = require('../models/user');
const mongoose = require('mongoose');
const express = require('express');
const router = express.Router();
router.get('/me', auth, async (req, res) => {
const user = await User.findById(req.user._id).select('-password');
res.send(user);
});
router.post('/', async (req, res) => {
const { error } = validate(req.body);
if (error) return res.status(400).send(error.details[0].message);
let user = await User.findOne({ email: req.body.email });
if (user) return res.status(400).send('User already registered.');
user = new User(_.pick(req.body, ['name', 'email', 'password']));
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(user.password, salt);
await user.save();
const token = user.generateAuthToken();
res.header('x-auth-token', token).send(.pick(user, ['id', 'name', 'email']));
});
module.exports = router;
// auth.js
const Joi = require('joi');
const bcrypt = require('bcrypt');
const _ = require('lodash');
const {User} = require('../models/user');
const mongoose = require('mongoose');
const express = require('express');
const router = express.Router();
router.post('/', async (req, res) => {
const { error } = validate(req.body);
if (error) return res.status(400).send(error.details[0].message);
let user = await User.findOne({ email: req.body.email });
if (!user) return res.status(400).send('Invalid email or password.');
const validPassword = await bcrypt.compare(req.body.password, user.password);
if (!validPassword) return res.status(400).send('Invalid email or password.');
const token = user.generateAuthToken();
res.send(token);
});
function validate(req) {
const schema = {
email: Joi.string().min(5).max(255).required().email(),
password: Joi.string().min(5).max(255).required()
};
return Joi.validate(req, schema);
}
module.exports = router;
// db.js
const winston = require('winston');
const mongoose = require('mongoose');
const config = require('config');
module.exports = function() {
const db = config.get('db');
mongoose.connect(db)
.then(() => winston.info(Connected to ${db}...));
}
// logging.js
const winston = require('winston');
// require('winston-mongodb');
require('express-async-errors');
module.exports = function() {
winston.handleExceptions(
new winston.transports.Console({ colorize: true, prettyPrint: true }),
new winston.transports.File({ filename: 'uncaughtExceptions.log' }));
process.on('unhandledRejection', (ex) => {
throw ex;
});
winston.add(winston.transports.File, { filename: 'logfile.log' });
// winston.add(winston.transports.MongoDB, {
// db: 'mongodb://localhost/vidly',
// level: 'info'
// });
}
// index.js
const winston = require('winston');
const express = require('express');
const app = express();
require('./startup/logging')();
require('./startup/routes')(app);
require('./startup/db')();
require('./startup/config')();
require('./startup/validation')();
const port = process.env.PORT || 3000;
app.listen(port, () => winston.info(Listening on port ${port}...));
// user.test.js
const {User} = require('../../../models/user');
const jwt = require('jsonwebtoken');
const config = require('config');
const mongoose = require('mongoose');
describe('user.generateAuthToken', () => {
it('should return a valid JWT', () => {
const payload = {
_id: new mongoose.Types.ObjectId().toHexString(),
isAdmin: true
};
const user = new User(payload);
const token = user.generateAuthToken();
const decoded = jwt.verify(token, config.get('jwtPrivateKey'));
expect(decoded).toMatchObject(payload);
});
});
// package.json
"scripts": {
"test": "jest --watchAll --verbose"
},
Solution 1:
the structure of your config files are wrong. if u check the https://www.npmjs.com/package/config
this is the structure of file:
{
"Customer": {
"dbConfig": {
"host": "prod-db-server"
},
"credit": {
"initialDays": 30
}
}
}
that page also provides this info:
config.get() will throw an exception for undefined keys to help catch typos and missing values. Use config.has() to test if a configuration value is defined.
Solution 2:
I think set does not work with visual studio code terminal. I had same issue, when i executed in Windows CMD it worked.
Solution 3:
Try config.get instead of config.has()
module.exports = function() {
if (!config.has('jwtPrivateKey')) {
throw new Error('FATAL ERROR: jwtPrivateKey is not defined.');
}