tangled
alpha
login
or
join now
andresitorresm.com
/
label-watcher
forked from
baileytownsend.dev/label-watcher
0
fork
atom
PDS Admin tool make it easier to moderate your PDS with labels
0
fork
atom
overview
issues
pulls
pipelines
takedown wip
baileytownsend.dev
1 month ago
b4e230ab
4841dbc8
+101
-19
4 changed files
expand all
collapse all
unified
split
src
handlers
handleNewLabel.ts
index.ts
mailer.ts
types
settings.ts
+69
-13
src/handlers/handleNewLabel.ts
···
6
6
import * as schema from "../db/schema.js";
7
7
import { and, eq } from "drizzle-orm";
8
8
import type PQueue from "p-queue";
9
9
+
import { Client, simpleFetchHandler, ok } from "@atcute/client";
10
10
+
import { ComAtprotoAdminUpdateSubjectStatus } from "@atcute/atproto";
11
11
+
const adminAuthHeader = (password: string) => ({
12
12
+
Authorization: `Basic ${Buffer.from(`admin:${password}`).toString("base64")}`,
13
13
+
});
9
14
10
15
export const handleNewLabel = async (
11
16
config: LabelerConfig,
···
111
116
}
112
117
113
118
// Perform action
114
114
-
if (labelConfig.action === "notify") {
115
115
-
await mailQueue.add(() =>
116
116
-
sendLabelNotification(pdsConfig.notifyEmails, {
117
117
-
did: targetDid,
118
118
-
pds: pdsConfig.host,
119
119
-
label: label.val,
120
120
-
labeler: config.host,
121
121
-
negated: label.neg ?? false,
122
122
-
dateApplied: labledDate,
123
123
-
}).catch((err) =>
124
124
-
logger.error({ err }, "Error sending label notification email"),
125
125
-
),
126
126
-
);
119
119
+
switch (labelConfig.action) {
120
120
+
case "notify":
121
121
+
await mailQueue.add(() =>
122
122
+
sendLabelNotification(pdsConfig.notifyEmails, {
123
123
+
did: targetDid,
124
124
+
pds: pdsConfig.host,
125
125
+
label: label.val,
126
126
+
labeler: config.host,
127
127
+
negated: label.neg ?? false,
128
128
+
dateApplied: labledDate,
129
129
+
takeDown: false,
130
130
+
}).catch((err) =>
131
131
+
logger.error({ err }, "Error sending label notification email"),
132
132
+
),
133
133
+
);
134
134
+
case "takedown":
135
135
+
if (pdsConfig.pdsAdminPassword) {
136
136
+
const rpc = new Client({
137
137
+
handler: simpleFetchHandler({
138
138
+
service: `https://${pdsConfig.host}`,
139
139
+
}),
140
140
+
});
141
141
+
142
142
+
logger.info("taking down the account");
143
143
+
//TODO do atcute actions and then send email
144
144
+
if (label.neg) {
145
145
+
//reverse takedown
146
146
+
let reverseTakeDown = rpc.call(
147
147
+
ComAtprotoAdminUpdateSubjectStatus,
148
148
+
{
149
149
+
input: {
150
150
+
subject: {
151
151
+
$type: "com.atproto.admin.defs#repoRef",
152
152
+
did: targetDid as `did:${string}:${string}.`,
153
153
+
},
154
154
+
takedown: {
155
155
+
applied: false,
156
156
+
},
157
157
+
},
158
158
+
headers: adminAuthHeader(pdsConfig.pdsAdminPassword),
159
159
+
},
160
160
+
);
161
161
+
} else {
162
162
+
//issue takedown
163
163
+
let takeDown = rpc.call(ComAtprotoAdminUpdateSubjectStatus, {
164
164
+
input: {
165
165
+
subject: {
166
166
+
$type: "com.atproto.admin.defs#repoRef",
167
167
+
did: targetDid as `did:${string}:${string}.`,
168
168
+
},
169
169
+
takedown: {
170
170
+
applied: true,
171
171
+
ref: Math.floor(Date.now() / 1000).toString(),
172
172
+
},
173
173
+
},
174
174
+
headers: adminAuthHeader(pdsConfig.pdsAdminPassword),
175
175
+
});
176
176
+
}
177
177
+
break;
178
178
+
} else {
179
179
+
logger.warn("PDS admin password not set, takedown not issued");
180
180
+
}
181
181
+
182
182
+
//Send the email here still. IF passwrod is not set always set takedown as false?
127
183
}
128
184
129
185
return;
+17
-2
src/index.ts
···
53
53
(cursor) => cursor.labelerId === config.host,
54
54
);
55
55
let lastCursor = lastCursorRow?.cursor ?? undefined;
56
56
-
return labelerSubscriber(config, lastCursor, db, labelQueue, settings.pds, mailQueue);
56
56
+
//If there is not a lastcusor do a full backfill
57
57
+
if (!lastCursor && config.backfillLabels) {
58
58
+
lastCursor = 0;
59
59
+
}
60
60
+
return labelerSubscriber(
61
61
+
config,
62
62
+
lastCursor,
63
63
+
db,
64
64
+
labelQueue,
65
65
+
settings.pds,
66
66
+
mailQueue,
67
67
+
);
57
68
})
58
69
.filter((x) => x !== null);
59
70
···
75
86
pdsSubscribers.forEach((close) => close());
76
87
77
88
logger.info("Draining the queues...");
78
78
-
await Promise.all([labelQueue.onIdle(), identityQueue.onIdle(), mailQueue.onIdle()]);
89
89
+
await Promise.all([
90
90
+
labelQueue.onIdle(),
91
91
+
identityQueue.onIdle(),
92
92
+
mailQueue.onIdle(),
93
93
+
]);
79
94
80
95
logger.info("Clean shutdown complete.");
81
96
process.exit(0);
+14
-3
src/mailer.ts
···
24
24
labeler: string;
25
25
negated: boolean;
26
26
dateApplied: Date;
27
27
+
takeDown: boolean;
27
28
},
28
29
) => {
29
29
-
const { did, pds, label, labeler, negated, dateApplied } = params;
30
30
+
const { did, pds, label, labeler, negated, dateApplied, takeDown } = params;
30
31
31
32
const subject = `Label "${label}" ${negated ? "negated" : "applied"} — ${did} - ${pds}`;
32
32
-
const text = [
33
33
+
let info = [
33
34
`A label event was detected.`,
34
35
``,
35
36
`DID: ${did}`,
···
38
39
`Labeler: ${labeler}`,
39
40
`Negated: ${negated}`,
40
41
`Date: ${dateApplied.toISOString()}`,
41
41
-
].join("\n");
42
42
+
];
43
43
+
44
44
+
if (takeDown) {
45
45
+
if (negated) {
46
46
+
info.push(`Label negated, takedown reversed.`);
47
47
+
} else {
48
48
+
info.push(`Takedown issued.`);
49
49
+
}
50
50
+
}
51
51
+
52
52
+
const text = info.join("\n");
42
53
43
54
if (resend) {
44
55
await resend.emails.send({
+1
-1
src/types/settings.ts
···
3
3
export interface PDSConfig {
4
4
host: string;
5
5
notifyEmails: string[];
6
6
-
pdsAdminPassword: string;
6
6
+
pdsAdminPassword?: string;
7
7
backfillAccounts: boolean;
8
8
listenForNewAccounts: boolean;
9
9
}