feat: add limit for attachment description (#2418)

* add limit for attachment description

* bot.transformers.reverse.attachment

* plugins/permissions: validate attachments
This commit is contained in:
LTS20050703
2022-09-03 23:35:41 +07:00
committed by GitHub
parent fec9d6e869
commit 3518ed1e18
13 changed files with 42 additions and 295 deletions

3
bot.ts
View File

@@ -158,6 +158,7 @@ import {
transformApplicationCommandOptionChoiceToDiscordApplicationCommandOptionChoice,
transformApplicationCommandOptionToDiscordApplicationCommandOption,
} from "./mod.ts";
import { transformAttachmentToDiscordAttachment } from "./transformers/reverse/attachment.ts";
export function createBot(options: CreateBotOptions): Bot {
const bot = {
@@ -419,6 +420,7 @@ export interface Transformers {
bot: Bot,
payload: ApplicationCommandOptionChoice,
) => DiscordApplicationCommandOptionChoice;
attachment: (bot: Bot, payload: Attachment) => DiscordAttachment;
};
snowflake: (snowflake: string) => bigint;
gatewayBot: (payload: DiscordGetGatewayBot) => GetGatewayBot;
@@ -483,6 +485,7 @@ export function createTransformers(options: Partial<Transformers>) {
transformApplicationCommandOptionToDiscordApplicationCommandOption,
applicationCommandOptionChoice: options.reverse?.applicationCommandOptionChoice ||
transformApplicationCommandOptionChoiceToDiscordApplicationCommandOptionChoice,
attachment: options.reverse?.attachment || transformAttachmentToDiscordAttachment,
},
automodRule: options.automodRule || transformAutoModerationRule,
automodActionExecution: options.automodActionExecution || transformAutoModerationActionExecution,

View File

@@ -1,7 +1,6 @@
import type { Bot } from "../../../bot.ts";
import { Message } from "../../../transformers/message.ts";
import { DiscordMessage } from "../../../types/discord.ts";
import { MessageComponentTypes } from "../../../types/shared.ts";
import { EditWebhookMessage } from "../../webhooks/editWebhookMessage.ts";
/** To edit your response to a application command. If a messageId is not provided it will default to editing the original response. */
@@ -24,80 +23,10 @@ export async function editInteractionResponse(
embeds: options.embeds?.map((embed) => bot.transformers.reverse.embed(bot, embed)),
file: options.file,
allowed_mentions: options.allowedMentions
? {
parse: options.allowedMentions.parse,
roles: options.allowedMentions.roles?.map((id) => id.toString()),
users: options.allowedMentions.users?.map((id) => id.toString()),
replied_user: options.allowedMentions.repliedUser,
}
? bot.transformers.reverse.allowedMentions(bot, options.allowedMentions)
: undefined,
attachments: options.attachments?.map((attachment) => ({
id: attachment.id.toString(),
filename: attachment.filename,
content_type: attachment.contentType,
size: attachment.size,
url: attachment.url,
proxy_url: attachment.proxyUrl,
height: attachment.height,
width: attachment.width,
ephemeral: attachment.ephemeral,
})),
components: options.components?.map((component) => ({
type: component.type,
components: component.components.map((subComponent) => {
if (subComponent.type === MessageComponentTypes.InputText) {
return {
type: subComponent.type,
style: subComponent.style,
custom_id: subComponent.customId,
label: subComponent.label,
placeholder: subComponent.placeholder,
min_length: subComponent.minLength ?? subComponent.required === false ? 0 : subComponent.minLength,
max_length: subComponent.maxLength,
};
}
if (subComponent.type === MessageComponentTypes.SelectMenu) {
return {
type: subComponent.type,
custom_id: subComponent.customId,
placeholder: subComponent.placeholder,
min_values: subComponent.minValues,
max_values: subComponent.maxValues,
disabled: "disabled" in subComponent ? subComponent.disabled : undefined,
options: subComponent.options.map((option) => ({
label: option.label,
value: option.value,
description: option.description,
emoji: option.emoji
? {
id: option.emoji.id?.toString(),
name: option.emoji.name,
animated: option.emoji.animated,
}
: undefined,
default: option.default,
})),
};
}
return {
type: subComponent.type,
custom_id: subComponent.customId,
label: subComponent.label,
style: subComponent.style,
emoji: "emoji" in subComponent && subComponent.emoji
? {
id: subComponent.emoji.id?.toString(),
name: subComponent.emoji.name,
animated: subComponent.emoji.animated,
}
: undefined,
url: "url" in subComponent ? subComponent.url : undefined,
disabled: "disabled" in subComponent ? subComponent.disabled : undefined,
};
}),
})),
attachments: options.attachments?.map((attachment) => bot.transformers.reverse.attachment(bot, attachment)),
components: options.components?.map((component) => bot.transformers.reverse.component(bot, component)),
message_id: options.messageId?.toString(),
},
);

View File

@@ -1,7 +1,6 @@
import { Bot } from "../../../bot.ts";
import { Message } from "../../../transformers/message.ts";
import { DiscordMessage } from "../../../types/discord.ts";
import { MessageComponentTypes } from "../../../types/shared.ts";
import { EditWebhookMessage } from "../../webhooks/editWebhookMessage.ts";
/** Edits a followup message for an Interaction. Functions the same as edit webhook message, however this uses your interaction token instead of bot token. Does not support ephemeral followups. */
@@ -20,80 +19,10 @@ export async function editFollowupMessage(
embeds: options.embeds?.map((embed) => bot.transformers.reverse.embed(bot, embed)),
file: options.file,
allowed_mentions: options.allowedMentions
? {
parse: options.allowedMentions.parse,
roles: options.allowedMentions.roles?.map((id) => id.toString()),
users: options.allowedMentions.users?.map((id) => id.toString()),
replied_user: options.allowedMentions.repliedUser,
}
? bot.transformers.reverse.allowedMentions(bot, options.allowedMentions)
: undefined,
attachments: options.attachments?.map((attachment) => ({
id: attachment.id.toString(),
filename: attachment.filename,
content_type: attachment.contentType,
size: attachment.size,
url: attachment.url,
proxy_url: attachment.proxyUrl,
height: attachment.height,
width: attachment.width,
ephemeral: attachment.ephemeral,
})),
components: options.components?.map((component) => ({
type: component.type,
components: component.components.map((subComponent) => {
if (subComponent.type === MessageComponentTypes.InputText) {
return {
type: subComponent.type,
style: subComponent.style,
custom_id: subComponent.customId,
label: subComponent.label,
placeholder: subComponent.placeholder,
min_length: subComponent.minLength ?? subComponent.required === false ? 0 : subComponent.minLength,
max_length: subComponent.maxLength,
};
}
if (subComponent.type === MessageComponentTypes.SelectMenu) {
return {
type: subComponent.type,
custom_id: subComponent.customId,
placeholder: subComponent.placeholder,
min_values: subComponent.minValues,
max_values: subComponent.maxValues,
disabled: "disabled" in subComponent ? subComponent.disabled : undefined,
options: subComponent.options.map((option) => ({
label: option.label,
value: option.value,
description: option.description,
emoji: option.emoji
? {
id: option.emoji.id?.toString(),
name: option.emoji.name,
animated: option.emoji.animated,
}
: undefined,
default: option.default,
})),
};
}
return {
type: subComponent.type,
custom_id: subComponent.customId,
label: subComponent.label,
style: subComponent.style,
emoji: subComponent.emoji
? {
id: subComponent.emoji.id?.toString(),
name: subComponent.emoji.name,
animated: subComponent.emoji.animated,
}
: undefined,
url: subComponent.url,
disabled: subComponent.disabled,
};
}),
})),
attachments: options.attachments?.map((attachment) => bot.transformers.reverse.attachment(bot, attachment)),
components: options.components?.map((component) => bot.transformers.reverse.component(bot, component)),
message_id: messageId?.toString(),
},
);

