summaryrefslogtreecommitdiff
path: root/src/services/relay.ts
blob: 0eb3bb41a1cb471214af128e38e8776406ef0efd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import { createSystemUser } from './create-system-user';
import { renderFollowRelay } from '../remote/activitypub/renderer/follow-relay';
import { renderActivity, attachLdSignature } from '../remote/activitypub/renderer';
import renderUndo from '../remote/activitypub/renderer/undo';
import { deliver } from '../queue';
import { ILocalUser } from '../models/entities/user';
import { Users, Relays } from '../models';
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: ILocalUser, 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);
	}
}