From 960ca1c97f64f0c16e880febb9d8900e39dc260f Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Thu, 26 Mar 2026 04:19:18 +0100 Subject: [PATCH] fix(federation): set correct homeInstance in relay payload and fix canonical backfill SQL - buildRelayPayload now uses config.domain for local users instead of empty string, so the relay receiver can resolve the user - Fixed canonical_pair_id backfill: SQLite NULL || ':' || x = NULL, so use COALESCE(home_user_id, id) instead of concatenation --- packages/server/src/db/migrate.ts | 16 ++++------------ packages/server/src/utils/federationOutbox.ts | 3 ++- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/packages/server/src/db/migrate.ts b/packages/server/src/db/migrate.ts index 318ce5ee..da357e9d 100644 --- a/packages/server/src/db/migrate.ts +++ b/packages/server/src/db/migrate.ts @@ -496,14 +496,14 @@ export function runMigrations(db: Database.Database): void { try { // Find 1-on-1 DM channels that don't have a canonical_pair_id yet const channelsNeedingPairId = db.prepare(` - SELECT dc.id, GROUP_CONCAT(u.home_user_id || ':' || u.id) as member_info + SELECT dc.id, GROUP_CONCAT(COALESCE(u.home_user_id, u.id)) as home_ids FROM dm_channels dc JOIN dm_members dm ON dc.id = dm.dm_channel_id JOIN users u ON dm.user_id = u.id WHERE dc.canonical_pair_id IS NULL GROUP BY dc.id HAVING COUNT(dm.user_id) = 2 - `).all() as { id: string; member_info: string }[]; + `).all() as { id: string; home_ids: string }[]; if (channelsNeedingPairId.length > 0) { const crypto = require('crypto'); @@ -511,16 +511,8 @@ export function runMigrations(db: Database.Database): void { let backfilled = 0; for (const channel of channelsNeedingPairId) { - // member_info is like "homeUserId1:id1,homeUserId2:id2" - // Extract the homeUserIds (or fall back to regular ids) - const members = channel.member_info.split(','); - const homeUserIds = members.map((m: string) => { - const parts = m.split(':'); - // home_user_id might be "null" string if NULL in DB - const homeUserId = parts[0]; - const regularId = parts[1]; - return (homeUserId && homeUserId !== 'null') ? homeUserId : regularId; - }); + // home_ids is like "homeUserId1,homeUserId2" (COALESCE handles NULL home_user_id) + const homeUserIds = channel.home_ids.split(','); if (homeUserIds.length === 2) { const sorted = homeUserIds.sort(); diff --git a/packages/server/src/utils/federationOutbox.ts b/packages/server/src/utils/federationOutbox.ts index c030c8cd..96716b9d 100644 --- a/packages/server/src/utils/federationOutbox.ts +++ b/packages/server/src/utils/federationOutbox.ts @@ -4,6 +4,7 @@ import { eq, and } from 'drizzle-orm'; import { generateSnowflake } from './snowflake.js'; import crypto from 'node:crypto'; import type { FederationRelayEvent } from '@backspace/shared'; +import { config } from '../config.js'; // ─── Settings Cache ────────────────────────────────────────────────────────── @@ -230,7 +231,7 @@ export function buildRelayPayload( return { userId: user.id, homeUserId: user.homeUserId || user.id, - homeInstance: user.homeInstance || '', + homeInstance: user.homeInstance || config.domain || '', content: message.content, replyToId: message.replyToId ?? null, editedAt: message.editedAt ?? null,