completed userDataMgmt

This commit is contained in:
2025-11-08 16:59:07 +01:00
parent 20d22d6ce4
commit 12277abb9e
7 changed files with 240 additions and 5 deletions

View File

@@ -0,0 +1,79 @@
import mysql from "mysql2";
import dotenv from "dotenv";
dotenv.config();
const pool = mysql
.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
})
.promise();
export const createUser = async (
username,
role,
password,
isAdmin,
email,
first_name,
last_name
) => {
const [result] = await pool.query(
"INSERT INTO users (username, role, password, is_admin, email, first_name, last_name) VALUES (?, ?, ?, ?, ?, ?, ?)",
[username, role, password, isAdmin, email, first_name, last_name]
);
if (result.affectedRows > 0) return { success: true };
return { success: false };
};
export const deleteUserById = async (userId) => {
const [result] = await pool.query("DELETE FROM users WHERE id = ?", [userId]);
if (result.affectedRows > 0) return { success: true };
return { success: false };
};
export const changePassword = async (userId, newPassword) => {
const [result] = await pool.query(
"UPDATE users SET password = ? WHERE id = ?",
[newPassword, userId]
);
if (result.affectedRows > 0) return { success: true };
return { success: false };
};
export const editUserById = async (
userId,
first_name,
last_name,
role,
email,
is_admin
) => {
const [result] = await pool.query(
"UPDATE users SET first_name = ?, last_name = ?, role = ?, email = ?, is_admin = ? WHERE id = ?",
[first_name, last_name, role, email, is_admin, userId]
);
if (result.affectedRows > 0) return { success: true };
return { success: false };
};
export const getAllUsers = async () => {
const [result] = await pool.query(
"SELECT id, username, first_name, last_name, role, email, is_admin FROM users"
);
if (result.length > 0) return { success: true, data: result };
return { success: false };
};
export const getUserById = async (userId) => {
const [rows] = await pool.query(
"SELECT id, username, first_name, last_name, role, email, is_admin FROM users WHERE id = ?",
[userId]
);
if (rows.length === 0) {
return { success: false };
}
return { success: true, data: rows[0] };
};

View File

