import bcrypt from "bcrypt"; import { Router } from "express"; import User from "../../models/User.js"; import { isValidObjectId, sanitizeAdminQuery } from "../../utils/adminUtils.js"; const router = Router(); const USER_FIELDS = ["username", "companyId", "role", "name", "buildIds"]; function toSafeUser(doc: { toJSON?: () => Record } | null) { if (!doc) return null; const json = doc.toJSON ? doc.toJSON() : (doc as Record); const { password, resetCode, ...safe } = json as Record; return safe; } router.get("/", async (req, res) => { try { const filter = sanitizeAdminQuery(req.query as Record, "users"); const result = await User.find(filter).select("-password -resetCode"); res.json(result); } catch (error) { res.json({ error: (error as Error).message }); } }); router.get("/:id", async (req, res) => { try { if (!isValidObjectId(req.params.id)) { return res.status(400).json({ error: "Некорректный ID" }); } const result = await User.findById(req.params.id).select("-password -resetCode"); res.json(result); } catch (error) { res.json({ error: (error as Error).message }); } }); router.post("/", async (req, res) => { try { if (!req.body.password || typeof req.body.password !== "string") { return res.status(400).json({ error: "Пароль обязателен" }); } const passwordHash = bcrypt.hashSync(req.body.password, 12); const body = Object.fromEntries( [...USER_FIELDS, "password"] .filter((k) => req.body[k] !== undefined) .map((k) => [k, k === "password" ? passwordHash : req.body[k]]) ); const result = await User.create(body); res.json(toSafeUser(result)); } catch (error) { res.json({ error: (error as Error).message }); } }); router.put("/:id", async (req, res) => { try { if (!isValidObjectId(req.params.id)) { return res.status(400).json({ error: "Некорректный ID" }); } const update: Record = Object.fromEntries( USER_FIELDS.filter((k) => req.body[k] !== undefined).map((k) => [ k, req.body[k], ]) ); if (req.body.password !== undefined && req.body.password !== "") { update.password = bcrypt.hashSync(req.body.password, 12); } const result = await User.findByIdAndUpdate(req.params.id, update, { new: true, }); res.json(toSafeUser(result)); } catch (error) { res.json({ error: (error as Error).message }); } }); router.delete("/:id", async (req, res) => { try { if (!isValidObjectId(req.params.id)) { return res.status(400).json({ error: "Некорректный ID" }); } const result = await User.findByIdAndRemove(req.params.id); res.json(result); } catch (error) { res.json({ error: (error as Error).message }); } }); const adminUsersRoute = router; export default adminUsersRoute;