feat(federation): Federate note deletions

This commit is contained in:
Jesse Wierzbinski 2024-06-05 19:25:49 -10:00
parent 431bc9c715
commit 88ad7178bf
No known key found for this signature in database
4 changed files with 47 additions and 18 deletions

View file

@ -67,3 +67,18 @@ export const objectToInboxRequest = async (
return signed; return signed;
}; };
export const undoFederationRequest = (
undoer: User,
uri: string,
): typeof EntityValidator.$Undo => {
const id = crypto.randomUUID();
return {
type: "Undo",
id,
author: undoer.getUri(),
created_at: new Date().toISOString(),
object: uri,
uri: new URL(`/undos/${id}`, config.http.base_url).toString(),
};
};

View file

@ -520,29 +520,33 @@ export class User {
data.endpoints || data.endpoints ||
data.isDiscoverable data.isDiscoverable
) { ) {
// Get followers await this.federateToFollowers(this.toLysand());
const followers = await User.manyFromSql(
and(
sql`EXISTS (SELECT 1 FROM "Relationships" WHERE "Relationships"."subjectId" = ${this.id} AND "Relationships"."ownerId" = ${Users.id} AND "Relationships"."following" = true)`,
isNotNull(Users.instanceId),
),
);
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; return this;
} }
async federateToFollowers(object: typeof EntityValidator.$Entity) {
// Get followers
const followers = await User.manyFromSql(
and(
sql`EXISTS (SELECT 1 FROM "Relationships" WHERE "Relationships"."subjectId" = ${this.id} AND "Relationships"."ownerId" = ${Users.id} AND "Relationships"."following" = true)`,
isNotNull(Users.instanceId),
),
);
for (const follower of followers) {
const federationRequest = await objectToInboxRequest(
object,
this,
follower,
);
// FIXME: Add to new queue system when it's implemented
fetch(federationRequest);
}
}
toAPI(isOwnAccount = false): APIAccount { toAPI(isOwnAccount = false): APIAccount {
const user = this.getUser(); const user = this.getUser();
return { return {

View file

@ -11,6 +11,7 @@ import { config } from "config-manager";
import type { Hono } from "hono"; import type { Hono } from "hono";
import ISO6391 from "iso-639-1"; import ISO6391 from "iso-639-1";
import { z } from "zod"; import { z } from "zod";
import { undoFederationRequest } from "~/database/entities/Federation";
import { db } from "~/drizzle/db"; import { db } from "~/drizzle/db";
import { Note } from "~/packages/database-interface/note"; import { Note } from "~/packages/database-interface/note";
@ -99,6 +100,10 @@ export default (app: Hono) =>
await foundStatus.delete(); await foundStatus.delete();
await user.federateToFollowers(
undoFederationRequest(user, foundStatus.getURI()),
);
return jsonResponse(await foundStatus.toAPI(user), 200); return jsonResponse(await foundStatus.toAPI(user), 200);
} }

View file

@ -4,6 +4,7 @@ import { zValidator } from "@hono/zod-validator";
import { and, eq } from "drizzle-orm"; import { and, eq } from "drizzle-orm";
import type { Hono } from "hono"; import type { Hono } from "hono";
import { z } from "zod"; import { z } from "zod";
import { undoFederationRequest } from "~/database/entities/Federation";
import { Notes } from "~/drizzle/schema"; import { Notes } from "~/drizzle/schema";
import { Note } from "~/packages/database-interface/note"; import { Note } from "~/packages/database-interface/note";
@ -58,6 +59,10 @@ export default (app: Hono) =>
await existingReblog.delete(); await existingReblog.delete();
await user.federateToFollowers(
undoFederationRequest(user, existingReblog.getURI()),
);
const newNote = await Note.fromId(id, user.id); const newNote = await Note.fromId(id, user.id);
if (!newNote) return errorResponse("Record not found", 404); if (!newNote) return errorResponse("Record not found", 404);