From ae41139ad804feccfe1cfbd0ccfcff3e77e27294 Mon Sep 17 00:00:00 2001 From: Jesse Wierzbinski Date: Thu, 23 Nov 2023 08:43:56 -1000 Subject: [PATCH] Add incoming Like federation --- database/entities/Like.ts | 29 ++++++++++++++++++++ server/api/api/v1/statuses/[id]/favourite.ts | 8 ++---- server/api/users/[uuid]/inbox/index.ts | 17 ++++++++++++ 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/database/entities/Like.ts b/database/entities/Like.ts index d173aef1..70ecc929 100644 --- a/database/entities/Like.ts +++ b/database/entities/Like.ts @@ -2,6 +2,9 @@ import type { Like as LysandLike } from "~types/lysand/Object"; import { getConfig } from "@config"; import type { Like } from "@prisma/client"; +import { client } from "~database/datasource"; +import type { UserWithRelations } from "./User"; +import type { StatusWithRelations } from "./Status"; /** * Represents a Like entity in the database. @@ -17,3 +20,29 @@ export const toLysand = (like: Like): LysandLike => { uri: `${getConfig().http.base_url}/actions/${like.id}`, }; }; + +export const createLike = async ( + user: UserWithRelations, + status: StatusWithRelations +) => { + await client.like.create({ + data: { + likedId: status.id, + likerId: user.id, + }, + }); + + if (status.author.instanceId === user.instanceId) { + // Notify the user that their post has been favourited + await client.notification.create({ + data: { + accountId: user.id, + type: "favourite", + notifiedId: status.authorId, + statusId: status.id, + }, + }); + } else { + // TODO: Add database jobs for federating this + } +}; diff --git a/server/api/api/v1/statuses/[id]/favourite.ts b/server/api/api/v1/statuses/[id]/favourite.ts index 5341fd43..d1f8c39a 100644 --- a/server/api/api/v1/statuses/[id]/favourite.ts +++ b/server/api/api/v1/statuses/[id]/favourite.ts @@ -3,6 +3,7 @@ import { applyConfig } from "@api"; import { errorResponse, jsonResponse } from "@response"; import type { MatchedRoute } from "bun"; import { client } from "~database/datasource"; +import { createLike } from "~database/entities/Like"; import { isViewableByUser, statusAndUserRelations, @@ -54,12 +55,7 @@ export default async ( }); if (!existingLike) { - await client.like.create({ - data: { - likedId: status.id, - likerId: user.id, - }, - }); + await createLike(user, status); } return jsonResponse({ diff --git a/server/api/users/[uuid]/inbox/index.ts b/server/api/users/[uuid]/inbox/index.ts index daea01c0..8903d522 100644 --- a/server/api/users/[uuid]/inbox/index.ts +++ b/server/api/users/[uuid]/inbox/index.ts @@ -7,6 +7,7 @@ import { errorResponse, jsonResponse } from "@response"; import type { MatchedRoute } from "bun"; import { client } from "~database/datasource"; import { parseEmojis } from "~database/entities/Emoji"; +import { createLike } from "~database/entities/Like"; import { createFromObject } from "~database/entities/Object"; import { createNewStatus, @@ -16,6 +17,7 @@ import { import { parseMentionsUris, userRelations } from "~database/entities/User"; import type { Announce, + Like, LysandAction, LysandPublication, Patch, @@ -250,8 +252,23 @@ export default async ( break; } case "Like": { + const like = body as Like; // Store the object in the LysandObject table await createFromObject(body); + + const likedStatus = await client.status.findUnique({ + where: { + uri: like.object, + }, + include: statusAndUserRelations, + }); + + if (!likedStatus) { + return errorResponse("Status not found", 404); + } + + await createLike(author, likedStatus); + break; } case "Dislike": {