diff --git a/src/lib/server/database.ts b/src/lib/server/database.ts index c923a34..bcb58e7 100644 --- a/src/lib/server/database.ts +++ b/src/lib/server/database.ts @@ -74,6 +74,9 @@ export class Report extends Model { declare auditor: Admin; @BelongsTo(() => StrikeReason, 'strike_reason_id') declare strike_reason: StrikeReason; + + @Column({ type: DataTypes.DATE }) + declare striked_at: Date | null; } @Table({ modelName: 'strike_reason', underscored: true, createdAt: false, updatedAt: false }) @@ -88,22 +91,10 @@ export class StrikeReason extends Model { export class StrikePunishment extends Model { @Column({ type: DataTypes.INTEGER, allowNull: false }) declare weight: number; + @Column({ type: DataTypes.ENUM('ban', 'outlawed'), allowNull: false }) + declare type: 'ban' | 'outlawed'; @Column({ type: DataTypes.INTEGER, allowNull: false }) - declare ban_in_seconds: number; -} - -@Table({ modelName: 'strike', underscored: true }) -export class Strike extends Model { - @Column({ type: DataTypes.INTEGER, allowNull: false, defaultValue: 0 }) - declare weight: number; - @Column({ type: DataTypes.DATE, allowNull: false, defaultValue: 0 }) - declare ban_until: Date; - @Column({ type: DataTypes.INTEGER, allowNull: false }) - @ForeignKey(() => User) - declare user_id: number; - - @BelongsTo(() => User, 'user_id') - declare user: User; + declare punishment_in_seconds: number; } @Table({ modelName: 'admin', underscored: true }) @@ -157,5 +148,5 @@ export class Settings extends Model { export const sequelize = new Sequelize(building ? 'sqlite::memory:' : env.DATABASE_URI, { // only log sql queries in dev mode logging: dev ? console.log : false, - models: [User, Report, StrikeReason, StrikePunishment, Strike, Admin, Settings] + models: [User, Report, StrikeReason, StrikePunishment, Admin, Settings] }); diff --git a/src/routes/admin/reports/+server.ts b/src/routes/admin/reports/+server.ts index 09fdf4d..75c669b 100644 --- a/src/routes/admin/reports/+server.ts +++ b/src/routes/admin/reports/+server.ts @@ -1,7 +1,7 @@ import type { RequestHandler } from '@sveltejs/kit'; import { getSession } from '$lib/server/session'; import { Permissions } from '$lib/permissions'; -import { Admin, Report, Strike, StrikePunishment, StrikeReason, User } from '$lib/server/database'; +import { Admin, Report, StrikeReason, User } from '$lib/server/database'; import type { Attributes } from 'sequelize'; import { Op } from 'sequelize'; import { env } from '$env/dynamic/private'; @@ -127,63 +127,14 @@ export const PATCH = (async ({ request, cookies }) => { if (strike_reason == null) return new Response(null, { status: 400 }); report.strike_reason_id = strike_reason.id; } - } else if (data.strike_reason == -1) { - const strike = await Strike.findOne({ where: { user_id: report.reported_id } }); - if (strike != null && report.strike_reason_id != null) { - const strike_weight = (await StrikeReason.findByPk(report.strike_reason_id, { - attributes: ['weight'] - }))!.weight; - const current_ban_in_seconds = ( - await StrikePunishment.findOne({ - attributes: ['ban_in_seconds'], - where: { weight: { [Op.lte]: strike.weight } } - }) - )?.ban_in_seconds; - if (current_ban_in_seconds) { - const new_ban_in_seconds = ( - await StrikePunishment.findOne({ - attributes: ['ban_in_seconds'], - where: { weight: { [Op.lte]: strike.weight - strike_weight } } - }) - )?.ban_in_seconds; - const time_left = - strike.ban_until.getTime() / 1000 - current_ban_in_seconds + (new_ban_in_seconds || 0); - strike.ban_until = new Date(time_left * 1000); - } - strike.weight -= strike_weight; - await strike.save(); - report.strike_reason_id = null; - } + } else if (data.strike_reason == -1 && report.strike_reason_id != null) { + report.strike_reason_id = null; } else if (data.strike_reason != report.strike_reason_id) { 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 }); - const [strike] = await Strike.findOrCreate({ where: { user_id: report.reported_id } }); - const old_punishment = ( - await StrikePunishment.findOne({ - attributes: ['ban_in_seconds'], - where: { weight: { [Op.lte]: strike.weight } } - }) - )?.ban_in_seconds; - if (report.strike_reason_id) { - strike.weight -= - (await StrikeReason.findByPk(report.strike_reason_id, { attributes: ['weight'] })) - ?.weight || 0; - } - strike.weight += (await StrikeReason.findByPk(strike_reason.id, { - attributes: ['weight'] - }))!.weight; - const new_punishment = ( - await StrikePunishment.findOne({ - attributes: ['ban_in_seconds'], - where: { weight: { [Op.lte]: strike.weight } } - }) - )?.ban_in_seconds; - if (old_punishment != new_punishment && new_punishment != null) { - strike.ban_until = new Date(Date.now() + new_punishment / 1000); - } - await strike.save(); report.strike_reason_id = strike_reason.id; + report.striked_at = new Date(Date.now()); } } if (admin != null) report.auditor_id = admin.id; diff --git a/src/routes/api/user/+server.ts b/src/routes/api/user/+server.ts index ba9c475..98f737d 100644 --- a/src/routes/api/user/+server.ts +++ b/src/routes/api/user/+server.ts @@ -1,6 +1,7 @@ import type { RequestHandler } from '@sveltejs/kit'; -import { Strike, User } from '$lib/server/database'; +import { Report, sequelize, StrikePunishment, StrikeReason, User } from '$lib/server/database'; import { env } from '$env/dynamic/private'; +import { Op } from 'sequelize'; export const GET = (async ({ url }) => { if (env.REPORT_SECRET && url.searchParams.get('secret') !== env.REPORT_SECRET) @@ -12,7 +13,28 @@ export const GET = (async ({ url }) => { const user = await User.findOne({ where: { uuid: uuid } }); if (user == null) return new Response(null, { status: 400 }); - const strike = await Strike.findOne({ where: { user_id: user.id } }); + const query = (await Report.findOne({ + where: { reported_id: user.id }, + attributes: [ + [sequelize.fn('SUM', sequelize.col('strike_reason.weight')), 'weight'], + 'striked_at' + ], + include: { model: StrikeReason, as: 'strike_reason' } + })) as { dataValues: { weight: number; striked_at: Date } } | null; + const ban_time = ( + await StrikePunishment.findOne({ + attributes: ['punishment_in_seconds'], + where: { type: ['ban'], weight: { [Op.lte]: query?.dataValues.weight } }, + order: [['weight', 'DESC']] + }) + )?.punishment_in_seconds; + const outlawed_time = ( + await StrikePunishment.findOne({ + attributes: ['punishment_in_seconds'], + where: { type: ['outlawed'], weight: { [Op.lte]: query?.dataValues.weight } }, + order: [['weight', 'DESC']] + }) + )?.punishment_in_seconds; return new Response( JSON.stringify({ @@ -20,9 +42,14 @@ export const GET = (async ({ url }) => { username: user.username, firstname: user.firstname, lastname: user.lastname, - banned: - new Date(new Date(Date.now()).toUTCString()) < - new Date((strike?.ban_until ?? new Date(0)).toUTCString()) + banned_until: + query && ban_time + ? Math.round(query.dataValues.striked_at.getTime() / 1000 + ban_time!) + : null, + outlawed_until: + query && outlawed_time + ? Math.round(query.dataValues.striked_at.getTime() / 1000 + outlawed_time!) + : null }), { status: 200 } );