mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 21:45:31 +09:00
chore(license): relicense artwork and move non-free media out (#3173)
This commit is contained in:
1 parent
71b7cffabc
commit
e7347b582c
145 files changed
+806
-3424
No files matched your search
Binary file not shown.
|
Before Width: | Height: | Size: 2.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 9.4 KiB |
@@ -76,7 +76,7 @@ describe('Attachment Decay', () => {
|
||||
const channel = await createChannel(harness, account.token, guild.id, 'test-channel');
|
||||
const channelId = guild.system_channel_id ?? channel.id;
|
||||
const file1Data = loadFixture('yeah.png');
|
||||
const file2Data = loadFixture('thisisfine.gif');
|
||||
const file2Data = loadFixture('animated.gif');
|
||||
const {response, json} = await sendMessageWithAttachments(
|
||||
harness,
|
||||
account.token,
|
||||
@@ -258,7 +258,7 @@ describe('Attachment Decay', () => {
|
||||
const channel = await createChannel(harness, account.token, guild.id, 'test-channel');
|
||||
const channelId = guild.system_channel_id ?? channel.id;
|
||||
const smallFile = loadFixture('yeah.png');
|
||||
const largeFile = loadFixture('thisisfine.gif');
|
||||
const largeFile = loadFixture('animated.gif');
|
||||
const smallResult = await sendMessageWithAttachments(
|
||||
harness,
|
||||
account.token,
|
||||
|
||||
@@ -327,17 +327,17 @@ describe('Attachment Upload Validation', () => {
|
||||
const channel = await createChannel(harness, account.token, guild.id, 'test-channel');
|
||||
const channelId = guild.system_channel_id ?? channel.id;
|
||||
const file1Data = loadFixture('yeah.png');
|
||||
const file2Data = loadFixture('thisisfine.gif');
|
||||
const file2Data = loadFixture('animated.gif');
|
||||
const payload = {
|
||||
content: 'Ordered files test',
|
||||
attachments: [
|
||||
{id: 0, filename: 'yeah.png', description: 'First file', title: 'First'},
|
||||
{id: 1, filename: 'thisisfine.gif', description: 'Second file', title: 'Second'},
|
||||
{id: 1, filename: 'animated.gif', description: 'Second file', title: 'Second'},
|
||||
],
|
||||
};
|
||||
const {response, json} = await sendMessageWithAttachments(harness, account.token, channelId, payload, [
|
||||
{index: 0, filename: 'yeah.png', data: file1Data},
|
||||
{index: 1, filename: 'thisisfine.gif', data: file2Data},
|
||||
{index: 1, filename: 'animated.gif', data: file2Data},
|
||||
]);
|
||||
expect(response.status).toBe(200);
|
||||
expect(json.attachments).toBeDefined();
|
||||
@@ -346,7 +346,7 @@ describe('Attachment Upload Validation', () => {
|
||||
expect(json.attachments![0].filename).toBe('yeah.png');
|
||||
expect(json.attachments![0].description).toBe('First file');
|
||||
expect(json.attachments![0].title).toBe('First');
|
||||
expect(json.attachments![1].filename).toBe('thisisfine.gif');
|
||||
expect(json.attachments![1].filename).toBe('animated.gif');
|
||||
expect(json.attachments![1].description).toBe('Second file');
|
||||
expect(json.attachments![1].title).toBe('Second');
|
||||
});
|
||||
@@ -356,17 +356,17 @@ describe('Attachment Upload Validation', () => {
|
||||
const channel = await createChannel(harness, account.token, guild.id, 'test-channel');
|
||||
const channelId = guild.system_channel_id ?? channel.id;
|
||||
const file1Data = loadFixture('yeah.png');
|
||||
const file2Data = loadFixture('thisisfine.gif');
|
||||
const file2Data = loadFixture('animated.gif');
|
||||
const payload = {
|
||||
content: 'Sparse IDs test',
|
||||
attachments: [
|
||||
{id: 2, filename: 'yeah.png', description: 'ID is 2', title: 'Two'},
|
||||
{id: 5, filename: 'thisisfine.gif', description: 'ID is 5', title: 'Five'},
|
||||
{id: 5, filename: 'animated.gif', description: 'ID is 5', title: 'Five'},
|
||||
],
|
||||
};
|
||||
const {response, json} = await sendMessageWithAttachments(harness, account.token, channelId, payload, [
|
||||
{index: 2, filename: 'yeah.png', data: file1Data},
|
||||
{index: 5, filename: 'thisisfine.gif', data: file2Data},
|
||||
{index: 5, filename: 'animated.gif', data: file2Data},
|
||||
]);
|
||||
expect(response.status).toBe(200);
|
||||
expect(json.attachments).toBeDefined();
|
||||
@@ -472,7 +472,7 @@ describe('Attachment Upload Validation', () => {
|
||||
const channel = await createChannel(harness, account.token, guild.id, 'test-channel');
|
||||
const channelId = guild.system_channel_id ?? channel.id;
|
||||
const file1Data = loadFixture('yeah.png');
|
||||
const file2Data = loadFixture('thisisfine.gif');
|
||||
const file2Data = loadFixture('animated.gif');
|
||||
const payload = {
|
||||
content: 'Mixed metadata test',
|
||||
attachments: [
|
||||
@@ -485,13 +485,13 @@ describe('Attachment Upload Validation', () => {
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
filename: 'thisisfine.gif',
|
||||
filename: 'animated.gif',
|
||||
},
|
||||
],
|
||||
};
|
||||
const {response, json} = await sendMessageWithAttachments(harness, account.token, channelId, payload, [
|
||||
{index: 0, filename: 'yeah.png', data: file1Data},
|
||||
{index: 1, filename: 'thisisfine.gif', data: file2Data},
|
||||
{index: 1, filename: 'animated.gif', data: file2Data},
|
||||
]);
|
||||
expect(response.status).toBe(200);
|
||||
expect(json.attachments).toBeDefined();
|
||||
|
||||
@@ -76,7 +76,7 @@ export async function sendWithImage(
|
||||
filenames.map((filename, index) => ({
|
||||
index,
|
||||
filename,
|
||||
data: loadFixture(filename.endsWith('.gif') ? 'thisisfine.gif' : 'yeah.png'),
|
||||
data: loadFixture(filename.endsWith('.gif') ? 'animated.gif' : 'yeah.png'),
|
||||
})),
|
||||
);
|
||||
if (response.status !== 200) {
|
||||
|
||||
@@ -86,25 +86,25 @@ describe('Embed Attachment URL Resolution', () => {
|
||||
const channel = await createChannel(harness, account.token, guild.id, 'test-channel');
|
||||
const channelId = guild.system_channel_id ?? channel.id;
|
||||
const file1Data = loadFixture('yeah.png');
|
||||
const file2Data = loadFixture('thisisfine.gif');
|
||||
const file2Data = loadFixture('animated.gif');
|
||||
const payload = {
|
||||
content: 'Both image and thumbnail',
|
||||
attachments: [
|
||||
{id: 0, filename: 'yeah.png'},
|
||||
{id: 1, filename: 'thisisfine.gif'},
|
||||
{id: 1, filename: 'animated.gif'},
|
||||
],
|
||||
embeds: [
|
||||
{
|
||||
title: 'Complete Embed',
|
||||
description: 'This embed uses both image and thumbnail',
|
||||
image: {url: 'attachment://thisisfine.gif'},
|
||||
image: {url: 'attachment://animated.gif'},
|
||||
thumbnail: {url: 'attachment://yeah.png'},
|
||||
},
|
||||
],
|
||||
};
|
||||
const {response, json} = await sendMessageWithAttachments(harness, account.token, channelId, payload, [
|
||||
{index: 0, filename: 'yeah.png', data: file1Data},
|
||||
{index: 1, filename: 'thisisfine.gif', data: file2Data},
|
||||
{index: 1, filename: 'animated.gif', data: file2Data},
|
||||
]);
|
||||
expect(response.status).toBe(200);
|
||||
expect(json.embeds).toBeDefined();
|
||||
@@ -576,12 +576,12 @@ describe('Embed Attachment URL Resolution', () => {
|
||||
const channel = await createChannel(harness, account.token, guild.id, 'test-channel');
|
||||
const channelId = guild.system_channel_id ?? channel.id;
|
||||
const file1Data = loadFixture('yeah.png');
|
||||
const file2Data = loadFixture('thisisfine.gif');
|
||||
const file2Data = loadFixture('animated.gif');
|
||||
const payload = {
|
||||
content: 'Multiple embeds with different attachments',
|
||||
attachments: [
|
||||
{id: 0, filename: 'yeah.png'},
|
||||
{id: 1, filename: 'thisisfine.gif'},
|
||||
{id: 1, filename: 'animated.gif'},
|
||||
],
|
||||
embeds: [
|
||||
{
|
||||
@@ -592,19 +592,19 @@ describe('Embed Attachment URL Resolution', () => {
|
||||
{
|
||||
title: 'Second Embed',
|
||||
description: 'Uses GIF',
|
||||
image: {url: 'attachment://thisisfine.gif'},
|
||||
image: {url: 'attachment://animated.gif'},
|
||||
},
|
||||
],
|
||||
};
|
||||
const {response, json} = await sendMessageWithAttachments(harness, account.token, channelId, payload, [
|
||||
{index: 0, filename: 'yeah.png', data: file1Data},
|
||||
{index: 1, filename: 'thisisfine.gif', data: file2Data},
|
||||
{index: 1, filename: 'animated.gif', data: file2Data},
|
||||
]);
|
||||
expect(response.status).toBe(200);
|
||||
expect(json.embeds).toBeDefined();
|
||||
expect(json.embeds).toHaveLength(2);
|
||||
expect(json.embeds![0].image?.url).toContain('yeah.png');
|
||||
expect(json.embeds![1].image?.url).toContain('thisisfine.gif');
|
||||
expect(json.embeds![1].image?.url).toContain('animated.gif');
|
||||
});
|
||||
it('should resolve multiple files referenced by embeds', async () => {
|
||||
const account = await createTestAccount(harness);
|
||||
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
-3154
File diff suppressed because it is too large.
Load diff
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 48 KiB |
@@ -113,13 +113,13 @@ describe('Favorite Meme Limits', () => {
|
||||
attachment_id: message1.attachments[0].id,
|
||||
name: 'PNG Meme',
|
||||
});
|
||||
const message2 = await createMessageWithImageAttachment(harness, account.token, channel.id, 'thisisfine.gif');
|
||||
const message2 = await createMessageWithImageAttachment(harness, account.token, channel.id, 'animated.gif');
|
||||
const meme2 = await createFavoriteMemeFromMessage(harness, account.token, channel.id, message2.id, {
|
||||
attachment_id: message2.attachments[0].id,
|
||||
name: 'GIF Meme',
|
||||
});
|
||||
expect(meme2.id).toBeTruthy();
|
||||
expect(meme2.filename).toBe('thisisfine.gif');
|
||||
expect(meme2.filename).toBe('animated.gif');
|
||||
});
|
||||
test('should return error for invalid attachment id', async () => {
|
||||
const account = await createTestAccountForAttachmentTests(harness);
|
||||
|
||||
@@ -244,7 +244,7 @@ describe('Favorite Meme Operations', () => {
|
||||
attachment_id: message1.attachments[0].id,
|
||||
name: 'First Meme',
|
||||
});
|
||||
const message2 = await createMessageWithImageAttachment(harness, account.token, channel.id, 'thisisfine.gif');
|
||||
const message2 = await createMessageWithImageAttachment(harness, account.token, channel.id, 'animated.gif');
|
||||
await createFavoriteMemeFromMessage(harness, account.token, channel.id, message2.id, {
|
||||
attachment_id: message2.attachments[0].id,
|
||||
name: 'Second Meme',
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import fs from 'node:fs/promises';
|
||||
import {stripOwnAttachmentSignature} from '@app/api/attachment/AttachmentUrls';
|
||||
import type {ChannelID, GuildID, MessageID, UserID, WebhookID, WebhookToken} from '@app/api/BrandedTypes';
|
||||
import {createChannelID, createGuildID, createWebhookID, createWebhookToken} from '@app/api/BrandedTypes';
|
||||
import {Config} from '@app/api/Config';
|
||||
import type {IChannelRepository} from '@app/api/channel/IChannelRepository';
|
||||
import type {MessageRequest, MessageUpdateRequest} from '@app/api/channel/MessageTypes';
|
||||
import {withChannelFollowLock} from '@app/api/channel/services/ChannelFollowers';
|
||||
@@ -29,7 +29,6 @@ import type {RequestCache} from '@app/api/middleware/RequestCacheMiddleware';
|
||||
import type {Channel} from '@app/api/models/Channel';
|
||||
import type {Message} from '@app/api/models/Message';
|
||||
import type {Webhook} from '@app/api/models/Webhook';
|
||||
import {resolveAssetPath} from '@app/api/utils/AssetPaths';
|
||||
import * as RandomUtils from '@app/api/utils/RandomUtils';
|
||||
import type {IWebhookRepository} from '@app/api/webhook/IWebhookRepository';
|
||||
import {transform as GitHubTransform} from '@app/api/webhook/transformers/GitHubTransformer';
|
||||
@@ -117,6 +116,10 @@ interface WebhookExecuteInstatusParams extends WebhookTokenParams {
|
||||
}
|
||||
|
||||
const WEBHOOK_AVATAR_MISSING_CACHE_VALUE = '__fluxer_webhook_avatar_missing__';
|
||||
const HOSTED_WEBHOOK_AVATAR_URLS = {
|
||||
github: 'https://fluxer.app/static/img/app-webhook-github.2d0319169a3aee33.webp',
|
||||
instatus: 'https://fluxer.app/static/img/app-webhook-instatus.22ad5aee16da872c.webp',
|
||||
} as const;
|
||||
|
||||
export class WebhookService {
|
||||
private static readonly NO_ALLOWED_MENTIONS: AllowedMentionsRequest = {parse: []};
|
||||
@@ -744,32 +747,22 @@ export class WebhookService {
|
||||
}
|
||||
|
||||
private async getGitHubWebhookAvatar(webhookId: WebhookID): Promise<string | null> {
|
||||
return this.getStaticWebhookAvatar({webhookId, provider: 'github'});
|
||||
return this.getHostedWebhookAvatar({webhookId, provider: 'github'});
|
||||
}
|
||||
|
||||
private async getInstatusWebhookAvatar(webhookId: WebhookID): Promise<string | null> {
|
||||
return this.getStaticWebhookAvatar({webhookId, provider: 'instatus'});
|
||||
return this.getHostedWebhookAvatar({webhookId, provider: 'instatus'});
|
||||
}
|
||||
|
||||
private async getStaticWebhookAvatar({
|
||||
private async getHostedWebhookAvatar({
|
||||
webhookId,
|
||||
provider,
|
||||
}: {
|
||||
webhookId: WebhookID;
|
||||
provider: 'github' | 'instatus';
|
||||
provider: keyof typeof HOSTED_WEBHOOK_AVATAR_URLS;
|
||||
}): Promise<string | null> {
|
||||
const cacheKey = `webhook:${webhookId}:avatar:${provider}`;
|
||||
const avatarCache = await this.cacheService.get<string | null>(cacheKey);
|
||||
if (avatarCache) return avatarCache;
|
||||
const avatarFile = await fs.readFile(resolveAssetPath('assets', `${provider}.webp`));
|
||||
const avatar = await this.avatarService.uploadAvatar({
|
||||
prefix: 'avatars',
|
||||
entityId: webhookId,
|
||||
errorPath: 'avatar',
|
||||
base64Image: avatarFile.toString('base64'),
|
||||
});
|
||||
await this.cacheService.set(cacheKey, avatar, seconds('1 day'));
|
||||
return avatar;
|
||||
if (Config.instance.selfHosted) return null;
|
||||
return this.getWebhookAvatar({webhookId, avatarUrl: HOSTED_WEBHOOK_AVATAR_URLS[provider]});
|
||||
}
|
||||
|
||||
private getWebhookMetadata(webhook: Webhook): Record<string, string> | undefined {
|
||||
|
||||
@@ -35,7 +35,7 @@ describe('Webhook emoji bypass', () => {
|
||||
user.token,
|
||||
guildId,
|
||||
'animated',
|
||||
'thisisfine.gif',
|
||||
'animated.gif',
|
||||
'image/gif',
|
||||
);
|
||||
const webhook = await createWebhook(harness, channelId, user.token, 'Emoji Test Webhook');
|
||||
|
||||
Reference in new issue
Block a user