From 165fda44a3796ffe601daf0f1f1ea613f920f793 Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Mon, 20 Apr 2026 18:01:47 +0200 Subject: [PATCH] fix: accept incoming handshake for awaiting_approval peers to break approval ping-pong MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When both instances have autoAcceptPeering off, the approval flow ping-ponged indefinitely. Admin A approves → handshakes to B → B queues (202) → A's peer becomes awaiting_approval. Admin B approves → handshakes to A → but A's gate only matched 'pending', not 'awaiting_approval', so it re-queued instead of accepting. Now the gate matches both 'pending' and 'awaiting_approval'. When the second admin approves and handshakes back, the first instance recognizes its admin already approved and accepts — completing the peering. --- packages/server/src/routes/federation.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/server/src/routes/federation.ts b/packages/server/src/routes/federation.ts index 841f3dc0..d086a43e 100644 --- a/packages/server/src/routes/federation.ts +++ b/packages/server/src/routes/federation.ts @@ -398,13 +398,18 @@ export async function federationRoutes(app: FastifyInstance): Promise { const autoAccept = settings?.autoAcceptPeering ?? 1; if (autoAccept === 0) { + // Check if the local admin already initiated or approved peering with this origin. + // 'pending' = admin used peer/initiate (handshake in progress) + // 'awaiting_approval' = admin approved an earlier request, handshake was sent, + // remote queued it (202). Now the remote admin approved too and is handshaking + // back to us. We should accept — both admins have approved. const localPending = db .select({ id: schema.federationPeers.id }) .from(schema.federationPeers) .where( and( eq(schema.federationPeers.origin, sourceOrigin), - eq(schema.federationPeers.status, 'pending'), + inArray(schema.federationPeers.status, ['pending', 'awaiting_approval']), ), ) .get();