Private
Public Access
A URL that points straight at an image file (Content-Type: image/*) has no HTML to scrape Open Graph tags from, so the fetch found nothing and the message showed no preview at all -- reported against https://imgs.xkcd.com/comics/creepy.png. link_preview_service now recognizes an allowed image content-type (same list storage.py uses for uploads) before falling through to the HTML/og: path, and returns the URL itself as the preview (LinkPreview.is_image). No need to download the body -- the already-SSRF-validated URL is the image. The frontend renders that case as a real expandable image (message-image + lightbox, same as an actual attachment) instead of the small title+description card, which would have nothing to show anyway. Verified end-to-end against the reported URL. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
47 lines
955 B
Python
47 lines
955 B
Python
import uuid
|
|
from datetime import datetime
|
|
|
|
from pydantic import BaseModel, ConfigDict
|
|
|
|
|
|
class ReactionSummary(BaseModel):
|
|
emoji: str
|
|
count: int
|
|
user_ids: list[str]
|
|
|
|
|
|
class MessageFileInfo(BaseModel):
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: uuid.UUID
|
|
filename: str
|
|
size_bytes: int
|
|
content_type: str
|
|
|
|
|
|
class LinkPreviewInfo(BaseModel):
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
url: str
|
|
title: str | None
|
|
description: str | None
|
|
image_url: str | None
|
|
site_name: str | None
|
|
is_image: bool
|
|
|
|
|
|
class MessageRead(BaseModel):
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: uuid.UUID
|
|
room_id: uuid.UUID
|
|
user_id: uuid.UUID
|
|
username: str
|
|
content: str | None
|
|
image_id: uuid.UUID | None
|
|
file: MessageFileInfo | None
|
|
link_preview: LinkPreviewInfo | None
|
|
reactions: list[ReactionSummary]
|
|
created_at: datetime
|
|
edited_at: datetime | None
|