View File

@@ -4,7 +4,6 @@ import { Embed } from "../../transformers/embed.ts";
import { Message } from "../../transformers/message.ts";
import { DiscordMessage } from "../../types/discord.ts";
import { AllowedMentions, FileContent, MessageComponents } from "../../types/discordeno.ts";
import { MessageComponentTypes } from "../../types/shared.ts";
/** Edit the message. */
export async function editMessage(
@@ -20,79 +19,12 @@ export async function editMessage(
{
content: content.content,
embeds: content.embeds?.map((embed) => bot.transformers.reverse.embed(bot, embed)),
allowed_mentions: {
parse: content.allowedMentions?.parse,
roles: content.allowedMentions?.roles?.map((id) => id.toString()),
users: content.allowedMentions?.users?.map((id) => id.toString()),
replied_user: content.allowedMentions?.repliedUser,
},
attachments: content.attachments?.map((attachment) => ({
id: attachment.id.toString(),
filename: attachment.filename,
content_type: attachment.contentType,
size: attachment.size,
url: attachment.url,
proxy_url: attachment.proxyUrl,
height: attachment.height,
width: attachment.width,
})),
allowed_mentions: content.allowedMentions
? bot.transformers.reverse.allowedMentions(bot, content.allowedMentions)
: undefined,
attachments: content.attachments?.map((attachment) => bot.transformers.reverse.attachment(bot, attachment)),
file: content.file,
components: content.components?.map((component) => ({
type: component.type,
components: component.components.map((subComponent) => {
if (subComponent.type === MessageComponentTypes.InputText) {
return {
type: subComponent.type,
style: subComponent.style,
custom_id: subComponent.customId,
label: subComponent.label,
placeholder: subComponent.placeholder,
min_length: subComponent.minLength ?? subComponent.required === false ? 0 : subComponent.minLength,
max_length: subComponent.maxLength,
};
}
if (subComponent.type === MessageComponentTypes.SelectMenu) {
return {
type: subComponent.type,
custom_id: subComponent.customId,
placeholder: subComponent.placeholder,
min_values: subComponent.minValues,
max_values: subComponent.maxValues,
disabled: "disabled" in subComponent ? subComponent.disabled : undefined,
options: subComponent.options.map((option) => ({
label: option.label,
value: option.value,
description: option.description,
emoji: option.emoji
? {
id: option.emoji.id?.toString(),
name: option.emoji.name,
animated: option.emoji.animated,
}
: undefined,
default: option.default,
})),
};
}
return {
type: subComponent.type,
custom_id: subComponent.customId,
label: subComponent.label,
style: subComponent.style,
emoji: "emoji" in subComponent && subComponent.emoji
? {
id: subComponent.emoji.id?.toString(),
name: subComponent.emoji.name,
animated: subComponent.emoji.animated,
}
: undefined,
url: "url" in subComponent ? subComponent.url : undefined,
disabled: "disabled" in subComponent ? subComponent.disabled : undefined,
};
}),
})),
components: content.components?.map((component) => bot.transformers.reverse.component(bot, component)),
},
);

View File

@@ -4,7 +4,6 @@ import { Embed } from "../../transformers/embed.ts";
import { Message } from "../../transformers/message.ts";
import { DiscordMessage } from "../../types/discord.ts";
import { AllowedMentions, FileContent, MessageComponents } from "../../types/discordeno.ts";
import { MessageComponentTypes } from "../../types/shared.ts";
export async function editWebhookMessage(
bot: Bot,
@@ -23,80 +22,10 @@ export async function editWebhookMessage(
embeds: options.embeds?.map((embed) => bot.transformers.reverse.embed(bot, embed)),
file: options.file,
allowed_mentions: options.allowedMentions
? {
parse: options.allowedMentions.parse,
roles: options.allowedMentions.roles?.map((id) => id.toString()),
users: options.allowedMentions.users?.map((id) => id.toString()),
replied_user: options.allowedMentions.repliedUser,
}
? bot.transformers.reverse.allowedMentions(bot, options.allowedMentions)
: undefined,
attachments: options.attachments?.map((attachment) => ({
id: attachment.id.toString(),
filename: attachment.filename,
content_type: attachment.contentType,
size: attachment.size,
url: attachment.url,
proxy_url: attachment.proxyUrl,
height: attachment.height,
width: attachment.width,
ephemeral: attachment.ephemeral,
})),
components: options.components?.map((component) => ({
type: component.type,
components: component.components.map((subComponent) => {
if (subComponent.type === MessageComponentTypes.InputText) {
return {
type: subComponent.type,
style: subComponent.style,
custom_id: subComponent.customId,
label: subComponent.label,
placeholder: subComponent.placeholder,
min_length: subComponent.minLength ?? subComponent.required === false ? 0 : subComponent.minLength,
max_length: subComponent.maxLength,
};
}
if (subComponent.type === MessageComponentTypes.SelectMenu) {
return {
type: subComponent.type,
custom_id: subComponent.customId,
placeholder: subComponent.placeholder,
min_values: subComponent.minValues,
max_values: subComponent.maxValues,
disabled: "disabled" in subComponent ? subComponent.disabled : undefined,
options: subComponent.options.map((option) => ({
label: option.label,
value: option.value,
description: option.description,
emoji: option.emoji
? {
id: option.emoji.id?.toString(),
name: option.emoji.name,
animated: option.emoji.animated,
}
: undefined,
default: option.default,
})),
};
}
return {
type: subComponent.type,
custom_id: subComponent.customId,
label: subComponent.label,
style: subComponent.style,
emoji: "emoji" in subComponent && subComponent.emoji
? {
id: subComponent.emoji.id?.toString(),
name: subComponent.emoji.name,
animated: subComponent.emoji.animated,
}
: undefined,
url: "url" in subComponent ? subComponent.url : undefined,
disabled: "disabled" in subComponent ? subComponent.disabled : undefined,
};
}),
})),
attachments: options.attachments?.map((attachment) => bot.transformers.reverse.attachment(bot, attachment)),
components: options.components?.map((component) => bot.transformers.reverse.component(bot, component)),
message_id: options.messageId?.toString(),
},
);

View File

@@ -0,0 +1,9 @@
import { Attachment, Bot } from "../deps.ts";
export function validateAttachments(bot: Bot, attachments: Attachment[]) {
attachments.forEach((attachment) => {
if (attachment.description && !bot.utils.validateLength(attachment.description, { min: 0, max: 1024 })) {
throw new Error("Attachment description length must be less than 1024 characters");
}
});
}

View File

@@ -7,6 +7,7 @@ import {
CONTEXT_MENU_COMMANDS_NAME_REGEX,
SLASH_COMMANDS_NAME_REGEX,
} from "../../deps.ts";
import { validateAttachments } from "../attachments.ts";
export function validateApplicationCommandOptions(
bot: BotWithCache,
@@ -176,6 +177,8 @@ export function editInteractionResponse(bot: BotWithCache) {
}
}
if (options.attachments) validateAttachments(bot, options.attachments);
return await editInteractionResponseOld(token, options);
};
}

