PDS Admin tool make it easier to moderate your PDS with labels

takedown wip

+101 -19
+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 + import { Client, simpleFetchHandler, ok } from "@atcute/client"; 10 + import { ComAtprotoAdminUpdateSubjectStatus } from "@atcute/atproto"; 11 + const adminAuthHeader = (password: string) => ({ 12 + Authorization: `Basic ${Buffer.from(`admin:${password}`).toString("base64")}`, 13 + }); 9 14 10 15 export const handleNewLabel = async ( 11 16 config: LabelerConfig, ··· 111 116 } 112 117 113 118 // Perform action 114 - if (labelConfig.action === "notify") { 115 - await mailQueue.add(() => 116 - sendLabelNotification(pdsConfig.notifyEmails, { 117 - did: targetDid, 118 - pds: pdsConfig.host, 119 - label: label.val, 120 - labeler: config.host, 121 - negated: label.neg ?? false, 122 - dateApplied: labledDate, 123 - }).catch((err) => 124 - logger.error({ err }, "Error sending label notification email"), 125 - ), 126 - ); 119 + switch (labelConfig.action) { 120 + case "notify": 121 + await mailQueue.add(() => 122 + sendLabelNotification(pdsConfig.notifyEmails, { 123 + did: targetDid, 124 + pds: pdsConfig.host, 125 + label: label.val, 126 + labeler: config.host, 127 + negated: label.neg ?? false, 128 + dateApplied: labledDate, 129 + takeDown: false, 130 + }).catch((err) => 131 + logger.error({ err }, "Error sending label notification email"), 132 + ), 133 + ); 134 + case "takedown": 135 + if (pdsConfig.pdsAdminPassword) { 136 + const rpc = new Client({ 137 + handler: simpleFetchHandler({ 138 + service: `https://${pdsConfig.host}`, 139 + }), 140 + }); 141 + 142 + logger.info("taking down the account"); 143 + //TODO do atcute actions and then send email 144 + if (label.neg) { 145 + //reverse takedown 146 + let reverseTakeDown = rpc.call( 147 + ComAtprotoAdminUpdateSubjectStatus, 148 + { 149 + input: { 150 + subject: { 151 + $type: "com.atproto.admin.defs#repoRef", 152 + did: targetDid as `did:${string}:${string}.`, 153 + }, 154 + takedown: { 155 + applied: false, 156 + }, 157 + }, 158 + headers: adminAuthHeader(pdsConfig.pdsAdminPassword), 159 + }, 160 + ); 161 + } else { 162 + //issue takedown 163 + let takeDown = rpc.call(ComAtprotoAdminUpdateSubjectStatus, { 164 + input: { 165 + subject: { 166 + $type: "com.atproto.admin.defs#repoRef", 167 + did: targetDid as `did:${string}:${string}.`, 168 + }, 169 + takedown: { 170 + applied: true, 171 + ref: Math.floor(Date.now() / 1000).toString(), 172 + }, 173 + }, 174 + headers: adminAuthHeader(pdsConfig.pdsAdminPassword), 175 + }); 176 + } 177 + break; 178 + } else { 179 + logger.warn("PDS admin password not set, takedown not issued"); 180 + } 181 + 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 - return labelerSubscriber(config, lastCursor, db, labelQueue, settings.pds, mailQueue); 56 + //If there is not a lastcusor do a full backfill 57 + if (!lastCursor && config.backfillLabels) { 58 + lastCursor = 0; 59 + } 60 + return labelerSubscriber( 61 + config, 62 + lastCursor, 63 + db, 64 + labelQueue, 65 + settings.pds, 66 + mailQueue, 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 - await Promise.all([labelQueue.onIdle(), identityQueue.onIdle(), mailQueue.onIdle()]); 89 + await Promise.all([ 90 + labelQueue.onIdle(), 91 + identityQueue.onIdle(), 92 + mailQueue.onIdle(), 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 + takeDown: boolean; 27 28 }, 28 29 ) => { 29 - const { did, pds, label, labeler, negated, dateApplied } = params; 30 + const { did, pds, label, labeler, negated, dateApplied, takeDown } = params; 30 31 31 32 const subject = `Label "${label}" ${negated ? "negated" : "applied"} — ${did} - ${pds}`; 32 - const text = [ 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 - ].join("\n"); 42 + ]; 43 + 44 + if (takeDown) { 45 + if (negated) { 46 + info.push(`Label negated, takedown reversed.`); 47 + } else { 48 + info.push(`Takedown issued.`); 49 + } 50 + } 51 + 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 - pdsAdminPassword: string; 6 + pdsAdminPassword?: string; 7 7 backfillAccounts: boolean; 8 8 listenForNewAccounts: boolean; 9 9 }