From db53a27f92197d59f745cf3b418e472e45f48b9f Mon Sep 17 00:00:00 2001 From: dholms Date: Mon, 9 Oct 2023 14:42:56 -0500 Subject: [PATCH 1/8] introduce new admin state endpoints --- lexicons/com/atproto/admin/defs.json | 17 +++ .../com/atproto/admin/getSubjectState.json | 39 +++++ .../com/atproto/admin/updateSubjectState.json | 52 +++++++ packages/api/src/client/index.ts | 26 ++++ packages/api/src/client/lexicons.ts | 134 ++++++++++++++++++ .../client/types/com/atproto/admin/defs.ts | 37 +++++ .../com/atproto/admin/getSubjectState.ts | 44 ++++++ .../com/atproto/admin/updateSubjectState.ts | 50 +++++++ packages/bsky/src/lexicon/index.ts | 24 ++++ packages/bsky/src/lexicon/lexicons.ts | 134 ++++++++++++++++++ .../lexicon/types/com/atproto/admin/defs.ts | 37 +++++ .../com/atproto/admin/getSubjectState.ts | 54 +++++++ .../com/atproto/admin/updateSubjectState.ts | 61 ++++++++ .../api/com/atproto/admin/getSubjectState.ts | 45 ++++++ .../com/atproto/admin/updateSubjectState.ts | 52 +++++++ packages/pds/src/db/tables/record.ts | 2 +- packages/pds/src/db/tables/repo-blob.ts | 2 +- packages/pds/src/db/tables/repo-root.ts | 2 +- packages/pds/src/db/util.ts | 2 +- packages/pds/src/lexicon/index.ts | 24 ++++ packages/pds/src/lexicon/lexicons.ts | 134 ++++++++++++++++++ .../lexicon/types/com/atproto/admin/defs.ts | 37 +++++ .../com/atproto/admin/getSubjectState.ts | 54 +++++++ .../com/atproto/admin/updateSubjectState.ts | 61 ++++++++ packages/pds/src/services/moderation/index.ts | 127 ++++++++++++++++- packages/pds/src/services/moderation/views.ts | 2 +- packages/pds/src/services/record/index.ts | 4 +- 27 files changed, 1246 insertions(+), 11 deletions(-) create mode 100644 lexicons/com/atproto/admin/getSubjectState.json create mode 100644 lexicons/com/atproto/admin/updateSubjectState.json create mode 100644 packages/api/src/client/types/com/atproto/admin/getSubjectState.ts create mode 100644 packages/api/src/client/types/com/atproto/admin/updateSubjectState.ts create mode 100644 packages/bsky/src/lexicon/types/com/atproto/admin/getSubjectState.ts create mode 100644 packages/bsky/src/lexicon/types/com/atproto/admin/updateSubjectState.ts create mode 100644 packages/pds/src/api/com/atproto/admin/getSubjectState.ts create mode 100644 packages/pds/src/api/com/atproto/admin/updateSubjectState.ts create mode 100644 packages/pds/src/lexicon/types/com/atproto/admin/getSubjectState.ts create mode 100644 packages/pds/src/lexicon/types/com/atproto/admin/updateSubjectState.ts diff --git a/lexicons/com/atproto/admin/defs.json b/lexicons/com/atproto/admin/defs.json index a04c77d68f8..6e066893d19 100644 --- a/lexicons/com/atproto/admin/defs.json +++ b/lexicons/com/atproto/admin/defs.json @@ -2,6 +2,14 @@ "lexicon": 1, "id": "com.atproto.admin.defs", "defs": { + "subjectState": { + "type": "object", + "required": ["applied"], + "properties": { + "applied": { "type": "boolean" }, + "ref": { "type": "string" } + } + }, "actionView": { "type": "object", "required": [ @@ -257,6 +265,15 @@ "did": { "type": "string", "format": "did" } } }, + "repoBlobRef": { + "type": "object", + "required": ["did", "cid"], + "properties": { + "did": { "type": "string", "format": "did" }, + "cid": { "type": "string", "format": "cid" }, + "recordUri": { "type": "string", "format": "at-uri" } + } + }, "recordView": { "type": "object", "required": [ diff --git a/lexicons/com/atproto/admin/getSubjectState.json b/lexicons/com/atproto/admin/getSubjectState.json new file mode 100644 index 00000000000..abe40ed1052 --- /dev/null +++ b/lexicons/com/atproto/admin/getSubjectState.json @@ -0,0 +1,39 @@ +{ + "lexicon": 1, + "id": "com.atproto.admin.getSubjectState", + "defs": { + "main": { + "type": "query", + "description": "Fetch the service-specific the admin state of a subject (account, record, or blob)", + "parameters": { + "type": "params", + "properties": { + "did": { "type": "string", "format": "did" }, + "uri": { "type": "string", "format": "at-uri" }, + "blob": { "type": "string", "format": "cid" } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["subject"], + "properties": { + "subject": { + "type": "union", + "refs": [ + "com.atproto.admin.defs#repoRef", + "com.atproto.repo.strongRef", + "com.atproto.admin.defs#repoBlobRef" + ] + }, + "takedown": { + "type": "ref", + "ref": "com.atproto.admin.defs#subjectState" + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/admin/updateSubjectState.json b/lexicons/com/atproto/admin/updateSubjectState.json new file mode 100644 index 00000000000..fe50c790388 --- /dev/null +++ b/lexicons/com/atproto/admin/updateSubjectState.json @@ -0,0 +1,52 @@ +{ + "lexicon": 1, + "id": "com.atproto.admin.updateSubjectState", + "defs": { + "main": { + "type": "procedure", + "description": "Update the service-specific admin state of a subject (account, record, or blob)", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["subject"], + "properties": { + "subject": { + "type": "union", + "refs": [ + "com.atproto.admin.defs#repoRef", + "com.atproto.repo.strongRef", + "com.atproto.admin.defs#repoBlobRef" + ] + }, + "takedown": { + "type": "ref", + "ref": "com.atproto.admin.defs#subjectState" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["subject"], + "properties": { + "subject": { + "type": "union", + "refs": [ + "com.atproto.admin.defs#repoRef", + "com.atproto.repo.strongRef", + "com.atproto.admin.defs#repoBlobRef" + ] + }, + "takedown": { + "type": "ref", + "ref": "com.atproto.admin.defs#subjectState" + } + } + } + } + } + } +} diff --git a/packages/api/src/client/index.ts b/packages/api/src/client/index.ts index e5286aa2eb1..bf6517e8ae4 100644 --- a/packages/api/src/client/index.ts +++ b/packages/api/src/client/index.ts @@ -18,6 +18,7 @@ import * as ComAtprotoAdminGetModerationReport from './types/com/atproto/admin/g import * as ComAtprotoAdminGetModerationReports from './types/com/atproto/admin/getModerationReports' import * as ComAtprotoAdminGetRecord from './types/com/atproto/admin/getRecord' import * as ComAtprotoAdminGetRepo from './types/com/atproto/admin/getRepo' +import * as ComAtprotoAdminGetSubjectState from './types/com/atproto/admin/getSubjectState' import * as ComAtprotoAdminResolveModerationReports from './types/com/atproto/admin/resolveModerationReports' import * as ComAtprotoAdminReverseModerationAction from './types/com/atproto/admin/reverseModerationAction' import * as ComAtprotoAdminSearchRepos from './types/com/atproto/admin/searchRepos' @@ -25,6 +26,7 @@ import * as ComAtprotoAdminSendEmail from './types/com/atproto/admin/sendEmail' import * as ComAtprotoAdminTakeModerationAction from './types/com/atproto/admin/takeModerationAction' import * as ComAtprotoAdminUpdateAccountEmail from './types/com/atproto/admin/updateAccountEmail' import * as ComAtprotoAdminUpdateAccountHandle from './types/com/atproto/admin/updateAccountHandle' +import * as ComAtprotoAdminUpdateSubjectState from './types/com/atproto/admin/updateSubjectState' import * as ComAtprotoIdentityResolveHandle from './types/com/atproto/identity/resolveHandle' import * as ComAtprotoIdentityUpdateHandle from './types/com/atproto/identity/updateHandle' import * as ComAtprotoLabelDefs from './types/com/atproto/label/defs' @@ -151,6 +153,7 @@ export * as ComAtprotoAdminGetModerationReport from './types/com/atproto/admin/g export * as ComAtprotoAdminGetModerationReports from './types/com/atproto/admin/getModerationReports' export * as ComAtprotoAdminGetRecord from './types/com/atproto/admin/getRecord' export * as ComAtprotoAdminGetRepo from './types/com/atproto/admin/getRepo' +export * as ComAtprotoAdminGetSubjectState from './types/com/atproto/admin/getSubjectState' export * as ComAtprotoAdminResolveModerationReports from './types/com/atproto/admin/resolveModerationReports' export * as ComAtprotoAdminReverseModerationAction from './types/com/atproto/admin/reverseModerationAction' export * as ComAtprotoAdminSearchRepos from './types/com/atproto/admin/searchRepos' @@ -158,6 +161,7 @@ export * as ComAtprotoAdminSendEmail from './types/com/atproto/admin/sendEmail' export * as ComAtprotoAdminTakeModerationAction from './types/com/atproto/admin/takeModerationAction' export * as ComAtprotoAdminUpdateAccountEmail from './types/com/atproto/admin/updateAccountEmail' export * as ComAtprotoAdminUpdateAccountHandle from './types/com/atproto/admin/updateAccountHandle' +export * as ComAtprotoAdminUpdateSubjectState from './types/com/atproto/admin/updateSubjectState' export * as ComAtprotoIdentityResolveHandle from './types/com/atproto/identity/resolveHandle' export * as ComAtprotoIdentityUpdateHandle from './types/com/atproto/identity/updateHandle' export * as ComAtprotoLabelDefs from './types/com/atproto/label/defs' @@ -471,6 +475,17 @@ export class AdminNS { }) } + getSubjectState( + params?: ComAtprotoAdminGetSubjectState.QueryParams, + opts?: ComAtprotoAdminGetSubjectState.CallOptions, + ): Promise { + return this._service.xrpc + .call('com.atproto.admin.getSubjectState', params, undefined, opts) + .catch((e) => { + throw ComAtprotoAdminGetSubjectState.toKnownErr(e) + }) + } + resolveModerationReports( data?: ComAtprotoAdminResolveModerationReports.InputSchema, opts?: ComAtprotoAdminResolveModerationReports.CallOptions, @@ -547,6 +562,17 @@ export class AdminNS { throw ComAtprotoAdminUpdateAccountHandle.toKnownErr(e) }) } + + updateSubjectState( + data?: ComAtprotoAdminUpdateSubjectState.InputSchema, + opts?: ComAtprotoAdminUpdateSubjectState.CallOptions, + ): Promise { + return this._service.xrpc + .call('com.atproto.admin.updateSubjectState', opts?.qp, data, opts) + .catch((e) => { + throw ComAtprotoAdminUpdateSubjectState.toKnownErr(e) + }) + } } export class IdentityNS { diff --git a/packages/api/src/client/lexicons.ts b/packages/api/src/client/lexicons.ts index ded6b1f86f6..4ebf1811194 100644 --- a/packages/api/src/client/lexicons.ts +++ b/packages/api/src/client/lexicons.ts @@ -8,6 +8,18 @@ export const schemaDict = { lexicon: 1, id: 'com.atproto.admin.defs', defs: { + subjectState: { + type: 'object', + required: ['applied'], + properties: { + applied: { + type: 'boolean', + }, + ref: { + type: 'string', + }, + }, + }, actionView: { type: 'object', required: [ @@ -444,6 +456,24 @@ export const schemaDict = { }, }, }, + repoBlobRef: { + type: 'object', + required: ['did', 'cid'], + properties: { + did: { + type: 'string', + format: 'did', + }, + cid: { + type: 'string', + format: 'cid', + }, + recordUri: { + type: 'string', + format: 'at-uri', + }, + }, + }, recordView: { type: 'object', required: [ @@ -1026,6 +1056,55 @@ export const schemaDict = { }, }, }, + ComAtprotoAdminGetSubjectState: { + lexicon: 1, + id: 'com.atproto.admin.getSubjectState', + defs: { + main: { + type: 'query', + description: + 'Fetch the service-specific the admin state of a subject (account, record, or blob)', + parameters: { + type: 'params', + properties: { + did: { + type: 'string', + format: 'did', + }, + uri: { + type: 'string', + format: 'at-uri', + }, + blob: { + type: 'string', + format: 'cid', + }, + }, + }, + output: { + encoding: 'application/json', + schema: { + type: 'object', + required: ['subject'], + properties: { + subject: { + type: 'union', + refs: [ + 'lex:com.atproto.admin.defs#repoRef', + 'lex:com.atproto.repo.strongRef', + 'lex:com.atproto.admin.defs#repoBlobRef', + ], + }, + takedown: { + type: 'ref', + ref: 'lex:com.atproto.admin.defs#subjectState', + }, + }, + }, + }, + }, + }, + }, ComAtprotoAdminResolveModerationReports: { lexicon: 1, id: 'com.atproto.admin.resolveModerationReports', @@ -1326,6 +1405,59 @@ export const schemaDict = { }, }, }, + ComAtprotoAdminUpdateSubjectState: { + lexicon: 1, + id: 'com.atproto.admin.updateSubjectState', + defs: { + main: { + type: 'procedure', + description: + 'Update the service-specific admin state of a subject (account, record, or blob)', + input: { + encoding: 'application/json', + schema: { + type: 'object', + required: ['subject'], + properties: { + subject: { + type: 'union', + refs: [ + 'lex:com.atproto.admin.defs#repoRef', + 'lex:com.atproto.repo.strongRef', + 'lex:com.atproto.admin.defs#repoBlobRef', + ], + }, + takedown: { + type: 'ref', + ref: 'lex:com.atproto.admin.defs#subjectState', + }, + }, + }, + }, + output: { + encoding: 'application/json', + schema: { + type: 'object', + required: ['subject'], + properties: { + subject: { + type: 'union', + refs: [ + 'lex:com.atproto.admin.defs#repoRef', + 'lex:com.atproto.repo.strongRef', + 'lex:com.atproto.admin.defs#repoBlobRef', + ], + }, + takedown: { + type: 'ref', + ref: 'lex:com.atproto.admin.defs#subjectState', + }, + }, + }, + }, + }, + }, + }, ComAtprotoIdentityResolveHandle: { lexicon: 1, id: 'com.atproto.identity.resolveHandle', @@ -7335,6 +7467,7 @@ export const ids = { ComAtprotoAdminGetModerationReports: 'com.atproto.admin.getModerationReports', ComAtprotoAdminGetRecord: 'com.atproto.admin.getRecord', ComAtprotoAdminGetRepo: 'com.atproto.admin.getRepo', + ComAtprotoAdminGetSubjectState: 'com.atproto.admin.getSubjectState', ComAtprotoAdminResolveModerationReports: 'com.atproto.admin.resolveModerationReports', ComAtprotoAdminReverseModerationAction: @@ -7344,6 +7477,7 @@ export const ids = { ComAtprotoAdminTakeModerationAction: 'com.atproto.admin.takeModerationAction', ComAtprotoAdminUpdateAccountEmail: 'com.atproto.admin.updateAccountEmail', ComAtprotoAdminUpdateAccountHandle: 'com.atproto.admin.updateAccountHandle', + ComAtprotoAdminUpdateSubjectState: 'com.atproto.admin.updateSubjectState', ComAtprotoIdentityResolveHandle: 'com.atproto.identity.resolveHandle', ComAtprotoIdentityUpdateHandle: 'com.atproto.identity.updateHandle', ComAtprotoLabelDefs: 'com.atproto.label.defs', diff --git a/packages/api/src/client/types/com/atproto/admin/defs.ts b/packages/api/src/client/types/com/atproto/admin/defs.ts index f98814ca8e2..4d2b3685cf5 100644 --- a/packages/api/src/client/types/com/atproto/admin/defs.ts +++ b/packages/api/src/client/types/com/atproto/admin/defs.ts @@ -10,6 +10,24 @@ import * as ComAtprotoModerationDefs from '../moderation/defs' import * as ComAtprotoServerDefs from '../server/defs' import * as ComAtprotoLabelDefs from '../label/defs' +export interface SubjectState { + applied: boolean + ref?: string + [k: string]: unknown +} + +export function isSubjectState(v: unknown): v is SubjectState { + return ( + isObj(v) && + hasProp(v, '$type') && + v.$type === 'com.atproto.admin.defs#subjectState' + ) +} + +export function validateSubjectState(v: unknown): ValidationResult { + return lexicons.validate('com.atproto.admin.defs#subjectState', v) +} + export interface ActionView { id: number action: ActionType @@ -272,6 +290,25 @@ export function validateRepoRef(v: unknown): ValidationResult { return lexicons.validate('com.atproto.admin.defs#repoRef', v) } +export interface RepoBlobRef { + did: string + cid: string + recordUri?: string + [k: string]: unknown +} + +export function isRepoBlobRef(v: unknown): v is RepoBlobRef { + return ( + isObj(v) && + hasProp(v, '$type') && + v.$type === 'com.atproto.admin.defs#repoBlobRef' + ) +} + +export function validateRepoBlobRef(v: unknown): ValidationResult { + return lexicons.validate('com.atproto.admin.defs#repoBlobRef', v) +} + export interface RecordView { uri: string cid: string diff --git a/packages/api/src/client/types/com/atproto/admin/getSubjectState.ts b/packages/api/src/client/types/com/atproto/admin/getSubjectState.ts new file mode 100644 index 00000000000..8d76fbb4720 --- /dev/null +++ b/packages/api/src/client/types/com/atproto/admin/getSubjectState.ts @@ -0,0 +1,44 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import { Headers, XRPCError } from '@atproto/xrpc' +import { ValidationResult, BlobRef } from '@atproto/lexicon' +import { isObj, hasProp } from '../../../../util' +import { lexicons } from '../../../../lexicons' +import { CID } from 'multiformats/cid' +import * as ComAtprotoAdminDefs from './defs' +import * as ComAtprotoRepoStrongRef from '../repo/strongRef' + +export interface QueryParams { + did?: string + uri?: string + blob?: string +} + +export type InputSchema = undefined + +export interface OutputSchema { + subject: + | ComAtprotoAdminDefs.RepoRef + | ComAtprotoRepoStrongRef.Main + | ComAtprotoAdminDefs.RepoBlobRef + | { $type: string; [k: string]: unknown } + takedown?: ComAtprotoAdminDefs.SubjectState + [k: string]: unknown +} + +export interface CallOptions { + headers?: Headers +} + +export interface Response { + success: boolean + headers: Headers + data: OutputSchema +} + +export function toKnownErr(e: any) { + if (e instanceof XRPCError) { + } + return e +} diff --git a/packages/api/src/client/types/com/atproto/admin/updateSubjectState.ts b/packages/api/src/client/types/com/atproto/admin/updateSubjectState.ts new file mode 100644 index 00000000000..55ae3eb5974 --- /dev/null +++ b/packages/api/src/client/types/com/atproto/admin/updateSubjectState.ts @@ -0,0 +1,50 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import { Headers, XRPCError } from '@atproto/xrpc' +import { ValidationResult, BlobRef } from '@atproto/lexicon' +import { isObj, hasProp } from '../../../../util' +import { lexicons } from '../../../../lexicons' +import { CID } from 'multiformats/cid' +import * as ComAtprotoAdminDefs from './defs' +import * as ComAtprotoRepoStrongRef from '../repo/strongRef' + +export interface QueryParams {} + +export interface InputSchema { + subject: + | ComAtprotoAdminDefs.RepoRef + | ComAtprotoRepoStrongRef.Main + | ComAtprotoAdminDefs.RepoBlobRef + | { $type: string; [k: string]: unknown } + takedown?: ComAtprotoAdminDefs.SubjectState + [k: string]: unknown +} + +export interface OutputSchema { + subject: + | ComAtprotoAdminDefs.RepoRef + | ComAtprotoRepoStrongRef.Main + | ComAtprotoAdminDefs.RepoBlobRef + | { $type: string; [k: string]: unknown } + takedown?: ComAtprotoAdminDefs.SubjectState + [k: string]: unknown +} + +export interface CallOptions { + headers?: Headers + qp?: QueryParams + encoding: 'application/json' +} + +export interface Response { + success: boolean + headers: Headers + data: OutputSchema +} + +export function toKnownErr(e: any) { + if (e instanceof XRPCError) { + } + return e +} diff --git a/packages/bsky/src/lexicon/index.ts b/packages/bsky/src/lexicon/index.ts index ac6ca933fcd..30c97349d0a 100644 --- a/packages/bsky/src/lexicon/index.ts +++ b/packages/bsky/src/lexicon/index.ts @@ -19,6 +19,7 @@ import * as ComAtprotoAdminGetModerationReport from './types/com/atproto/admin/g import * as ComAtprotoAdminGetModerationReports from './types/com/atproto/admin/getModerationReports' import * as ComAtprotoAdminGetRecord from './types/com/atproto/admin/getRecord' import * as ComAtprotoAdminGetRepo from './types/com/atproto/admin/getRepo' +import * as ComAtprotoAdminGetSubjectState from './types/com/atproto/admin/getSubjectState' import * as ComAtprotoAdminResolveModerationReports from './types/com/atproto/admin/resolveModerationReports' import * as ComAtprotoAdminReverseModerationAction from './types/com/atproto/admin/reverseModerationAction' import * as ComAtprotoAdminSearchRepos from './types/com/atproto/admin/searchRepos' @@ -26,6 +27,7 @@ import * as ComAtprotoAdminSendEmail from './types/com/atproto/admin/sendEmail' import * as ComAtprotoAdminTakeModerationAction from './types/com/atproto/admin/takeModerationAction' import * as ComAtprotoAdminUpdateAccountEmail from './types/com/atproto/admin/updateAccountEmail' import * as ComAtprotoAdminUpdateAccountHandle from './types/com/atproto/admin/updateAccountHandle' +import * as ComAtprotoAdminUpdateSubjectState from './types/com/atproto/admin/updateSubjectState' import * as ComAtprotoIdentityResolveHandle from './types/com/atproto/identity/resolveHandle' import * as ComAtprotoIdentityUpdateHandle from './types/com/atproto/identity/updateHandle' import * as ComAtprotoLabelQueryLabels from './types/com/atproto/label/queryLabels' @@ -301,6 +303,17 @@ export class AdminNS { return this._server.xrpc.method(nsid, cfg) } + getSubjectState( + cfg: ConfigOf< + AV, + ComAtprotoAdminGetSubjectState.Handler>, + ComAtprotoAdminGetSubjectState.HandlerReqCtx> + >, + ) { + const nsid = 'com.atproto.admin.getSubjectState' // @ts-ignore + return this._server.xrpc.method(nsid, cfg) + } + resolveModerationReports( cfg: ConfigOf< AV, @@ -377,6 +390,17 @@ export class AdminNS { const nsid = 'com.atproto.admin.updateAccountHandle' // @ts-ignore return this._server.xrpc.method(nsid, cfg) } + + updateSubjectState( + cfg: ConfigOf< + AV, + ComAtprotoAdminUpdateSubjectState.Handler>, + ComAtprotoAdminUpdateSubjectState.HandlerReqCtx> + >, + ) { + const nsid = 'com.atproto.admin.updateSubjectState' // @ts-ignore + return this._server.xrpc.method(nsid, cfg) + } } export class IdentityNS { diff --git a/packages/bsky/src/lexicon/lexicons.ts b/packages/bsky/src/lexicon/lexicons.ts index ded6b1f86f6..4ebf1811194 100644 --- a/packages/bsky/src/lexicon/lexicons.ts +++ b/packages/bsky/src/lexicon/lexicons.ts @@ -8,6 +8,18 @@ export const schemaDict = { lexicon: 1, id: 'com.atproto.admin.defs', defs: { + subjectState: { + type: 'object', + required: ['applied'], + properties: { + applied: { + type: 'boolean', + }, + ref: { + type: 'string', + }, + }, + }, actionView: { type: 'object', required: [ @@ -444,6 +456,24 @@ export const schemaDict = { }, }, }, + repoBlobRef: { + type: 'object', + required: ['did', 'cid'], + properties: { + did: { + type: 'string', + format: 'did', + }, + cid: { + type: 'string', + format: 'cid', + }, + recordUri: { + type: 'string', + format: 'at-uri', + }, + }, + }, recordView: { type: 'object', required: [ @@ -1026,6 +1056,55 @@ export const schemaDict = { }, }, }, + ComAtprotoAdminGetSubjectState: { + lexicon: 1, + id: 'com.atproto.admin.getSubjectState', + defs: { + main: { + type: 'query', + description: + 'Fetch the service-specific the admin state of a subject (account, record, or blob)', + parameters: { + type: 'params', + properties: { + did: { + type: 'string', + format: 'did', + }, + uri: { + type: 'string', + format: 'at-uri', + }, + blob: { + type: 'string', + format: 'cid', + }, + }, + }, + output: { + encoding: 'application/json', + schema: { + type: 'object', + required: ['subject'], + properties: { + subject: { + type: 'union', + refs: [ + 'lex:com.atproto.admin.defs#repoRef', + 'lex:com.atproto.repo.strongRef', + 'lex:com.atproto.admin.defs#repoBlobRef', + ], + }, + takedown: { + type: 'ref', + ref: 'lex:com.atproto.admin.defs#subjectState', + }, + }, + }, + }, + }, + }, + }, ComAtprotoAdminResolveModerationReports: { lexicon: 1, id: 'com.atproto.admin.resolveModerationReports', @@ -1326,6 +1405,59 @@ export const schemaDict = { }, }, }, + ComAtprotoAdminUpdateSubjectState: { + lexicon: 1, + id: 'com.atproto.admin.updateSubjectState', + defs: { + main: { + type: 'procedure', + description: + 'Update the service-specific admin state of a subject (account, record, or blob)', + input: { + encoding: 'application/json', + schema: { + type: 'object', + required: ['subject'], + properties: { + subject: { + type: 'union', + refs: [ + 'lex:com.atproto.admin.defs#repoRef', + 'lex:com.atproto.repo.strongRef', + 'lex:com.atproto.admin.defs#repoBlobRef', + ], + }, + takedown: { + type: 'ref', + ref: 'lex:com.atproto.admin.defs#subjectState', + }, + }, + }, + }, + output: { + encoding: 'application/json', + schema: { + type: 'object', + required: ['subject'], + properties: { + subject: { + type: 'union', + refs: [ + 'lex:com.atproto.admin.defs#repoRef', + 'lex:com.atproto.repo.strongRef', + 'lex:com.atproto.admin.defs#repoBlobRef', + ], + }, + takedown: { + type: 'ref', + ref: 'lex:com.atproto.admin.defs#subjectState', + }, + }, + }, + }, + }, + }, + }, ComAtprotoIdentityResolveHandle: { lexicon: 1, id: 'com.atproto.identity.resolveHandle', @@ -7335,6 +7467,7 @@ export const ids = { ComAtprotoAdminGetModerationReports: 'com.atproto.admin.getModerationReports', ComAtprotoAdminGetRecord: 'com.atproto.admin.getRecord', ComAtprotoAdminGetRepo: 'com.atproto.admin.getRepo', + ComAtprotoAdminGetSubjectState: 'com.atproto.admin.getSubjectState', ComAtprotoAdminResolveModerationReports: 'com.atproto.admin.resolveModerationReports', ComAtprotoAdminReverseModerationAction: @@ -7344,6 +7477,7 @@ export const ids = { ComAtprotoAdminTakeModerationAction: 'com.atproto.admin.takeModerationAction', ComAtprotoAdminUpdateAccountEmail: 'com.atproto.admin.updateAccountEmail', ComAtprotoAdminUpdateAccountHandle: 'com.atproto.admin.updateAccountHandle', + ComAtprotoAdminUpdateSubjectState: 'com.atproto.admin.updateSubjectState', ComAtprotoIdentityResolveHandle: 'com.atproto.identity.resolveHandle', ComAtprotoIdentityUpdateHandle: 'com.atproto.identity.updateHandle', ComAtprotoLabelDefs: 'com.atproto.label.defs', diff --git a/packages/bsky/src/lexicon/types/com/atproto/admin/defs.ts b/packages/bsky/src/lexicon/types/com/atproto/admin/defs.ts index 968252a4c2c..6209cc46c4f 100644 --- a/packages/bsky/src/lexicon/types/com/atproto/admin/defs.ts +++ b/packages/bsky/src/lexicon/types/com/atproto/admin/defs.ts @@ -10,6 +10,24 @@ import * as ComAtprotoModerationDefs from '../moderation/defs' import * as ComAtprotoServerDefs from '../server/defs' import * as ComAtprotoLabelDefs from '../label/defs' +export interface SubjectState { + applied: boolean + ref?: string + [k: string]: unknown +} + +export function isSubjectState(v: unknown): v is SubjectState { + return ( + isObj(v) && + hasProp(v, '$type') && + v.$type === 'com.atproto.admin.defs#subjectState' + ) +} + +export function validateSubjectState(v: unknown): ValidationResult { + return lexicons.validate('com.atproto.admin.defs#subjectState', v) +} + export interface ActionView { id: number action: ActionType @@ -272,6 +290,25 @@ export function validateRepoRef(v: unknown): ValidationResult { return lexicons.validate('com.atproto.admin.defs#repoRef', v) } +export interface RepoBlobRef { + did: string + cid: string + recordUri?: string + [k: string]: unknown +} + +export function isRepoBlobRef(v: unknown): v is RepoBlobRef { + return ( + isObj(v) && + hasProp(v, '$type') && + v.$type === 'com.atproto.admin.defs#repoBlobRef' + ) +} + +export function validateRepoBlobRef(v: unknown): ValidationResult { + return lexicons.validate('com.atproto.admin.defs#repoBlobRef', v) +} + export interface RecordView { uri: string cid: string diff --git a/packages/bsky/src/lexicon/types/com/atproto/admin/getSubjectState.ts b/packages/bsky/src/lexicon/types/com/atproto/admin/getSubjectState.ts new file mode 100644 index 00000000000..b828c39c1aa --- /dev/null +++ b/packages/bsky/src/lexicon/types/com/atproto/admin/getSubjectState.ts @@ -0,0 +1,54 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from 'express' +import { ValidationResult, BlobRef } from '@atproto/lexicon' +import { lexicons } from '../../../../lexicons' +import { isObj, hasProp } from '../../../../util' +import { CID } from 'multiformats/cid' +import { HandlerAuth } from '@atproto/xrpc-server' +import * as ComAtprotoAdminDefs from './defs' +import * as ComAtprotoRepoStrongRef from '../repo/strongRef' + +export interface QueryParams { + did?: string + uri?: string + blob?: string +} + +export type InputSchema = undefined + +export interface OutputSchema { + subject: + | ComAtprotoAdminDefs.RepoRef + | ComAtprotoRepoStrongRef.Main + | ComAtprotoAdminDefs.RepoBlobRef + | { $type: string; [k: string]: unknown } + takedown?: ComAtprotoAdminDefs.SubjectState + [k: string]: unknown +} + +export type HandlerInput = undefined + +export interface HandlerSuccess { + encoding: 'application/json' + body: OutputSchema + headers?: { [key: string]: string } +} + +export interface HandlerError { + status: number + message?: string +} + +export type HandlerOutput = HandlerError | HandlerSuccess +export type HandlerReqCtx = { + auth: HA + params: QueryParams + input: HandlerInput + req: express.Request + res: express.Response +} +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput diff --git a/packages/bsky/src/lexicon/types/com/atproto/admin/updateSubjectState.ts b/packages/bsky/src/lexicon/types/com/atproto/admin/updateSubjectState.ts new file mode 100644 index 00000000000..6d79a8b67ed --- /dev/null +++ b/packages/bsky/src/lexicon/types/com/atproto/admin/updateSubjectState.ts @@ -0,0 +1,61 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from 'express' +import { ValidationResult, BlobRef } from '@atproto/lexicon' +import { lexicons } from '../../../../lexicons' +import { isObj, hasProp } from '../../../../util' +import { CID } from 'multiformats/cid' +import { HandlerAuth } from '@atproto/xrpc-server' +import * as ComAtprotoAdminDefs from './defs' +import * as ComAtprotoRepoStrongRef from '../repo/strongRef' + +export interface QueryParams {} + +export interface InputSchema { + subject: + | ComAtprotoAdminDefs.RepoRef + | ComAtprotoRepoStrongRef.Main + | ComAtprotoAdminDefs.RepoBlobRef + | { $type: string; [k: string]: unknown } + takedown?: ComAtprotoAdminDefs.SubjectState + [k: string]: unknown +} + +export interface OutputSchema { + subject: + | ComAtprotoAdminDefs.RepoRef + | ComAtprotoRepoStrongRef.Main + | ComAtprotoAdminDefs.RepoBlobRef + | { $type: string; [k: string]: unknown } + takedown?: ComAtprotoAdminDefs.SubjectState + [k: string]: unknown +} + +export interface HandlerInput { + encoding: 'application/json' + body: InputSchema +} + +export interface HandlerSuccess { + encoding: 'application/json' + body: OutputSchema + headers?: { [key: string]: string } +} + +export interface HandlerError { + status: number + message?: string +} + +export type HandlerOutput = HandlerError | HandlerSuccess +export type HandlerReqCtx = { + auth: HA + params: QueryParams + input: HandlerInput + req: express.Request + res: express.Response +} +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput diff --git a/packages/pds/src/api/com/atproto/admin/getSubjectState.ts b/packages/pds/src/api/com/atproto/admin/getSubjectState.ts new file mode 100644 index 00000000000..7cdb3c2e6dd --- /dev/null +++ b/packages/pds/src/api/com/atproto/admin/getSubjectState.ts @@ -0,0 +1,45 @@ +import { CID } from 'multiformats/cid' +import { AtUri } from '@atproto/syntax' +import { Server } from '../../../../lexicon' +import AppContext from '../../../../context' +import { OutputSchema } from '../../../../lexicon/types/com/atproto/admin/getSubjectState' +import { AuthRequiredError, InvalidRequestError } from '@atproto/xrpc-server' + +export default function (server: Server, ctx: AppContext) { + server.com.atproto.admin.getSubjectState({ + auth: ctx.roleVerifier, + handler: async ({ params, auth }) => { + const access = auth.credentials + // if less than admin access then cannot perform a takedown + if (!access.moderator) { + throw new AuthRequiredError( + 'Must be a full moderator to update subject state', + ) + } + const { did, uri, blob } = params + const modSrvc = ctx.services.moderation(ctx.db) + let body: OutputSchema | null + if (uri) { + body = await modSrvc.getRecordTakedownState(new AtUri(uri)) + } else if (blob) { + if (!did) { + throw new InvalidRequestError( + 'Must provide a did to request blob state', + ) + } + body = await modSrvc.getBlobTakedownState(did, CID.parse(blob)) + } else if (did) { + body = await modSrvc.getRepoTakedownState(did) + } else { + throw new InvalidRequestError('No provided subject') + } + if (body === null) { + throw new InvalidRequestError('Subject not found', 'NotFound') + } + return { + encoding: 'application/json', + body, + } + }, + }) +} diff --git a/packages/pds/src/api/com/atproto/admin/updateSubjectState.ts b/packages/pds/src/api/com/atproto/admin/updateSubjectState.ts new file mode 100644 index 00000000000..8002236de6d --- /dev/null +++ b/packages/pds/src/api/com/atproto/admin/updateSubjectState.ts @@ -0,0 +1,52 @@ +import { CID } from 'multiformats/cid' +import { AtUri } from '@atproto/syntax' +import { Server } from '../../../../lexicon' +import AppContext from '../../../../context' +import { + isRepoRef, + isRepoBlobRef, +} from '../../../../lexicon/types/com/atproto/admin/defs' +import { isMain as isStrongRef } from '../../../../lexicon/types/com/atproto/repo/strongRef' +import { AuthRequiredError, InvalidRequestError } from '@atproto/xrpc-server' + +export default function (server: Server, ctx: AppContext) { + server.com.atproto.admin.updateSubjectState({ + auth: ctx.roleVerifier, + handler: async ({ input, auth }) => { + const access = auth.credentials + // if less than admin access then cannot perform a takedown + if (!access.moderator) { + throw new AuthRequiredError( + 'Must be a full moderator to update subject state', + ) + } + const { subject, takedown } = input.body + const modSrvc = ctx.services.moderation(ctx.db) + if (takedown) { + if (isRepoRef(subject)) { + await modSrvc.updateRepoTakedownState(subject.did, takedown) + } else if (isStrongRef(subject)) { + await modSrvc.updateRecordTakedownState( + new AtUri(subject.uri), + takedown, + ) + } else if (isRepoBlobRef(subject)) { + await modSrvc.updateBlobTakedownState( + subject.did, + CID.parse(subject.cid), + takedown, + ) + } else { + throw new InvalidRequestError('Invalid subject') + } + } + return { + encoding: 'application/json', + body: { + subject, + takedown, + }, + } + }, + }) +} diff --git a/packages/pds/src/db/tables/record.ts b/packages/pds/src/db/tables/record.ts index 03f1008ef0f..af56a786079 100644 --- a/packages/pds/src/db/tables/record.ts +++ b/packages/pds/src/db/tables/record.ts @@ -7,7 +7,7 @@ export interface Record { rkey: string repoRev: string | null indexedAt: string - takedownId: number | null + takedownId: string | null } export const tableName = 'record' diff --git a/packages/pds/src/db/tables/repo-blob.ts b/packages/pds/src/db/tables/repo-blob.ts index a1fed0877e5..226b526e45d 100644 --- a/packages/pds/src/db/tables/repo-blob.ts +++ b/packages/pds/src/db/tables/repo-blob.ts @@ -3,7 +3,7 @@ export interface RepoBlob { recordUri: string repoRev: string | null did: string - takedownId: number | null + takedownId: string | null } export const tableName = 'repo_blob' diff --git a/packages/pds/src/db/tables/repo-root.ts b/packages/pds/src/db/tables/repo-root.ts index 6b6c921f380..11d27992067 100644 --- a/packages/pds/src/db/tables/repo-root.ts +++ b/packages/pds/src/db/tables/repo-root.ts @@ -4,7 +4,7 @@ export interface RepoRoot { root: string rev: string | null indexedAt: string - takedownId: number | null + takedownId: string | null } export const tableName = 'repo_root' diff --git a/packages/pds/src/db/util.ts b/packages/pds/src/db/util.ts index 696ac7dee8b..4fcd93a1d44 100644 --- a/packages/pds/src/db/util.ts +++ b/packages/pds/src/db/util.ts @@ -23,7 +23,7 @@ export const notSoftDeletedClause = (alias: DbRef) => { return sql`${alias}."takedownId" is null` } -export const softDeleted = (repoOrRecord: { takedownId: number | null }) => { +export const softDeleted = (repoOrRecord: { takedownId: string | null }) => { return repoOrRecord.takedownId !== null } diff --git a/packages/pds/src/lexicon/index.ts b/packages/pds/src/lexicon/index.ts index ac6ca933fcd..30c97349d0a 100644 --- a/packages/pds/src/lexicon/index.ts +++ b/packages/pds/src/lexicon/index.ts @@ -19,6 +19,7 @@ import * as ComAtprotoAdminGetModerationReport from './types/com/atproto/admin/g import * as ComAtprotoAdminGetModerationReports from './types/com/atproto/admin/getModerationReports' import * as ComAtprotoAdminGetRecord from './types/com/atproto/admin/getRecord' import * as ComAtprotoAdminGetRepo from './types/com/atproto/admin/getRepo' +import * as ComAtprotoAdminGetSubjectState from './types/com/atproto/admin/getSubjectState' import * as ComAtprotoAdminResolveModerationReports from './types/com/atproto/admin/resolveModerationReports' import * as ComAtprotoAdminReverseModerationAction from './types/com/atproto/admin/reverseModerationAction' import * as ComAtprotoAdminSearchRepos from './types/com/atproto/admin/searchRepos' @@ -26,6 +27,7 @@ import * as ComAtprotoAdminSendEmail from './types/com/atproto/admin/sendEmail' import * as ComAtprotoAdminTakeModerationAction from './types/com/atproto/admin/takeModerationAction' import * as ComAtprotoAdminUpdateAccountEmail from './types/com/atproto/admin/updateAccountEmail' import * as ComAtprotoAdminUpdateAccountHandle from './types/com/atproto/admin/updateAccountHandle' +import * as ComAtprotoAdminUpdateSubjectState from './types/com/atproto/admin/updateSubjectState' import * as ComAtprotoIdentityResolveHandle from './types/com/atproto/identity/resolveHandle' import * as ComAtprotoIdentityUpdateHandle from './types/com/atproto/identity/updateHandle' import * as ComAtprotoLabelQueryLabels from './types/com/atproto/label/queryLabels' @@ -301,6 +303,17 @@ export class AdminNS { return this._server.xrpc.method(nsid, cfg) } + getSubjectState( + cfg: ConfigOf< + AV, + ComAtprotoAdminGetSubjectState.Handler>, + ComAtprotoAdminGetSubjectState.HandlerReqCtx> + >, + ) { + const nsid = 'com.atproto.admin.getSubjectState' // @ts-ignore + return this._server.xrpc.method(nsid, cfg) + } + resolveModerationReports( cfg: ConfigOf< AV, @@ -377,6 +390,17 @@ export class AdminNS { const nsid = 'com.atproto.admin.updateAccountHandle' // @ts-ignore return this._server.xrpc.method(nsid, cfg) } + + updateSubjectState( + cfg: ConfigOf< + AV, + ComAtprotoAdminUpdateSubjectState.Handler>, + ComAtprotoAdminUpdateSubjectState.HandlerReqCtx> + >, + ) { + const nsid = 'com.atproto.admin.updateSubjectState' // @ts-ignore + return this._server.xrpc.method(nsid, cfg) + } } export class IdentityNS { diff --git a/packages/pds/src/lexicon/lexicons.ts b/packages/pds/src/lexicon/lexicons.ts index ded6b1f86f6..4ebf1811194 100644 --- a/packages/pds/src/lexicon/lexicons.ts +++ b/packages/pds/src/lexicon/lexicons.ts @@ -8,6 +8,18 @@ export const schemaDict = { lexicon: 1, id: 'com.atproto.admin.defs', defs: { + subjectState: { + type: 'object', + required: ['applied'], + properties: { + applied: { + type: 'boolean', + }, + ref: { + type: 'string', + }, + }, + }, actionView: { type: 'object', required: [ @@ -444,6 +456,24 @@ export const schemaDict = { }, }, }, + repoBlobRef: { + type: 'object', + required: ['did', 'cid'], + properties: { + did: { + type: 'string', + format: 'did', + }, + cid: { + type: 'string', + format: 'cid', + }, + recordUri: { + type: 'string', + format: 'at-uri', + }, + }, + }, recordView: { type: 'object', required: [ @@ -1026,6 +1056,55 @@ export const schemaDict = { }, }, }, + ComAtprotoAdminGetSubjectState: { + lexicon: 1, + id: 'com.atproto.admin.getSubjectState', + defs: { + main: { + type: 'query', + description: + 'Fetch the service-specific the admin state of a subject (account, record, or blob)', + parameters: { + type: 'params', + properties: { + did: { + type: 'string', + format: 'did', + }, + uri: { + type: 'string', + format: 'at-uri', + }, + blob: { + type: 'string', + format: 'cid', + }, + }, + }, + output: { + encoding: 'application/json', + schema: { + type: 'object', + required: ['subject'], + properties: { + subject: { + type: 'union', + refs: [ + 'lex:com.atproto.admin.defs#repoRef', + 'lex:com.atproto.repo.strongRef', + 'lex:com.atproto.admin.defs#repoBlobRef', + ], + }, + takedown: { + type: 'ref', + ref: 'lex:com.atproto.admin.defs#subjectState', + }, + }, + }, + }, + }, + }, + }, ComAtprotoAdminResolveModerationReports: { lexicon: 1, id: 'com.atproto.admin.resolveModerationReports', @@ -1326,6 +1405,59 @@ export const schemaDict = { }, }, }, + ComAtprotoAdminUpdateSubjectState: { + lexicon: 1, + id: 'com.atproto.admin.updateSubjectState', + defs: { + main: { + type: 'procedure', + description: + 'Update the service-specific admin state of a subject (account, record, or blob)', + input: { + encoding: 'application/json', + schema: { + type: 'object', + required: ['subject'], + properties: { + subject: { + type: 'union', + refs: [ + 'lex:com.atproto.admin.defs#repoRef', + 'lex:com.atproto.repo.strongRef', + 'lex:com.atproto.admin.defs#repoBlobRef', + ], + }, + takedown: { + type: 'ref', + ref: 'lex:com.atproto.admin.defs#subjectState', + }, + }, + }, + }, + output: { + encoding: 'application/json', + schema: { + type: 'object', + required: ['subject'], + properties: { + subject: { + type: 'union', + refs: [ + 'lex:com.atproto.admin.defs#repoRef', + 'lex:com.atproto.repo.strongRef', + 'lex:com.atproto.admin.defs#repoBlobRef', + ], + }, + takedown: { + type: 'ref', + ref: 'lex:com.atproto.admin.defs#subjectState', + }, + }, + }, + }, + }, + }, + }, ComAtprotoIdentityResolveHandle: { lexicon: 1, id: 'com.atproto.identity.resolveHandle', @@ -7335,6 +7467,7 @@ export const ids = { ComAtprotoAdminGetModerationReports: 'com.atproto.admin.getModerationReports', ComAtprotoAdminGetRecord: 'com.atproto.admin.getRecord', ComAtprotoAdminGetRepo: 'com.atproto.admin.getRepo', + ComAtprotoAdminGetSubjectState: 'com.atproto.admin.getSubjectState', ComAtprotoAdminResolveModerationReports: 'com.atproto.admin.resolveModerationReports', ComAtprotoAdminReverseModerationAction: @@ -7344,6 +7477,7 @@ export const ids = { ComAtprotoAdminTakeModerationAction: 'com.atproto.admin.takeModerationAction', ComAtprotoAdminUpdateAccountEmail: 'com.atproto.admin.updateAccountEmail', ComAtprotoAdminUpdateAccountHandle: 'com.atproto.admin.updateAccountHandle', + ComAtprotoAdminUpdateSubjectState: 'com.atproto.admin.updateSubjectState', ComAtprotoIdentityResolveHandle: 'com.atproto.identity.resolveHandle', ComAtprotoIdentityUpdateHandle: 'com.atproto.identity.updateHandle', ComAtprotoLabelDefs: 'com.atproto.label.defs', diff --git a/packages/pds/src/lexicon/types/com/atproto/admin/defs.ts b/packages/pds/src/lexicon/types/com/atproto/admin/defs.ts index 968252a4c2c..6209cc46c4f 100644 --- a/packages/pds/src/lexicon/types/com/atproto/admin/defs.ts +++ b/packages/pds/src/lexicon/types/com/atproto/admin/defs.ts @@ -10,6 +10,24 @@ import * as ComAtprotoModerationDefs from '../moderation/defs' import * as ComAtprotoServerDefs from '../server/defs' import * as ComAtprotoLabelDefs from '../label/defs' +export interface SubjectState { + applied: boolean + ref?: string + [k: string]: unknown +} + +export function isSubjectState(v: unknown): v is SubjectState { + return ( + isObj(v) && + hasProp(v, '$type') && + v.$type === 'com.atproto.admin.defs#subjectState' + ) +} + +export function validateSubjectState(v: unknown): ValidationResult { + return lexicons.validate('com.atproto.admin.defs#subjectState', v) +} + export interface ActionView { id: number action: ActionType @@ -272,6 +290,25 @@ export function validateRepoRef(v: unknown): ValidationResult { return lexicons.validate('com.atproto.admin.defs#repoRef', v) } +export interface RepoBlobRef { + did: string + cid: string + recordUri?: string + [k: string]: unknown +} + +export function isRepoBlobRef(v: unknown): v is RepoBlobRef { + return ( + isObj(v) && + hasProp(v, '$type') && + v.$type === 'com.atproto.admin.defs#repoBlobRef' + ) +} + +export function validateRepoBlobRef(v: unknown): ValidationResult { + return lexicons.validate('com.atproto.admin.defs#repoBlobRef', v) +} + export interface RecordView { uri: string cid: string diff --git a/packages/pds/src/lexicon/types/com/atproto/admin/getSubjectState.ts b/packages/pds/src/lexicon/types/com/atproto/admin/getSubjectState.ts new file mode 100644 index 00000000000..b828c39c1aa --- /dev/null +++ b/packages/pds/src/lexicon/types/com/atproto/admin/getSubjectState.ts @@ -0,0 +1,54 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from 'express' +import { ValidationResult, BlobRef } from '@atproto/lexicon' +import { lexicons } from '../../../../lexicons' +import { isObj, hasProp } from '../../../../util' +import { CID } from 'multiformats/cid' +import { HandlerAuth } from '@atproto/xrpc-server' +import * as ComAtprotoAdminDefs from './defs' +import * as ComAtprotoRepoStrongRef from '../repo/strongRef' + +export interface QueryParams { + did?: string + uri?: string + blob?: string +} + +export type InputSchema = undefined + +export interface OutputSchema { + subject: + | ComAtprotoAdminDefs.RepoRef + | ComAtprotoRepoStrongRef.Main + | ComAtprotoAdminDefs.RepoBlobRef + | { $type: string; [k: string]: unknown } + takedown?: ComAtprotoAdminDefs.SubjectState + [k: string]: unknown +} + +export type HandlerInput = undefined + +export interface HandlerSuccess { + encoding: 'application/json' + body: OutputSchema + headers?: { [key: string]: string } +} + +export interface HandlerError { + status: number + message?: string +} + +export type HandlerOutput = HandlerError | HandlerSuccess +export type HandlerReqCtx = { + auth: HA + params: QueryParams + input: HandlerInput + req: express.Request + res: express.Response +} +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput diff --git a/packages/pds/src/lexicon/types/com/atproto/admin/updateSubjectState.ts b/packages/pds/src/lexicon/types/com/atproto/admin/updateSubjectState.ts new file mode 100644 index 00000000000..6d79a8b67ed --- /dev/null +++ b/packages/pds/src/lexicon/types/com/atproto/admin/updateSubjectState.ts @@ -0,0 +1,61 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from 'express' +import { ValidationResult, BlobRef } from '@atproto/lexicon' +import { lexicons } from '../../../../lexicons' +import { isObj, hasProp } from '../../../../util' +import { CID } from 'multiformats/cid' +import { HandlerAuth } from '@atproto/xrpc-server' +import * as ComAtprotoAdminDefs from './defs' +import * as ComAtprotoRepoStrongRef from '../repo/strongRef' + +export interface QueryParams {} + +export interface InputSchema { + subject: + | ComAtprotoAdminDefs.RepoRef + | ComAtprotoRepoStrongRef.Main + | ComAtprotoAdminDefs.RepoBlobRef + | { $type: string; [k: string]: unknown } + takedown?: ComAtprotoAdminDefs.SubjectState + [k: string]: unknown +} + +export interface OutputSchema { + subject: + | ComAtprotoAdminDefs.RepoRef + | ComAtprotoRepoStrongRef.Main + | ComAtprotoAdminDefs.RepoBlobRef + | { $type: string; [k: string]: unknown } + takedown?: ComAtprotoAdminDefs.SubjectState + [k: string]: unknown +} + +export interface HandlerInput { + encoding: 'application/json' + body: InputSchema +} + +export interface HandlerSuccess { + encoding: 'application/json' + body: OutputSchema + headers?: { [key: string]: string } +} + +export interface HandlerError { + status: number + message?: string +} + +export type HandlerOutput = HandlerError | HandlerSuccess +export type HandlerReqCtx = { + auth: HA + params: QueryParams + input: HandlerInput + req: express.Request + res: express.Response +} +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput diff --git a/packages/pds/src/services/moderation/index.ts b/packages/pds/src/services/moderation/index.ts index 9e46332cf33..88458773911 100644 --- a/packages/pds/src/services/moderation/index.ts +++ b/packages/pds/src/services/moderation/index.ts @@ -8,7 +8,13 @@ import { ModerationAction, ModerationReport } from '../../db/tables/moderation' import { RecordService } from '../record' import { ModerationViews } from './views' import SqlRepoStorage from '../../sql-repo-storage' -import { TAKEDOWN } from '../../lexicon/types/com/atproto/admin/defs' +import { + TAKEDOWN, + RepoBlobRef, + RepoRef, + SubjectState, +} from '../../lexicon/types/com/atproto/admin/defs' +import { Main as StrongRef } from '../../lexicon/types/com/atproto/repo/strongRef' import { addHoursToDate } from '../../util/date' export class ModerationService { @@ -24,6 +30,106 @@ export class ModerationService { record: RecordService.creator(), } + async getRepoTakedownState( + did: string, + ): Promise | null> { + const res = await this.db.db + .selectFrom('repo_root') + .select('takedownId') + .where('did', '=', did) + .executeTakeFirst() + if (!res) return null + const state = takedownIdToSubjectState(res.takedownId ?? null) + return { + subject: { + $type: 'com.atproto.admin.defs#repoRef', + did: did, + }, + state: { + takedown: state, + }, + } + } + + async getRecordTakedownState( + uri: AtUri, + ): Promise | null> { + const res = await this.db.db + .selectFrom('record') + .select(['takedownId', 'cid']) + .where('uri', '=', uri.toString()) + .executeTakeFirst() + if (!res) return null + const state = takedownIdToSubjectState(res.takedownId ?? null) + return { + subject: { + $type: 'com.atproto.repo.strongRef', + uri: uri.toString(), + cid: res.cid, + }, + state: { + takedown: state, + }, + } + } + + async getBlobTakedownState( + did: string, + cid: CID, + ): Promise | null> { + const res = await this.db.db + .selectFrom('repo_blob') + .select('takedownId') + .where('did', '=', did) + .where('cid', '=', cid.toString()) + .executeTakeFirst() + if (!res) return null + const state = takedownIdToSubjectState(res.takedownId ?? null) + return { + subject: { + $type: 'com.atproto.admin.defs#repoBlobRef', + did: did, + cid: cid.toString(), + }, + state: { + takedown: state, + }, + } + } + + async updateRepoTakedownState(did: string, state: SubjectState) { + const takedownId = subjectStateToTakedownId(state) + await this.db.db + .updateTable('repo_root') + .set({ takedownId }) + .where('did', '=', did) + .executeTakeFirst() + } + + async updateRecordTakedownState(uri: AtUri, state: SubjectState) { + const takedownId = subjectStateToTakedownId(state) + await this.db.db + .updateTable('record') + .set({ takedownId }) + .where('uri', '=', uri.toString()) + .executeTakeFirst() + } + + async updateBlobTakedownState(did: string, blob: CID, state: SubjectState) { + const takedownId = subjectStateToTakedownId(state) + await this.db.db + .updateTable('repo_blob') + .set({ takedownId }) + .where('did', '=', did) + .where('cid', '=', blob.toString()) + .executeTakeFirst() + if (state.applied) { + await this.blobstore.unquarantine(blob) + } else { + await this.blobstore.quarantine(blob) + } + } + async getAction(id: number): Promise { return await this.db.db .selectFrom('moderation_action') @@ -437,7 +543,7 @@ export class ModerationService { async takedownRepo(info: { takedownId: number; did: string }) { await this.db.db .updateTable('repo_root') - .set({ takedownId: info.takedownId }) + .set({ takedownId: info.takedownId.toString() }) .where('did', '=', info.did) .where('takedownId', 'is', null) .executeTakeFirst() @@ -459,14 +565,14 @@ export class ModerationService { this.db.assertTransaction() await this.db.db .updateTable('record') - .set({ takedownId: info.takedownId }) + .set({ takedownId: info.takedownId.toString() }) .where('uri', '=', info.uri.toString()) .where('takedownId', 'is', null) .executeTakeFirst() if (info.blobCids?.length) { await this.db.db .updateTable('repo_blob') - .set({ takedownId: info.takedownId }) + .set({ takedownId: info.takedownId.toString() }) .where('recordUri', '=', info.uri.toString()) .where( 'cid', @@ -609,6 +715,19 @@ export class ModerationService { } } +const takedownIdToSubjectState = (id: string | null): SubjectState => { + return id === null ? { applied: false } : { applied: true, ref: id } +} + +const subjectStateToTakedownId = (state: SubjectState): string | null => { + return state.applied ? state.ref ?? new Date().toISOString() : null +} + +type StateResponse = { + subject: T + state: { takedown: SubjectState } +} + export type ModerationActionRow = Selectable export type ModerationReportRow = Selectable diff --git a/packages/pds/src/services/moderation/views.ts b/packages/pds/src/services/moderation/views.ts index e8d89620d73..b38b9fa987e 100644 --- a/packages/pds/src/services/moderation/views.ts +++ b/packages/pds/src/services/moderation/views.ts @@ -616,7 +616,7 @@ type RecordResult = { cid: string value: object indexedAt: string - takedownId: number | null + takedownId: string | null } type SubjectResult = Pick< diff --git a/packages/pds/src/services/record/index.ts b/packages/pds/src/services/record/index.ts index 1914d1b8c61..c6d894e6d36 100644 --- a/packages/pds/src/services/record/index.ts +++ b/packages/pds/src/services/record/index.ts @@ -164,7 +164,7 @@ export class RecordService { cid: string value: object indexedAt: string - takedownId: number | null + takedownId: string | null } | null> { const { ref } = this.db.db.dynamic let builder = this.db.db @@ -189,7 +189,7 @@ export class RecordService { cid: record.cid, value: cborToLexRecord(record.content), indexedAt: record.indexedAt, - takedownId: record.takedownId, + takedownId: record.takedownId ? record.takedownId.toString() : null, } } From cae1381a6cd082b17e65a4c7ea22718c798a664e Mon Sep 17 00:00:00 2001 From: dholms Date: Mon, 9 Oct 2023 16:21:09 -0500 Subject: [PATCH 2/8] wire up routes --- packages/pds/src/api/com/atproto/admin/index.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/pds/src/api/com/atproto/admin/index.ts b/packages/pds/src/api/com/atproto/admin/index.ts index 84d1fe3218a..ec3feb2076f 100644 --- a/packages/pds/src/api/com/atproto/admin/index.ts +++ b/packages/pds/src/api/com/atproto/admin/index.ts @@ -3,6 +3,8 @@ import { Server } from '../../../../lexicon' import resolveModerationReports from './resolveModerationReports' import reverseModerationAction from './reverseModerationAction' import takeModerationAction from './takeModerationAction' +import updateSubjectState from './updateSubjectState' +import getSubjectState from './getSubjectState' import searchRepos from './searchRepos' import getRecord from './getRecord' import getRepo from './getRepo' @@ -22,6 +24,8 @@ export default function (server: Server, ctx: AppContext) { resolveModerationReports(server, ctx) reverseModerationAction(server, ctx) takeModerationAction(server, ctx) + updateSubjectState(server, ctx) + getSubjectState(server, ctx) searchRepos(server, ctx) getRecord(server, ctx) getRepo(server, ctx) From ff7365fe4411d5a1e35344857f1ad48696691ea8 Mon Sep 17 00:00:00 2001 From: dholms Date: Mon, 9 Oct 2023 17:44:52 -0500 Subject: [PATCH 3/8] revoke refresh tokens --- .../pds/src/api/com/atproto/admin/updateSubjectState.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/pds/src/api/com/atproto/admin/updateSubjectState.ts b/packages/pds/src/api/com/atproto/admin/updateSubjectState.ts index 8002236de6d..7657124e9e3 100644 --- a/packages/pds/src/api/com/atproto/admin/updateSubjectState.ts +++ b/packages/pds/src/api/com/atproto/admin/updateSubjectState.ts @@ -22,9 +22,13 @@ export default function (server: Server, ctx: AppContext) { } const { subject, takedown } = input.body const modSrvc = ctx.services.moderation(ctx.db) + const authSrvc = ctx.services.auth(ctx.db) if (takedown) { if (isRepoRef(subject)) { - await modSrvc.updateRepoTakedownState(subject.did, takedown) + await Promise.all([ + await modSrvc.updateRepoTakedownState(subject.did, takedown), + await authSrvc.revokeRefreshTokensByDid(subject.did), + ]) } else if (isStrongRef(subject)) { await modSrvc.updateRecordTakedownState( new AtUri(subject.uri), From 7c76bedc6912a90f86e3ce3e272ab5ead980d805 Mon Sep 17 00:00:00 2001 From: dholms Date: Tue, 10 Oct 2023 13:57:30 -0500 Subject: [PATCH 4/8] pr tidy --- .../pds/src/api/com/atproto/admin/getSubjectState.ts | 11 ++--------- .../src/api/com/atproto/admin/updateSubjectState.ts | 2 +- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/packages/pds/src/api/com/atproto/admin/getSubjectState.ts b/packages/pds/src/api/com/atproto/admin/getSubjectState.ts index 7cdb3c2e6dd..16ce00164cc 100644 --- a/packages/pds/src/api/com/atproto/admin/getSubjectState.ts +++ b/packages/pds/src/api/com/atproto/admin/getSubjectState.ts @@ -3,19 +3,12 @@ import { AtUri } from '@atproto/syntax' import { Server } from '../../../../lexicon' import AppContext from '../../../../context' import { OutputSchema } from '../../../../lexicon/types/com/atproto/admin/getSubjectState' -import { AuthRequiredError, InvalidRequestError } from '@atproto/xrpc-server' +import { InvalidRequestError } from '@atproto/xrpc-server' export default function (server: Server, ctx: AppContext) { server.com.atproto.admin.getSubjectState({ auth: ctx.roleVerifier, - handler: async ({ params, auth }) => { - const access = auth.credentials - // if less than admin access then cannot perform a takedown - if (!access.moderator) { - throw new AuthRequiredError( - 'Must be a full moderator to update subject state', - ) - } + handler: async ({ params }) => { const { did, uri, blob } = params const modSrvc = ctx.services.moderation(ctx.db) let body: OutputSchema | null diff --git a/packages/pds/src/api/com/atproto/admin/updateSubjectState.ts b/packages/pds/src/api/com/atproto/admin/updateSubjectState.ts index 7657124e9e3..d8552c98835 100644 --- a/packages/pds/src/api/com/atproto/admin/updateSubjectState.ts +++ b/packages/pds/src/api/com/atproto/admin/updateSubjectState.ts @@ -14,7 +14,7 @@ export default function (server: Server, ctx: AppContext) { auth: ctx.roleVerifier, handler: async ({ input, auth }) => { const access = auth.credentials - // if less than admin access then cannot perform a takedown + // if less than moderator access then cannot perform a takedown if (!access.moderator) { throw new AuthRequiredError( 'Must be a full moderator to update subject state', From 70f067fdde7e73f15dfc1600fadd180ea1ffda4f Mon Sep 17 00:00:00 2001 From: dholms Date: Thu, 12 Oct 2023 11:59:37 -0500 Subject: [PATCH 5/8] tweak naming --- lexicons/com/atproto/admin/defs.json | 2 +- ...ubjectState.json => getSubjectStatus.json} | 6 +-- ...ectState.json => updateSubjectStatus.json} | 8 +-- packages/api/src/client/index.ts | 32 ++++++------ packages/api/src/client/lexicons.ts | 24 ++++----- .../client/types/com/atproto/admin/defs.ts | 10 ++-- ...getSubjectState.ts => getSubjectStatus.ts} | 2 +- ...SubjectState.ts => updateSubjectStatus.ts} | 4 +- packages/bsky/src/lexicon/index.ts | 20 +++---- packages/bsky/src/lexicon/lexicons.ts | 24 ++++----- .../lexicon/types/com/atproto/admin/defs.ts | 10 ++-- ...getSubjectState.ts => getSubjectStatus.ts} | 2 +- ...SubjectState.ts => updateSubjectStatus.ts} | 4 +- ...getSubjectState.ts => getSubjectStatus.ts} | 10 ++-- .../pds/src/api/com/atproto/admin/index.ts | 8 +-- ...SubjectState.ts => updateSubjectStatus.ts} | 2 +- packages/pds/src/lexicon/index.ts | 20 +++---- packages/pds/src/lexicon/lexicons.ts | 24 ++++----- .../lexicon/types/com/atproto/admin/defs.ts | 10 ++-- ...getSubjectState.ts => getSubjectStatus.ts} | 2 +- ...SubjectState.ts => updateSubjectStatus.ts} | 4 +- packages/pds/src/services/moderation/index.ts | 52 ++++++++----------- 22 files changed, 137 insertions(+), 143 deletions(-) rename lexicons/com/atproto/admin/{getSubjectState.json => getSubjectStatus.json} (80%) rename lexicons/com/atproto/admin/{updateSubjectState.json => updateSubjectStatus.json} (80%) rename packages/api/src/client/types/com/atproto/admin/{getSubjectState.ts => getSubjectStatus.ts} (95%) rename packages/api/src/client/types/com/atproto/admin/{updateSubjectState.ts => updateSubjectStatus.ts} (92%) rename packages/bsky/src/lexicon/types/com/atproto/admin/{getSubjectState.ts => getSubjectStatus.ts} (96%) rename packages/bsky/src/lexicon/types/com/atproto/admin/{updateSubjectState.ts => updateSubjectStatus.ts} (94%) rename packages/pds/src/api/com/atproto/admin/{getSubjectState.ts => getSubjectStatus.ts} (91%) rename packages/pds/src/api/com/atproto/admin/{updateSubjectState.ts => updateSubjectStatus.ts} (97%) rename packages/pds/src/lexicon/types/com/atproto/admin/{getSubjectState.ts => getSubjectStatus.ts} (96%) rename packages/pds/src/lexicon/types/com/atproto/admin/{updateSubjectState.ts => updateSubjectStatus.ts} (94%) diff --git a/lexicons/com/atproto/admin/defs.json b/lexicons/com/atproto/admin/defs.json index 6e066893d19..a8f81b5cbdc 100644 --- a/lexicons/com/atproto/admin/defs.json +++ b/lexicons/com/atproto/admin/defs.json @@ -2,7 +2,7 @@ "lexicon": 1, "id": "com.atproto.admin.defs", "defs": { - "subjectState": { + "statusAttr": { "type": "object", "required": ["applied"], "properties": { diff --git a/lexicons/com/atproto/admin/getSubjectState.json b/lexicons/com/atproto/admin/getSubjectStatus.json similarity index 80% rename from lexicons/com/atproto/admin/getSubjectState.json rename to lexicons/com/atproto/admin/getSubjectStatus.json index abe40ed1052..aba7b268b7f 100644 --- a/lexicons/com/atproto/admin/getSubjectState.json +++ b/lexicons/com/atproto/admin/getSubjectStatus.json @@ -1,10 +1,10 @@ { "lexicon": 1, - "id": "com.atproto.admin.getSubjectState", + "id": "com.atproto.admin.getSubjectStatus", "defs": { "main": { "type": "query", - "description": "Fetch the service-specific the admin state of a subject (account, record, or blob)", + "description": "Fetch the service-specific the admin status of a subject (account, record, or blob)", "parameters": { "type": "params", "properties": { @@ -29,7 +29,7 @@ }, "takedown": { "type": "ref", - "ref": "com.atproto.admin.defs#subjectState" + "ref": "com.atproto.admin.defs#subjectStatus" } } } diff --git a/lexicons/com/atproto/admin/updateSubjectState.json b/lexicons/com/atproto/admin/updateSubjectStatus.json similarity index 80% rename from lexicons/com/atproto/admin/updateSubjectState.json rename to lexicons/com/atproto/admin/updateSubjectStatus.json index fe50c790388..5273aea4da6 100644 --- a/lexicons/com/atproto/admin/updateSubjectState.json +++ b/lexicons/com/atproto/admin/updateSubjectStatus.json @@ -1,10 +1,10 @@ { "lexicon": 1, - "id": "com.atproto.admin.updateSubjectState", + "id": "com.atproto.admin.updateSubjectStatus", "defs": { "main": { "type": "procedure", - "description": "Update the service-specific admin state of a subject (account, record, or blob)", + "description": "Update the service-specific admin status of a subject (account, record, or blob)", "input": { "encoding": "application/json", "schema": { @@ -21,7 +21,7 @@ }, "takedown": { "type": "ref", - "ref": "com.atproto.admin.defs#subjectState" + "ref": "com.atproto.admin.defs#statusAttr" } } } @@ -42,7 +42,7 @@ }, "takedown": { "type": "ref", - "ref": "com.atproto.admin.defs#subjectState" + "ref": "com.atproto.admin.defs#statusAttr" } } } diff --git a/packages/api/src/client/index.ts b/packages/api/src/client/index.ts index bf6517e8ae4..8c2b4f559f9 100644 --- a/packages/api/src/client/index.ts +++ b/packages/api/src/client/index.ts @@ -18,7 +18,7 @@ import * as ComAtprotoAdminGetModerationReport from './types/com/atproto/admin/g import * as ComAtprotoAdminGetModerationReports from './types/com/atproto/admin/getModerationReports' import * as ComAtprotoAdminGetRecord from './types/com/atproto/admin/getRecord' import * as ComAtprotoAdminGetRepo from './types/com/atproto/admin/getRepo' -import * as ComAtprotoAdminGetSubjectState from './types/com/atproto/admin/getSubjectState' +import * as ComAtprotoAdminGetSubjectStatus from './types/com/atproto/admin/getSubjectStatus' import * as ComAtprotoAdminResolveModerationReports from './types/com/atproto/admin/resolveModerationReports' import * as ComAtprotoAdminReverseModerationAction from './types/com/atproto/admin/reverseModerationAction' import * as ComAtprotoAdminSearchRepos from './types/com/atproto/admin/searchRepos' @@ -26,7 +26,7 @@ import * as ComAtprotoAdminSendEmail from './types/com/atproto/admin/sendEmail' import * as ComAtprotoAdminTakeModerationAction from './types/com/atproto/admin/takeModerationAction' import * as ComAtprotoAdminUpdateAccountEmail from './types/com/atproto/admin/updateAccountEmail' import * as ComAtprotoAdminUpdateAccountHandle from './types/com/atproto/admin/updateAccountHandle' -import * as ComAtprotoAdminUpdateSubjectState from './types/com/atproto/admin/updateSubjectState' +import * as ComAtprotoAdminUpdateSubjectStatus from './types/com/atproto/admin/updateSubjectStatus' import * as ComAtprotoIdentityResolveHandle from './types/com/atproto/identity/resolveHandle' import * as ComAtprotoIdentityUpdateHandle from './types/com/atproto/identity/updateHandle' import * as ComAtprotoLabelDefs from './types/com/atproto/label/defs' @@ -153,7 +153,7 @@ export * as ComAtprotoAdminGetModerationReport from './types/com/atproto/admin/g export * as ComAtprotoAdminGetModerationReports from './types/com/atproto/admin/getModerationReports' export * as ComAtprotoAdminGetRecord from './types/com/atproto/admin/getRecord' export * as ComAtprotoAdminGetRepo from './types/com/atproto/admin/getRepo' -export * as ComAtprotoAdminGetSubjectState from './types/com/atproto/admin/getSubjectState' +export * as ComAtprotoAdminGetSubjectStatus from './types/com/atproto/admin/getSubjectStatus' export * as ComAtprotoAdminResolveModerationReports from './types/com/atproto/admin/resolveModerationReports' export * as ComAtprotoAdminReverseModerationAction from './types/com/atproto/admin/reverseModerationAction' export * as ComAtprotoAdminSearchRepos from './types/com/atproto/admin/searchRepos' @@ -161,7 +161,7 @@ export * as ComAtprotoAdminSendEmail from './types/com/atproto/admin/sendEmail' export * as ComAtprotoAdminTakeModerationAction from './types/com/atproto/admin/takeModerationAction' export * as ComAtprotoAdminUpdateAccountEmail from './types/com/atproto/admin/updateAccountEmail' export * as ComAtprotoAdminUpdateAccountHandle from './types/com/atproto/admin/updateAccountHandle' -export * as ComAtprotoAdminUpdateSubjectState from './types/com/atproto/admin/updateSubjectState' +export * as ComAtprotoAdminUpdateSubjectStatus from './types/com/atproto/admin/updateSubjectStatus' export * as ComAtprotoIdentityResolveHandle from './types/com/atproto/identity/resolveHandle' export * as ComAtprotoIdentityUpdateHandle from './types/com/atproto/identity/updateHandle' export * as ComAtprotoLabelDefs from './types/com/atproto/label/defs' @@ -475,14 +475,14 @@ export class AdminNS { }) } - getSubjectState( - params?: ComAtprotoAdminGetSubjectState.QueryParams, - opts?: ComAtprotoAdminGetSubjectState.CallOptions, - ): Promise { + getSubjectStatus( + params?: ComAtprotoAdminGetSubjectStatus.QueryParams, + opts?: ComAtprotoAdminGetSubjectStatus.CallOptions, + ): Promise { return this._service.xrpc - .call('com.atproto.admin.getSubjectState', params, undefined, opts) + .call('com.atproto.admin.getSubjectStatus', params, undefined, opts) .catch((e) => { - throw ComAtprotoAdminGetSubjectState.toKnownErr(e) + throw ComAtprotoAdminGetSubjectStatus.toKnownErr(e) }) } @@ -563,14 +563,14 @@ export class AdminNS { }) } - updateSubjectState( - data?: ComAtprotoAdminUpdateSubjectState.InputSchema, - opts?: ComAtprotoAdminUpdateSubjectState.CallOptions, - ): Promise { + updateSubjectStatus( + data?: ComAtprotoAdminUpdateSubjectStatus.InputSchema, + opts?: ComAtprotoAdminUpdateSubjectStatus.CallOptions, + ): Promise { return this._service.xrpc - .call('com.atproto.admin.updateSubjectState', opts?.qp, data, opts) + .call('com.atproto.admin.updateSubjectStatus', opts?.qp, data, opts) .catch((e) => { - throw ComAtprotoAdminUpdateSubjectState.toKnownErr(e) + throw ComAtprotoAdminUpdateSubjectStatus.toKnownErr(e) }) } } diff --git a/packages/api/src/client/lexicons.ts b/packages/api/src/client/lexicons.ts index 4ebf1811194..35a7ec3c6cb 100644 --- a/packages/api/src/client/lexicons.ts +++ b/packages/api/src/client/lexicons.ts @@ -8,7 +8,7 @@ export const schemaDict = { lexicon: 1, id: 'com.atproto.admin.defs', defs: { - subjectState: { + statusAttr: { type: 'object', required: ['applied'], properties: { @@ -1056,14 +1056,14 @@ export const schemaDict = { }, }, }, - ComAtprotoAdminGetSubjectState: { + ComAtprotoAdminGetSubjectStatus: { lexicon: 1, - id: 'com.atproto.admin.getSubjectState', + id: 'com.atproto.admin.getSubjectStatus', defs: { main: { type: 'query', description: - 'Fetch the service-specific the admin state of a subject (account, record, or blob)', + 'Fetch the service-specific the admin status of a subject (account, record, or blob)', parameters: { type: 'params', properties: { @@ -1097,7 +1097,7 @@ export const schemaDict = { }, takedown: { type: 'ref', - ref: 'lex:com.atproto.admin.defs#subjectState', + ref: 'lex:com.atproto.admin.defs#subjectStatus', }, }, }, @@ -1405,14 +1405,14 @@ export const schemaDict = { }, }, }, - ComAtprotoAdminUpdateSubjectState: { + ComAtprotoAdminUpdateSubjectStatus: { lexicon: 1, - id: 'com.atproto.admin.updateSubjectState', + id: 'com.atproto.admin.updateSubjectStatus', defs: { main: { type: 'procedure', description: - 'Update the service-specific admin state of a subject (account, record, or blob)', + 'Update the service-specific admin status of a subject (account, record, or blob)', input: { encoding: 'application/json', schema: { @@ -1429,7 +1429,7 @@ export const schemaDict = { }, takedown: { type: 'ref', - ref: 'lex:com.atproto.admin.defs#subjectState', + ref: 'lex:com.atproto.admin.defs#statusAttr', }, }, }, @@ -1450,7 +1450,7 @@ export const schemaDict = { }, takedown: { type: 'ref', - ref: 'lex:com.atproto.admin.defs#subjectState', + ref: 'lex:com.atproto.admin.defs#statusAttr', }, }, }, @@ -7467,7 +7467,7 @@ export const ids = { ComAtprotoAdminGetModerationReports: 'com.atproto.admin.getModerationReports', ComAtprotoAdminGetRecord: 'com.atproto.admin.getRecord', ComAtprotoAdminGetRepo: 'com.atproto.admin.getRepo', - ComAtprotoAdminGetSubjectState: 'com.atproto.admin.getSubjectState', + ComAtprotoAdminGetSubjectStatus: 'com.atproto.admin.getSubjectStatus', ComAtprotoAdminResolveModerationReports: 'com.atproto.admin.resolveModerationReports', ComAtprotoAdminReverseModerationAction: @@ -7477,7 +7477,7 @@ export const ids = { ComAtprotoAdminTakeModerationAction: 'com.atproto.admin.takeModerationAction', ComAtprotoAdminUpdateAccountEmail: 'com.atproto.admin.updateAccountEmail', ComAtprotoAdminUpdateAccountHandle: 'com.atproto.admin.updateAccountHandle', - ComAtprotoAdminUpdateSubjectState: 'com.atproto.admin.updateSubjectState', + ComAtprotoAdminUpdateSubjectStatus: 'com.atproto.admin.updateSubjectStatus', ComAtprotoIdentityResolveHandle: 'com.atproto.identity.resolveHandle', ComAtprotoIdentityUpdateHandle: 'com.atproto.identity.updateHandle', ComAtprotoLabelDefs: 'com.atproto.label.defs', diff --git a/packages/api/src/client/types/com/atproto/admin/defs.ts b/packages/api/src/client/types/com/atproto/admin/defs.ts index 4d2b3685cf5..2c2297a34c4 100644 --- a/packages/api/src/client/types/com/atproto/admin/defs.ts +++ b/packages/api/src/client/types/com/atproto/admin/defs.ts @@ -10,22 +10,22 @@ import * as ComAtprotoModerationDefs from '../moderation/defs' import * as ComAtprotoServerDefs from '../server/defs' import * as ComAtprotoLabelDefs from '../label/defs' -export interface SubjectState { +export interface StatusAttr { applied: boolean ref?: string [k: string]: unknown } -export function isSubjectState(v: unknown): v is SubjectState { +export function isStatusAttr(v: unknown): v is StatusAttr { return ( isObj(v) && hasProp(v, '$type') && - v.$type === 'com.atproto.admin.defs#subjectState' + v.$type === 'com.atproto.admin.defs#statusAttr' ) } -export function validateSubjectState(v: unknown): ValidationResult { - return lexicons.validate('com.atproto.admin.defs#subjectState', v) +export function validateStatusAttr(v: unknown): ValidationResult { + return lexicons.validate('com.atproto.admin.defs#statusAttr', v) } export interface ActionView { diff --git a/packages/api/src/client/types/com/atproto/admin/getSubjectState.ts b/packages/api/src/client/types/com/atproto/admin/getSubjectStatus.ts similarity index 95% rename from packages/api/src/client/types/com/atproto/admin/getSubjectState.ts rename to packages/api/src/client/types/com/atproto/admin/getSubjectStatus.ts index 8d76fbb4720..de9bd5c59d3 100644 --- a/packages/api/src/client/types/com/atproto/admin/getSubjectState.ts +++ b/packages/api/src/client/types/com/atproto/admin/getSubjectStatus.ts @@ -23,7 +23,7 @@ export interface OutputSchema { | ComAtprotoRepoStrongRef.Main | ComAtprotoAdminDefs.RepoBlobRef | { $type: string; [k: string]: unknown } - takedown?: ComAtprotoAdminDefs.SubjectState + takedown?: ComAtprotoAdminDefs.SubjectStatus [k: string]: unknown } diff --git a/packages/api/src/client/types/com/atproto/admin/updateSubjectState.ts b/packages/api/src/client/types/com/atproto/admin/updateSubjectStatus.ts similarity index 92% rename from packages/api/src/client/types/com/atproto/admin/updateSubjectState.ts rename to packages/api/src/client/types/com/atproto/admin/updateSubjectStatus.ts index 55ae3eb5974..c7e17b50582 100644 --- a/packages/api/src/client/types/com/atproto/admin/updateSubjectState.ts +++ b/packages/api/src/client/types/com/atproto/admin/updateSubjectStatus.ts @@ -17,7 +17,7 @@ export interface InputSchema { | ComAtprotoRepoStrongRef.Main | ComAtprotoAdminDefs.RepoBlobRef | { $type: string; [k: string]: unknown } - takedown?: ComAtprotoAdminDefs.SubjectState + takedown?: ComAtprotoAdminDefs.StatusAttr [k: string]: unknown } @@ -27,7 +27,7 @@ export interface OutputSchema { | ComAtprotoRepoStrongRef.Main | ComAtprotoAdminDefs.RepoBlobRef | { $type: string; [k: string]: unknown } - takedown?: ComAtprotoAdminDefs.SubjectState + takedown?: ComAtprotoAdminDefs.StatusAttr [k: string]: unknown } diff --git a/packages/bsky/src/lexicon/index.ts b/packages/bsky/src/lexicon/index.ts index 30c97349d0a..bbed8fccb04 100644 --- a/packages/bsky/src/lexicon/index.ts +++ b/packages/bsky/src/lexicon/index.ts @@ -19,7 +19,7 @@ import * as ComAtprotoAdminGetModerationReport from './types/com/atproto/admin/g import * as ComAtprotoAdminGetModerationReports from './types/com/atproto/admin/getModerationReports' import * as ComAtprotoAdminGetRecord from './types/com/atproto/admin/getRecord' import * as ComAtprotoAdminGetRepo from './types/com/atproto/admin/getRepo' -import * as ComAtprotoAdminGetSubjectState from './types/com/atproto/admin/getSubjectState' +import * as ComAtprotoAdminGetSubjectStatus from './types/com/atproto/admin/getSubjectStatus' import * as ComAtprotoAdminResolveModerationReports from './types/com/atproto/admin/resolveModerationReports' import * as ComAtprotoAdminReverseModerationAction from './types/com/atproto/admin/reverseModerationAction' import * as ComAtprotoAdminSearchRepos from './types/com/atproto/admin/searchRepos' @@ -27,7 +27,7 @@ import * as ComAtprotoAdminSendEmail from './types/com/atproto/admin/sendEmail' import * as ComAtprotoAdminTakeModerationAction from './types/com/atproto/admin/takeModerationAction' import * as ComAtprotoAdminUpdateAccountEmail from './types/com/atproto/admin/updateAccountEmail' import * as ComAtprotoAdminUpdateAccountHandle from './types/com/atproto/admin/updateAccountHandle' -import * as ComAtprotoAdminUpdateSubjectState from './types/com/atproto/admin/updateSubjectState' +import * as ComAtprotoAdminUpdateSubjectStatus from './types/com/atproto/admin/updateSubjectStatus' import * as ComAtprotoIdentityResolveHandle from './types/com/atproto/identity/resolveHandle' import * as ComAtprotoIdentityUpdateHandle from './types/com/atproto/identity/updateHandle' import * as ComAtprotoLabelQueryLabels from './types/com/atproto/label/queryLabels' @@ -303,14 +303,14 @@ export class AdminNS { return this._server.xrpc.method(nsid, cfg) } - getSubjectState( + getSubjectStatus( cfg: ConfigOf< AV, - ComAtprotoAdminGetSubjectState.Handler>, - ComAtprotoAdminGetSubjectState.HandlerReqCtx> + ComAtprotoAdminGetSubjectStatus.Handler>, + ComAtprotoAdminGetSubjectStatus.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.admin.getSubjectState' // @ts-ignore + const nsid = 'com.atproto.admin.getSubjectStatus' // @ts-ignore return this._server.xrpc.method(nsid, cfg) } @@ -391,14 +391,14 @@ export class AdminNS { return this._server.xrpc.method(nsid, cfg) } - updateSubjectState( + updateSubjectStatus( cfg: ConfigOf< AV, - ComAtprotoAdminUpdateSubjectState.Handler>, - ComAtprotoAdminUpdateSubjectState.HandlerReqCtx> + ComAtprotoAdminUpdateSubjectStatus.Handler>, + ComAtprotoAdminUpdateSubjectStatus.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.admin.updateSubjectState' // @ts-ignore + const nsid = 'com.atproto.admin.updateSubjectStatus' // @ts-ignore return this._server.xrpc.method(nsid, cfg) } } diff --git a/packages/bsky/src/lexicon/lexicons.ts b/packages/bsky/src/lexicon/lexicons.ts index 4ebf1811194..35a7ec3c6cb 100644 --- a/packages/bsky/src/lexicon/lexicons.ts +++ b/packages/bsky/src/lexicon/lexicons.ts @@ -8,7 +8,7 @@ export const schemaDict = { lexicon: 1, id: 'com.atproto.admin.defs', defs: { - subjectState: { + statusAttr: { type: 'object', required: ['applied'], properties: { @@ -1056,14 +1056,14 @@ export const schemaDict = { }, }, }, - ComAtprotoAdminGetSubjectState: { + ComAtprotoAdminGetSubjectStatus: { lexicon: 1, - id: 'com.atproto.admin.getSubjectState', + id: 'com.atproto.admin.getSubjectStatus', defs: { main: { type: 'query', description: - 'Fetch the service-specific the admin state of a subject (account, record, or blob)', + 'Fetch the service-specific the admin status of a subject (account, record, or blob)', parameters: { type: 'params', properties: { @@ -1097,7 +1097,7 @@ export const schemaDict = { }, takedown: { type: 'ref', - ref: 'lex:com.atproto.admin.defs#subjectState', + ref: 'lex:com.atproto.admin.defs#subjectStatus', }, }, }, @@ -1405,14 +1405,14 @@ export const schemaDict = { }, }, }, - ComAtprotoAdminUpdateSubjectState: { + ComAtprotoAdminUpdateSubjectStatus: { lexicon: 1, - id: 'com.atproto.admin.updateSubjectState', + id: 'com.atproto.admin.updateSubjectStatus', defs: { main: { type: 'procedure', description: - 'Update the service-specific admin state of a subject (account, record, or blob)', + 'Update the service-specific admin status of a subject (account, record, or blob)', input: { encoding: 'application/json', schema: { @@ -1429,7 +1429,7 @@ export const schemaDict = { }, takedown: { type: 'ref', - ref: 'lex:com.atproto.admin.defs#subjectState', + ref: 'lex:com.atproto.admin.defs#statusAttr', }, }, }, @@ -1450,7 +1450,7 @@ export const schemaDict = { }, takedown: { type: 'ref', - ref: 'lex:com.atproto.admin.defs#subjectState', + ref: 'lex:com.atproto.admin.defs#statusAttr', }, }, }, @@ -7467,7 +7467,7 @@ export const ids = { ComAtprotoAdminGetModerationReports: 'com.atproto.admin.getModerationReports', ComAtprotoAdminGetRecord: 'com.atproto.admin.getRecord', ComAtprotoAdminGetRepo: 'com.atproto.admin.getRepo', - ComAtprotoAdminGetSubjectState: 'com.atproto.admin.getSubjectState', + ComAtprotoAdminGetSubjectStatus: 'com.atproto.admin.getSubjectStatus', ComAtprotoAdminResolveModerationReports: 'com.atproto.admin.resolveModerationReports', ComAtprotoAdminReverseModerationAction: @@ -7477,7 +7477,7 @@ export const ids = { ComAtprotoAdminTakeModerationAction: 'com.atproto.admin.takeModerationAction', ComAtprotoAdminUpdateAccountEmail: 'com.atproto.admin.updateAccountEmail', ComAtprotoAdminUpdateAccountHandle: 'com.atproto.admin.updateAccountHandle', - ComAtprotoAdminUpdateSubjectState: 'com.atproto.admin.updateSubjectState', + ComAtprotoAdminUpdateSubjectStatus: 'com.atproto.admin.updateSubjectStatus', ComAtprotoIdentityResolveHandle: 'com.atproto.identity.resolveHandle', ComAtprotoIdentityUpdateHandle: 'com.atproto.identity.updateHandle', ComAtprotoLabelDefs: 'com.atproto.label.defs', diff --git a/packages/bsky/src/lexicon/types/com/atproto/admin/defs.ts b/packages/bsky/src/lexicon/types/com/atproto/admin/defs.ts index 6209cc46c4f..7753c97e157 100644 --- a/packages/bsky/src/lexicon/types/com/atproto/admin/defs.ts +++ b/packages/bsky/src/lexicon/types/com/atproto/admin/defs.ts @@ -10,22 +10,22 @@ import * as ComAtprotoModerationDefs from '../moderation/defs' import * as ComAtprotoServerDefs from '../server/defs' import * as ComAtprotoLabelDefs from '../label/defs' -export interface SubjectState { +export interface StatusAttr { applied: boolean ref?: string [k: string]: unknown } -export function isSubjectState(v: unknown): v is SubjectState { +export function isStatusAttr(v: unknown): v is StatusAttr { return ( isObj(v) && hasProp(v, '$type') && - v.$type === 'com.atproto.admin.defs#subjectState' + v.$type === 'com.atproto.admin.defs#statusAttr' ) } -export function validateSubjectState(v: unknown): ValidationResult { - return lexicons.validate('com.atproto.admin.defs#subjectState', v) +export function validateStatusAttr(v: unknown): ValidationResult { + return lexicons.validate('com.atproto.admin.defs#statusAttr', v) } export interface ActionView { diff --git a/packages/bsky/src/lexicon/types/com/atproto/admin/getSubjectState.ts b/packages/bsky/src/lexicon/types/com/atproto/admin/getSubjectStatus.ts similarity index 96% rename from packages/bsky/src/lexicon/types/com/atproto/admin/getSubjectState.ts rename to packages/bsky/src/lexicon/types/com/atproto/admin/getSubjectStatus.ts index b828c39c1aa..425865847e0 100644 --- a/packages/bsky/src/lexicon/types/com/atproto/admin/getSubjectState.ts +++ b/packages/bsky/src/lexicon/types/com/atproto/admin/getSubjectStatus.ts @@ -24,7 +24,7 @@ export interface OutputSchema { | ComAtprotoRepoStrongRef.Main | ComAtprotoAdminDefs.RepoBlobRef | { $type: string; [k: string]: unknown } - takedown?: ComAtprotoAdminDefs.SubjectState + takedown?: ComAtprotoAdminDefs.SubjectStatus [k: string]: unknown } diff --git a/packages/bsky/src/lexicon/types/com/atproto/admin/updateSubjectState.ts b/packages/bsky/src/lexicon/types/com/atproto/admin/updateSubjectStatus.ts similarity index 94% rename from packages/bsky/src/lexicon/types/com/atproto/admin/updateSubjectState.ts rename to packages/bsky/src/lexicon/types/com/atproto/admin/updateSubjectStatus.ts index 6d79a8b67ed..559ee948380 100644 --- a/packages/bsky/src/lexicon/types/com/atproto/admin/updateSubjectState.ts +++ b/packages/bsky/src/lexicon/types/com/atproto/admin/updateSubjectStatus.ts @@ -18,7 +18,7 @@ export interface InputSchema { | ComAtprotoRepoStrongRef.Main | ComAtprotoAdminDefs.RepoBlobRef | { $type: string; [k: string]: unknown } - takedown?: ComAtprotoAdminDefs.SubjectState + takedown?: ComAtprotoAdminDefs.StatusAttr [k: string]: unknown } @@ -28,7 +28,7 @@ export interface OutputSchema { | ComAtprotoRepoStrongRef.Main | ComAtprotoAdminDefs.RepoBlobRef | { $type: string; [k: string]: unknown } - takedown?: ComAtprotoAdminDefs.SubjectState + takedown?: ComAtprotoAdminDefs.StatusAttr [k: string]: unknown } diff --git a/packages/pds/src/api/com/atproto/admin/getSubjectState.ts b/packages/pds/src/api/com/atproto/admin/getSubjectStatus.ts similarity index 91% rename from packages/pds/src/api/com/atproto/admin/getSubjectState.ts rename to packages/pds/src/api/com/atproto/admin/getSubjectStatus.ts index 16ce00164cc..62fc1f9f0d7 100644 --- a/packages/pds/src/api/com/atproto/admin/getSubjectState.ts +++ b/packages/pds/src/api/com/atproto/admin/getSubjectStatus.ts @@ -2,25 +2,25 @@ import { CID } from 'multiformats/cid' import { AtUri } from '@atproto/syntax' import { Server } from '../../../../lexicon' import AppContext from '../../../../context' -import { OutputSchema } from '../../../../lexicon/types/com/atproto/admin/getSubjectState' +import { OutputSchema } from '../../../../lexicon/types/com/atproto/admin/getSubjectStatus' import { InvalidRequestError } from '@atproto/xrpc-server' export default function (server: Server, ctx: AppContext) { - server.com.atproto.admin.getSubjectState({ + server.com.atproto.admin.getSubjectStatus({ auth: ctx.roleVerifier, handler: async ({ params }) => { const { did, uri, blob } = params const modSrvc = ctx.services.moderation(ctx.db) let body: OutputSchema | null - if (uri) { - body = await modSrvc.getRecordTakedownState(new AtUri(uri)) - } else if (blob) { + if (blob) { if (!did) { throw new InvalidRequestError( 'Must provide a did to request blob state', ) } body = await modSrvc.getBlobTakedownState(did, CID.parse(blob)) + } else if (uri) { + body = await modSrvc.getRecordTakedownState(new AtUri(uri)) } else if (did) { body = await modSrvc.getRepoTakedownState(did) } else { diff --git a/packages/pds/src/api/com/atproto/admin/index.ts b/packages/pds/src/api/com/atproto/admin/index.ts index ec3feb2076f..4f18cef55f9 100644 --- a/packages/pds/src/api/com/atproto/admin/index.ts +++ b/packages/pds/src/api/com/atproto/admin/index.ts @@ -3,8 +3,8 @@ import { Server } from '../../../../lexicon' import resolveModerationReports from './resolveModerationReports' import reverseModerationAction from './reverseModerationAction' import takeModerationAction from './takeModerationAction' -import updateSubjectState from './updateSubjectState' -import getSubjectState from './getSubjectState' +import updateSubjectStatus from './updateSubjectStatus' +import getSubjectStatus from './getSubjectStatus' import searchRepos from './searchRepos' import getRecord from './getRecord' import getRepo from './getRepo' @@ -24,8 +24,8 @@ export default function (server: Server, ctx: AppContext) { resolveModerationReports(server, ctx) reverseModerationAction(server, ctx) takeModerationAction(server, ctx) - updateSubjectState(server, ctx) - getSubjectState(server, ctx) + updateSubjectStatus(server, ctx) + getSubjectStatus(server, ctx) searchRepos(server, ctx) getRecord(server, ctx) getRepo(server, ctx) diff --git a/packages/pds/src/api/com/atproto/admin/updateSubjectState.ts b/packages/pds/src/api/com/atproto/admin/updateSubjectStatus.ts similarity index 97% rename from packages/pds/src/api/com/atproto/admin/updateSubjectState.ts rename to packages/pds/src/api/com/atproto/admin/updateSubjectStatus.ts index d8552c98835..898e7d4b586 100644 --- a/packages/pds/src/api/com/atproto/admin/updateSubjectState.ts +++ b/packages/pds/src/api/com/atproto/admin/updateSubjectStatus.ts @@ -10,7 +10,7 @@ import { isMain as isStrongRef } from '../../../../lexicon/types/com/atproto/rep import { AuthRequiredError, InvalidRequestError } from '@atproto/xrpc-server' export default function (server: Server, ctx: AppContext) { - server.com.atproto.admin.updateSubjectState({ + server.com.atproto.admin.updateSubjectStatus({ auth: ctx.roleVerifier, handler: async ({ input, auth }) => { const access = auth.credentials diff --git a/packages/pds/src/lexicon/index.ts b/packages/pds/src/lexicon/index.ts index 30c97349d0a..bbed8fccb04 100644 --- a/packages/pds/src/lexicon/index.ts +++ b/packages/pds/src/lexicon/index.ts @@ -19,7 +19,7 @@ import * as ComAtprotoAdminGetModerationReport from './types/com/atproto/admin/g import * as ComAtprotoAdminGetModerationReports from './types/com/atproto/admin/getModerationReports' import * as ComAtprotoAdminGetRecord from './types/com/atproto/admin/getRecord' import * as ComAtprotoAdminGetRepo from './types/com/atproto/admin/getRepo' -import * as ComAtprotoAdminGetSubjectState from './types/com/atproto/admin/getSubjectState' +import * as ComAtprotoAdminGetSubjectStatus from './types/com/atproto/admin/getSubjectStatus' import * as ComAtprotoAdminResolveModerationReports from './types/com/atproto/admin/resolveModerationReports' import * as ComAtprotoAdminReverseModerationAction from './types/com/atproto/admin/reverseModerationAction' import * as ComAtprotoAdminSearchRepos from './types/com/atproto/admin/searchRepos' @@ -27,7 +27,7 @@ import * as ComAtprotoAdminSendEmail from './types/com/atproto/admin/sendEmail' import * as ComAtprotoAdminTakeModerationAction from './types/com/atproto/admin/takeModerationAction' import * as ComAtprotoAdminUpdateAccountEmail from './types/com/atproto/admin/updateAccountEmail' import * as ComAtprotoAdminUpdateAccountHandle from './types/com/atproto/admin/updateAccountHandle' -import * as ComAtprotoAdminUpdateSubjectState from './types/com/atproto/admin/updateSubjectState' +import * as ComAtprotoAdminUpdateSubjectStatus from './types/com/atproto/admin/updateSubjectStatus' import * as ComAtprotoIdentityResolveHandle from './types/com/atproto/identity/resolveHandle' import * as ComAtprotoIdentityUpdateHandle from './types/com/atproto/identity/updateHandle' import * as ComAtprotoLabelQueryLabels from './types/com/atproto/label/queryLabels' @@ -303,14 +303,14 @@ export class AdminNS { return this._server.xrpc.method(nsid, cfg) } - getSubjectState( + getSubjectStatus( cfg: ConfigOf< AV, - ComAtprotoAdminGetSubjectState.Handler>, - ComAtprotoAdminGetSubjectState.HandlerReqCtx> + ComAtprotoAdminGetSubjectStatus.Handler>, + ComAtprotoAdminGetSubjectStatus.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.admin.getSubjectState' // @ts-ignore + const nsid = 'com.atproto.admin.getSubjectStatus' // @ts-ignore return this._server.xrpc.method(nsid, cfg) } @@ -391,14 +391,14 @@ export class AdminNS { return this._server.xrpc.method(nsid, cfg) } - updateSubjectState( + updateSubjectStatus( cfg: ConfigOf< AV, - ComAtprotoAdminUpdateSubjectState.Handler>, - ComAtprotoAdminUpdateSubjectState.HandlerReqCtx> + ComAtprotoAdminUpdateSubjectStatus.Handler>, + ComAtprotoAdminUpdateSubjectStatus.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.admin.updateSubjectState' // @ts-ignore + const nsid = 'com.atproto.admin.updateSubjectStatus' // @ts-ignore return this._server.xrpc.method(nsid, cfg) } } diff --git a/packages/pds/src/lexicon/lexicons.ts b/packages/pds/src/lexicon/lexicons.ts index 4ebf1811194..35a7ec3c6cb 100644 --- a/packages/pds/src/lexicon/lexicons.ts +++ b/packages/pds/src/lexicon/lexicons.ts @@ -8,7 +8,7 @@ export const schemaDict = { lexicon: 1, id: 'com.atproto.admin.defs', defs: { - subjectState: { + statusAttr: { type: 'object', required: ['applied'], properties: { @@ -1056,14 +1056,14 @@ export const schemaDict = { }, }, }, - ComAtprotoAdminGetSubjectState: { + ComAtprotoAdminGetSubjectStatus: { lexicon: 1, - id: 'com.atproto.admin.getSubjectState', + id: 'com.atproto.admin.getSubjectStatus', defs: { main: { type: 'query', description: - 'Fetch the service-specific the admin state of a subject (account, record, or blob)', + 'Fetch the service-specific the admin status of a subject (account, record, or blob)', parameters: { type: 'params', properties: { @@ -1097,7 +1097,7 @@ export const schemaDict = { }, takedown: { type: 'ref', - ref: 'lex:com.atproto.admin.defs#subjectState', + ref: 'lex:com.atproto.admin.defs#subjectStatus', }, }, }, @@ -1405,14 +1405,14 @@ export const schemaDict = { }, }, }, - ComAtprotoAdminUpdateSubjectState: { + ComAtprotoAdminUpdateSubjectStatus: { lexicon: 1, - id: 'com.atproto.admin.updateSubjectState', + id: 'com.atproto.admin.updateSubjectStatus', defs: { main: { type: 'procedure', description: - 'Update the service-specific admin state of a subject (account, record, or blob)', + 'Update the service-specific admin status of a subject (account, record, or blob)', input: { encoding: 'application/json', schema: { @@ -1429,7 +1429,7 @@ export const schemaDict = { }, takedown: { type: 'ref', - ref: 'lex:com.atproto.admin.defs#subjectState', + ref: 'lex:com.atproto.admin.defs#statusAttr', }, }, }, @@ -1450,7 +1450,7 @@ export const schemaDict = { }, takedown: { type: 'ref', - ref: 'lex:com.atproto.admin.defs#subjectState', + ref: 'lex:com.atproto.admin.defs#statusAttr', }, }, }, @@ -7467,7 +7467,7 @@ export const ids = { ComAtprotoAdminGetModerationReports: 'com.atproto.admin.getModerationReports', ComAtprotoAdminGetRecord: 'com.atproto.admin.getRecord', ComAtprotoAdminGetRepo: 'com.atproto.admin.getRepo', - ComAtprotoAdminGetSubjectState: 'com.atproto.admin.getSubjectState', + ComAtprotoAdminGetSubjectStatus: 'com.atproto.admin.getSubjectStatus', ComAtprotoAdminResolveModerationReports: 'com.atproto.admin.resolveModerationReports', ComAtprotoAdminReverseModerationAction: @@ -7477,7 +7477,7 @@ export const ids = { ComAtprotoAdminTakeModerationAction: 'com.atproto.admin.takeModerationAction', ComAtprotoAdminUpdateAccountEmail: 'com.atproto.admin.updateAccountEmail', ComAtprotoAdminUpdateAccountHandle: 'com.atproto.admin.updateAccountHandle', - ComAtprotoAdminUpdateSubjectState: 'com.atproto.admin.updateSubjectState', + ComAtprotoAdminUpdateSubjectStatus: 'com.atproto.admin.updateSubjectStatus', ComAtprotoIdentityResolveHandle: 'com.atproto.identity.resolveHandle', ComAtprotoIdentityUpdateHandle: 'com.atproto.identity.updateHandle', ComAtprotoLabelDefs: 'com.atproto.label.defs', diff --git a/packages/pds/src/lexicon/types/com/atproto/admin/defs.ts b/packages/pds/src/lexicon/types/com/atproto/admin/defs.ts index 6209cc46c4f..7753c97e157 100644 --- a/packages/pds/src/lexicon/types/com/atproto/admin/defs.ts +++ b/packages/pds/src/lexicon/types/com/atproto/admin/defs.ts @@ -10,22 +10,22 @@ import * as ComAtprotoModerationDefs from '../moderation/defs' import * as ComAtprotoServerDefs from '../server/defs' import * as ComAtprotoLabelDefs from '../label/defs' -export interface SubjectState { +export interface StatusAttr { applied: boolean ref?: string [k: string]: unknown } -export function isSubjectState(v: unknown): v is SubjectState { +export function isStatusAttr(v: unknown): v is StatusAttr { return ( isObj(v) && hasProp(v, '$type') && - v.$type === 'com.atproto.admin.defs#subjectState' + v.$type === 'com.atproto.admin.defs#statusAttr' ) } -export function validateSubjectState(v: unknown): ValidationResult { - return lexicons.validate('com.atproto.admin.defs#subjectState', v) +export function validateStatusAttr(v: unknown): ValidationResult { + return lexicons.validate('com.atproto.admin.defs#statusAttr', v) } export interface ActionView { diff --git a/packages/pds/src/lexicon/types/com/atproto/admin/getSubjectState.ts b/packages/pds/src/lexicon/types/com/atproto/admin/getSubjectStatus.ts similarity index 96% rename from packages/pds/src/lexicon/types/com/atproto/admin/getSubjectState.ts rename to packages/pds/src/lexicon/types/com/atproto/admin/getSubjectStatus.ts index b828c39c1aa..425865847e0 100644 --- a/packages/pds/src/lexicon/types/com/atproto/admin/getSubjectState.ts +++ b/packages/pds/src/lexicon/types/com/atproto/admin/getSubjectStatus.ts @@ -24,7 +24,7 @@ export interface OutputSchema { | ComAtprotoRepoStrongRef.Main | ComAtprotoAdminDefs.RepoBlobRef | { $type: string; [k: string]: unknown } - takedown?: ComAtprotoAdminDefs.SubjectState + takedown?: ComAtprotoAdminDefs.SubjectStatus [k: string]: unknown } diff --git a/packages/pds/src/lexicon/types/com/atproto/admin/updateSubjectState.ts b/packages/pds/src/lexicon/types/com/atproto/admin/updateSubjectStatus.ts similarity index 94% rename from packages/pds/src/lexicon/types/com/atproto/admin/updateSubjectState.ts rename to packages/pds/src/lexicon/types/com/atproto/admin/updateSubjectStatus.ts index 6d79a8b67ed..559ee948380 100644 --- a/packages/pds/src/lexicon/types/com/atproto/admin/updateSubjectState.ts +++ b/packages/pds/src/lexicon/types/com/atproto/admin/updateSubjectStatus.ts @@ -18,7 +18,7 @@ export interface InputSchema { | ComAtprotoRepoStrongRef.Main | ComAtprotoAdminDefs.RepoBlobRef | { $type: string; [k: string]: unknown } - takedown?: ComAtprotoAdminDefs.SubjectState + takedown?: ComAtprotoAdminDefs.StatusAttr [k: string]: unknown } @@ -28,7 +28,7 @@ export interface OutputSchema { | ComAtprotoRepoStrongRef.Main | ComAtprotoAdminDefs.RepoBlobRef | { $type: string; [k: string]: unknown } - takedown?: ComAtprotoAdminDefs.SubjectState + takedown?: ComAtprotoAdminDefs.StatusAttr [k: string]: unknown } diff --git a/packages/pds/src/services/moderation/index.ts b/packages/pds/src/services/moderation/index.ts index 88458773911..28d2d07407c 100644 --- a/packages/pds/src/services/moderation/index.ts +++ b/packages/pds/src/services/moderation/index.ts @@ -12,7 +12,7 @@ import { TAKEDOWN, RepoBlobRef, RepoRef, - SubjectState, + StatusAttr, } from '../../lexicon/types/com/atproto/admin/defs' import { Main as StrongRef } from '../../lexicon/types/com/atproto/repo/strongRef' import { addHoursToDate } from '../../util/date' @@ -32,51 +32,47 @@ export class ModerationService { async getRepoTakedownState( did: string, - ): Promise | null> { + ): Promise | null> { const res = await this.db.db .selectFrom('repo_root') .select('takedownId') .where('did', '=', did) .executeTakeFirst() if (!res) return null - const state = takedownIdToSubjectState(res.takedownId ?? null) + const state = takedownIdToStatus(res.takedownId ?? null) return { subject: { $type: 'com.atproto.admin.defs#repoRef', did: did, }, - state: { - takedown: state, - }, + takedown: state, } } async getRecordTakedownState( uri: AtUri, - ): Promise | null> { + ): Promise | null> { const res = await this.db.db .selectFrom('record') .select(['takedownId', 'cid']) .where('uri', '=', uri.toString()) .executeTakeFirst() if (!res) return null - const state = takedownIdToSubjectState(res.takedownId ?? null) + const state = takedownIdToStatus(res.takedownId ?? null) return { subject: { $type: 'com.atproto.repo.strongRef', uri: uri.toString(), cid: res.cid, }, - state: { - takedown: state, - }, + takedown: state, } } async getBlobTakedownState( did: string, cid: CID, - ): Promise | null> { + ): Promise | null> { const res = await this.db.db .selectFrom('repo_blob') .select('takedownId') @@ -84,21 +80,19 @@ export class ModerationService { .where('cid', '=', cid.toString()) .executeTakeFirst() if (!res) return null - const state = takedownIdToSubjectState(res.takedownId ?? null) + const state = takedownIdToStatus(res.takedownId ?? null) return { subject: { $type: 'com.atproto.admin.defs#repoBlobRef', did: did, cid: cid.toString(), }, - state: { - takedown: state, - }, + takedown: state, } } - async updateRepoTakedownState(did: string, state: SubjectState) { - const takedownId = subjectStateToTakedownId(state) + async updateRepoTakedownState(did: string, takedown: StatusAttr) { + const takedownId = statusToTakedownId(takedown) await this.db.db .updateTable('repo_root') .set({ takedownId }) @@ -106,8 +100,8 @@ export class ModerationService { .executeTakeFirst() } - async updateRecordTakedownState(uri: AtUri, state: SubjectState) { - const takedownId = subjectStateToTakedownId(state) + async updateRecordTakedownState(uri: AtUri, takedown: StatusAttr) { + const takedownId = statusToTakedownId(takedown) await this.db.db .updateTable('record') .set({ takedownId }) @@ -115,18 +109,18 @@ export class ModerationService { .executeTakeFirst() } - async updateBlobTakedownState(did: string, blob: CID, state: SubjectState) { - const takedownId = subjectStateToTakedownId(state) + async updateBlobTakedownState(did: string, blob: CID, takedown: StatusAttr) { + const takedownId = statusToTakedownId(takedown) await this.db.db .updateTable('repo_blob') .set({ takedownId }) .where('did', '=', did) .where('cid', '=', blob.toString()) .executeTakeFirst() - if (state.applied) { - await this.blobstore.unquarantine(blob) - } else { + if (takedown.applied) { await this.blobstore.quarantine(blob) + } else { + await this.blobstore.unquarantine(blob) } } @@ -715,17 +709,17 @@ export class ModerationService { } } -const takedownIdToSubjectState = (id: string | null): SubjectState => { +const takedownIdToStatus = (id: string | null): StatusAttr => { return id === null ? { applied: false } : { applied: true, ref: id } } -const subjectStateToTakedownId = (state: SubjectState): string | null => { +const statusToTakedownId = (state: StatusAttr): string | null => { return state.applied ? state.ref ?? new Date().toISOString() : null } -type StateResponse = { +type StatusResponse = { subject: T - state: { takedown: SubjectState } + takedown: StatusAttr } export type ModerationActionRow = Selectable From 074d4c09e79d41262295cec059d3536e6d6b556e Mon Sep 17 00:00:00 2001 From: dholms Date: Thu, 12 Oct 2023 12:07:52 -0500 Subject: [PATCH 6/8] missed a rename --- lexicons/com/atproto/admin/getSubjectStatus.json | 2 +- packages/api/src/client/lexicons.ts | 2 +- .../api/src/client/types/com/atproto/admin/getSubjectStatus.ts | 2 +- packages/bsky/src/lexicon/lexicons.ts | 2 +- .../src/lexicon/types/com/atproto/admin/getSubjectStatus.ts | 2 +- packages/pds/src/lexicon/lexicons.ts | 2 +- .../pds/src/lexicon/types/com/atproto/admin/getSubjectStatus.ts | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lexicons/com/atproto/admin/getSubjectStatus.json b/lexicons/com/atproto/admin/getSubjectStatus.json index aba7b268b7f..a6ce340c009 100644 --- a/lexicons/com/atproto/admin/getSubjectStatus.json +++ b/lexicons/com/atproto/admin/getSubjectStatus.json @@ -29,7 +29,7 @@ }, "takedown": { "type": "ref", - "ref": "com.atproto.admin.defs#subjectStatus" + "ref": "com.atproto.admin.defs#statusAttr" } } } diff --git a/packages/api/src/client/lexicons.ts b/packages/api/src/client/lexicons.ts index 35a7ec3c6cb..3f02f26ee01 100644 --- a/packages/api/src/client/lexicons.ts +++ b/packages/api/src/client/lexicons.ts @@ -1097,7 +1097,7 @@ export const schemaDict = { }, takedown: { type: 'ref', - ref: 'lex:com.atproto.admin.defs#subjectStatus', + ref: 'lex:com.atproto.admin.defs#statusAttr', }, }, }, diff --git a/packages/api/src/client/types/com/atproto/admin/getSubjectStatus.ts b/packages/api/src/client/types/com/atproto/admin/getSubjectStatus.ts index de9bd5c59d3..26986e5dde7 100644 --- a/packages/api/src/client/types/com/atproto/admin/getSubjectStatus.ts +++ b/packages/api/src/client/types/com/atproto/admin/getSubjectStatus.ts @@ -23,7 +23,7 @@ export interface OutputSchema { | ComAtprotoRepoStrongRef.Main | ComAtprotoAdminDefs.RepoBlobRef | { $type: string; [k: string]: unknown } - takedown?: ComAtprotoAdminDefs.SubjectStatus + takedown?: ComAtprotoAdminDefs.StatusAttr [k: string]: unknown } diff --git a/packages/bsky/src/lexicon/lexicons.ts b/packages/bsky/src/lexicon/lexicons.ts index 35a7ec3c6cb..3f02f26ee01 100644 --- a/packages/bsky/src/lexicon/lexicons.ts +++ b/packages/bsky/src/lexicon/lexicons.ts @@ -1097,7 +1097,7 @@ export const schemaDict = { }, takedown: { type: 'ref', - ref: 'lex:com.atproto.admin.defs#subjectStatus', + ref: 'lex:com.atproto.admin.defs#statusAttr', }, }, }, diff --git a/packages/bsky/src/lexicon/types/com/atproto/admin/getSubjectStatus.ts b/packages/bsky/src/lexicon/types/com/atproto/admin/getSubjectStatus.ts index 425865847e0..7315e51e8c2 100644 --- a/packages/bsky/src/lexicon/types/com/atproto/admin/getSubjectStatus.ts +++ b/packages/bsky/src/lexicon/types/com/atproto/admin/getSubjectStatus.ts @@ -24,7 +24,7 @@ export interface OutputSchema { | ComAtprotoRepoStrongRef.Main | ComAtprotoAdminDefs.RepoBlobRef | { $type: string; [k: string]: unknown } - takedown?: ComAtprotoAdminDefs.SubjectStatus + takedown?: ComAtprotoAdminDefs.StatusAttr [k: string]: unknown } diff --git a/packages/pds/src/lexicon/lexicons.ts b/packages/pds/src/lexicon/lexicons.ts index 35a7ec3c6cb..3f02f26ee01 100644 --- a/packages/pds/src/lexicon/lexicons.ts +++ b/packages/pds/src/lexicon/lexicons.ts @@ -1097,7 +1097,7 @@ export const schemaDict = { }, takedown: { type: 'ref', - ref: 'lex:com.atproto.admin.defs#subjectStatus', + ref: 'lex:com.atproto.admin.defs#statusAttr', }, }, }, diff --git a/packages/pds/src/lexicon/types/com/atproto/admin/getSubjectStatus.ts b/packages/pds/src/lexicon/types/com/atproto/admin/getSubjectStatus.ts index 425865847e0..7315e51e8c2 100644 --- a/packages/pds/src/lexicon/types/com/atproto/admin/getSubjectStatus.ts +++ b/packages/pds/src/lexicon/types/com/atproto/admin/getSubjectStatus.ts @@ -24,7 +24,7 @@ export interface OutputSchema { | ComAtprotoRepoStrongRef.Main | ComAtprotoAdminDefs.RepoBlobRef | { $type: string; [k: string]: unknown } - takedown?: ComAtprotoAdminDefs.SubjectStatus + takedown?: ComAtprotoAdminDefs.StatusAttr [k: string]: unknown } From 1af3650dca8f1c5815afd60b2797cef434e91b88 Mon Sep 17 00:00:00 2001 From: dholms Date: Sat, 14 Oct 2023 11:59:08 -0500 Subject: [PATCH 7/8] fix build --- packages/pds/src/api/com/atproto/admin/getSubjectStatus.ts | 2 +- packages/pds/src/api/com/atproto/admin/updateSubjectStatus.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/pds/src/api/com/atproto/admin/getSubjectStatus.ts b/packages/pds/src/api/com/atproto/admin/getSubjectStatus.ts index 62fc1f9f0d7..7f700ef4bb3 100644 --- a/packages/pds/src/api/com/atproto/admin/getSubjectStatus.ts +++ b/packages/pds/src/api/com/atproto/admin/getSubjectStatus.ts @@ -7,7 +7,7 @@ import { InvalidRequestError } from '@atproto/xrpc-server' export default function (server: Server, ctx: AppContext) { server.com.atproto.admin.getSubjectStatus({ - auth: ctx.roleVerifier, + auth: ctx.authVerifier.role, handler: async ({ params }) => { const { did, uri, blob } = params const modSrvc = ctx.services.moderation(ctx.db) diff --git a/packages/pds/src/api/com/atproto/admin/updateSubjectStatus.ts b/packages/pds/src/api/com/atproto/admin/updateSubjectStatus.ts index 898e7d4b586..a79fe2ea87c 100644 --- a/packages/pds/src/api/com/atproto/admin/updateSubjectStatus.ts +++ b/packages/pds/src/api/com/atproto/admin/updateSubjectStatus.ts @@ -11,7 +11,7 @@ import { AuthRequiredError, InvalidRequestError } from '@atproto/xrpc-server' export default function (server: Server, ctx: AppContext) { server.com.atproto.admin.updateSubjectStatus({ - auth: ctx.roleVerifier, + auth: ctx.authVerifier.role, handler: async ({ input, auth }) => { const access = auth.credentials // if less than moderator access then cannot perform a takedown From 2efe4fa5afbd0fa1e5725642c859f312ceb9aa8c Mon Sep 17 00:00:00 2001 From: dholms Date: Sat, 14 Oct 2023 17:29:47 -0400 Subject: [PATCH 8/8] cleanup repeat process all --- packages/bsky/tests/views/posts.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/bsky/tests/views/posts.test.ts b/packages/bsky/tests/views/posts.test.ts index a2710a02cf7..69bade5b91a 100644 --- a/packages/bsky/tests/views/posts.test.ts +++ b/packages/bsky/tests/views/posts.test.ts @@ -18,7 +18,6 @@ describe('pds posts views', () => { sc = network.getSeedClient() await basicSeed(sc) await network.processAll() - await network.bsky.processAll() }) afterAll(async () => { @@ -98,7 +97,6 @@ describe('pds posts views', () => { ) await network.processAll() - await network.bsky.processAll() const { data } = await agent.api.app.bsky.feed.getPosts({ uris: [uri] })