Discord Permissions will be revoked, when under a penalty
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import { DISCORD_ROLES, MissionLog, NotificationPayload, prisma } from "@repo/db";
|
import { DISCORD_ROLES, MissionLog, NotificationPayload, prisma } from "@repo/db";
|
||||||
import { io } from "index";
|
import { io } from "index";
|
||||||
import cron from "node-cron";
|
import cron from "node-cron";
|
||||||
|
import { setUserStandardNamePermissions } from "routes/helper";
|
||||||
import { changeMemberRoles } from "routes/member";
|
import { changeMemberRoles } from "routes/member";
|
||||||
|
|
||||||
const removeMission = async (id: number, reason: string) => {
|
const removeMission = async (id: number, reason: string) => {
|
||||||
@@ -141,21 +142,12 @@ const removeConnectedAircrafts = async () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
const removePermissionsForBannedUsers = async () => {
|
const removePermissionsForBannedUsers = async () => {
|
||||||
const activePenalties = await prisma.penalty.findMany({
|
const removePermissionsPenaltys = await prisma.penalty.findMany({
|
||||||
where: {
|
where: {
|
||||||
OR: [
|
removePermissionApplied: false,
|
||||||
{
|
User: {
|
||||||
type: "BAN",
|
DiscordAccount: { isNot: null },
|
||||||
suspended: false,
|
},
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "TIME_BAN",
|
|
||||||
suspended: false,
|
|
||||||
until: {
|
|
||||||
gt: new Date().toISOString(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
include: {
|
include: {
|
||||||
User: {
|
User: {
|
||||||
@@ -167,16 +159,33 @@ const removePermissionsForBannedUsers = async () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const penalty of activePenalties) {
|
const addPermissionsPenaltys = await prisma.penalty.findMany({
|
||||||
const user = penalty.User;
|
where: {
|
||||||
|
addPermissionApplied: false,
|
||||||
|
User: {
|
||||||
|
DiscordAccount: { isNot: null },
|
||||||
|
},
|
||||||
|
OR: [{ suspended: true }, { until: { lt: new Date().toISOString() } }],
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
User: {
|
||||||
|
include: {
|
||||||
|
DiscordAccount: true,
|
||||||
|
FormerDiscordAccounts: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (user.DiscordAccount) {
|
for (const penalty of removePermissionsPenaltys) {
|
||||||
await changeMemberRoles(
|
const user = penalty.User;
|
||||||
user.DiscordAccount.discordId,
|
console.log(`Removing roles for user ${user.id} due to penalty ${penalty.id}`);
|
||||||
[DISCORD_ROLES.PILOT, DISCORD_ROLES.DISPATCHER],
|
|
||||||
"remove",
|
await changeMemberRoles(
|
||||||
);
|
user.DiscordAccount!.discordId,
|
||||||
}
|
[DISCORD_ROLES.PILOT, DISCORD_ROLES.DISPATCHER],
|
||||||
|
"remove",
|
||||||
|
);
|
||||||
|
|
||||||
for (const formerAccount of user.FormerDiscordAccounts) {
|
for (const formerAccount of user.FormerDiscordAccounts) {
|
||||||
await changeMemberRoles(
|
await changeMemberRoles(
|
||||||
@@ -185,15 +194,29 @@ const removePermissionsForBannedUsers = async () => {
|
|||||||
"remove",
|
"remove",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
await prisma.penalty.update({
|
||||||
|
where: { id: penalty.id },
|
||||||
|
data: { removePermissionApplied: true },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for (const penalty of addPermissionsPenaltys) {
|
||||||
|
console.log(`Restoring roles for user ${penalty.userId} due to penalty ${penalty.id}`);
|
||||||
|
await setUserStandardNamePermissions({
|
||||||
|
memberId: penalty.User.DiscordAccount!.discordId,
|
||||||
|
userId: penalty.userId,
|
||||||
|
});
|
||||||
|
await prisma.penalty.update({
|
||||||
|
where: { id: penalty.id },
|
||||||
|
data: { addPermissionApplied: true },
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
cron.schedule("*/5 * * * *", async () => {
|
removePermissionsForBannedUsers();
|
||||||
await removePermissionsForBannedUsers();
|
|
||||||
});
|
|
||||||
|
|
||||||
cron.schedule("*/1 * * * *", async () => {
|
cron.schedule("*/1 * * * *", async () => {
|
||||||
try {
|
try {
|
||||||
|
await removePermissionsForBannedUsers();
|
||||||
await removeClosedMissions();
|
await removeClosedMissions();
|
||||||
await removeConnectedAircrafts();
|
await removeConnectedAircrafts();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -10,18 +10,22 @@ export const eventCompleted = (event: Event, participant?: Participant) => {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
router.post("/set-standard-name", async (req, res) => {
|
export const setUserStandardNamePermissions = async ({
|
||||||
const { memberId, userId } = req.body;
|
memberId,
|
||||||
|
userId,
|
||||||
|
}: {
|
||||||
|
memberId: string;
|
||||||
|
userId: string;
|
||||||
|
}) => {
|
||||||
const user = await prisma.user.findUnique({
|
const user = await prisma.user.findUnique({
|
||||||
where: {
|
where: {
|
||||||
id: userId,
|
id: userId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (!user) {
|
if (!user) {
|
||||||
res.status(404).json({ error: "User not found" });
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const participant = await prisma.participant.findMany({
|
const participant = await prisma.participant.findMany({
|
||||||
where: {
|
where: {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
@@ -72,6 +76,13 @@ router.post("/set-standard-name", async (req, res) => {
|
|||||||
await changeMemberRoles(memberId, [DISCORD_ROLES.PILOT], isPilot ? "add" : "remove");
|
await changeMemberRoles(memberId, [DISCORD_ROLES.PILOT], isPilot ? "add" : "remove");
|
||||||
await changeMemberRoles(memberId, [DISCORD_ROLES.DISPATCHER], isDispatcher ? "add" : "remove");
|
await changeMemberRoles(memberId, [DISCORD_ROLES.DISPATCHER], isDispatcher ? "add" : "remove");
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
router.post("/set-standard-name", async (req, res) => {
|
||||||
|
const { memberId, userId } = req.body;
|
||||||
|
|
||||||
|
await setUserStandardNamePermissions({ memberId, userId });
|
||||||
|
res.status(200).json({ message: "Standard name and permissions set" });
|
||||||
});
|
});
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Penalty" ADD COLUMN "addPermissionApplied" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
ADD COLUMN "removePermissionApplied" BOOLEAN NOT NULL DEFAULT false;
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- The primary key for the `FormerDiscordAccount` table will be changed. If it partially fails, the table could be left without primary key constraint.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- DropIndex
|
||||||
|
DROP INDEX "FormerDiscordAccount_discord_id_key";
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "FormerDiscordAccount" DROP CONSTRAINT "FormerDiscordAccount_pkey",
|
||||||
|
ADD COLUMN "id" SERIAL NOT NULL,
|
||||||
|
ADD CONSTRAINT "FormerDiscordAccount_pkey" PRIMARY KEY ("id");
|
||||||
@@ -10,6 +10,10 @@ model Penalty {
|
|||||||
|
|
||||||
suspended Boolean @default(false)
|
suspended Boolean @default(false)
|
||||||
|
|
||||||
|
// For Chronjob to know if permissions were already applied/removed
|
||||||
|
removePermissionApplied Boolean @default(false)
|
||||||
|
addPermissionApplied Boolean @default(false)
|
||||||
|
|
||||||
timestamp DateTime @default(now())
|
timestamp DateTime @default(now())
|
||||||
|
|
||||||
// relations:
|
// relations:
|
||||||
|
|||||||
@@ -94,14 +94,13 @@ model User {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model FormerDiscordAccount {
|
model FormerDiscordAccount {
|
||||||
discordId String @unique @map(name: "discord_id")
|
id Int @id @default(autoincrement())
|
||||||
|
discordId String @map(name: "discord_id")
|
||||||
userId String @map(name: "user_id")
|
userId String @map(name: "user_id")
|
||||||
removedAt DateTime @default(now()) @map(name: "removed_at")
|
removedAt DateTime @default(now()) @map(name: "removed_at")
|
||||||
|
|
||||||
DiscordAccount DiscordAccount? @relation(fields: [discordId], references: [discordId], onDelete: SetNull)
|
DiscordAccount DiscordAccount? @relation(fields: [discordId], references: [discordId], onDelete: SetNull)
|
||||||
User User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
User User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
@@id([discordId, userId])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
model DiscordAccount {
|
model DiscordAccount {
|
||||||
@@ -119,9 +118,9 @@ model DiscordAccount {
|
|||||||
updatedAt DateTime @default(now()) @map(name: "updated_at")
|
updatedAt DateTime @default(now()) @map(name: "updated_at")
|
||||||
|
|
||||||
// Related User
|
// Related User
|
||||||
userId String? @unique
|
userId String? @unique
|
||||||
User User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
User User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
||||||
formerDiscordAccount FormerDiscordAccount?
|
formerDiscordAccount FormerDiscordAccount[]
|
||||||
|
|
||||||
@@map(name: "discord_accounts")
|
@@map(name: "discord_accounts")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import { ReactNode, useState } from "react";
|
import { ReactNode, useState } from "react";
|
||||||
import { cn } from "../helper/cn";
|
import { cn } from "../helper/cn";
|
||||||
|
import { Button } from "./Button";
|
||||||
|
|
||||||
export const PenaltyDropdown = ({
|
export const PenaltyDropdown = ({
|
||||||
onClick,
|
onClick,
|
||||||
@@ -79,10 +80,10 @@ export const PenaltyDropdown = ({
|
|||||||
<option value="1y">1 Jahr</option>
|
<option value="1y">1 Jahr</option>
|
||||||
</select>
|
</select>
|
||||||
)}
|
)}
|
||||||
<button
|
<Button
|
||||||
className={cn("btn btn-square btn-soft tooltip tooltip-bottom w-full", btnClassName)}
|
className={cn("btn btn-square btn-soft tooltip tooltip-bottom w-full", btnClassName)}
|
||||||
data-tip={btnTip}
|
data-tip={btnTip}
|
||||||
onClick={() => {
|
onClick={async () => {
|
||||||
let untilDate: Date | null = null;
|
let untilDate: Date | null = null;
|
||||||
if (until !== "default") {
|
if (until !== "default") {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
@@ -124,11 +125,11 @@ export const PenaltyDropdown = ({
|
|||||||
untilDate = null;
|
untilDate = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onClick({ reason, until: untilDate });
|
await onClick({ reason, until: untilDate });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{Icon} {btnName}
|
{Icon} {btnName}
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user