fix(federation): use canonical_pair_id for sync scope instead of home_instance matching

The old query missed channels where both members appear as 'local'
(e.g., native Nova + native youruser on orbit). Using
canonical_pair_id is simpler and correct — any channel with a pair
ID is a federated DM that should be synced.
This commit is contained in:
Jannis Braun
2026-03-26 04:41:00 +01:00
parent 49f88c2552
commit cb9a70d7a6
+6 -27
View File
@@ -525,34 +525,13 @@ export async function federationRoutes(app: FastifyInstance): Promise<void> {
let limit = typeof body.limit === 'number' ? body.limit : 100; let limit = typeof body.limit === 'number' ? body.limit : 100;
limit = Math.max(1, Math.min(500, Math.floor(limit))); limit = Math.max(1, Math.min(500, Math.floor(limit)));
// 3. Determine shared DM channels between this instance and the requesting peer // 3. Determine which DM channels to sync.
// Shared channels have one local user (home_instance IS NULL) and // Use canonical_pair_id: any channel with a pair ID is a federated 1-on-1 DM
// one peer user (home_instance = peer hostname), with exactly 2 members. // that should be synced. The peer's relay endpoint will create the channel
let peerHost: string; // if it doesn't exist, or match by canonical_pair_id if it does.
try {
peerHost = new URL(peer.origin).host;
} catch {
return reply.code(500).send({ error: 'Invalid peer origin in database', statusCode: 500 });
}
// Find shared 1-on-1 DM channel IDs using raw SQL for the complex JOIN.
// A shared channel is one where:
// - There are exactly 2 members
// - One member is a local user (home_instance IS NULL)
// - One member is a user from the peer (home_instance = peerHost)
const sharedChannelRows = rawDb.prepare(` const sharedChannelRows = rawDb.prepare(`
SELECT DISTINCT dm1.dm_channel_id SELECT id as dm_channel_id FROM dm_channels WHERE canonical_pair_id IS NOT NULL
FROM dm_members dm1 `).all() as Array<{ dm_channel_id: string }>;
JOIN dm_members dm2 ON dm1.dm_channel_id = dm2.dm_channel_id AND dm1.user_id != dm2.user_id
JOIN users u1 ON dm1.user_id = u1.id
JOIN users u2 ON dm2.user_id = u2.id
WHERE u1.home_instance IS NULL
AND u2.home_instance = ?
AND (
SELECT COUNT(*) FROM dm_members dm3
WHERE dm3.dm_channel_id = dm1.dm_channel_id
) = 2
`).all(peerHost) as Array<{ dm_channel_id: string }>;
const sharedChannelIds = sharedChannelRows.map(r => r.dm_channel_id); const sharedChannelIds = sharedChannelRows.map(r => r.dm_channel_id);