Implement CRUD for automod
This commit is contained in:
parent
bc0a43053b
commit
3f7d26118d
147
src/api/routes/guilds/#guild_id/auto-moderation/rules.ts
Normal file
147
src/api/routes/guilds/#guild_id/auto-moderation/rules.ts
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||
Copyright (C) 2024 Spacebar and Spacebar Contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { route } from "@spacebar/api";
|
||||
import { User, AutomodRuleSchema, AutomodRule } from "@spacebar/util";
|
||||
import { Request, Response, Router } from "express";
|
||||
import { HTTPError } from "lambert-server";
|
||||
|
||||
const router: Router = Router();
|
||||
|
||||
router.get(
|
||||
"/",
|
||||
route({
|
||||
permission: ["MANAGE_GUILD"],
|
||||
responses: {
|
||||
200: {
|
||||
body: "AutomodRuleSchemaWithId[]",
|
||||
},
|
||||
403: {
|
||||
body: "APIErrorResponse",
|
||||
},
|
||||
},
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const { guild_id } = req.params;
|
||||
const rules = await AutomodRule.find({ where: { guild_id } });
|
||||
return res.json(rules);
|
||||
},
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/",
|
||||
route({
|
||||
// requestBody: "AutomodRuleSchema",
|
||||
permission: ["MANAGE_GUILD"],
|
||||
responses: {
|
||||
200: {
|
||||
body: "AutomodRuleSchemaWithId",
|
||||
},
|
||||
400: {
|
||||
body: "APIErrorResponse",
|
||||
},
|
||||
403: {
|
||||
body: "APIErrorResponse",
|
||||
},
|
||||
},
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const { guild_id } = req.params;
|
||||
if (req.user_id !== req.body.creator_id)
|
||||
throw new HTTPError(
|
||||
"You can't create a rule for someone else",
|
||||
403,
|
||||
);
|
||||
|
||||
if (guild_id !== req.body.guild_id)
|
||||
throw new HTTPError(
|
||||
"You can't create a rule for another guild",
|
||||
403,
|
||||
);
|
||||
|
||||
if (req.body.id) {
|
||||
throw new HTTPError("You can't specify an ID for a new rule", 400);
|
||||
}
|
||||
|
||||
const data = req.body as AutomodRuleSchema;
|
||||
|
||||
const created = AutomodRule.create({
|
||||
creator: await User.findOneOrFail({
|
||||
where: { id: data.creator_id },
|
||||
}),
|
||||
...data,
|
||||
});
|
||||
|
||||
const savedRule = await AutomodRule.save(created);
|
||||
return res.json(savedRule);
|
||||
},
|
||||
);
|
||||
|
||||
router.patch(
|
||||
"/:rule_id",
|
||||
route({
|
||||
// requestBody: "AutomodRuleSchema
|
||||
permission: ["MANAGE_GUILD"],
|
||||
responses: {
|
||||
200: {
|
||||
body: "AutomodRuleSchemaWithId",
|
||||
},
|
||||
400: {
|
||||
body: "APIErrorResponse",
|
||||
},
|
||||
403: {
|
||||
body: "APIErrorResponse",
|
||||
},
|
||||
},
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const { rule_id } = req.params;
|
||||
const rule = await AutomodRule.findOneOrFail({
|
||||
where: { id: rule_id },
|
||||
});
|
||||
|
||||
const data = req.body as AutomodRuleSchema;
|
||||
|
||||
AutomodRule.merge(rule, data);
|
||||
const savedRule = await AutomodRule.save(rule);
|
||||
return res.json(savedRule);
|
||||
},
|
||||
);
|
||||
|
||||
router.delete(
|
||||
"/:rule_id",
|
||||
route({
|
||||
permission: ["MANAGE_GUILD"],
|
||||
responses: {
|
||||
204: {},
|
||||
403: {
|
||||
body: "APIErrorResponse",
|
||||
},
|
||||
404: {
|
||||
body: "APIErrorResponse",
|
||||
},
|
||||
},
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const { rule_id } = req.params;
|
||||
await AutomodRule.delete({ id: rule_id });
|
||||
return res.status(204).send();
|
||||
},
|
||||
);
|
||||
|
||||
export default router;
|
||||
88
src/util/entities/AutomodRule.ts
Normal file
88
src/util/entities/AutomodRule.ts
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||
Copyright (C) 2024 Spacebar and Spacebar Contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { dbEngine, User } from "@spacebar/util";
|
||||
import { BaseClass } from "./BaseClass";
|
||||
import { Entity, JoinColumn, ManyToOne, Column } from "typeorm";
|
||||
|
||||
export class AutomodMentionSpamRule {
|
||||
mention_total_limit: number;
|
||||
mention_raid_protection_enabled: boolean;
|
||||
}
|
||||
|
||||
export class AutomodSuspectedSpamRule {}
|
||||
|
||||
export class AutomodCommonlyFlaggedWordsRule {
|
||||
allow_list: [string];
|
||||
presets: [number];
|
||||
}
|
||||
|
||||
export class AutomodCustomWordsRule {
|
||||
allow_list: [string];
|
||||
keyword_filter: [string];
|
||||
regex_patterns: [string];
|
||||
}
|
||||
|
||||
@Entity({
|
||||
name: "automod_rules",
|
||||
engine: dbEngine,
|
||||
})
|
||||
export class AutomodRule extends BaseClass {
|
||||
@JoinColumn({ name: "creator_id" })
|
||||
@ManyToOne(() => User, { onDelete: "CASCADE" })
|
||||
creator: User;
|
||||
|
||||
@Column()
|
||||
enabled: boolean;
|
||||
|
||||
@Column()
|
||||
event_type: number; // No idea...
|
||||
|
||||
@Column({ type: "simple-array" })
|
||||
exempt_channels: [string];
|
||||
|
||||
@Column({ type: "simple-array" })
|
||||
exempt_roles: [string];
|
||||
|
||||
@Column()
|
||||
guild_id: string;
|
||||
|
||||
@Column()
|
||||
name: string;
|
||||
|
||||
@Column()
|
||||
position: number;
|
||||
|
||||
@Column()
|
||||
trigger_type: number;
|
||||
|
||||
@Column({
|
||||
type: "simple-json",
|
||||
nullable: true,
|
||||
})
|
||||
trigger_metadata?: // this is null for "Block suspected spam content"
|
||||
| AutomodMentionSpamRule
|
||||
| AutomodSuspectedSpamRule
|
||||
| AutomodCommonlyFlaggedWordsRule
|
||||
| AutomodCustomWordsRule;
|
||||
|
||||
@Column({
|
||||
type: "simple-json",
|
||||
})
|
||||
actions: { type: number; metadata: unknown }[];
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||
Copyright (C) 2024 Spacebar and Spacebar Contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
@ -19,6 +19,7 @@
|
||||
export * from "./Application";
|
||||
export * from "./Attachment";
|
||||
export * from "./AuditLog";
|
||||
export * from "./AutomodRule";
|
||||
export * from "./BackupCodes";
|
||||
export * from "./Badge";
|
||||
export * from "./Ban";
|
||||
|
||||
56
src/util/schemas/AutomodRuleSchema.ts
Normal file
56
src/util/schemas/AutomodRuleSchema.ts
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||
Copyright (C) 2024 Spacebar and Spacebar Contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export interface AutomodMentionSpamRuleSchema {
|
||||
mention_total_limit: number;
|
||||
mention_raid_protection_enabled: boolean;
|
||||
}
|
||||
|
||||
export interface AutomodSuspectedSpamRuleSchema {}
|
||||
|
||||
export interface AutomodCommonlyFlaggedWordsRuleSchema {
|
||||
allow_list: [string];
|
||||
presets: [number];
|
||||
}
|
||||
|
||||
export interface AutomodCustomWordsRuleSchema {
|
||||
allow_list: [string];
|
||||
keyword_filter: [string];
|
||||
regex_patterns: [string];
|
||||
}
|
||||
|
||||
export interface AutomodRuleSchema {
|
||||
creator_id: string;
|
||||
enabled: boolean;
|
||||
event_type: number; // No idea...
|
||||
exempt_channels: [string];
|
||||
exempt_roles: [string];
|
||||
guild_id: string;
|
||||
name: string;
|
||||
position: number;
|
||||
trigger_type: number; //AutomodTriggerTypes
|
||||
trigger_metadata:
|
||||
| AutomodMentionSpamRuleSchema
|
||||
| AutomodSuspectedSpamRuleSchema
|
||||
| AutomodCommonlyFlaggedWordsRuleSchema
|
||||
| AutomodCustomWordsRuleSchema;
|
||||
}
|
||||
|
||||
export interface AutomodRuleSchemaWithId extends AutomodRuleSchema {
|
||||
id: string;
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||
Copyright (C) 2024 Spacebar and Spacebar Contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
@ -21,6 +21,7 @@ export * from "./ActivitySchema";
|
||||
export * from "./ApplicationAuthorizeSchema";
|
||||
export * from "./ApplicationCreateSchema";
|
||||
export * from "./ApplicationModifySchema";
|
||||
export * from "./AutomodRuleSchema";
|
||||
export * from "./BackupCodesChallengeSchema";
|
||||
export * from "./BanCreateSchema";
|
||||
export * from "./BanModeratorSchema";
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||
Copyright (C) 2024 Spacebar and Spacebar Contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
@ -320,6 +320,20 @@ export const ClientApplicationAssetTypes = {
|
||||
BIG: 2,
|
||||
};
|
||||
|
||||
export const AutomodActionTypes = {
|
||||
BLOCK_MESSAGE: 1,
|
||||
SEND_ALERT: 2,
|
||||
TIMEOUT_MEMBER: 3,
|
||||
};
|
||||
|
||||
export const AutomodTriggerTypes = {
|
||||
CUSTOM_WORDS: 1,
|
||||
UNKNOWN_2: 2,
|
||||
SUSPECTED_SPAM_CONTENT: 3,
|
||||
COMMONLY_FLAGGED_WORDS: 4,
|
||||
MENTION_SPAM: 5,
|
||||
};
|
||||
|
||||
export const Colors = {
|
||||
DEFAULT: 0x000000,
|
||||
WHITE: 0xffffff,
|
||||
|
||||
Reference in New Issue
Block a user