fix: accept incoming handshake for awaiting_approval peers to break approval ping-pong

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.
This commit is contained in:
Jannis Braun
2026-04-20 18:01:47 +02:00
parent 072858cbbb
commit 165fda44a3
+6 -1
View File
@@ -398,13 +398,18 @@ export async function federationRoutes(app: FastifyInstance): Promise<void> {
const autoAccept = settings?.autoAcceptPeering ?? 1; const autoAccept = settings?.autoAcceptPeering ?? 1;
if (autoAccept === 0) { 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 const localPending = db
.select({ id: schema.federationPeers.id }) .select({ id: schema.federationPeers.id })
.from(schema.federationPeers) .from(schema.federationPeers)
.where( .where(
and( and(
eq(schema.federationPeers.origin, sourceOrigin), eq(schema.federationPeers.origin, sourceOrigin),
eq(schema.federationPeers.status, 'pending'), inArray(schema.federationPeers.status, ['pending', 'awaiting_approval']),
), ),
) )
.get(); .get();