feat: real-time Federation panel updates via WS events

Added federation_peers_changed (no-payload signal) broadcast from every
peer state mutation, and federation_approval_request_received when a new
approval request is queued. Client subscribes via onFederationPeersChanged
callback registry. FederationPanel and PendingApprovals debounce-refetch
on any event. sendToAdmins helper broadcasts only to admin users.
This commit is contained in:
Jannis Braun
2026-04-20 18:28:10 +02:00
parent 6afad97bd1
commit 3d8709d20a
7 changed files with 95 additions and 0 deletions
+21
View File
@@ -469,6 +469,13 @@ export async function federationRoutes(app: FastifyInstance): Promise<void> {
.run();
}
// Notify admin users that a new approval request arrived
connectionManager.sendToAdmins({
type: 'federation_approval_request_received' as const,
origin: sourceOrigin,
instanceName: reqInstanceName ?? undefined,
});
return reply.code(202).send({
queued: true,
message: 'Request queued for admin approval',
@@ -514,6 +521,8 @@ export async function federationRoutes(app: FastifyInstance): Promise<void> {
});
}
connectionManager.sendToAdmins({ type: 'federation_peers_changed' as const });
return reply.code(200).send({ accepted: true });
}
if (existing.status === 'awaiting_approval') {
@@ -535,6 +544,8 @@ export async function federationRoutes(app: FastifyInstance): Promise<void> {
});
}
connectionManager.sendToAdmins({ type: 'federation_peers_changed' as const });
return reply.code(200).send({ accepted: true });
}
// Pending — update with new secret and activate
@@ -547,6 +558,8 @@ export async function federationRoutes(app: FastifyInstance): Promise<void> {
.where(eq(schema.federationPeers.id, existing.id))
.run();
connectionManager.sendToAdmins({ type: 'federation_peers_changed' as const });
return reply.code(200).send({ accepted: true });
}
@@ -561,6 +574,8 @@ export async function federationRoutes(app: FastifyInstance): Promise<void> {
createdAt: Date.now(),
}).run();
connectionManager.sendToAdmins({ type: 'federation_peers_changed' as const });
return reply.code(200).send({ accepted: true });
},
);
@@ -733,6 +748,8 @@ export async function federationRoutes(app: FastifyInstance): Promise<void> {
.where(eq(schema.federationPeers.id, peer.id))
.run();
connectionManager.sendToAdmins({ type: 'federation_peers_changed' as const });
// Push federation_peer_rejected WS event to affected users
const entries = db
.select({
@@ -1041,6 +1058,8 @@ export async function federationRoutes(app: FastifyInstance): Promise<void> {
.where(eq(schema.peerApprovalRequests.id, id))
.run();
connectionManager.sendToAdmins({ type: 'federation_peers_changed' as const });
const peer = db
.select()
.from(schema.federationPeers)
@@ -1137,6 +1156,8 @@ export async function federationRoutes(app: FastifyInstance): Promise<void> {
.run();
}
connectionManager.sendToAdmins({ type: 'federation_peers_changed' as const });
db.delete(schema.peerApprovalRequests)
.where(eq(schema.peerApprovalRequests.id, id))
.run();