feat(federation): capture dm_close/reopen/read_state/profile/file_rejected in mutation log

Four event types previously bypassed appendMutationLog, making
them unrecoverable via /api/federation/sync after peer inactivity:
  - queueDmCloseRelay (dm_close, dm_reopen)
  - queueReadStateRelay (read_state_update)
  - handleSizeRejection in federationWorker (file_rejected)
  - profile PATCH route (profile_update) — two call sites,
    one appendMutationLog per profile change (not per target origin)

The /api/federation/sync response builder is extended to
serialize these event types in the next task.
This commit is contained in:
Jannis Braun
2026-04-22 00:48:49 +02:00
parent 250596c0f6
commit a23e02339e
4 changed files with 175 additions and 2 deletions
+13 -1
View File
@@ -2,7 +2,7 @@ import { getDb } from '../db/index.js';
import * as schema from '../db/schema.js';
import { eq, and, lte, asc, inArray, sql } from 'drizzle-orm';
import { config } from '../config.js';
import { isFederationRelayEnabled, queueOutboxEvent } from './federationOutbox.js';
import { isFederationRelayEnabled, queueOutboxEvent, appendMutationLog } from './federationOutbox.js';
import { runFederationJanitor } from './storageJanitor.js';
import { buildFederationHeaders, getOurOrigin, generateHmacSecret, ROTATION_GRACE_PERIOD_MS } from './federationAuth.js';
import { evaluateAuthFailure, AUTH_FAILURE_THRESHOLD } from './federationAuthFailure.js';
@@ -703,6 +703,18 @@ function handleSizeRejection(
affectedUserIds,
};
appendMutationLog(
localMsg.sourceMessageId,
localMsg.dmChannelId,
'file_rejected',
JSON.stringify({
attachmentId: att?.id ?? entry.sourceUrl,
sourceFilename,
rejectionReason: 'size_limit_exceeded',
rejectionLimit: maxUploadSize,
affectedUserIds,
}),
);
queueOutboxEvent(
localMsg.sourceMessageId,
localMsg.dmChannelId,