'use strict' const jwt = require('jsonwebtoken') const bcrypt = require('bcryptjs') const { loadUsers, saveUsers } = require('./config') const SECRET = process.env.JWT_SECRET || 'dev-secret-change-in-prod' // ─── Ensure default admin exists on first run ───────────────────────────────── function ensureDefaultAdmin() { const users = loadUsers() if (Object.keys(users).length === 0) { const adminUser = process.env.ADMIN_USER || 'admin' const adminPass = process.env.ADMIN_PASS || 'changeme' users[adminUser] = { passwordHash: bcrypt.hashSync(adminPass, 10), role: 'admin', createdAt: new Date().toISOString() } saveUsers(users) console.log(`[Auth] Created default admin: ${adminUser} / ${adminPass}`) console.log('[Auth] ⚠️ Change the password after first login!') } } // ─── Verify login ───────────────────────────────────────────────────────────── function login(username, password) { const users = loadUsers() const user = users[username] if (!user) return null if (!bcrypt.compareSync(password, user.passwordHash)) return null const token = jwt.sign({ username, role: user.role }, SECRET, { expiresIn: '7d' }) return token } // ─── Change password ────────────────────────────────────────────────────────── function changePassword(username, newPassword) { const users = loadUsers() if (!users[username]) return false users[username].passwordHash = bcrypt.hashSync(newPassword, 10) saveUsers(users) return true } // ─── Middleware: verify JWT from Authorization header ───────────────────────── function requireAuth(req, res, next) { const header = req.headers.authorization || '' const token = header.startsWith('Bearer ') ? header.slice(7) : null if (!token) return res.status(401).json({ error: 'Unauthorized' }) try { req.user = jwt.verify(token, SECRET) next() } catch { res.status(401).json({ error: 'Invalid token' }) } } // ─── Verify JWT for WebSocket connections ──────────────────────────────────── function verifyJwt(token) { try { return jwt.verify(token, SECRET) } catch { return null } } module.exports = { ensureDefaultAdmin, login, changePassword, requireAuth, verifyJwt }