View File

@@ -1,4 +1,5 @@
import { AllowedMentionsTypes, BotWithCache } from "../../deps.ts";
import { validateAttachments } from "../attachments.ts";
export default function editFollowupMessage(bot: BotWithCache) {
const editFollowupMessageOld = bot.helpers.editFollowupMessage;
@@ -56,6 +57,8 @@ export default function editFollowupMessage(bot: BotWithCache) {
}
}
if (options.attachments) validateAttachments(bot, options.attachments);
return await editFollowupMessageOld(token, messageId, options);
};
}

View File

@@ -1,4 +1,5 @@
import { AllowedMentionsTypes, BotWithCache, ChannelTypes, PermissionStrings } from "../../deps.ts";
import { validateAttachments } from "../attachments.ts";
import { validateComponents } from "../components.ts";
import { requireBotChannelPermissions } from "../permissions.ts";
@@ -165,6 +166,8 @@ export function editMessage(bot: BotWithCache) {
);
}
if (content.attachments) validateAttachments(bot, content.attachments);
return editMessageOld(channelId, messageId, content);
};
}

View File

@@ -1,4 +1,5 @@
import { AllowedMentionsTypes, BotWithCache } from "../../deps.ts";
import { validateAttachments } from "../attachments.ts";
import { validateComponents } from "../components.ts";
export function editWebhookMessage(bot: BotWithCache) {
@@ -62,6 +63,8 @@ export function editWebhookMessage(bot: BotWithCache) {
if (options.components) validateComponents(bot, options.components);
if (options.attachments) validateAttachments(bot, options.attachments);
return await editWebhookMessageOld(webhookId, webhookToken, options);
};
}

View File

@@ -13,6 +13,7 @@ export function transformAttachment(bot: Bot, payload: DiscordAttachment) {
height: payload.height ?? undefined,
width: payload.width ?? undefined,
ephemeral: payload.ephemeral,
description: payload.description,
};
return attachment as Optionalize<typeof attachment>;

View File

@@ -13,5 +13,6 @@ export function transformAttachmentToDiscordAttachment(bot: Bot, payload: Attach
height: payload.height,
width: payload.width,
ephemeral: payload.ephemeral,
description: payload.description,
};
}

View File

@@ -436,6 +436,8 @@ export interface DiscordAttachment {
/** Attachment id */
id: string;
/** description for the file (max 1024 characters) */
description?: string;
/** Height of file (if image) */
height?: number | null;
/** Width of file (if image) */