fix(embed): Allow attachment protocols for thumbnails and images (#10795)

fix(embed): allow attachment protocols for thumbnails and images

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
Jiralite
2025-03-07 20:19:14 +00:00
committed by GitHub
parent c78407e751
commit 12638cd43c
2 changed files with 23 additions and 11 deletions

View File

@@ -207,6 +207,12 @@ describe('Embed', () => {
expect(embed.toJSON()).toStrictEqual({ ...base, thumbnail: { url: 'https://discord.js.org/static/logo.svg' } });
});
test('GIVEN an embed using Embed#setThumbnail with attachment protocol THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder();
embed.setThumbnail('attachment://discordjs.webp');
expect(embed.toJSON()).toStrictEqual({ ...base, thumbnail: { url: 'attachment://discordjs.webp' } });
});
test('GIVEN an embed with a pre-defined thumbnail THEN unset thumbnail THEN return valid toJSON data', () => {
const embed = new EmbedBuilder({ thumbnail: { url: 'https://discord.js.org/static/logo.svg' }, ...dummy });
embed.clearThumbnail();
@@ -228,6 +234,12 @@ describe('Embed', () => {
expect(embed.toJSON()).toStrictEqual({ ...base, image: { url: 'https://discord.js.org/static/logo.svg' } });
});
test('GIVEN an embed using Embed#setImage with attachment protocol THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder();
embed.setImage('attachment://discordjs.webp');
expect(embed.toJSON()).toStrictEqual({ ...base, image: { url: 'attachment://discordjs.webp' } });
});
test('GIVEN an embed using Embed#setImage THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder();
embed.setImage('https://discord.js.org/static/logo.svg');

View File

@@ -4,18 +4,18 @@ import { embedLength } from '../../util/componentUtil.js';
const namePredicate = z.string().max(256);
const iconURLPredicate = z
.string()
.url()
.refine(refineURLPredicate(['http:', 'https:', 'attachment:']), {
message: 'Invalid protocol for icon URL. Must be http:, https:, or attachment:',
});
const URLPredicate = z
.string()
.url()
.refine(refineURLPredicate(['http:', 'https:']), { message: 'Invalid protocol for URL. Must be http: or https:' });
const URLWithAttachmentProtocolPredicate = z
.string()
.url()
.refine(refineURLPredicate(['http:', 'https:', 'attachment:']), {
message: 'Invalid protocol for URL. Must be http:, https:, or attachment:',
});
export const embedFieldPredicate = z.object({
name: namePredicate,
value: z.string().max(1_024),
@@ -24,13 +24,13 @@ export const embedFieldPredicate = z.object({
export const embedAuthorPredicate = z.object({
name: namePredicate.min(1),
icon_url: iconURLPredicate.optional(),
icon_url: URLWithAttachmentProtocolPredicate.optional(),
url: URLPredicate.optional(),
});
export const embedFooterPredicate = z.object({
text: z.string().min(1).max(2_048),
icon_url: iconURLPredicate.optional(),
icon_url: URLWithAttachmentProtocolPredicate.optional(),
});
export const embedPredicate = z
@@ -41,8 +41,8 @@ export const embedPredicate = z
timestamp: z.string().optional(),
color: z.number().int().min(0).max(0xffffff).optional(),
footer: embedFooterPredicate.optional(),
image: z.object({ url: URLPredicate }).optional(),
thumbnail: z.object({ url: URLPredicate }).optional(),
image: z.object({ url: URLWithAttachmentProtocolPredicate }).optional(),
thumbnail: z.object({ url: URLWithAttachmentProtocolPredicate }).optional(),
author: embedAuthorPredicate.optional(),
fields: z.array(embedFieldPredicate).max(25).optional(),
})