fix(federation): auto-create and hydrate user profiles during DM relay

Federated 1-on-1 DMs showed the raw snowflake ID as the display name
and no avatar when the remote user had no pre-existing local record.
processCreateEvent used resolveLocalUser (find-only) instead of
resolveOrCreateReplicatedUser, and relay events carried no profile data
for participants.

- Add profile snapshot (displayName, avatar, avatarColor) to
  FederationRelayParticipant and populate it in getDmParticipants
- Change processCreateEvent to auto-create replicated user stubs and
  hydrate them with profile data from the relay event
- Fix hydrateReplicatedUserProfile URL resolution for homeInstance
  values without protocol prefix
- Fix WelcomeHeader: return null while DM data is loading (eliminates
  "unknown" flash on reload), use displayName for @mention text
This commit is contained in:
Jannis Braun
2026-03-27 03:43:45 +01:00
parent 6df80aa1f0
commit 0d6bb9dbd3
4 changed files with 25 additions and 10 deletions
@@ -245,6 +245,9 @@ export function getDmParticipants(dmChannelId: string): FederationRelayParticipa
homeUserId: schema.users.homeUserId,
homeInstance: schema.users.homeInstance,
id: schema.users.id,
displayName: schema.users.displayName,
avatar: schema.users.avatar,
avatarColor: schema.users.avatarColor,
})
.from(schema.dmMembers)
.innerJoin(schema.users, eq(schema.dmMembers.userId, schema.users.id))
@@ -256,6 +259,11 @@ export function getDmParticipants(dmChannelId: string): FederationRelayParticipa
return members.map(m => ({
homeUserId: m.homeUserId || m.id,
homeInstance: m.homeInstance || domainOrigin,
profile: {
displayName: m.displayName ?? null,
avatar: m.avatar ?? null,
avatarColor: m.avatarColor ?? null,
},
}));
}