107 lines
2.9 KiB
TypeScript
107 lines
2.9 KiB
TypeScript
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<string, unknown> } | null) {
|
|
if (!doc) return null;
|
|
const json = doc.toJSON ? doc.toJSON() : (doc as Record<string, unknown>);
|
|
const { password, resetCode, ...safe } = json as Record<string, unknown>;
|
|
return safe;
|
|
}
|
|
|
|
router.get("/", async (req, res) => {
|
|
try {
|
|
const filter = sanitizeAdminQuery(req.query as Record<string, unknown>, "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<string, unknown> = 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;
|