Refactor code, add more filtering

This commit is contained in:
Jesse Wierzbinski 2023-09-17 19:38:08 -10:00
parent 768d1858dc
commit 4d0283caf0
No known key found for this signature in database
GPG key ID: F9A1E418934E40B0
8 changed files with 397 additions and 151 deletions

View file

@ -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: {