94
packages/backend/src/services/relay.ts
Normal file
94
packages/backend/src/services/relay.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
import { createSystemUser } from './create-system-user';
|
||||
import { renderFollowRelay } from '@/remote/activitypub/renderer/follow-relay';
|
||||
import { renderActivity, attachLdSignature } from '@/remote/activitypub/renderer/index';
|
||||
import renderUndo from '@/remote/activitypub/renderer/undo';
|
||||
import { deliver } from '@/queue/index';
|
||||
import { ILocalUser, User } from '@/models/entities/user';
|
||||
import { Users, Relays } from '@/models/index';
|
||||
import { genId } from '@/misc/gen-id';
|
||||
|
||||
const ACTOR_USERNAME = 'relay.actor' as const;
|
||||
|
||||
export async function getRelayActor(): Promise<ILocalUser> {
|
||||
const user = await Users.findOne({
|
||||
host: null,
|
||||
username: ACTOR_USERNAME
|
||||
});
|
||||
|
||||
if (user) return user as ILocalUser;
|
||||
|
||||
const created = await createSystemUser(ACTOR_USERNAME);
|
||||
return created as ILocalUser;
|
||||
}
|
||||
|
||||
export async function addRelay(inbox: string) {
|
||||
const relay = await Relays.save({
|
||||
id: genId(),
|
||||
inbox,
|
||||
status: 'requesting'
|
||||
});
|
||||
|
||||
const relayActor = await getRelayActor();
|
||||
const follow = await renderFollowRelay(relay, relayActor);
|
||||
const activity = renderActivity(follow);
|
||||
deliver(relayActor, activity, relay.inbox);
|
||||
|
||||
return relay;
|
||||
}
|
||||
|
||||
export async function removeRelay(inbox: string) {
|
||||
const relay = await Relays.findOne({
|
||||
inbox
|
||||
});
|
||||
|
||||
if (relay == null) {
|
||||
throw 'relay not found';
|
||||
}
|
||||
|
||||
const relayActor = await getRelayActor();
|
||||
const follow = renderFollowRelay(relay, relayActor);
|
||||
const undo = renderUndo(follow, relayActor);
|
||||
const activity = renderActivity(undo);
|
||||
deliver(relayActor, activity, relay.inbox);
|
||||
|
||||
await Relays.delete(relay.id);
|
||||
}
|
||||
|
||||
export async function listRelay() {
|
||||
const relays = await Relays.find();
|
||||
return relays;
|
||||
}
|
||||
|
||||
export async function relayAccepted(id: string) {
|
||||
const result = await Relays.update(id, {
|
||||
status: 'accepted'
|
||||
});
|
||||
|
||||
return JSON.stringify(result);
|
||||
}
|
||||
|
||||
export async function relayRejected(id: string) {
|
||||
const result = await Relays.update(id, {
|
||||
status: 'rejected'
|
||||
});
|
||||
|
||||
return JSON.stringify(result);
|
||||
}
|
||||
|
||||
export async function deliverToRelays(user: { id: User['id']; host: null; }, activity: any) {
|
||||
if (activity == null) return;
|
||||
|
||||
const relays = await Relays.find({
|
||||
status: 'accepted'
|
||||
});
|
||||
if (relays.length === 0) return;
|
||||
|
||||
const copy = JSON.parse(JSON.stringify(activity));
|
||||
if (!copy.to) copy.to = ['https://www.w3.org/ns/activitystreams#Public'];
|
||||
|
||||
const signed = await attachLdSignature(copy, user);
|
||||
|
||||
for (const relay of relays) {
|
||||
deliver(user, signed, relay.inbox);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user