From 1596fb605e7940e53ad2445db743ea77e3e6da15 Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 24 Dec 2024 01:17:36 +0100 Subject: [PATCH] update report admin endpoint --- src/lib/server/database.ts | 30 +++++------ src/routes/admin/reports/+server.ts | 79 ++++++++++++++--------------- 2 files changed, 52 insertions(+), 57 deletions(-) diff --git a/src/lib/server/database.ts b/src/lib/server/database.ts index 8646559..fa5cd4a 100644 --- a/src/lib/server/database.ts +++ b/src/lib/server/database.ts @@ -24,16 +24,16 @@ export class User extends Model { @Column({ type: DataTypes.DATE, allowNull: false }) declare birthday: Date; @Column({ type: DataTypes.STRING }) - declare telephone: string; + declare telephone: string | null; @Column({ type: DataTypes.STRING, allowNull: false }) declare username: string; @Column({ type: DataTypes.ENUM('java', 'bedrock', 'noauth'), allowNull: false }) declare playertype: 'java' | 'bedrock' | 'noauth'; @Column({ type: DataTypes.STRING }) - declare password: string; + declare password: string | null; @Column({ type: DataTypes.UUID, unique: true }) @Index - declare uuid: string; + declare uuid: string | null; } @Table({ modelName: 'report', underscored: true }) @@ -44,15 +44,15 @@ export class Report extends Model { @Column({ type: DataTypes.STRING, allowNull: false }) declare subject: string; @Column({ type: DataTypes.STRING }) - declare body: string; + declare body: string | null; @Column({ type: DataTypes.BOOLEAN, allowNull: false }) declare draft: boolean; @Column({ type: DataTypes.ENUM('none', 'review', 'reviewed'), allowNull: false }) declare status: 'none' | 'review' | 'reviewed'; @Column({ type: DataTypes.STRING }) - declare notice: string; + declare notice: string | null; @Column({ type: DataTypes.STRING }) - declare statement: string; + declare statement: string | null; @Column({ type: DataTypes.DATE }) declare striked_at: Date | null; @Column({ type: DataTypes.INTEGER, allowNull: false }) @@ -60,10 +60,10 @@ export class Report extends Model { declare reporter_id: number; @Column({ type: DataTypes.INTEGER }) @ForeignKey(() => User) - declare reported_id: number; + declare reported_id: number | null; @Column({ type: DataTypes.INTEGER }) @ForeignKey(() => Admin) - declare auditor_id: number; + declare auditor_id: number | null; @Column({ type: DataTypes.INTEGER }) @ForeignKey(() => StrikeReason) declare strike_reason_id: number | null; @@ -72,22 +72,22 @@ export class Report extends Model { onDelete: 'CASCADE', foreignKey: 'reporter_id' }) - declare reporter: User; + declare reporter: User | null; @BelongsTo(() => User, { onDelete: 'CASCADE', foreignKey: 'reported_id' }) - declare reported: User; + declare reported: User | null; @BelongsTo(() => Admin, { onDelete: 'CASCADE', foreignKey: 'auditor_id' }) - declare auditor: Admin; + declare auditor: Admin | null; @BelongsTo(() => StrikeReason, { onDelete: 'CASCADE', foreignKey: 'strike_reason_id' }) - declare strike_reason: StrikeReason; + declare strike_reason: StrikeReason | null; } @Table({ modelName: 'strike_reason', underscored: true, createdAt: false, updatedAt: false }) @@ -113,19 +113,19 @@ export class Feedback extends Model { @Column({ type: DataTypes.STRING, allowNull: false }) declare event: string; @Column({ type: DataTypes.STRING }) - declare content: string; + declare content: string | null; @Column({ type: DataTypes.STRING, allowNull: false, unique: true }) @Index declare url_hash: string; @Column({ type: DataTypes.INTEGER }) @ForeignKey(() => User) - declare user_id: number; + declare user_id: number | null; @BelongsTo(() => User, { onDelete: 'CASCADE', foreignKey: 'user_id' }) - declare user: User; + declare user: User | null; } @Table({ modelName: 'admin', underscored: true }) diff --git a/src/routes/admin/reports/+server.ts b/src/routes/admin/reports/+server.ts index b9bb58d..94e2bab 100644 --- a/src/routes/admin/reports/+server.ts +++ b/src/routes/admin/reports/+server.ts @@ -97,65 +97,60 @@ export const PATCH = (async ({ request, cookies }) => { } const data = parseResult.data; - const report = await Report.findOne({ where: { id: data.id } }); + const report = await Report.findOne({ where: { id: data.id }, include: [{ all: true }] }); const admin = await Admin.findOne({ where: { id: data.auditor } }); - const reported = data.reported - ? await User.findOne({ where: { uuid: data.reported } }) - : undefined; - if (report === null || (admin === null && data.auditor != -1) || reported === null) + const reported = data.reported ? await User.findOne({ where: { uuid: data.reported } }) : null; + if (report === null || (admin === null && data.auditor != -1)) return new Response(null, { status: 400 }); const webhookTriggerUsers: string[] = []; - if (report.reported_id != reported?.id) { - const oldReportUser = await User.findByPk(report.reported_id); - if (oldReportUser) webhookTriggerUsers.push(oldReportUser.uuid); - if (reported) webhookTriggerUsers.push(reported.uuid); - } else if ( - reported && - report.reported_id != null && - report.strike_reason_id != data.strike_reason + + // check if strike reason has changed and return 400 if it doesn't exist + if ( + (report.strike_reason?.id ?? -1) != data.strike_reason && + data.strike_reason != null && + data.strike_reason != -1 ) { - webhookTriggerUsers.push(reported.uuid); + const strike_reason = await StrikeReason.findByPk(data.strike_reason); + if (strike_reason == null) return new Response(null, { status: 400 }); } - report.reported_id = reported?.id ?? null; - if (data.strike_reason != null) { - if (data.status !== 'reviewed') { - if (data.strike_reason == -1) { - report.strike_reason_id = null; - } else { - const strike_reason = await StrikeReason.findByPk(data.strike_reason); - if (strike_reason == null) return new Response(null, { status: 400 }); - report.strike_reason_id = strike_reason.id; - } - } else if (data.strike_reason == -1 && report.strike_reason_id != null) { - report.strike_reason_id = null; - report.striked_at = null; - } else if ( - data.strike_reason != -1 && - (data.strike_reason != report.strike_reason_id || data.status != report.status) + if (data.status === 'reviewed') { + // trigger webhook if status changed to reviewed + if (report.status !== 'reviewed' && data.strike_reason != -1 && reported) { + webhookTriggerUsers.push(reported.uuid!); + } + // trigger webhook if strike reason has changed + else if ( + (report.strike_reason?.id ?? -1) != data.strike_reason && + report.reported && + reported ) { - if (!report.reported_id) return new Response(null, { status: 400 }); - const strike_reason = await StrikeReason.findByPk(data.strike_reason); - if (strike_reason == null) return new Response(null, { status: 400 }); - report.strike_reason_id = strike_reason.id; - report.striked_at = new Date(Date.now()); + webhookTriggerUsers.push(reported.uuid!); + } + } else if (report.status === 'reviewed') { + // trigger webhook if report status is reviewed and reported user has changed + if (report.strike_reason != null && report.reported) { + webhookTriggerUsers.push(report.reported.uuid!); } } + if (data.notice != null) report.notice = data.notice; if (data.statement != null) report.statement = data.statement; if (data.status != null) report.status = data.status; + if (data.strike_reason != null) + report.strike_reason_id = data.strike_reason == -1 ? null : data.strike_reason; + if (data.strike_reason != null) + report.striked_at = data.strike_reason == -1 ? null : new Date(Date.now()); if (admin != null) report.auditor_id = admin.id; await report.save(); - if (webhookTriggerUsers.length > 0 && data.status == 'reviewed' && env.REPORTED_WEBHOOK) { - for (const webhookTriggerUser of webhookTriggerUsers) { - // no `await` to avoid blocking - webhookUserReported(env.REPORTED_WEBHOOK, webhookTriggerUser).catch((e) => - console.error(`failed to send reported webhook: ${e}`) - ); - } + for (const webhookTriggerUser of webhookTriggerUsers) { + // no `await` to avoid blocking + webhookUserReported(env.REPORTED_WEBHOOK, webhookTriggerUser).catch((e) => + console.error(`failed to send reported webhook: ${e}`) + ); } return new Response();