mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-10-22 08:25:21 +08:00
fix(web): omit referrer when loading message images
Set no-referrer on message thumbnails and previews to prevent QQ image requests from returning 400 and triggering ORB. Add browser coverage for image loading and request headers.
This commit is contained in:
@@ -87,6 +87,7 @@ export function MessageContentRenderer({
|
||||
<span key={index} className="inline-block align-middle mx-1">
|
||||
<img
|
||||
src={imageUrl}
|
||||
referrerPolicy="no-referrer"
|
||||
alt="Message attachment"
|
||||
className="w-20 h-20 object-cover rounded cursor-pointer hover:opacity-80 transition-opacity border"
|
||||
onClick={(e) => {
|
||||
|
||||
@@ -35,6 +35,7 @@ export default function ImagePreviewDialog({
|
||||
{/* 图片 */}
|
||||
<img
|
||||
src={imageUrl}
|
||||
referrerPolicy="no-referrer"
|
||||
alt="Preview"
|
||||
className="max-w-[50vw] max-h-[50vh] object-contain rounded-lg shadow-2xl bg-white"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
|
||||
@@ -24,6 +24,69 @@ const pageOf = (
|
||||
next_offset = items.length,
|
||||
) => ({ items, has_more, next_offset });
|
||||
|
||||
test('loads external input images and previews without sending a referrer', async ({
|
||||
page,
|
||||
}) => {
|
||||
await installLangBotApiMocks(page, {
|
||||
authenticated: true,
|
||||
monitoringData: monitoring,
|
||||
});
|
||||
const imageUrl = 'https://images.example.test/attachment.png';
|
||||
const referrers: (string | undefined)[] = [];
|
||||
await page.route(imageUrl, async (route) => {
|
||||
const referrer = route.request().headers().referer;
|
||||
referrers.push(referrer);
|
||||
// Match providers that return JSON errors for embedded requests.
|
||||
if (referrer) {
|
||||
await route.fulfill({ status: 400, json: { error: 'Invalid referrer' } });
|
||||
return;
|
||||
}
|
||||
await route.fulfill({
|
||||
contentType: 'image/png',
|
||||
headers: { 'Cache-Control': 'no-store' },
|
||||
body: Buffer.from(
|
||||
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+aX1sAAAAASUVORK5CYII=',
|
||||
'base64',
|
||||
),
|
||||
});
|
||||
});
|
||||
await page.route('**/api/v1/monitoring/executions/*/*?*', async (route) => {
|
||||
await route.fulfill({
|
||||
json: {
|
||||
code: 0,
|
||||
data: {
|
||||
source: 'pipeline',
|
||||
row,
|
||||
pages: {
|
||||
inputs: pageOf([
|
||||
{ id: 'image', content: [{ type: 'Image', url: imageUrl }] },
|
||||
]),
|
||||
outputs: pageOf([]),
|
||||
deliveries: pageOf([]),
|
||||
errors: pageOf([]),
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
await page.goto('/home/monitoring');
|
||||
await page
|
||||
.getByRole('button')
|
||||
.filter({ hasText: 'Open this execution' })
|
||||
.click();
|
||||
const thumbnail = page.getByRole('img', { name: 'Message attachment' });
|
||||
await expect
|
||||
.poll(() => thumbnail.evaluate((img: HTMLImageElement) => img.naturalWidth))
|
||||
.toBe(1);
|
||||
await thumbnail.click();
|
||||
const preview = page.getByRole('img', { name: 'Preview', exact: true });
|
||||
await expect(preview).toBeVisible();
|
||||
await expect
|
||||
.poll(() => preview.evaluate((img: HTMLImageElement) => img.naturalWidth))
|
||||
.toBe(1);
|
||||
expect(referrers).toEqual([undefined, undefined]);
|
||||
});
|
||||
|
||||
test('loads collapsed history on demand, retries and pages without reloading it on reopen', async ({
|
||||
page,
|
||||
}) => {
|
||||
|
||||
Reference in New Issue
Block a user