mirror of
https://github.com/versia-pub/server.git
synced 2026-03-13 13:59:16 +01:00
Refactor code, add more filtering
This commit is contained in:
parent
768d1858dc
commit
4d0283caf0
8 changed files with 397 additions and 151 deletions
|
|
@ -13,9 +13,7 @@ import {
|
|||
APUpdate,
|
||||
} from "activitypub-types";
|
||||
import { MatchedRoute } from "bun";
|
||||
import { appendFile } from "fs/promises";
|
||||
import { RawActivity } from "~database/entities/RawActivity";
|
||||
import { RawObject } from "~database/entities/RawObject";
|
||||
|
||||
/**
|
||||
* ActivityPub user inbox endpoint
|
||||
|
|
@ -44,63 +42,11 @@ export default async (
|
|||
// TODO: Add authentication
|
||||
|
||||
// Check is Activity already exists
|
||||
const exists = await RawActivity.createQueryBuilder("activity")
|
||||
.where("activity.data->>'id' = :id", {
|
||||
id: body.id,
|
||||
})
|
||||
.getOne();
|
||||
const activity = await RawActivity.addIfNotExists(body);
|
||||
|
||||
if (exists) return errorResponse("Activity already exists", 409);
|
||||
|
||||
// Check if object already exists
|
||||
const objectExists = await RawObject.createQueryBuilder("object")
|
||||
.where("object.data->>'id' = :id", {
|
||||
id: (body.object as APObject).id,
|
||||
})
|
||||
.getOne();
|
||||
|
||||
if (objectExists)
|
||||
return errorResponse("Object already exists", 409);
|
||||
|
||||
// Check if object body contains any filtered terms
|
||||
const filter_result = await Promise.all(
|
||||
config.filters.note_filters.map(async filter => {
|
||||
if (
|
||||
(body.object as APObject).type === "Note" &&
|
||||
(body.object as APObject).content?.match(filter)
|
||||
) {
|
||||
// Log filter
|
||||
|
||||
if (config.logging.log_filters)
|
||||
await appendFile(
|
||||
process.cwd() + "/logs/filters.log",
|
||||
`${new Date().toISOString()} Filtered note content: "${(
|
||||
body.object as APObject
|
||||
).content?.replaceAll("\n", " ")}" (ID: ${
|
||||
(body.object as APObject).id
|
||||
}) based on rule: ${filter}\n`
|
||||
);
|
||||
return true;
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
if (filter_result.includes(true)) return jsonResponse({});
|
||||
|
||||
const activity = new RawActivity();
|
||||
const object = new RawObject();
|
||||
|
||||
activity.data = {
|
||||
...body,
|
||||
object: undefined,
|
||||
};
|
||||
object.data = body.object as APObject;
|
||||
|
||||
activity.objects = [object];
|
||||
|
||||
// Save the new object and activity
|
||||
await object.save();
|
||||
await activity.save();
|
||||
if (activity instanceof Error) {
|
||||
return errorResponse(activity.message, 409);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "Update" as APUpdate: {
|
||||
|
|
@ -108,26 +54,20 @@ export default async (
|
|||
// Replace the object in database with the new provided object
|
||||
// TODO: Add authentication
|
||||
|
||||
const object = await RawObject.createQueryBuilder("object")
|
||||
.where("object.data->>'id' = :id", {
|
||||
id: (body.object as APObject).id,
|
||||
})
|
||||
.getOne();
|
||||
const object = await RawActivity.updateObjectIfExists(
|
||||
body.object as APObject
|
||||
);
|
||||
|
||||
if (!object) return errorResponse("Object not found", 404);
|
||||
if (object instanceof Error) {
|
||||
return errorResponse(object.message, 409);
|
||||
}
|
||||
|
||||
object.data = body.object as APObject;
|
||||
const activity = await RawActivity.addIfNotExists(body);
|
||||
|
||||
// Store the Update event in database
|
||||
const activity = new RawActivity();
|
||||
activity.data = {
|
||||
...body,
|
||||
object: undefined,
|
||||
};
|
||||
activity.objects = [object];
|
||||
if (activity instanceof Error) {
|
||||
return errorResponse(activity.message, 409);
|
||||
}
|
||||
|
||||
await object.save();
|
||||
await activity.save();
|
||||
break;
|
||||
}
|
||||
case "Delete" as APDelete: {
|
||||
|
|
@ -135,59 +75,10 @@ export default async (
|
|||
// Delete the object from database
|
||||
// TODO: Add authentication
|
||||
|
||||
const object = await RawObject.createQueryBuilder("object")
|
||||
.where("object.data->>'id' = :id", {
|
||||
id: (body.object as APObject).id,
|
||||
})
|
||||
.getOne();
|
||||
|
||||
if (!object) return errorResponse("Object not found", 404);
|
||||
|
||||
const activities = await RawActivity.createQueryBuilder("activity")
|
||||
// Objects is a many-to-many relationship
|
||||
.leftJoinAndSelect("activity.objects", "objects")
|
||||
.where("objects.data @> :data", {
|
||||
data: JSON.stringify({
|
||||
id: object.id,
|
||||
}),
|
||||
})
|
||||
.getMany();
|
||||
|
||||
if (config.activitypub.use_tombstones) {
|
||||
object.data = {
|
||||
...object.data,
|
||||
type: "Tombstone",
|
||||
deleted: new Date(),
|
||||
formerType: object.data.type,
|
||||
} as APTombstone;
|
||||
|
||||
await object.save();
|
||||
} else {
|
||||
activities.forEach(
|
||||
activity =>
|
||||
(activity.objects = activity.objects.filter(
|
||||
o => o.id !== object.id
|
||||
))
|
||||
);
|
||||
|
||||
await Promise.all(
|
||||
activities.map(async activity => await activity.save())
|
||||
);
|
||||
|
||||
await object.remove();
|
||||
}
|
||||
await RawActivity.deleteObjectIfExists(body.object as APObject);
|
||||
|
||||
// Store the Delete event in the database
|
||||
const activity = new RawActivity();
|
||||
activity.data = {
|
||||
...body,
|
||||
object: undefined,
|
||||
};
|
||||
activity.objects = config.activitypub.use_tombstones
|
||||
? [object]
|
||||
: [];
|
||||
|
||||
await activity.save();
|
||||
const activity = RawActivity.addIfNotExists(body);
|
||||
break;
|
||||
}
|
||||
case "Accept" as APAccept: {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue