(Feat-Fix): Lots of fixes done, reporting system fixed, stricter types
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { Router } from "@oak/oak";
|
||||
import { hash, genSalt } from "bcrypt";
|
||||
import { type Context, Router } from "@oak/oak";
|
||||
import { genSalt, hash } from "bcrypt";
|
||||
import { db } from "../config/database.ts";
|
||||
import { config } from "../config/env.ts";
|
||||
|
||||
@@ -8,20 +8,28 @@ async function hashPassword(password: string): Promise<string> {
|
||||
const salt = await genSalt(config.BCRYPT_ROUNDS);
|
||||
return await hash(password, salt);
|
||||
}
|
||||
import { authenticateToken, authorize, getCurrentUser } from "../middleware/auth.ts";
|
||||
import { sanitizeInput, isValidEmail } from "../middleware/security.ts";
|
||||
import type { User, CreateUserRequest, UpdateUserRequest } from "../types/index.ts";
|
||||
import {
|
||||
authenticateToken,
|
||||
authorize,
|
||||
getCurrentUser,
|
||||
} from "../middleware/auth.ts";
|
||||
import { isValidEmail, sanitizeInput } from "../middleware/security.ts";
|
||||
import type {
|
||||
CreateUserRequest,
|
||||
UpdateUserRequest,
|
||||
User,
|
||||
} from "../types/index.ts";
|
||||
|
||||
const router = new Router();
|
||||
|
||||
// Get all users (with filters)
|
||||
router.get("/", authenticateToken, async (ctx) => {
|
||||
router.get("/", authenticateToken, async (ctx: Context) => {
|
||||
try {
|
||||
const currentUser = getCurrentUser(ctx);
|
||||
const params = ctx.request.url.searchParams;
|
||||
const role = params.get("role");
|
||||
const departmentId = params.get("departmentId");
|
||||
|
||||
|
||||
let query = `
|
||||
SELECT u.id, u.username, u.name, u.email, u.role, u.department_id,
|
||||
u.contractor_id, u.is_active, u.created_at,
|
||||
@@ -36,25 +44,25 @@ router.get("/", authenticateToken, async (ctx) => {
|
||||
WHERE 1=1
|
||||
`;
|
||||
const queryParams: unknown[] = [];
|
||||
|
||||
|
||||
// Supervisors can only see users in their department
|
||||
if (currentUser.role === "Supervisor") {
|
||||
query += " AND u.department_id = ?";
|
||||
queryParams.push(currentUser.departmentId);
|
||||
}
|
||||
|
||||
|
||||
if (role) {
|
||||
query += " AND u.role = ?";
|
||||
queryParams.push(role);
|
||||
}
|
||||
|
||||
|
||||
if (departmentId) {
|
||||
query += " AND u.department_id = ?";
|
||||
queryParams.push(departmentId);
|
||||
}
|
||||
|
||||
|
||||
query += " ORDER BY u.created_at DESC";
|
||||
|
||||
|
||||
const users = await db.query<User[]>(query, queryParams);
|
||||
ctx.response.body = users;
|
||||
} catch (error) {
|
||||
@@ -65,11 +73,11 @@ router.get("/", authenticateToken, async (ctx) => {
|
||||
});
|
||||
|
||||
// Get user by ID
|
||||
router.get("/:id", authenticateToken, async (ctx) => {
|
||||
router.get("/:id", authenticateToken, async (ctx: Context) => {
|
||||
try {
|
||||
const currentUser = getCurrentUser(ctx);
|
||||
const userId = ctx.params.id;
|
||||
|
||||
|
||||
const users = await db.query<User[]>(
|
||||
`SELECT u.id, u.username, u.name, u.email, u.role, u.department_id,
|
||||
u.contractor_id, u.is_active, u.created_at,
|
||||
@@ -82,22 +90,25 @@ router.get("/:id", authenticateToken, async (ctx) => {
|
||||
LEFT JOIN departments d ON u.department_id = d.id
|
||||
LEFT JOIN users c ON u.contractor_id = c.id
|
||||
WHERE u.id = ?`,
|
||||
[userId]
|
||||
[userId],
|
||||
);
|
||||
|
||||
|
||||
if (users.length === 0) {
|
||||
ctx.response.status = 404;
|
||||
ctx.response.body = { error: "User not found" };
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Supervisors can only view users in their department
|
||||
if (currentUser.role === "Supervisor" && users[0].department_id !== currentUser.departmentId) {
|
||||
if (
|
||||
currentUser.role === "Supervisor" &&
|
||||
users[0].department_id !== currentUser.departmentId
|
||||
) {
|
||||
ctx.response.status = 403;
|
||||
ctx.response.body = { error: "Access denied" };
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ctx.response.body = users[0];
|
||||
} catch (error) {
|
||||
console.error("Get user error:", error);
|
||||
@@ -107,215 +118,98 @@ router.get("/:id", authenticateToken, async (ctx) => {
|
||||
});
|
||||
|
||||
// Create user
|
||||
router.post("/", authenticateToken, authorize("SuperAdmin", "Supervisor"), async (ctx) => {
|
||||
try {
|
||||
const currentUser = getCurrentUser(ctx);
|
||||
const body = await ctx.request.body.json() as CreateUserRequest;
|
||||
const {
|
||||
username, name, email, password, role, departmentId, contractorId,
|
||||
phoneNumber, aadharNumber, bankAccountNumber, bankName, bankIfsc,
|
||||
contractorAgreementNumber, pfNumber, esicNumber
|
||||
} = body;
|
||||
|
||||
// Input validation
|
||||
if (!username || !name || !email || !password || !role) {
|
||||
ctx.response.status = 400;
|
||||
ctx.response.body = { error: "Missing required fields" };
|
||||
return;
|
||||
}
|
||||
|
||||
// Sanitize inputs
|
||||
const sanitizedUsername = sanitizeInput(username);
|
||||
const sanitizedName = sanitizeInput(name);
|
||||
const sanitizedEmail = sanitizeInput(email);
|
||||
|
||||
// Validate email
|
||||
if (!isValidEmail(sanitizedEmail)) {
|
||||
ctx.response.status = 400;
|
||||
ctx.response.body = { error: "Invalid email format" };
|
||||
return;
|
||||
}
|
||||
|
||||
// Supervisors can only create users in their department
|
||||
if (currentUser.role === "Supervisor") {
|
||||
if (departmentId !== currentUser.departmentId) {
|
||||
ctx.response.status = 403;
|
||||
ctx.response.body = { error: "Can only create users in your department" };
|
||||
return;
|
||||
}
|
||||
if (role === "SuperAdmin" || role === "Supervisor") {
|
||||
ctx.response.status = 403;
|
||||
ctx.response.body = { error: "Cannot create admin or supervisor users" };
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Hash password
|
||||
const hashedPassword = await hashPassword(password);
|
||||
|
||||
const result = await db.execute(
|
||||
`INSERT INTO users (username, name, email, password, role, department_id, contractor_id,
|
||||
phone_number, aadhar_number, bank_account_number, bank_name, bank_ifsc,
|
||||
contractor_agreement_number, pf_number, esic_number)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
[
|
||||
sanitizedUsername, sanitizedName, sanitizedEmail, hashedPassword, role,
|
||||
departmentId || null, contractorId || null,
|
||||
phoneNumber || null, aadharNumber || null, bankAccountNumber || null,
|
||||
bankName || null, bankIfsc || null,
|
||||
contractorAgreementNumber || null, pfNumber || null, esicNumber || null
|
||||
]
|
||||
);
|
||||
|
||||
const newUser = await db.query<User[]>(
|
||||
`SELECT u.id, u.username, u.name, u.email, u.role, u.department_id,
|
||||
u.contractor_id, u.is_active, u.created_at,
|
||||
u.phone_number, u.aadhar_number, u.bank_account_number,
|
||||
u.bank_name, u.bank_ifsc,
|
||||
u.contractor_agreement_number, u.pf_number, u.esic_number,
|
||||
d.name as department_name,
|
||||
c.name as contractor_name
|
||||
FROM users u
|
||||
LEFT JOIN departments d ON u.department_id = d.id
|
||||
LEFT JOIN users c ON u.contractor_id = c.id
|
||||
WHERE u.id = ?`,
|
||||
[result.insertId]
|
||||
);
|
||||
|
||||
ctx.response.status = 201;
|
||||
ctx.response.body = newUser[0];
|
||||
} catch (error) {
|
||||
const err = error as { code?: string };
|
||||
if (err.code === "ER_DUP_ENTRY") {
|
||||
ctx.response.status = 400;
|
||||
ctx.response.body = { error: "Username or email already exists" };
|
||||
return;
|
||||
}
|
||||
console.error("Create user error:", error);
|
||||
ctx.response.status = 500;
|
||||
ctx.response.body = { error: "Internal server error" };
|
||||
}
|
||||
});
|
||||
router.post(
|
||||
"/",
|
||||
authenticateToken,
|
||||
authorize("SuperAdmin", "Supervisor"),
|
||||
async (ctx: Context) => {
|
||||
try {
|
||||
const currentUser = getCurrentUser(ctx);
|
||||
const body = await ctx.request.body.json() as CreateUserRequest;
|
||||
const {
|
||||
username,
|
||||
name,
|
||||
email,
|
||||
password,
|
||||
role,
|
||||
departmentId,
|
||||
contractorId,
|
||||
phoneNumber,
|
||||
aadharNumber,
|
||||
bankAccountNumber,
|
||||
bankName,
|
||||
bankIfsc,
|
||||
contractorAgreementNumber,
|
||||
pfNumber,
|
||||
esicNumber,
|
||||
} = body;
|
||||
|
||||
// Update user
|
||||
router.put("/:id", authenticateToken, authorize("SuperAdmin", "Supervisor"), async (ctx) => {
|
||||
try {
|
||||
const currentUser = getCurrentUser(ctx);
|
||||
const userId = ctx.params.id;
|
||||
const body = await ctx.request.body.json() as UpdateUserRequest;
|
||||
const {
|
||||
name, email, role, departmentId, contractorId, isActive,
|
||||
phoneNumber, aadharNumber, bankAccountNumber, bankName, bankIfsc,
|
||||
contractorAgreementNumber, pfNumber, esicNumber
|
||||
} = body;
|
||||
|
||||
// Check if user exists
|
||||
const existingUsers = await db.query<User[]>(
|
||||
"SELECT * FROM users WHERE id = ?",
|
||||
[userId]
|
||||
);
|
||||
|
||||
if (existingUsers.length === 0) {
|
||||
ctx.response.status = 404;
|
||||
ctx.response.body = { error: "User not found" };
|
||||
return;
|
||||
}
|
||||
|
||||
// Supervisors can only update users in their department
|
||||
if (currentUser.role === "Supervisor") {
|
||||
if (existingUsers[0].department_id !== currentUser.departmentId) {
|
||||
ctx.response.status = 403;
|
||||
ctx.response.body = { error: "Can only update users in your department" };
|
||||
// Input validation
|
||||
if (!username || !name || !email || !password || !role) {
|
||||
ctx.response.status = 400;
|
||||
ctx.response.body = { error: "Missing required fields" };
|
||||
return;
|
||||
}
|
||||
if (role === "SuperAdmin" || role === "Supervisor") {
|
||||
ctx.response.status = 403;
|
||||
ctx.response.body = { error: "Cannot modify admin or supervisor roles" };
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const updates: string[] = [];
|
||||
const params: unknown[] = [];
|
||||
|
||||
if (name !== undefined) {
|
||||
updates.push("name = ?");
|
||||
params.push(sanitizeInput(name));
|
||||
}
|
||||
if (email !== undefined) {
|
||||
if (!isValidEmail(email)) {
|
||||
|
||||
// Sanitize inputs
|
||||
const sanitizedUsername = sanitizeInput(username);
|
||||
const sanitizedName = sanitizeInput(name);
|
||||
const sanitizedEmail = sanitizeInput(email);
|
||||
|
||||
// Validate email
|
||||
if (!isValidEmail(sanitizedEmail)) {
|
||||
ctx.response.status = 400;
|
||||
ctx.response.body = { error: "Invalid email format" };
|
||||
return;
|
||||
}
|
||||
updates.push("email = ?");
|
||||
params.push(sanitizeInput(email));
|
||||
}
|
||||
if (role !== undefined) {
|
||||
updates.push("role = ?");
|
||||
params.push(role);
|
||||
}
|
||||
if (departmentId !== undefined) {
|
||||
updates.push("department_id = ?");
|
||||
params.push(departmentId);
|
||||
}
|
||||
if (contractorId !== undefined) {
|
||||
updates.push("contractor_id = ?");
|
||||
params.push(contractorId);
|
||||
}
|
||||
if (isActive !== undefined) {
|
||||
updates.push("is_active = ?");
|
||||
params.push(isActive);
|
||||
}
|
||||
// New fields
|
||||
if (phoneNumber !== undefined) {
|
||||
updates.push("phone_number = ?");
|
||||
params.push(phoneNumber);
|
||||
}
|
||||
if (aadharNumber !== undefined) {
|
||||
updates.push("aadhar_number = ?");
|
||||
params.push(aadharNumber);
|
||||
}
|
||||
if (bankAccountNumber !== undefined) {
|
||||
updates.push("bank_account_number = ?");
|
||||
params.push(bankAccountNumber);
|
||||
}
|
||||
if (bankName !== undefined) {
|
||||
updates.push("bank_name = ?");
|
||||
params.push(bankName);
|
||||
}
|
||||
if (bankIfsc !== undefined) {
|
||||
updates.push("bank_ifsc = ?");
|
||||
params.push(bankIfsc);
|
||||
}
|
||||
if (contractorAgreementNumber !== undefined) {
|
||||
updates.push("contractor_agreement_number = ?");
|
||||
params.push(contractorAgreementNumber);
|
||||
}
|
||||
if (pfNumber !== undefined) {
|
||||
updates.push("pf_number = ?");
|
||||
params.push(pfNumber);
|
||||
}
|
||||
if (esicNumber !== undefined) {
|
||||
updates.push("esic_number = ?");
|
||||
params.push(esicNumber);
|
||||
}
|
||||
|
||||
if (updates.length === 0) {
|
||||
ctx.response.status = 400;
|
||||
ctx.response.body = { error: "No fields to update" };
|
||||
return;
|
||||
}
|
||||
|
||||
params.push(userId);
|
||||
|
||||
await db.execute(
|
||||
`UPDATE users SET ${updates.join(", ")} WHERE id = ?`,
|
||||
params
|
||||
);
|
||||
|
||||
const updatedUser = await db.query<User[]>(
|
||||
`SELECT u.id, u.username, u.name, u.email, u.role, u.department_id,
|
||||
|
||||
// Supervisors can only create users in their department
|
||||
if (currentUser.role === "Supervisor") {
|
||||
if (departmentId !== currentUser.departmentId) {
|
||||
ctx.response.status = 403;
|
||||
ctx.response.body = {
|
||||
error: "Can only create users in your department",
|
||||
};
|
||||
return;
|
||||
}
|
||||
if (role === "SuperAdmin" || role === "Supervisor") {
|
||||
ctx.response.status = 403;
|
||||
ctx.response.body = {
|
||||
error: "Cannot create admin or supervisor users",
|
||||
};
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Hash password
|
||||
const hashedPassword = await hashPassword(password);
|
||||
|
||||
const result = await db.execute(
|
||||
`INSERT INTO users (username, name, email, password, role, department_id, contractor_id,
|
||||
phone_number, aadhar_number, bank_account_number, bank_name, bank_ifsc,
|
||||
contractor_agreement_number, pf_number, esic_number)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
[
|
||||
sanitizedUsername,
|
||||
sanitizedName,
|
||||
sanitizedEmail,
|
||||
hashedPassword,
|
||||
role,
|
||||
departmentId || null,
|
||||
contractorId || null,
|
||||
phoneNumber || null,
|
||||
aadharNumber || null,
|
||||
bankAccountNumber || null,
|
||||
bankName || null,
|
||||
bankIfsc || null,
|
||||
contractorAgreementNumber || null,
|
||||
pfNumber || null,
|
||||
esicNumber || null,
|
||||
],
|
||||
);
|
||||
|
||||
const newUser = await db.query<User[]>(
|
||||
`SELECT u.id, u.username, u.name, u.email, u.role, u.department_id,
|
||||
u.contractor_id, u.is_active, u.created_at,
|
||||
u.phone_number, u.aadhar_number, u.bank_account_number,
|
||||
u.bank_name, u.bank_ifsc,
|
||||
@@ -326,55 +220,232 @@ router.put("/:id", authenticateToken, authorize("SuperAdmin", "Supervisor"), asy
|
||||
LEFT JOIN departments d ON u.department_id = d.id
|
||||
LEFT JOIN users c ON u.contractor_id = c.id
|
||||
WHERE u.id = ?`,
|
||||
[userId]
|
||||
);
|
||||
|
||||
ctx.response.body = updatedUser[0];
|
||||
} catch (error) {
|
||||
console.error("Update user error:", error);
|
||||
ctx.response.status = 500;
|
||||
ctx.response.body = { error: "Internal server error" };
|
||||
}
|
||||
});
|
||||
[result.insertId],
|
||||
);
|
||||
|
||||
ctx.response.status = 201;
|
||||
ctx.response.body = newUser[0];
|
||||
} catch (error) {
|
||||
const err = error as { code?: string };
|
||||
if (err.code === "ER_DUP_ENTRY") {
|
||||
ctx.response.status = 400;
|
||||
ctx.response.body = { error: "Username or email already exists" };
|
||||
return;
|
||||
}
|
||||
console.error("Create user error:", error);
|
||||
ctx.response.status = 500;
|
||||
ctx.response.body = { error: "Internal server error" };
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Update user
|
||||
router.put(
|
||||
"/:id",
|
||||
authenticateToken,
|
||||
authorize("SuperAdmin", "Supervisor"),
|
||||
async (ctx: Context) => {
|
||||
try {
|
||||
const currentUser = getCurrentUser(ctx);
|
||||
const userId = ctx.params.id;
|
||||
const body = await ctx.request.body.json() as UpdateUserRequest;
|
||||
const {
|
||||
name,
|
||||
email,
|
||||
role,
|
||||
departmentId,
|
||||
contractorId,
|
||||
isActive,
|
||||
phoneNumber,
|
||||
aadharNumber,
|
||||
bankAccountNumber,
|
||||
bankName,
|
||||
bankIfsc,
|
||||
contractorAgreementNumber,
|
||||
pfNumber,
|
||||
esicNumber,
|
||||
} = body;
|
||||
|
||||
// Check if user exists
|
||||
const existingUsers = await db.query<User[]>(
|
||||
"SELECT * FROM users WHERE id = ?",
|
||||
[userId],
|
||||
);
|
||||
|
||||
if (existingUsers.length === 0) {
|
||||
ctx.response.status = 404;
|
||||
ctx.response.body = { error: "User not found" };
|
||||
return;
|
||||
}
|
||||
|
||||
// Supervisors can only update users in their department
|
||||
if (currentUser.role === "Supervisor") {
|
||||
if (existingUsers[0].department_id !== currentUser.departmentId) {
|
||||
ctx.response.status = 403;
|
||||
ctx.response.body = {
|
||||
error: "Can only update users in your department",
|
||||
};
|
||||
return;
|
||||
}
|
||||
if (role === "SuperAdmin" || role === "Supervisor") {
|
||||
ctx.response.status = 403;
|
||||
ctx.response.body = {
|
||||
error: "Cannot modify admin or supervisor roles",
|
||||
};
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const updates: string[] = [];
|
||||
const params: unknown[] = [];
|
||||
|
||||
if (name !== undefined) {
|
||||
updates.push("name = ?");
|
||||
params.push(sanitizeInput(name));
|
||||
}
|
||||
if (email !== undefined) {
|
||||
if (!isValidEmail(email)) {
|
||||
ctx.response.status = 400;
|
||||
ctx.response.body = { error: "Invalid email format" };
|
||||
return;
|
||||
}
|
||||
updates.push("email = ?");
|
||||
params.push(sanitizeInput(email));
|
||||
}
|
||||
if (role !== undefined) {
|
||||
updates.push("role = ?");
|
||||
params.push(role);
|
||||
}
|
||||
if (departmentId !== undefined) {
|
||||
updates.push("department_id = ?");
|
||||
params.push(departmentId);
|
||||
}
|
||||
if (contractorId !== undefined) {
|
||||
updates.push("contractor_id = ?");
|
||||
params.push(contractorId);
|
||||
}
|
||||
if (isActive !== undefined) {
|
||||
updates.push("is_active = ?");
|
||||
params.push(isActive);
|
||||
}
|
||||
// New fields
|
||||
if (phoneNumber !== undefined) {
|
||||
updates.push("phone_number = ?");
|
||||
params.push(phoneNumber);
|
||||
}
|
||||
if (aadharNumber !== undefined) {
|
||||
updates.push("aadhar_number = ?");
|
||||
params.push(aadharNumber);
|
||||
}
|
||||
if (bankAccountNumber !== undefined) {
|
||||
updates.push("bank_account_number = ?");
|
||||
params.push(bankAccountNumber);
|
||||
}
|
||||
if (bankName !== undefined) {
|
||||
updates.push("bank_name = ?");
|
||||
params.push(bankName);
|
||||
}
|
||||
if (bankIfsc !== undefined) {
|
||||
updates.push("bank_ifsc = ?");
|
||||
params.push(bankIfsc);
|
||||
}
|
||||
if (contractorAgreementNumber !== undefined) {
|
||||
updates.push("contractor_agreement_number = ?");
|
||||
params.push(contractorAgreementNumber);
|
||||
}
|
||||
if (pfNumber !== undefined) {
|
||||
updates.push("pf_number = ?");
|
||||
params.push(pfNumber);
|
||||
}
|
||||
if (esicNumber !== undefined) {
|
||||
updates.push("esic_number = ?");
|
||||
params.push(esicNumber);
|
||||
}
|
||||
|
||||
if (updates.length === 0) {
|
||||
ctx.response.status = 400;
|
||||
ctx.response.body = { error: "No fields to update" };
|
||||
return;
|
||||
}
|
||||
|
||||
params.push(userId);
|
||||
|
||||
await db.execute(
|
||||
`UPDATE users SET ${updates.join(", ")} WHERE id = ?`,
|
||||
params,
|
||||
);
|
||||
|
||||
const updatedUser = await db.query<User[]>(
|
||||
`SELECT u.id, u.username, u.name, u.email, u.role, u.department_id,
|
||||
u.contractor_id, u.is_active, u.created_at,
|
||||
u.phone_number, u.aadhar_number, u.bank_account_number,
|
||||
u.bank_name, u.bank_ifsc,
|
||||
u.contractor_agreement_number, u.pf_number, u.esic_number,
|
||||
d.name as department_name,
|
||||
c.name as contractor_name
|
||||
FROM users u
|
||||
LEFT JOIN departments d ON u.department_id = d.id
|
||||
LEFT JOIN users c ON u.contractor_id = c.id
|
||||
WHERE u.id = ?`,
|
||||
[userId],
|
||||
);
|
||||
|
||||
ctx.response.body = updatedUser[0];
|
||||
} catch (error) {
|
||||
console.error("Update user error:", error);
|
||||
ctx.response.status = 500;
|
||||
ctx.response.body = { error: "Internal server error" };
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Delete user
|
||||
router.delete("/:id", authenticateToken, authorize("SuperAdmin", "Supervisor"), async (ctx) => {
|
||||
try {
|
||||
const currentUser = getCurrentUser(ctx);
|
||||
const userId = ctx.params.id;
|
||||
|
||||
const users = await db.query<User[]>(
|
||||
"SELECT * FROM users WHERE id = ?",
|
||||
[userId]
|
||||
);
|
||||
|
||||
if (users.length === 0) {
|
||||
ctx.response.status = 404;
|
||||
ctx.response.body = { error: "User not found" };
|
||||
return;
|
||||
}
|
||||
|
||||
// Supervisors can only delete users in their department
|
||||
if (currentUser.role === "Supervisor") {
|
||||
if (users[0].department_id !== currentUser.departmentId) {
|
||||
ctx.response.status = 403;
|
||||
ctx.response.body = { error: "Can only delete users in your department" };
|
||||
router.delete(
|
||||
"/:id",
|
||||
authenticateToken,
|
||||
authorize("SuperAdmin", "Supervisor"),
|
||||
async (ctx) => {
|
||||
try {
|
||||
const currentUser = getCurrentUser(ctx);
|
||||
const userId = ctx.params.id;
|
||||
|
||||
const users = await db.query<User[]>(
|
||||
"SELECT * FROM users WHERE id = ?",
|
||||
[userId],
|
||||
);
|
||||
|
||||
if (users.length === 0) {
|
||||
ctx.response.status = 404;
|
||||
ctx.response.body = { error: "User not found" };
|
||||
return;
|
||||
}
|
||||
if (users[0].role === "SuperAdmin" || users[0].role === "Supervisor") {
|
||||
ctx.response.status = 403;
|
||||
ctx.response.body = { error: "Cannot delete admin or supervisor users" };
|
||||
return;
|
||||
|
||||
// Supervisors can only delete users in their department
|
||||
if (currentUser.role === "Supervisor") {
|
||||
if (users[0].department_id !== currentUser.departmentId) {
|
||||
ctx.response.status = 403;
|
||||
ctx.response.body = {
|
||||
error: "Can only delete users in your department",
|
||||
};
|
||||
return;
|
||||
}
|
||||
if (users[0].role === "SuperAdmin" || users[0].role === "Supervisor") {
|
||||
ctx.response.status = 403;
|
||||
ctx.response.body = {
|
||||
error: "Cannot delete admin or supervisor users",
|
||||
};
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await db.execute("DELETE FROM users WHERE id = ?", [userId]);
|
||||
ctx.response.body = { message: "User deleted successfully" };
|
||||
} catch (error) {
|
||||
console.error("Delete user error:", error);
|
||||
ctx.response.status = 500;
|
||||
ctx.response.body = { error: "Internal server error" };
|
||||
}
|
||||
|
||||
await db.execute("DELETE FROM users WHERE id = ?", [userId]);
|
||||
ctx.response.body = { message: "User deleted successfully" };
|
||||
} catch (error) {
|
||||
console.error("Delete user error:", error);
|
||||
ctx.response.status = 500;
|
||||
ctx.response.body = { error: "Internal server error" };
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
export default router;
|
||||
|
||||
Reference in New Issue
Block a user