188 lines
4.9 KiB
TypeScript
188 lines
4.9 KiB
TypeScript
import {
|
|
AdminMessage,
|
|
ConnectedAircraft,
|
|
getPublicUser,
|
|
MissionLog,
|
|
Prisma,
|
|
prisma,
|
|
} from "@repo/db";
|
|
import { Router } from "express";
|
|
import { io } from "../index";
|
|
|
|
const router: Router = Router();
|
|
|
|
// Get all connectedAircrafts
|
|
router.post("/", async (req, res) => {
|
|
try {
|
|
const filter = req.body?.filter || {};
|
|
const connectedAircrafts = await prisma.connectedAircraft.findMany({
|
|
where: filter,
|
|
});
|
|
res.json(connectedAircrafts);
|
|
} catch (error) {
|
|
console.error(error);
|
|
res.status(500).json({ error: "Failed to fetch connectedAircrafts" });
|
|
}
|
|
});
|
|
|
|
// Get a single connectedAircraft by ID
|
|
router.get("/:id", async (req, res) => {
|
|
const { id } = req.params;
|
|
try {
|
|
const connectedAircraft = await prisma.connectedAircraft.findUnique({
|
|
where: { id: Number(id) },
|
|
});
|
|
if (connectedAircraft) {
|
|
res.json(connectedAircraft);
|
|
} else {
|
|
res.status(404).json({ error: "ConnectedAircraft not found" });
|
|
}
|
|
} catch (error) {
|
|
console.error(error);
|
|
res.status(500).json({ error: "Failed to fetch connectedAircraft" });
|
|
}
|
|
});
|
|
|
|
// Update a connectedAircraft by ID
|
|
router.patch("/:id", async (req, res) => {
|
|
const { id } = req.params;
|
|
const aircraftUpdate = req.body as Prisma.ConnectedAircraftUpdateInput;
|
|
try {
|
|
const oldConnectedAircraft = await prisma.connectedAircraft.findUnique({
|
|
where: { id: Number(id) },
|
|
include: {
|
|
Station: true,
|
|
User: true,
|
|
},
|
|
});
|
|
const updatedConnectedAircraft = await prisma.connectedAircraft.update({
|
|
where: { id: Number(id) },
|
|
data: {
|
|
...aircraftUpdate,
|
|
},
|
|
});
|
|
|
|
const mission = await prisma.mission.findFirst({
|
|
where: {
|
|
state: "running",
|
|
missionStationIds: {
|
|
has: updatedConnectedAircraft.stationId,
|
|
},
|
|
},
|
|
});
|
|
if (
|
|
mission &&
|
|
aircraftUpdate.fmsStatus &&
|
|
oldConnectedAircraft &&
|
|
updatedConnectedAircraft &&
|
|
oldConnectedAircraft.fmsStatus !== updatedConnectedAircraft.fmsStatus
|
|
) {
|
|
const newMissionLog = mission.missionLog as any as MissionLog[];
|
|
newMissionLog.push({
|
|
type: "station-log",
|
|
auto: true,
|
|
data: {
|
|
oldFMSstatus: oldConnectedAircraft.fmsStatus,
|
|
newFMSstatus: updatedConnectedAircraft.fmsStatus,
|
|
station: oldConnectedAircraft.Station,
|
|
stationId: updatedConnectedAircraft.stationId,
|
|
user: getPublicUser(oldConnectedAircraft.User),
|
|
},
|
|
timeStamp: new Date().toISOString(),
|
|
});
|
|
await prisma.mission.update({
|
|
where: { id: mission.id },
|
|
data: {
|
|
missionLog: newMissionLog as any,
|
|
},
|
|
});
|
|
}
|
|
|
|
res.json(updatedConnectedAircraft);
|
|
// When change is only the estimated logout time, we don't need to emit an event
|
|
if (Object.keys(aircraftUpdate).length === 1 && aircraftUpdate.esimatedLogoutTime) return;
|
|
io.to("dispatchers").emit("update-connectedAircraft", updatedConnectedAircraft);
|
|
|
|
io.to(`user:${updatedConnectedAircraft.userId}`).emit(
|
|
"aircraft-update",
|
|
updatedConnectedAircraft,
|
|
);
|
|
} catch (error) {
|
|
console.error(error);
|
|
res.status(500).json({ error: "Failed to update connectedAircraft" });
|
|
}
|
|
});
|
|
|
|
// Kick a connectedAircraft by ID
|
|
router.delete("/:id", async (req, res) => {
|
|
const { id } = req.params;
|
|
const bann = req.body?.bann as boolean;
|
|
const reason = req.body?.reason as string;
|
|
const until = req.body?.until as Date | null;
|
|
|
|
const requiredPermission = bann ? "ADMIN_USER" : "ADMIN_KICK";
|
|
|
|
if (!req.user) {
|
|
res.status(401).json({ error: "Unauthorized" });
|
|
return;
|
|
}
|
|
|
|
if (!req.user.permissions.includes(requiredPermission)) {
|
|
res.status(403).json({ error: "Forbidden" });
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const aircraft = await prisma.connectedAircraft.update({
|
|
where: { id: Number(id) },
|
|
data: { logoutTime: new Date() },
|
|
include: bann ? { User: true } : undefined,
|
|
});
|
|
|
|
if (!aircraft) {
|
|
res.status(404).json({ error: "ConnectedAircraft not found" });
|
|
return;
|
|
}
|
|
|
|
const status = bann ? "ban" : "kick";
|
|
|
|
io.to(`user:${aircraft.userId}`).emit("notification", {
|
|
type: "admin-message",
|
|
message: `Du wurdest von ${getPublicUser(req.user).publicId} ${until ? `bis zum ${new Date(until).toLocaleString()} ` : ""} ${
|
|
status === "ban" ? "gebannt" : "gekickt"
|
|
}`,
|
|
status,
|
|
data: { admin: getPublicUser(req.user), reason },
|
|
} as AdminMessage);
|
|
|
|
io.in(`user:${aircraft.userId}`).disconnectSockets(true);
|
|
|
|
if (bann && !until) {
|
|
await prisma.user.update({
|
|
where: { id: aircraft.userId },
|
|
data: {
|
|
permissions: {
|
|
set: req.user.permissions.filter((p) => p !== "PILOT"),
|
|
},
|
|
},
|
|
});
|
|
}
|
|
await prisma.penalty.create({
|
|
data: {
|
|
userId: aircraft.userId,
|
|
type: bann ? (until ? "TIME_BAN" : "BAN") : "KICK",
|
|
until: until ? new Date(until) : new Date(Date.now() + 1000 * 60 * 60 * 24 * 365 * 50),
|
|
reason: reason,
|
|
createdUserId: req.user.id,
|
|
},
|
|
});
|
|
|
|
res.status(204).send();
|
|
} catch (error) {
|
|
console.error(error);
|
|
res.status(500).json({ error: "Failed to disconnect pilot" });
|
|
}
|
|
});
|
|
|
|
export default router;
|