fix(federation): resolve code review issues in upload size mismatch

- Fix critical: outbox worker now copies file_rejected payload fields
  (attachmentId, sourceFilename, rejectionReason, rejectionLimit,
  affectedUserIds) so the reverse relay actually delivers them
- Fix: add sourceFilename to file_rejected event for reliable
  multi-attachment matching on the sender side
- Fix: change text-accent-warning to text-accent-amber (valid class)
- Add Array.isArray guard on federationMeta parse
This commit is contained in:
Jannis Braun
2026-03-27 04:51:30 +01:00
parent 589af25b45
commit ceb0c9812d
4 changed files with 20 additions and 9 deletions
+8 -8
View File
@@ -2312,14 +2312,13 @@ function processFileRejectedEvent(
.where(eq(schema.attachments.dmMessageId, localMsg.id))
.all();
// The attachmentId from the remote is their local attachment ID, not ours.
// Match by sourceUrl instead — the remote's sourceUrl points to our upload endpoint.
const ourOrigin = getOurOrigin();
let matchedAttachment = messageAttachments.find(a =>
a.sourceUrl && a.sourceUrl.startsWith(ourOrigin),
);
// Match by filename from the sourceUrl — the remote sends the filename portion
// (e.g., "12345.png") which matches our local attachment's filename.
let matchedAttachment = event.sourceFilename
? messageAttachments.find(a => a.filename === event.sourceFilename)
: undefined;
// If only one attachment, use it directly
// Fallback: if only one attachment, use it directly
if (!matchedAttachment && messageAttachments.length === 1) {
matchedAttachment = messageAttachments[0];
}
@@ -2357,7 +2356,8 @@ function processFileRejectedEvent(
let existingMeta: Array<{ userId: string; username: string; limit: number }> = [];
if (matchedAttachment.federationMeta) {
try {
existingMeta = JSON.parse(matchedAttachment.federationMeta);
const parsed = JSON.parse(matchedAttachment.federationMeta);
existingMeta = Array.isArray(parsed) ? parsed : [];
} catch { /* ignore parse errors */ }
}
@@ -179,6 +179,12 @@ async function processOutboxTick(): Promise<void> {
if (parsed.ownership) evt.ownership = parsed.ownership;
if (parsed.group) evt.group = parsed.group;
if (parsed.friendship) evt.friendship = parsed.friendship;
// file_rejected event fields
if (parsed.attachmentId) evt.attachmentId = parsed.attachmentId;
if (parsed.sourceFilename) evt.sourceFilename = parsed.sourceFilename;
if (parsed.rejectionReason) evt.rejectionReason = parsed.rejectionReason;
if (parsed.rejectionLimit != null) evt.rejectionLimit = parsed.rejectionLimit;
if (parsed.affectedUserIds) evt.affectedUserIds = parsed.affectedUserIds;
return evt;
});
@@ -420,12 +426,16 @@ function handleSizeRejection(
}
// Queue a file_rejected reverse relay event to the sender's instance
// Extract the filename from the sourceUrl (e.g., "https://sender/api/uploads/12345.png" → "12345.png")
const sourceFilename = entry.sourceUrl.split('/').pop() ?? entry.sourceUrl;
const event: FederationRelayEvent = {
eventType: 'file_rejected',
messageId: localMsg.sourceMessageId,
encryptionVersion: 0,
timestamp: now,
attachmentId: att?.id ?? entry.sourceUrl,
sourceFilename,
rejectionReason: 'size_limit_exceeded',
rejectionLimit: maxUploadSize,
affectedUserIds,
+1
View File
@@ -770,6 +770,7 @@ export interface FederationRelayEvent {
friendship?: FederationFriendshipPayload;
// file_rejected event fields
attachmentId?: string;
sourceFilename?: string;
rejectionReason?: string;
rejectionLimit?: number;
affectedUserIds?: string[];
@@ -70,7 +70,7 @@ export function AttachmentRenderer({ attachment }: AttachmentRendererProps) {
}
return (
<Tooltip content={tooltipText} position="top">
<div className="absolute top-2 right-2 flex items-center gap-1 px-1.5 py-0.5 rounded glass-pill text-xs text-accent-warning">
<div className="absolute top-2 right-2 flex items-center gap-1 px-1.5 py-0.5 rounded glass-pill text-xs text-accent-amber">
<svg className="w-3 h-3" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" />
<line x1="12" y1="9" x2="12" y2="13" />