diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 44bb466..9dba70a 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -27,6 +27,7 @@ services: environment: - MONGO_URL=mongodb://user:user-password@db:27017/odyssey-test - DOCKER_NETWORK=linux-odyssey-players + - SECRET_KEY=${SECRET_KEY} analytics: image: lancatlin/linux-odyssey:analytics diff --git a/docker-compose.testing.yml b/docker-compose.testing.yml index aa4756b..707ddca 100644 --- a/docker-compose.testing.yml +++ b/docker-compose.testing.yml @@ -49,6 +49,7 @@ services: - GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET} - GITHUB_CLIENT_ID=${GITHUB_CLIENT_ID} - GITHUB_CLIENT_SECRET=${GITHUB_CLIENT_SECRET} + - SECRET_KEY=${SECRET_KEY} db-test: image: mongo diff --git a/docker-compose.yml b/docker-compose.yml index f52c403..8c88224 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -41,6 +41,7 @@ services: - GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET} - GITHUB_CLIENT_ID=${GITHUB_CLIENT_ID} - GITHUB_CLIENT_SECRET=${GITHUB_CLIENT_SECRET} + - SECRET_KEY=${SECRET_KEY} analytics: build: diff --git a/package.json b/package.json index cb6fbb1..601f97b 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "test": "yarn node --experimental-vm-modules $(yarn bin jest)", "test:e2e": "yarn workspace tests test", "analytics": "yarn workspace analytics dev", + "setup": "yarn workspace server setup", "clean": "yarn workspace server clean" }, "devDependencies": { diff --git a/server/package.json b/server/package.json index e78fd12..d744625 100644 --- a/server/package.json +++ b/server/package.json @@ -7,6 +7,7 @@ "start": "node src/index.js", "dev": "nodemon src/index.js", "test": "yarn node --experimental-vm-modules $(yarn bin jest)", + "setup": "node src/cli/setup.js", "clean": "node src/cli/clean.js" }, "dependencies": { @@ -20,6 +21,7 @@ "express": "^4.18.2", "express-rate-limit": "^7.1.3", "express-session": "^1.17.3", + "express-validator": "^7.0.1", "jsonwebtoken": "^9.0.1", "minimist": "^1.2.8", "mongoose": "^7.4.0", diff --git a/server/src/auth/jwtStrategy.js b/server/src/auth/jwtStrategy.js index f1b2cd4..446b852 100644 --- a/server/src/auth/jwtStrategy.js +++ b/server/src/auth/jwtStrategy.js @@ -3,7 +3,7 @@ import config from '../config.js' const jwtOptions = { jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), - secretOrKey: config.jwtSecret, + secretOrKey: config.secret, } function verifyJwt(jwtPayload, done) { diff --git a/server/src/cli/setup.js b/server/src/cli/setup.js new file mode 100644 index 0000000..b146e3a --- /dev/null +++ b/server/src/cli/setup.js @@ -0,0 +1,9 @@ +import { genSecret } from '../utils/env.js' + +function setup() { + console.log('Setting up .env file...') + const secret = genSecret() + console.log(`SECRET_KEY=${secret}`) +} + +setup() diff --git a/server/src/config.js b/server/src/config.js index e987cf4..d51a71e 100644 --- a/server/src/config.js +++ b/server/src/config.js @@ -1,10 +1,10 @@ -import { get } from './utils/env.js' +import { get, genSecret } from './utils/env.js' const config = { host: get('HOST', 'localhost'), port: get('PORT', 3000), db: get('MONGO_URL', 'mongodb://localhost:27017/odyssey-test'), - jwtSecret: get('JWT_SECRET', 'secret'), + secret: get('SECRET_KEY', ''), dockerNetwork: get('DOCKER_NETWORK', 'linux-odyssey-players'), isProduction: process.env.NODE_ENV === 'production', hostPwd: get('HOST_PWD', ''), @@ -22,4 +22,11 @@ const config = { config.baseUrl = get('BASE_URL', `http://${config.host}:${config.port}`) +if (!config.secret) { + config.secret = genSecret() + console.warn( + 'No SECRET_KEY found in .env! A temporary secret key has been generated. To set up a persistent key, please run the setup script.' + ) +} + export default config diff --git a/server/src/middleware/session.js b/server/src/middleware/session.js index 8822b4c..38ce0a2 100644 --- a/server/src/middleware/session.js +++ b/server/src/middleware/session.js @@ -4,7 +4,7 @@ import MongoStore from 'connect-mongo' import config from '../config.js' export default session({ - secret: config.jwtSecret, + secret: config.secret, resave: false, saveUninitialized: false, rolling: true, diff --git a/server/src/utils/env.js b/server/src/utils/env.js index 3195d31..6f2c883 100644 --- a/server/src/utils/env.js +++ b/server/src/utils/env.js @@ -1,4 +1,5 @@ -/* eslint-disable import/prefer-default-export */ +import crypto from 'crypto' + export function get(key, defaultValue) { const value = process.env[key] if (value != null) { @@ -6,3 +7,7 @@ export function get(key, defaultValue) { } return defaultValue } + +export function genSecret() { + return crypto.randomUUID() +} diff --git a/yarn.lock b/yarn.lock index e09ea3d..f12962e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2867,6 +2867,14 @@ express-session@^1.17.3: safe-buffer "5.2.1" uid-safe "~2.1.5" +express-validator@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/express-validator/-/express-validator-7.0.1.tgz#435fac6b5fa838763f78eca05d2206317b92106e" + integrity sha512-oB+z9QOzQIE8FnlINqyIFA8eIckahC6qc8KtqLdLJcU3/phVyuhXH3bA4qzcrhme+1RYaCSwrq+TlZ/kAKIARA== + dependencies: + lodash "^4.17.21" + validator "^13.9.0" + express@^4.18.2: version "4.18.2" resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" @@ -6379,6 +6387,11 @@ v8-to-istanbul@^9.0.1: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" +validator@^13.9.0: + version "13.11.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-13.11.0.tgz#23ab3fd59290c61248364eabf4067f04955fbb1b" + integrity sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ== + vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"