fix(desktop): fetch media bytes via the local resource proxy (#3263)

This commit is contained in:
Hampus authored and GitHub committed 2026-10-08 03:02:15 +02:00
1 parent 8b312c610e
commit 6a24ac3f4e
4 files changed
+66 -4

No files matched your search

@@ -0,0 +1,59 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest';
const runtime = vi.hoisted(() => ({desktop: false}));
vi.mock('@lingui/core/macro', () => ({msg: (descriptor: unknown) => descriptor}));
vi.mock('@app/features/platform/DesktopLocalAppRuntime', async (importOriginal) => ({
...(await importOriginal<typeof import('@app/features/platform/DesktopLocalAppRuntime')>()),
isDesktopLocalAppDocument: () => runtime.desktop,
}));
vi.mock('@app/features/app/state/RuntimeConfig', () => ({
default: {
mediaEndpoint: 'https://fluxerusercontent.com',
staticCdnEndpoint: 'https://fluxerstatic.com',
uploadRelayEndpoint: null,
getSnapshot: () => ({apiEndpoint: 'https://api.fluxer.app'}),
},
}));
vi.mock('@app/features/app/state/InstanceSnapshotStore', () => ({runtimeInstanceKey: () => 'instance-key'}));
vi.mock('@app/features/messaging/state/AttachmentUrlRefresher', () => ({
default: {refresh: async (url: string) => url},
}));
const {fetchTextualPreviewText} = await import(
'@app/features/channel/components/embeds/attachments/TextualAttachmentPreviewFetch'
);
const ATTACHMENT_URL = 'https://fluxerusercontent.com/attachments/1/2/message.txt?ex=1&is=2&hm=3';
describe('fetchTextualPreviewText', () => {
const fetchMock = vi.fn(async (_input: RequestInfo | URL, _init?: RequestInit) => new Response('hello'));
beforeEach(() => {
vi.stubGlobal('fetch', fetchMock);
vi.stubGlobal('window', {location: {href: 'fluxer-app://app/channels/@me'}});
});
afterEach(() => {
vi.unstubAllGlobals();
fetchMock.mockClear();
runtime.desktop = false;
});
it('routes media fetches through the desktop resource proxy', async () => {
runtime.desktop = true;
await expect(fetchTextualPreviewText(ATTACHMENT_URL, new AbortController().signal)).resolves.toBe('hello');
const requested = new URL(String(fetchMock.mock.calls[0]?.[0]));
expect(requested.protocol).toBe('fluxer-app:');
expect(requested.pathname).toBe('/proxy/instance-key');
expect(requested.searchParams.get('url')).toBe(ATTACHMENT_URL);
});
it('fetches media directly on the web', async () => {
await expect(fetchTextualPreviewText(ATTACHMENT_URL, new AbortController().signal)).resolves.toBe('hello');
expect(fetchMock.mock.calls[0]?.[0]).toBe(ATTACHMENT_URL);
});
});
@@ -2,6 +2,7 @@
import AttachmentUrlRefresher from '@app/features/messaging/state/AttachmentUrlRefresher';
import {TEXT_PREVIEW_MAX_BYTES} from '@app/features/messaging/utils/AttachmentPreviewUtils';
import {wrapDesktopLocalResourceURL} from '@app/features/messaging/utils/DesktopResourceUrl';
const SIGNATURE_REFUSAL_STATUSES = new Set([401, 403, 404, 410]);
@@ -65,7 +66,7 @@ function requestFailed(response: Response): Error {
export async function fetchTextualPreviewText(url: string, signal: AbortSignal): Promise<string> {
const target = await AttachmentUrlRefresher.refresh(url);
const response = await fetch(target, {signal});
const response = await fetch(wrapDesktopLocalResourceURL(target), {signal});
if (response.ok) {
return readPreviewText(response);
}
@@ -76,7 +77,7 @@ export async function fetchTextualPreviewText(url: string, signal: AbortSignal):
if (refreshed === target) {
throw requestFailed(response);
}
const retried = await fetch(refreshed, {signal});
const retried = await fetch(wrapDesktopLocalResourceURL(refreshed), {signal});
if (!retried.ok) {
throw requestFailed(retried);
}
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {Gif} from '@app/features/expressions/commands/GifCommands';
import {wrapDesktopLocalResourceURL} from '@app/features/messaging/utils/DesktopResourceUrl';
const GIF_IMAGE_FORMAT_KEYS = ['gif', 'tinygif', 'nanogif'] as const;
const GIF_VIDEO_FORMAT_KEYS = ['mp4', 'tinymp4'] as const;
@@ -60,7 +61,7 @@ async function downloadFirstAvailableTarget(targets: Array<GifDownloadTarget>, b
seenUrls.add(target.url);
attempts += 1;
try {
const response = await fetch(target.url);
const response = await fetch(wrapDesktopLocalResourceURL(target.url));
if (!response.ok) continue;
const blob = await response.blob();
if (blob.size === 0) continue;
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {wrapDesktopLocalResourceURL} from '@app/features/messaging/utils/DesktopResourceUrl';
import {Logger} from '@app/features/platform/utils/AppLogger';
import StreamerMode from '@app/features/streamer_mode/state/StreamerMode';
import Sound from '@app/features/ui/state/Sound';
@@ -66,7 +67,7 @@ class EntranceSoundPlaybackEngine {
const ctx = this.ensureContext();
if (!ctx) return null;
try {
const response = await fetch(url, {cache: 'force-cache'});
const response = await fetch(wrapDesktopLocalResourceURL(url), {cache: 'force-cache'});
if (!response.ok) {
logger.warn('Entrance sound fetch failed', {url, status: response.status});
return null;