fix: multiple federation peering bugs
1. queueOutboxEvent no longer creates pending peer placeholders when autoAcceptPeering is disabled — prevents bypassing the admin's peering control 2. Approval endpoint checks for 202 before response.ok — when the remote also has autoAcceptPeering off, sets peer to awaiting_approval instead of incorrectly activating it 3. awaiting_approval status added to Federation panel UI — status label, colors, filter options so these peers are visible and manageable
This commit is contained in:
@@ -996,6 +996,24 @@ export async function federationRoutes(app: FastifyInstance): Promise<void> {
|
||||
signal: AbortSignal.timeout(10_000),
|
||||
});
|
||||
|
||||
if (response.status === 202) {
|
||||
// Remote instance also has autoAcceptPeering off — they queued our request.
|
||||
// Don't activate our peer. Set to awaiting_approval until their admin also approves.
|
||||
db.update(schema.federationPeers)
|
||||
.set({ status: 'awaiting_approval' })
|
||||
.where(eq(schema.federationPeers.id, peerId))
|
||||
.run();
|
||||
// Delete the approval request since we already acted on it
|
||||
db.delete(schema.peerApprovalRequests)
|
||||
.where(eq(schema.peerApprovalRequests.id, id))
|
||||
.run();
|
||||
return reply.code(200).send({
|
||||
success: true,
|
||||
awaitingRemoteApproval: true,
|
||||
message: 'Remote instance also requires admin approval. Your request has been queued on their side.',
|
||||
});
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
let errorMessage = `Remote instance rejected handshake (HTTP ${response.status})`;
|
||||
try {
|
||||
|
||||
@@ -152,12 +152,23 @@ export function queueOutboxEvent(
|
||||
: peers;
|
||||
|
||||
// For targeted origins with no existing peer record, create pending placeholders
|
||||
// (only when autoAcceptPeering is enabled — otherwise the admin controls all peering)
|
||||
if (targetPeerOrigins) {
|
||||
const autoAcceptSettings = db
|
||||
.select({ autoAcceptPeering: schema.instanceSettings.autoAcceptPeering })
|
||||
.from(schema.instanceSettings)
|
||||
.where(eq(schema.instanceSettings.id, 1))
|
||||
.get();
|
||||
const autoAcceptPeering = (autoAcceptSettings?.autoAcceptPeering ?? 1) === 1;
|
||||
|
||||
const matchedOrigins = new Set(matchedPeers.map(p => p.origin));
|
||||
|
||||
for (const origin of targetPeerOrigins) {
|
||||
if (matchedOrigins.has(origin)) continue;
|
||||
|
||||
// Don't auto-create placeholders when autoAcceptPeering is off
|
||||
if (!autoAcceptPeering) continue;
|
||||
|
||||
// Check if there's a rejected/revoked peer we should skip
|
||||
const existingPeer = db
|
||||
.select({ status: schema.federationPeers.status })
|
||||
|
||||
Reference in New Issue
Block a user