From 6321e7839f42b68cd548abcbd4e7b682fd21422b Mon Sep 17 00:00:00 2001 From: devin ivy <devinivy@gmail.com> Date: Mon, 7 Aug 2023 17:20:26 -0400 Subject: [PATCH] Include pds account info on mod report and action details (#1441) hydrate pds repo state onto mod report and action subject details --- .../com/atproto/admin/getModerationAction.ts | 34 ++++++++--- .../com/atproto/admin/getModerationReport.ts | 33 +++++++++-- .../proxied/__snapshots__/admin.test.ts.snap | 56 +++++++++++++++++++ 3 files changed, 110 insertions(+), 13 deletions(-) diff --git a/packages/pds/src/api/com/atproto/admin/getModerationAction.ts b/packages/pds/src/api/com/atproto/admin/getModerationAction.ts index 60058169..251979cb 100644 --- a/packages/pds/src/api/com/atproto/admin/getModerationAction.ts +++ b/packages/pds/src/api/com/atproto/admin/getModerationAction.ts @@ -1,28 +1,48 @@ import { Server } from '../../../../lexicon' import AppContext from '../../../../context' -import { authPassthru } from './util' +import { authPassthru, mergeRepoViewPdsDetails } from './util' +import { isRepoView } from '@atproto/api/src/client/types/com/atproto/admin/defs' export default function (server: Server, ctx: AppContext) { server.com.atproto.admin.getModerationAction({ auth: ctx.roleVerifier, handler: async ({ req, params, auth }) => { + const access = auth.credentials + const { db, services } = ctx + const accountService = services.account(db) + const moderationService = services.moderation(db) + if (ctx.shouldProxyModeration()) { - // @TODO merge invite details into action subject - const { data: result } = + const { data: resultAppview } = await ctx.appviewAgent.com.atproto.admin.getModerationAction( params, authPassthru(req), ) + // merge local repo state for subject if available + if (isRepoView(resultAppview.subject)) { + const account = await accountService.getAccount( + resultAppview.subject.did, + true, + ) + const repo = + account && + (await moderationService.views.repo(account, { + includeEmails: access.moderator, + })) + if (repo) { + resultAppview.subject = mergeRepoViewPdsDetails( + resultAppview.subject, + repo, + ) + } + } return { encoding: 'application/json', - body: result, + body: resultAppview, } } - const access = auth.credentials - const { db, services } = ctx const { id } = params - const moderationService = services.moderation(db) const result = await moderationService.getActionOrThrow(id) return { encoding: 'application/json', diff --git a/packages/pds/src/api/com/atproto/admin/getModerationReport.ts b/packages/pds/src/api/com/atproto/admin/getModerationReport.ts index 0368a337..5af7381f 100644 --- a/packages/pds/src/api/com/atproto/admin/getModerationReport.ts +++ b/packages/pds/src/api/com/atproto/admin/getModerationReport.ts @@ -1,27 +1,48 @@ +import { isRepoView } from '@atproto/api/src/client/types/com/atproto/admin/defs' import { Server } from '../../../../lexicon' import AppContext from '../../../../context' -import { authPassthru } from './util' +import { authPassthru, mergeRepoViewPdsDetails } from './util' export default function (server: Server, ctx: AppContext) { server.com.atproto.admin.getModerationReport({ auth: ctx.roleVerifier, handler: async ({ req, params, auth }) => { + const access = auth.credentials + const { db, services } = ctx + const accountService = services.account(db) + const moderationService = services.moderation(db) + if (ctx.shouldProxyModeration()) { - const { data: result } = + const { data: resultAppview } = await ctx.appviewAgent.com.atproto.admin.getModerationReport( params, authPassthru(req), ) + // merge local repo state for subject if available + if (isRepoView(resultAppview.subject)) { + const account = await accountService.getAccount( + resultAppview.subject.did, + true, + ) + const repo = + account && + (await moderationService.views.repo(account, { + includeEmails: access.moderator, + })) + if (repo) { + resultAppview.subject = mergeRepoViewPdsDetails( + resultAppview.subject, + repo, + ) + } + } return { encoding: 'application/json', - body: result, + body: resultAppview, } } - const access = auth.credentials - const { db, services } = ctx const { id } = params - const moderationService = services.moderation(db) const result = await moderationService.getReportOrThrow(id) return { encoding: 'application/json', diff --git a/packages/pds/tests/proxied/__snapshots__/admin.test.ts.snap b/packages/pds/tests/proxied/__snapshots__/admin.test.ts.snap index ebdd162f..46a88622 100644 --- a/packages/pds/tests/proxied/__snapshots__/admin.test.ts.snap +++ b/packages/pds/tests/proxied/__snapshots__/admin.test.ts.snap @@ -122,8 +122,36 @@ Object { "subject": Object { "$type": "com.atproto.admin.defs#repoView", "did": "user(0)", + "email": "bob@test.com", "handle": "bob.test", "indexedAt": "1970-01-01T00:00:00.000Z", + "invitedBy": Object { + "available": 10, + "code": "invite-code", + "createdAt": "1970-01-01T00:00:00.000Z", + "createdBy": "admin", + "disabled": false, + "forAccount": "admin", + "uses": Array [ + Object { + "usedAt": "1970-01-01T00:00:00.000Z", + "usedBy": "user(1)", + }, + Object { + "usedAt": "1970-01-01T00:00:00.000Z", + "usedBy": "user(0)", + }, + Object { + "usedAt": "1970-01-01T00:00:00.000Z", + "usedBy": "user(2)", + }, + Object { + "usedAt": "1970-01-01T00:00:00.000Z", + "usedBy": "user(3)", + }, + ], + }, + "invitesDisabled": true, "moderation": Object {}, "relatedRecords": Array [ Object { @@ -300,8 +328,36 @@ Object { "subject": Object { "$type": "com.atproto.admin.defs#repoView", "did": "user(1)", + "email": "bob@test.com", "handle": "bob.test", "indexedAt": "1970-01-01T00:00:00.000Z", + "invitedBy": Object { + "available": 10, + "code": "invite-code", + "createdAt": "1970-01-01T00:00:00.000Z", + "createdBy": "admin", + "disabled": false, + "forAccount": "admin", + "uses": Array [ + Object { + "usedAt": "1970-01-01T00:00:00.000Z", + "usedBy": "user(0)", + }, + Object { + "usedAt": "1970-01-01T00:00:00.000Z", + "usedBy": "user(1)", + }, + Object { + "usedAt": "1970-01-01T00:00:00.000Z", + "usedBy": "user(2)", + }, + Object { + "usedAt": "1970-01-01T00:00:00.000Z", + "usedBy": "user(3)", + }, + ], + }, + "invitesDisabled": true, "moderation": Object { "currentAction": Object { "action": "com.atproto.admin.defs#acknowledge",