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:
@@ -2312,14 +2312,13 @@ function processFileRejectedEvent(
|
|||||||
.where(eq(schema.attachments.dmMessageId, localMsg.id))
|
.where(eq(schema.attachments.dmMessageId, localMsg.id))
|
||||||
.all();
|
.all();
|
||||||
|
|
||||||
// The attachmentId from the remote is their local attachment ID, not ours.
|
// Match by filename from the sourceUrl — the remote sends the filename portion
|
||||||
// Match by sourceUrl instead — the remote's sourceUrl points to our upload endpoint.
|
// (e.g., "12345.png") which matches our local attachment's filename.
|
||||||
const ourOrigin = getOurOrigin();
|
let matchedAttachment = event.sourceFilename
|
||||||
let matchedAttachment = messageAttachments.find(a =>
|
? messageAttachments.find(a => a.filename === event.sourceFilename)
|
||||||
a.sourceUrl && a.sourceUrl.startsWith(ourOrigin),
|
: undefined;
|
||||||
);
|
|
||||||
|
|
||||||
// If only one attachment, use it directly
|
// Fallback: if only one attachment, use it directly
|
||||||
if (!matchedAttachment && messageAttachments.length === 1) {
|
if (!matchedAttachment && messageAttachments.length === 1) {
|
||||||
matchedAttachment = messageAttachments[0];
|
matchedAttachment = messageAttachments[0];
|
||||||
}
|
}
|
||||||
@@ -2357,7 +2356,8 @@ function processFileRejectedEvent(
|
|||||||
let existingMeta: Array<{ userId: string; username: string; limit: number }> = [];
|
let existingMeta: Array<{ userId: string; username: string; limit: number }> = [];
|
||||||
if (matchedAttachment.federationMeta) {
|
if (matchedAttachment.federationMeta) {
|
||||||
try {
|
try {
|
||||||
existingMeta = JSON.parse(matchedAttachment.federationMeta);
|
const parsed = JSON.parse(matchedAttachment.federationMeta);
|
||||||
|
existingMeta = Array.isArray(parsed) ? parsed : [];
|
||||||
} catch { /* ignore parse errors */ }
|
} catch { /* ignore parse errors */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -179,6 +179,12 @@ async function processOutboxTick(): Promise<void> {
|
|||||||
if (parsed.ownership) evt.ownership = parsed.ownership;
|
if (parsed.ownership) evt.ownership = parsed.ownership;
|
||||||
if (parsed.group) evt.group = parsed.group;
|
if (parsed.group) evt.group = parsed.group;
|
||||||
if (parsed.friendship) evt.friendship = parsed.friendship;
|
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;
|
return evt;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -420,12 +426,16 @@ function handleSizeRejection(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Queue a file_rejected reverse relay event to the sender's instance
|
// 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 = {
|
const event: FederationRelayEvent = {
|
||||||
eventType: 'file_rejected',
|
eventType: 'file_rejected',
|
||||||
messageId: localMsg.sourceMessageId,
|
messageId: localMsg.sourceMessageId,
|
||||||
encryptionVersion: 0,
|
encryptionVersion: 0,
|
||||||
timestamp: now,
|
timestamp: now,
|
||||||
attachmentId: att?.id ?? entry.sourceUrl,
|
attachmentId: att?.id ?? entry.sourceUrl,
|
||||||
|
sourceFilename,
|
||||||
rejectionReason: 'size_limit_exceeded',
|
rejectionReason: 'size_limit_exceeded',
|
||||||
rejectionLimit: maxUploadSize,
|
rejectionLimit: maxUploadSize,
|
||||||
affectedUserIds,
|
affectedUserIds,
|
||||||
|
|||||||
@@ -770,6 +770,7 @@ export interface FederationRelayEvent {
|
|||||||
friendship?: FederationFriendshipPayload;
|
friendship?: FederationFriendshipPayload;
|
||||||
// file_rejected event fields
|
// file_rejected event fields
|
||||||
attachmentId?: string;
|
attachmentId?: string;
|
||||||
|
sourceFilename?: string;
|
||||||
rejectionReason?: string;
|
rejectionReason?: string;
|
||||||
rejectionLimit?: number;
|
rejectionLimit?: number;
|
||||||
affectedUserIds?: string[];
|
affectedUserIds?: string[];
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ export function AttachmentRenderer({ attachment }: AttachmentRendererProps) {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Tooltip content={tooltipText} position="top">
|
<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">
|
<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" />
|
<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" />
|
<line x1="12" y1="9" x2="12" y2="13" />
|
||||||
|
|||||||
Reference in New Issue
Block a user