diff --git a/packages/database-interface/user.ts b/packages/database-interface/user.ts index 25ef7158..b164f8e9 100644 --- a/packages/database-interface/user.ts +++ b/packages/database-interface/user.ts @@ -48,6 +48,7 @@ import { Users, } from "~/drizzle/schema"; import { type Config, config } from "~/packages/config-manager"; +import { undoFederationRequest } from "../../classes/functions/federation.ts"; import { BaseInterface } from "./base"; import { Emoji } from "./emoji"; import { Instance } from "./instance"; @@ -254,6 +255,46 @@ export class User extends BaseInterface { return foundRelationship; } + async unfollow(followee: User, relationship: Relationship) { + if (followee.isRemote()) { + // TODO: This should reschedule for a later time and maybe notify the server admin if it fails too often + const { ok } = await this.federateToUser( + undoFederationRequest( + this, + new URL( + `/follows/${relationship.id}`, + config.http.base_url, + ).toString(), + ), + followee, + ); + + if (!ok) { + return false; + } + } else if (!this.data.isLocked) { + if (relationship.data.following) { + await db.insert(Notifications).values({ + accountId: followee.id, + type: "unfollow", + notifiedId: this.id, + }); + } else { + await db.insert(Notifications).values({ + accountId: followee.id, + type: "cancel-follow", + notifiedId: this.id, + }); + } + } + + await relationship.update({ + following: false, + }); + + return true; + } + static async webFinger( manager: FederationRequester, username: string, diff --git a/server/api/api/v1/accounts/:id/unfollow.ts b/server/api/api/v1/accounts/:id/unfollow.ts index 6a21bbae..a1d1523b 100644 --- a/server/api/api/v1/accounts/:id/unfollow.ts +++ b/server/api/api/v1/accounts/:id/unfollow.ts @@ -57,10 +57,8 @@ export default (app: Hono) => otherUser, ); - if (foundRelationship.data.following) { - await foundRelationship.update({ - following: false, - }); + if (!(await self.unfollow(otherUser, foundRelationship))) { + return errorResponse("Failed to unfollow user", 500); } return jsonResponse(foundRelationship.toApi());