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

Configure Feed

Select the types of activity you want to include in your feed.

start of support for post label checks too

+24 -19
+1
pnpm-workspace.yaml
··· 1 1 onlyBuiltDependencies: 2 2 - core-js 3 + - esbuild
+17 -6
src/handlers/handleNewLabel.ts
··· 13 13 pdsConfigs: Record<string, PDSConfig>, 14 14 ) => { 15 15 try { 16 + let targetDid = ""; 17 + if (label.uri.startsWith("did:")) { 18 + // Identity label 19 + targetDid = label.uri; 20 + } else { 21 + // Content label for a Record 22 + //TODO need to pass on the full url later for logging to the db and notifiation 23 + let atUriSplit = label.uri.split("/"); 24 + let repoDid = atUriSplit[2]; 25 + } 26 + 16 27 // TODO: MAKE SURE TO CHECK NEG 17 28 let labledDate = new Date(label.cts); 18 29 logger.debug( ··· 33 44 .from(schema.watchedRepos) 34 45 .where( 35 46 and( 36 - eq(schema.watchedRepos.did, label.uri), 47 + eq(schema.watchedRepos.did, targetDid), 37 48 eq(schema.watchedRepos.active, true), 38 49 ), 39 50 ) ··· 42 53 if (isRepoWatched.length > 0) { 43 54 const watchedRepo = isRepoWatched[0]; 44 55 if (watchedRepo == undefined) { 45 - throw new Error(`Unexpected error on watched repo: ${label.uri}`); 56 + throw new Error(`Unexpected error on watched repo: ${targetDid}`); 46 57 } 47 58 const pdsConfig = Object.values(pdsConfigs).find( 48 59 (config) => config.host === watchedRepo.pdsHost, ··· 61 72 .from(schema.labelsApplied) 62 73 .where( 63 74 and( 64 - eq(schema.labelsApplied.did, label.uri), 75 + eq(schema.labelsApplied.did, targetDid), 65 76 eq(schema.labelsApplied.label, label.val), 66 77 eq(schema.labelsApplied.labeler, config.host), 67 78 ), ··· 79 90 }) 80 91 .where(eq(schema.labelsApplied.id, existingRecord.id)); 81 92 logger.debug( 82 - { did: label.uri, label: label.val }, 93 + { did: targetDid, label: label.val }, 83 94 "Updated existing label record", 84 95 ); 85 96 } else { 86 97 await db.insert(schema.labelsApplied).values({ 87 - did: label.uri, 98 + did: targetDid, 88 99 label: label.val, 89 100 labeler: config.host, 90 101 action: labelConfig.action, ··· 97 108 if (labelConfig.action === "notify") { 98 109 //TODO need to prob move this to a queue cause backfill can hit rate limit 99 110 await sendLabelNotification(pdsConfig.notifyEmails, { 100 - did: label.uri, 111 + did: targetDid, 101 112 pds: pdsConfig.host, 102 113 label: label.val, 103 114 labeler: config.host,
+6 -6
src/handlers/lablerSubscriber.ts
··· 34 34 // Saves the cursor for resume and re connect 35 35 if ("seq" in message) { 36 36 cursor = message.seq; 37 + // May change to only save cursor every so often to cut down on writes 38 + // if (cursor % 10 === 0) { 37 39 await db 38 40 .insert(labelerCursor) 39 41 .values({ labelerId: config.host, cursor: message.seq }) ··· 41 43 target: [labelerCursor.labelerId], 42 44 set: { cursor: message.seq }, 43 45 }); 46 + // } 44 47 } 45 48 switch (message.$type) { 46 49 case "com.atproto.label.subscribeLabels#info": { ··· 49 52 } 50 53 case "com.atproto.label.subscribeLabels#labels": { 51 54 for (const label of message.labels) { 52 - // We only care about labels for identities, not content for now 53 - if (label.uri.startsWith("did:")) { 54 - queue.add(async () => { 55 - await handleNewLabel(config, label, db, pdsConfigs); 56 - }); 57 - } 55 + queue.add(async () => { 56 + await handleNewLabel(config, label, db, pdsConfigs); 57 + }); 58 58 } 59 59 break; 60 60 }
-7
src/index.ts
··· 13 13 const labelQueue = new PQueue({ concurrency: 2 }); 14 14 const identityQueue = new PQueue({ concurrency: 2 }); 15 15 16 - // TODO 17 - // 1. Figure out a schema for settings we want. PDSs to watch.Labelers and their Labels 18 - // and which actions to do for them (notification/email) or auto takedown. thinking toml file maybe? 19 - // 2. Add a CLI argument to backfill PDS repos on start up. If finds a new active repo adds it 20 - // 3. Add a firehose listener that subscribes to the PDSs for new identities? (I say maybe not cause of bandwidth) 21 - // 4. We can save the last sen sequence from the labler to the db and restore it on startup for backfill 22 - 23 16 // Run Drizzle migrations on startup 24 17 migrate(db, { migrationsFolder: process.env.MIGRATIONS_FOLDER ?? "drizzle" }); 25 18