diff --git a/apps/core-server/routes/report.ts b/apps/core-server/routes/report.ts index a37c912c..b9f2ef95 100644 --- a/apps/core-server/routes/report.ts +++ b/apps/core-server/routes/report.ts @@ -43,14 +43,20 @@ router.post("/admin-embed", async (req, res) => { { name: "angemeldet als", value: report.reportedUserRole, inline: true }, { name: "gemeldet von", - value: `${report.Sender?.firstname} ${report.Sender?.lastname} (${report.Sender?.publicId})`, + value: report.Sender + ? `${report.Sender?.firstname} ${report.Sender?.lastname} (${report.Sender?.publicId})` + : "System", }, ) .setFooter({ text: "Bitte reagiere mit 🫡, wenn du den Report bearbeitet hast, oder mit ✅, wenn er abgeschlossen ist.", }) - .setTimestamp(new Date(report.timestamp)) - .setColor("DarkRed"); + .setTimestamp(new Date(report.timestamp)); + if (report.reviewed) { + embed.setColor("DarkGreen"); + } else { + embed.setColor("DarkRed"); + } const reportsChannel = await client.channels.fetch(process.env.DISCORD_REPORT_CHANNEL!); if (!reportsChannel || !reportsChannel.isSendable()) { @@ -59,7 +65,9 @@ router.post("/admin-embed", async (req, res) => { } const message = await reportsChannel.send({ embeds: [embed] }); message.react("🫡").catch(console.error); - message.react("✅").catch(console.error); + if (!report.reviewed) { + message.react("✅").catch(console.error); + } res.json({ message: "Report embed sent to Discord channel", }); diff --git a/apps/hub/app/(app)/admin/report/_components/form.tsx b/apps/hub/app/(app)/admin/report/_components/form.tsx index 38e3ca81..c57853d0 100644 --- a/apps/hub/app/(app)/admin/report/_components/form.tsx +++ b/apps/hub/app/(app)/admin/report/_components/form.tsx @@ -4,6 +4,7 @@ import { editReport } from "(app)/admin/report/actions"; import { zodResolver } from "@hookform/resolvers/zod"; import { Report as IReport, Prisma, User } from "@repo/db"; import { ReportSchema, Report as IReportZod } from "@repo/db/zod"; +import { cn } from "@repo/shared-components"; import { PaginatedTable } from "_components/PaginatedTable"; import { Button } from "_components/ui/Button"; import { Switch } from "_components/ui/Switch"; @@ -31,14 +32,23 @@ export const ReportSenderInfo = ({ {report.reportedUserRole} -
+ gemeldet vom System am {new Date(report.timestamp).toLocaleString()} +
+ )} ); }; diff --git a/apps/hub/app/(app)/admin/report/columns.tsx b/apps/hub/app/(app)/admin/report/columns.tsx index e0ad7bbf..207ff792 100644 --- a/apps/hub/app/(app)/admin/report/columns.tsx +++ b/apps/hub/app/(app)/admin/report/columns.tsx @@ -25,8 +25,12 @@ export const reportColumns: ColumnDefSystem
; + return ( + {`${user.firstname} ${user.lastname} (${user.publicId})`} + ); }, }, { diff --git a/apps/hub/app/(app)/admin/user/[id]/_components/AccountLog.tsx b/apps/hub/app/(app)/admin/user/[id]/_components/AccountLog.tsx index a12a4cc5..2b934160 100644 --- a/apps/hub/app/(app)/admin/user/[id]/_components/AccountLog.tsx +++ b/apps/hub/app/(app)/admin/user/[id]/_components/AccountLog.tsx @@ -47,30 +47,42 @@ export const AccountLog = ({ sameIPLogs, userId }: { sameIPLogs: Log[]; userId: } getFilter={(searchTerm) => { - return { - AND: [ - onlyImportant - ? { - type: { - in: ["REGISTER", "PROFILE_CHANGE"], - }, - } - : {}, - { - AND: [ - { ip: { contains: searchTerm } }, - { browser: { contains: searchTerm } }, - { - id: { - in: sameIPLogs - .filter((log) => log.id.toString().includes(searchTerm)) - .map((log) => log.id), - }, + if (onlyImportant) { + return { + AND: [ + { ip: { contains: searchTerm } }, + { browser: { contains: searchTerm } }, + { + id: { + in: sameIPLogs + .filter((log) => log.id.toString().includes(searchTerm)) + .map((log) => log.id), }, - ], - }, - ], - } as Prisma.LogWhereInput; + }, + ], + } as Prisma.LogWhereInput; + } else { + return { + OR: [ + { + AND: [ + { ip: { contains: searchTerm } }, + { browser: { contains: searchTerm } }, + { + id: { + in: sameIPLogs + .filter((log) => log.id.toString().includes(searchTerm)) + .map((log) => log.id), + }, + }, + ], + }, + { + userId: userId, + }, + ], + } as Prisma.LogWhereInput; + } }} include={{ User: true, diff --git a/apps/hub/app/(auth)/login/_components/action.ts b/apps/hub/app/(auth)/login/_components/action.ts index d32c300b..40392332 100644 --- a/apps/hub/app/(auth)/login/_components/action.ts +++ b/apps/hub/app/(auth)/login/_components/action.ts @@ -55,18 +55,45 @@ export const logAction = async ( }, }); if (existingLogs.length > 0 && user?.user.id) { - // Möglicherweise ein doppelter Account, Report erstellen - const report = await prisma.report.create({ - data: { - text: `Möglicher doppelter Account erkannt bei Login-Versuch.\n\nÜbereinstimmende Logs:\n${existingLogs - .map((log) => `- Log ID: ${log.id}, IP: ${log.ip}, Zeitstempel: ${log.timestamp}`) - .join("\n")}`, - reportedUserId: user?.user.id, - reportedUserRole: "LOGIN - Doppelter Account Verdacht", + const existingReport = await prisma.report.findFirst({ + where: { + reportedUserId: user.user.id, + reportedUserRole: { + contains: "Doppelter Account Verdacht", + }, }, }); + // keine Doppel-Reports für denselben Nutzer erstellen + if (!existingReport) { + // Möglicherweise ein doppelter Account, Report erstellen + const report = await prisma.report.create({ + data: { + text: `Möglicher doppelter Account erkannt bei Login-Versuch.\n\nÜbereinstimmende Logs:\n${existingLogs + .map((log) => `- Log ID: ${log.id}, IP: ${log.ip}, Zeitstempel: ${log.timestamp}`) + .join("\n")}`, + reportedUserId: user?.user.id, + reportedUserRole: "LOGIN - Doppelter Account Verdacht", + }, + }); - await sendReportEmbed(report.id); + await sendReportEmbed(report.id); + } else { + // Update report and send it again to Discord + const updatedReport = await prisma.report.update({ + where: { + id: existingReport.id, + }, + data: { + text: `Möglicher doppelter Account erkannt bei Login-Versuch.\n\nÜbereinstimmende Logs:\n${existingLogs + .map( + (log) => + `- Log ID: ${log.id}, IP: ${log.ip}, Zeitstempel: ${new Date(log.timestamp).toLocaleString("de-DE")}`, + ) + .join("\n")}`, + }, + }); + await sendReportEmbed(updatedReport.id); + } } }