From 8b442c241cb3e40d2dcf08ec5316bbd06b11eefc Mon Sep 17 00:00:00 2001 From: Jesse Wierzbinski Date: Sun, 26 Nov 2023 15:40:44 -1000 Subject: [PATCH] Work on federation --- bun.lockb | Bin 312200 -> 322720 bytes config/config.example.toml | 8 +- database/datasource.ts | 12 +- database/entities/Queue.ts | 197 ++++++++++++++++++ database/entities/Status.ts | 1 + package.json | 1 + .../migration.sql | 20 ++ utils/config.ts | 17 ++ 8 files changed, 254 insertions(+), 2 deletions(-) create mode 100644 database/entities/Queue.ts create mode 100644 prisma/migrations/20231127010521_add_notifications/migration.sql diff --git a/bun.lockb b/bun.lockb index 20aad1e5d073588fee86f5f003eaaf87b77c7a03..d1271c65d80f7f7a5a40b00fd3d45a1b8895c693 100755 GIT binary patch delta 60134 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 delta 54006 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 Z#!H9x7SzzHx^?{Wb9ei1$-+$%{=e%G*U { + await job.updateProgress(0); + + switch (job.name) { + case "federation": { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + const statusId = job.data.id as string; + + const status = await client.status.findUnique({ + where: { id: statusId }, + include: statusAndUserRelations, + }); + + if (!status) return; + + // Only get remote users that follow the author of the status, and the remote mentioned users + const peopleToSendTo = await client.user.findMany({ + where: { + OR: [ + ["public", "unlisted", "private"].includes( + status.visibility + ) + ? { + relationships: { + some: { + subjectId: status.authorId, + following: true, + }, + }, + instanceId: { + not: null, + }, + } + : {}, + // Mentioned users + { + id: { + in: status.mentions.map(m => m.id), + }, + instanceId: { + not: null, + }, + }, + ], + }, + }); + + let peopleDone = 0; + + // Spawn sendToServer job for each user + for (const person of peopleToSendTo) { + await federationQueue.add("sendToServer", { + id: statusId, + user: person, + }); + + peopleDone++; + + await job.updateProgress( + Math.round((peopleDone / peopleToSendTo.length) * 100) + ); + } + break; + } + case "sendToServer": { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + const statusId = job.data.id as string; + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + const user = job.data.user as User; + + const status = await client.status.findUnique({ + where: { id: statusId }, + include: statusAndUserRelations, + }); + + if (!status) return; + + const response = await federateStatusTo( + status, + status.author, + user + ); + + if (response.status !== 200) { + throw new Error( + `Federation error: ${response.status} ${response.statusText}` + ); + } + + break; + } + } + + await job.updateProgress(100); + + return true; + }, + { + connection: { + host: config.redis.queue.host, + port: config.redis.queue.port, + password: config.redis.queue.password, + db: config.redis.queue.database, + }, + removeOnComplete: { + count: 400, + }, + removeOnFail: { + count: 3000, + }, + } +); + +/** + * Convert a string into an ArrayBuffer + * from https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String + */ +export const str2ab = (str: string) => { + const buf = new ArrayBuffer(str.length); + const bufView = new Uint8Array(buf); + for (let i = 0, strLen = str.length; i < strLen; i++) { + bufView[i] = str.charCodeAt(i); + } + return buf; +}; + +export const federateStatusTo = async ( + status: StatusWithRelations, + sender: User, + user: User +) => { + const privateKey = await crypto.subtle.importKey( + "pkcs8", + str2ab(atob(user.privateKey ?? "")), + "Ed25519", + false, + ["sign"] + ); + + const digest = await crypto.subtle.digest( + "SHA-256", + new TextEncoder().encode("request_body") + ); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + const userInbox = new URL((user.endpoints as any).inbox); + + const date = new Date(); + + const signature = await crypto.subtle.sign( + "Ed25519", + privateKey, + new TextEncoder().encode( + `(request-target): post ${userInbox.pathname}\n` + + `host: ${userInbox.host}\n` + + `date: ${date.toUTCString()}\n` + + `digest: SHA-256=${btoa( + String.fromCharCode(...new Uint8Array(digest)) + )}\n` + ) + ); + + const signatureBase64 = btoa( + String.fromCharCode(...new Uint8Array(signature)) + ); + + return fetch(userInbox, { + method: "POST", + headers: { + "Content-Type": "application/json", + Date: date.toUTCString(), + Origin: config.http.base_url, + Signature: `keyId="${sender.uri}",algorithm="ed25519",headers="(request-target) host date digest",signature="${signatureBase64}"`, + }, + body: JSON.stringify(statusToLysand(status)), + }); +}; + +export const addStatusFederationJob = async (statusId: string) => { + await federationQueue.add("federation", { + id: statusId, + }); +}; diff --git a/database/entities/Status.ts b/database/entities/Status.ts index 10fec1b6..7731c7f3 100644 --- a/database/entities/Status.ts +++ b/database/entities/Status.ts @@ -422,6 +422,7 @@ export const statusToAPI = async ( id: status.id, in_reply_to_id: status.inReplyToPostId || null, in_reply_to_account_id: status.inReplyToPost?.authorId || null, + // @ts-expect-error Prisma TypeScript types dont include relations account: userToAPI(status.author), created_at: new Date(status.createdAt).toISOString(), application: status.application diff --git a/package.json b/package.json index 44457c58..85e165d3 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "@aws-sdk/client-s3": "^3.429.0", "@prisma/client": "^5.6.0", "blurhash": "^2.0.5", + "bullmq": "^4.14.2", "chalk": "^5.3.0", "eventemitter3": "^5.0.1", "html-to-text": "^9.0.5", diff --git a/prisma/migrations/20231127010521_add_notifications/migration.sql b/prisma/migrations/20231127010521_add_notifications/migration.sql new file mode 100644 index 00000000..77d5b111 --- /dev/null +++ b/prisma/migrations/20231127010521_add_notifications/migration.sql @@ -0,0 +1,20 @@ +-- CreateTable +CREATE TABLE "Notification" ( + "id" UUID NOT NULL DEFAULT uuid_generate_v7(), + "type" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "notifiedId" UUID NOT NULL, + "accountId" UUID NOT NULL, + "statusId" UUID, + + CONSTRAINT "Notification_pkey" PRIMARY KEY ("id") +); + +-- AddForeignKey +ALTER TABLE "Notification" ADD CONSTRAINT "Notification_notifiedId_fkey" FOREIGN KEY ("notifiedId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Notification" ADD CONSTRAINT "Notification_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Notification" ADD CONSTRAINT "Notification_statusId_fkey" FOREIGN KEY ("statusId") REFERENCES "Status"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/utils/config.ts b/utils/config.ts index f48498f4..522e6e74 100644 --- a/utils/config.ts +++ b/utils/config.ts @@ -9,6 +9,15 @@ export interface ConfigType { database: string; }; + redis: { + queue: { + host: string; + port: number; + password: string; + database: number; + }; + }; + http: { base_url: string; bind: string; @@ -145,6 +154,14 @@ export const configDefaults: ConfigType = { password: "postgres", database: "lysand", }, + redis: { + queue: { + host: "localhost", + port: 6379, + password: "", + database: 0, + }, + }, instance: { banner: "", description: "",