@@ -11,7 +11,7 @@ const pool = mysql
}) })
.promise(); .promise();
export const loginFunc = async (username, password) => { export const loginAdmin = async (username, password) => {
const [rows] = await pool.query( const [rows] = await pool.query(
"SELECT id, username, first_name, last_name, role, is_admin FROM users WHERE username = ? AND password = ?", "SELECT id, username, first_name, last_name, role, is_admin FROM users WHERE username = ? AND password = ?",
[username, password] [username, password]

View File

@@ -0,0 +1,126 @@
import express from "express";
import { authenticateAdmin } from "../../services/authentication.js";
const router = express.Router();
import nodemailer from "nodemailer";
import dotenv from "dotenv";
dotenv.config();
// database funcs import
import {
createUser,
deleteUserById,
editUserById,
changePassword,
getAllUsers,
getUserById,
} from "./database/userDataMgmt.database.js";
router.post("/create-user", authenticateAdmin, async (req, res) => {
const username = req.body.username;
const role = req.body.role;
const password = req.body.password;
const isAdmin = req.body.isAdmin;
const email = req.body.email;
const first_name = req.body.first_name;
const last_name = req.body.last_name;
const result = await createUser(
username,
role,
password,
isAdmin,
email,
first_name,
last_name
);
if (result.success) {
return res.status(201).json({ message: "User created successfully" });
}
return res.status(500).json({ message: "Failed to create user" });
});
router.delete("/delete-user/:id", authenticateAdmin, async (req, res) => {
const userId = req.params.id;
const result = await deleteUserById(userId);
if (result.success) {
return res.status(200).json({ message: "User deleted successfully" });
}
return res.status(500).json({ message: "Failed to delete user" });
});
router.post("/edit-user/:id", authenticateAdmin, async (req, res) => {
const password = req.body.password;
const first_name = req.body.first_name;
const last_name = req.body.last_name;
const role = req.body.role;
const email = req.body.email;
const userId = req.params.id;
const is_admin = req.body.is_admin;
const result = await editUserById(
userId,
password,
first_name,
last_name,
role,
email,
is_admin
);
if (result.success) {
return res.status(200).json({ message: "User edited successfully" });
}
return res.status(500).json({ message: "Failed to edit user" });
});
router.post("/change-password", authenticateAdmin, async (req, res) => {
const username = req.body.username;
const password = req.body.password;
const result = await changePassword(username, password);
if (result.success) {
return res.status(200).json({ message: "Password reset successfully" });
}
return res.status(500).json({ message: "Failed to reset password" });
});
router.post("/edit-user/:id", authenticateAdmin, async (req, res) => {
const userId = req.params.id;
const first_name = req.body.first_name;
const last_name = req.body.last_name;
const role = req.body.role;
const email = req.body.email;
const is_admin = req.body.is_admin;
const result = await editUserById(
userId,
first_name,
last_name,
role,
email,
is_admin
);
if (result.success) {
return res.status(200).json({ message: "User edited successfully" });
}
return res.status(500).json({ message: "Failed to edit user" });
});
router.get("/users", authenticateAdmin, async (req, res) => {
const result = await getAllUsers();
if (result.success) {
return res.status(200).json({ users: result.data });
}
return res.status(500).json({ message: "Failed to retrieve users" });
});
router.get("/user/:id", authenticateAdmin, async (req, res) => {
const result = await getUserById(req.params.id);
if (result.success) {
return res.status(200).json({ user: result.data });
}
return res.status(500).json({ message: "Failed to retrieve user" });
});
export default router;

View File

@@ -1,22 +1,22 @@
import express from "express"; import express from "express";
import { authenticate, generateToken } from "../services/tokenService.js"; import { authenticate, generateToken } from "../../services/authentication.js";
const router = express.Router(); const router = express.Router();
import nodemailer from "nodemailer"; import nodemailer from "nodemailer";
import dotenv from "dotenv"; import dotenv from "dotenv";
dotenv.config(); dotenv.config();
// database funcs import // database funcs import
import { loginFunc } from "./database/userMgmt.database.js"; import { loginAdmin } from "./database/userMgmt.database.js";
router.post("/login", async (req, res) => { router.post("/login", async (req, res) => {
const result = await loginFunc(req.body.username, req.body.password); const result = await loginAdmin(req.body.username, req.body.password);
if (result.success) { if (result.success) {
const token = await generateToken({ const token = await generateToken({
username: result.data.username, username: result.data.username,
first_name: result.data.first_name, first_name: result.data.first_name,
last_name: result.data.last_name, last_name: result.data.last_name,
role: result.data.role, admin: result.data.is_admin,
}); });
return res.status(200).json({ message: "Login erfolgreich", token }); return res.status(200).json({ message: "Login erfolgreich", token });
} }

View File

@@ -3,13 +3,20 @@ import cors from "cors";
import env from "dotenv"; import env from "dotenv";
import loansMgmtRouter from "./routes/app/loanMgmt.route.js"; import loansMgmtRouter from "./routes/app/loanMgmt.route.js";
import userMgmtRouter from "./routes/app/userMgmt.route.js"; import userMgmtRouter from "./routes/app/userMgmt.route.js";
import userDataMgmtRouter from "./routes/admin/userDataMgmt.route.js"
env.config(); env.config();
const app = express(); const app = express();
const port = 8002; const port = 8002;
app.use(cors()); app.use(cors());
// frontend routes
app.use("/api/loans", loansMgmtRouter); app.use("/api/loans", loansMgmtRouter);
app.use("/api/users", userMgmtRouter); app.use("/api/users", userMgmtRouter);
// admin routes
app.use("/api/admin/user-data", userDataMgmtRouter);
// Increase body size limits to support large CSV JSON payloads // Increase body size limits to support large CSV JSON payloads
app.use(express.urlencoded({ extended: true, limit: "10mb" })); app.use(express.urlencoded({ extended: true, limit: "10mb" }));
app.set("view engine", "ejs"); app.set("view engine", "ejs");

View File

@@ -17,6 +17,29 @@ export async function generateToken(payload) {
.sign(secret); .sign(secret);
} }
export async function authenticateAdmin(req, res, next) {
const authHeader = req.headers["authorization"];
if (!authHeader) {
return res.status(401).json({ message: "Unauthorized" });
}
const [scheme, token] = authHeader.split(" ");
if (!/^Bearer$/i.test(scheme) || !token) {
return res.status(401).json({ message: "Unauthorized" });
}
try {
const payload = await verifyToken(token);
if (!payload?.admin) {
return res.status(403).json({ message: "Forbidden: admin only" });
}
req.user = payload;
return next();
} catch {
return res.status(403).json({ message: "Forbidden" });
}
}
export async function authenticate(req, res, next) { export async function authenticate(req, res, next) {
const authHeader = req.headers["authorization"]; const authHeader = req.headers["authorization"];
const apiKey = req.params.apiKey; const apiKey = req.params.apiKey;