From 4c22b0edcc92526f0b95229d220febf05407c784 Mon Sep 17 00:00:00 2001 From: Jesse Wierzbinski Date: Wed, 5 Jun 2024 18:58:28 -1000 Subject: [PATCH] feat(federation): :sparkles: Federate user profile changes to other instances --- packages/database-interface/user.ts | 38 ++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/packages/database-interface/user.ts b/packages/database-interface/user.ts index 1d18fc03..8834cc58 100644 --- a/packages/database-interface/user.ts +++ b/packages/database-interface/user.ts @@ -14,6 +14,7 @@ import { gte, inArray, isNull, + sql, } from "drizzle-orm"; import { htmlToText } from "html-to-text"; import { @@ -21,6 +22,7 @@ import { emojiToLysand, fetchEmoji, } from "~/database/entities/Emoji"; +import { objectToInboxRequest } from "~/database/entities/Federation"; import { addInstanceIfNotExists } from "~/database/entities/Instance"; import { type UserWithRelations, @@ -202,7 +204,9 @@ export class User { async updateFromRemote() { if (!this.isRemote()) { - throw new Error("Cannot update local user from remote"); + throw new Error( + "Cannot refetch a local user (they are not remote)", + ); } const updated = await User.saveFromRemote(this.getUri()); @@ -500,6 +504,38 @@ export class User { this.user = newUser.getUser(); + // If something important is updated, federate it + if ( + data.username || + data.displayName || + data.note || + data.avatar || + data.header || + data.fields || + data.publicKey || + data.isAdmin || + data.isBot || + data.isLocked || + data.endpoints || + data.isDiscoverable + ) { + // Get followers + const followers = await User.manyFromSql( + sql`EXISTS (SELECT 1 FROM "Relationships" WHERE "Relationships"."subjectId" = ${Users.id} AND "Relationships"."ownerId" = ${this.id} AND "Relationships"."following" = true)`, + ); + + for (const follower of followers) { + const federationRequest = await objectToInboxRequest( + this.toLysand(), + this, + follower, + ); + + // FIXME: Add to new queue system when it's implemented + fetch(federationRequest); + } + } + return this; }