diff --git a/.env.example b/.env.example index a9f9080..a80c9e2 100755 --- a/.env.example +++ b/.env.example @@ -1,2 +1,10 @@ PORT=5000 MONGO_URI=mongodb://localhost:27017/deathwatch + +# Database credentials - CHANGE THESE IN PRODUCTION +DB_PASSWORD=your_secure_database_password_here + +# Authentication secrets - CHANGE THESE IN PRODUCTION +GM_SECRET=your_secure_gm_secret_here +GM_PASSWORD=your_secure_gm_password_here +PLAYER_PASSWORD=your_secure_player_password_here diff --git a/database/ensure-gm.js b/database/ensure-gm.js index ed2a994..34e60a2 100644 --- a/database/ensure-gm.js +++ b/database/ensure-gm.js @@ -10,13 +10,14 @@ function logToFile(...args) { const existingGm = db.prepare('SELECT * FROM players WHERE name = ?').get('gm'); if (!existingGm) { - // Create GM user with password 'bongo' + // Create GM user with password from environment variable + const gmPassword = process.env.GM_PASSWORD || 'defaultpassword'; const stmt = db.prepare(` - INSERT INTO players (name, pw, pw_hash, tab_info) + INSERT INTO players (name, pw, pw_hash, tab_info) VALUES (?, ?, ?, ?) `); - stmt.run('gm', 'bongo', 'bongo', JSON.stringify({ + stmt.run('gm', gmPassword, gmPassword, JSON.stringify({ rp: 999999, inventory: [], renown: 'None' @@ -26,13 +27,14 @@ if (!existingGm) { console.log('Created GM user'); } else { // Update GM user password if needed + const gmPassword = process.env.GM_PASSWORD || 'defaultpassword'; const stmt = db.prepare(` - UPDATE players + UPDATE players SET pw = ?, pw_hash = ? WHERE name = 'gm' `); - stmt.run('bongo', 'bongo'); + stmt.run(gmPassword, gmPassword); logToFile('Updated GM user'); console.log('Updated GM user'); diff --git a/database/mariadb.js b/database/mariadb.js index 1c95d6a..4317a89 100644 --- a/database/mariadb.js +++ b/database/mariadb.js @@ -17,7 +17,7 @@ function logToFile(...args) { const dbConfig = { host: 'localhost', user: 'deathwatch', - password: 'dwroller2025', + password: process.env.DB_PASSWORD || 'defaultpassword', database: 'deathwatch', waitForConnections: true, connectionLimit: 10, diff --git a/database/migrate-sqlite-to-mariadb.js b/database/migrate-sqlite-to-mariadb.js index 09c1bce..7d023af 100644 --- a/database/migrate-sqlite-to-mariadb.js +++ b/database/migrate-sqlite-to-mariadb.js @@ -11,7 +11,7 @@ const sqliteDbPath = path.join(__dirname, 'sqlite', 'deathwatch.db'); const mariadbConfig = { host: 'localhost', user: 'deathwatch', - password: 'dwroller2025', + password: process.env.DB_PASSWORD || 'defaultpassword', database: 'deathwatch' }; diff --git a/database/requireSession.js b/database/requireSession.js index 4437403..25444ee 100644 --- a/database/requireSession.js +++ b/database/requireSession.js @@ -7,7 +7,7 @@ function logToFile(...args) { } // Express middleware to require a valid sessionId in req.headers['x-session-id'] or req.body.sessionId -// Accepts a GM bypass header 'x-gm-secret' matching process.env.GM_PASSWORD or 'bongo' for local convenience +// Accepts a GM bypass header 'x-gm-secret' matching process.env.GM_SECRET module.exports = async function requireSession(req, res, next) { try { // Ensure req.body is always an object before any access @@ -16,7 +16,7 @@ module.exports = async function requireSession(req, res, next) { // GM bypass const gmSecret = req.headers['x-gm-secret'] || (req.query && req.query.gmSecret) || (req.body && req.body.gmSecret); - const gmPassword = process.env.GM_PASSWORD || 'bongo'; + const gmPassword = process.env.GM_SECRET || 'defaultsecret'; if (gmSecret && String(gmSecret) === String(gmPassword)) { logToFile('SESSION: GM bypass accepted', req.method, req.originalUrl); req.session = { data: { playerName: 'GM' }, playerName: 'GM' }; diff --git a/database/routes/bestiaryRoutes.js b/database/routes/bestiaryRoutes.js index f53839c..622df64 100644 --- a/database/routes/bestiaryRoutes.js +++ b/database/routes/bestiaryRoutes.js @@ -158,7 +158,8 @@ router.post('/reload', async (req, res) => { try { // Check for GM secret const gmSecret = req.headers['x-gm-secret']; - if (gmSecret !== 'bongo') { + const expectedGmSecret = process.env.GM_SECRET || 'defaultsecret'; + if (gmSecret !== expectedGmSecret) { return res.status(403).json({ error: 'Unauthorized' }); } diff --git a/database/routes/playerRoutes.js b/database/routes/playerRoutes.js index c9f5bf1..b1aace2 100644 --- a/database/routes/playerRoutes.js +++ b/database/routes/playerRoutes.js @@ -14,12 +14,14 @@ router.post('/login', async (req, res) => { // Special handling for GM user if (name.toLowerCase() === 'gm') { - if (password !== 'bongo') { + const gmPassword = process.env.GM_PASSWORD || 'defaultpassword'; + if (password !== gmPassword) { return res.status(401).json({ error: 'Invalid password' }); } } else { - // For regular players, use password '1234' - if (password !== '1234') { + // For regular players, use environment variable or default + const playerPassword = process.env.PLAYER_PASSWORD || 'defaultpassword'; + if (password !== playerPassword) { return res.status(401).json({ error: 'Invalid password' }); } } diff --git a/database/routes/rulesRoutes.js b/database/routes/rulesRoutes.js index 4ab6422..5d143d4 100644 --- a/database/routes/rulesRoutes.js +++ b/database/routes/rulesRoutes.js @@ -199,7 +199,8 @@ router.get('/stats', async (req, res) => { router.post('/reload', async (req, res) => { try { const gmSecret = req.headers['x-gm-secret']; - if (gmSecret !== 'bongo') return res.status(403).json({ error: 'Unauthorized' }); + const expectedGmSecret = process.env.GM_SECRET || 'defaultsecret'; + if (gmSecret !== expectedGmSecret) return res.status(403).json({ error: 'Unauthorized' }); const allRules = await getAllRules(); const totalRules = allRules.length; diff --git a/database/scripts/reset_pw_andreas_chris.js b/database/scripts/reset_pw_andreas_chris.js index 58ca859..f4ce3ef 100644 --- a/database/scripts/reset_pw_andreas_chris.js +++ b/database/scripts/reset_pw_andreas_chris.js @@ -18,7 +18,7 @@ const { playerHelpers } = require('../sqlite-db'); fs.writeFileSync(beforePath, JSON.stringify(player, null, 2), 'utf8'); console.log('Backup written:', beforePath); - const plain = '1234'; + const plain = process.env.PLAYER_PASSWORD || 'defaultpassword'; const hash = await bcrypt.hash(plain, 10); const ok = playerHelpers.update(name, { name, rollerInfo: player.rollerInfo || {}, shopInfo: player.shopInfo || {}, tabInfo: player.tabInfo || {}, pw: '', pwHash: hash }); if (!ok) { @@ -31,5 +31,5 @@ const { playerHelpers } = require('../sqlite-db'); console.log('Updated player:', name, 'pwHash set. After backup:', afterPath); console.log(JSON.stringify({ name: updated.name, pwHashPresent: !!updated.pwHash, _id: updated._id }, null, 2)); } - console.log('All done. Password for andreas and chris set to "1234" (hashed).'); + console.log('All done. Password for andreas and chris set to environment default (hashed).'); })(); diff --git a/database/server.js b/database/server.js index b4c7fe5..0ae8d9e 100755 --- a/database/server.js +++ b/database/server.js @@ -126,7 +126,8 @@ try { app.post('/api/gmkit/upload', express.json({ limit: '20mb' }), (req, res) => { try { const gmSecret = req.headers['x-gm-secret']; - if (gmSecret !== 'bongo') return res.status(403).json({ error: 'Unauthorized' }); + const expectedGmSecret = process.env.GM_SECRET || 'defaultsecret'; + if (gmSecret !== expectedGmSecret) return res.status(403).json({ error: 'Unauthorized' }); const { name, b64 } = req.body || {}; if (!name || !b64) return res.status(400).json({ error: 'Missing name or b64 body' }); if (!fs.existsSync(gmkitDir)) fs.mkdirSync(gmkitDir, { recursive: true }); diff --git a/database/update_passwords.js b/database/update_passwords.js index cf19d2b..5a36825 100644 --- a/database/update_passwords.js +++ b/database/update_passwords.js @@ -1,17 +1,18 @@ const { db, playerHelpers } = require('./sqlite-db'); -// Update all player passwords to '1234' +// Update all player passwords to environment default function updateAllPasswords() { try { // First check the table structure const columns = db.prepare("PRAGMA table_info(players)").all(); console.log('Table columns:', columns.map(c => c.name)); - + // Update only the pw column (pwHash might not exist) + const defaultPassword = process.env.PLAYER_PASSWORD || 'defaultpassword'; const updateStmt = db.prepare('UPDATE players SET pw = ?'); - const result = updateStmt.run('1234'); - - console.log(`Updated ${result.changes} player passwords to '1234'`); + const result = updateStmt.run(defaultPassword); + + console.log(`Updated ${result.changes} player passwords to environment default`); // Verify the changes const players = playerHelpers.getAll(); diff --git a/src/App.js b/src/App.js index 3344ae0..7af9204 100755 --- a/src/App.js +++ b/src/App.js @@ -335,7 +335,7 @@ function App() { {players && players.length > 0 ? players.map(player => (