// trackaccess-backend/server.js import express from 'express'; import cors from 'cors'; import jwt from 'jsonwebtoken'; import dotenv from 'dotenv'; import { pool } from './db.js'; import { authenticateToken } from './middleware/auth.js'; dotenv.config(); const app = express(); const PORT = process.env.PORT || 4000; app.use(cors()); app.use(express.json()); // ——— AUTH ——— app.post('/api/login', (req, res) => { const { username, password } = req.body; if (username === process.env.ADMIN_USER && password === process.env.ADMIN_PASS) { const token = jwt.sign({ username }, process.env.JWT_SECRET, { expiresIn: '8h' }); return res.json({ token }); } res.status(401).json({ message: 'Invalid credentials' }); }); // ——— DEPARTMENT ROLES ——— app.get('/api/departmentroles', authenticateToken, async (_, res) => { const [rows] = await pool.query('SELECT * FROM DepartmentRoles'); res.json(rows); }); app.post('/api/departmentroles', authenticateToken, async (req, res) => { const { department, role } = req.body; const [result] = await pool.query( 'INSERT INTO DepartmentRoles (department, role) VALUES (?,?)', [department, role] ); res.json({ DepartmentRoleId: result.insertId, department, role }); }); app.put('/api/departmentroles/:id', authenticateToken, async (req, res) => { const { id } = req.params; const { department, role } = req.body; await pool.query( 'UPDATE DepartmentRoles SET department=?, role=? WHERE DepartmentRoleId=?', [department, role, id] ); res.json({ DepartmentRoleId: Number(id), department, role }); }); app.delete('/api/departmentroles/:id', authenticateToken, async (req, res) => { await pool.query('DELETE FROM DepartmentRoles WHERE DepartmentRoleId = ?', [req.params.id]); res.json({ message: 'Deleted' }); }); // ——— ACCESS LEVELS ——— app.get('/api/accesslevels', authenticateToken, async (_, res) => { const [rows] = await pool.query('SELECT * FROM AccessLevels'); res.json(rows); }); app.post('/api/accesslevels', authenticateToken, async (req, res) => { const { access_level } = req.body; await pool.query('INSERT INTO AccessLevels (access_level) VALUES (?)', [access_level]); res.json({ access_level }); }); app.put('/api/accesslevels/:level', authenticateToken, async (req, res) => { const { level } = req.params; const { access_level } = req.body; await pool.query('UPDATE AccessLevels SET access_level=? WHERE access_level=?', [ access_level, level ]); res.json({ access_level }); }); app.delete('/api/accesslevels/:level', authenticateToken, async (req, res) => { await pool.query('DELETE FROM AccessLevels WHERE access_level=?', [req.params.level]); res.json({ message: 'Deleted' }); }); // ——— USERS ——— app.get('/api/users', authenticateToken, async (_, res) => { const [rows] = await pool.query('SELECT * FROM Users'); res.json(rows); }); app.post('/api/users', authenticateToken, async (req, res) => { const { name } = req.body; const [result] = await pool.query('INSERT INTO Users (name) VALUES (?)', [name]); res.json({ UserId: result.insertId, name }); }); app.put('/api/users/:id', authenticateToken, async (req, res) => { const { id } = req.params; const { name } = req.body; await pool.query('UPDATE Users SET name=? WHERE UserId=?', [name, id]); res.json({ UserId: Number(id), name }); }); app.delete('/api/users/:id', authenticateToken, async (req, res) => { await pool.query('DELETE FROM Users WHERE UserId=?', [req.params.id]); res.json({ message: 'Deleted' }); }); // ——— USER ROLES ——— // list all assignments app.get('/api/userroles', authenticateToken, async (_, res) => { const [rows] = await pool.query(` SELECT ur.UserRoleId, ur.UserId, u.name AS userName, ur.DepartmentRoleId, dr.department, dr.role FROM UserRoles ur JOIN Users u ON ur.UserId = u.UserId JOIN DepartmentRoles dr ON ur.DepartmentRoleId = dr.DepartmentRoleId `); res.json(rows); }); // create assignment app.post('/api/userroles', authenticateToken, async (req, res) => { const { UserId, DepartmentRoleId } = req.body; const [result] = await pool.query( 'INSERT INTO UserRoles (UserId, DepartmentRoleId) VALUES (?,?)', [UserId, DepartmentRoleId] ); res.json({ UserRoleId: result.insertId }); }); // remove assignment app.delete('/api/userroles/:id', authenticateToken, async (req, res) => { await pool.query('DELETE FROM UserRoles WHERE UserRoleId=?', [req.params.id]); res.json({ message: 'Deleted' }); }); // ——— ACCESS RECORDS ——— app.get('/api/accessrecords', authenticateToken, async (_, res) => { // Use UserRoleId as the reference const [rows] = await pool.query(` SELECT ar.RecordId, ar.UserRoleId, u.name AS userName, dr.department, dr.role, ar.system_name, ar.access_level, ar.local_account, ar.additional_access FROM AccessRecords ar JOIN UserRoles ur ON ar.UserRoleId = ur.UserRoleId JOIN Users u ON ur.UserId = u.UserId JOIN DepartmentRoles dr ON ur.DepartmentRoleId = dr.DepartmentRoleId `); res.json(rows); }); app.post('/api/accessrecords', authenticateToken, async (req, res) => { const p = req.body; const [result] = await pool.query( `INSERT INTO AccessRecords (UserRoleId, system_name, access_level, local_account, additional_access) VALUES (?,?,?,?,?)`, [p.UserRoleId, p.system_name, p.access_level, p.local_account, p.additional_access] ); res.json({ RecordId: result.insertId }); }); app.put('/api/accessrecords/:id', authenticateToken, async (req, res) => { const { id } = req.params; const p = req.body; await pool.query( `UPDATE AccessRecords SET UserRoleId=?, system_name=?, access_level=?, local_account=?, additional_access=? WHERE RecordId=?`, [p.UserRoleId, p.system_name, p.access_level, p.local_account, p.additional_access, id] ); res.json({ RecordId: Number(id) }); }); app.delete('/api/accessrecords/:id', authenticateToken, async (req, res) => { await pool.query('DELETE FROM AccessRecords WHERE RecordId=?', [req.params.id]); res.json({ message: 'Deleted' }); }); // ——— START SERVER ——— app.listen(PORT, () => { console.log(`🚀 Backend listening on http://localhost:${PORT}`); });