✨ Allow ignoring moderation reports by subject (#1091)
* ✨ Allow ignoring moderation reports by subject * 🔧 Remove unwanted package.json change * ✨ Remove subject format specifier * ✨ Port over ignore subject implementation to bsky package * Revert "✨ Port over ignore subject implementation to bsky package" This reverts commit 3c782c1805548d1ebdbbd08b68b6e92ac97fdee5. * 🚧 Port over ignore subject implementation to bsky package * ✨ Generate lexicons for bsky
This commit is contained in:
parent
237bb97e20
commit
3414fcedbf
lexicons/com/atproto/admin
packages
api/src/client
bsky/src
api/com/atproto/admin
lexicon
services/moderation
pds
src
api/com/atproto/admin
lexicon
services/moderation
tests/views/admin
@ -9,6 +9,7 @@
|
||||
"type": "params",
|
||||
"properties": {
|
||||
"subject": {"type": "string"},
|
||||
"ignoreSubjects": {"type": "array", "items": {"type": "string"}},
|
||||
"resolved": {"type": "boolean"},
|
||||
"actionType": {
|
||||
"type": "string",
|
||||
|
@ -856,6 +856,12 @@ export const schemaDict = {
|
||||
subject: {
|
||||
type: 'string',
|
||||
},
|
||||
ignoreSubjects: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
resolved: {
|
||||
type: 'boolean',
|
||||
},
|
||||
|
@ -10,6 +10,7 @@ import * as ComAtprotoAdminDefs from './defs'
|
||||
|
||||
export interface QueryParams {
|
||||
subject?: string
|
||||
ignoreSubjects?: string[]
|
||||
resolved?: boolean
|
||||
actionType?:
|
||||
| 'com.atproto.admin.defs#takedown'
|
||||
|
@ -7,7 +7,14 @@ export default function (server: Server, ctx: AppContext) {
|
||||
auth: adminVerifier(ctx.cfg.adminPassword),
|
||||
handler: async ({ params }) => {
|
||||
const { db, services } = ctx
|
||||
const { subject, resolved, actionType, limit = 50, cursor } = params
|
||||
const {
|
||||
subject,
|
||||
resolved,
|
||||
actionType,
|
||||
limit = 50,
|
||||
cursor,
|
||||
ignoreSubjects,
|
||||
} = params
|
||||
const moderationService = services.moderation(db)
|
||||
const results = await moderationService.getReports({
|
||||
subject,
|
||||
@ -15,6 +22,7 @@ export default function (server: Server, ctx: AppContext) {
|
||||
actionType,
|
||||
limit,
|
||||
cursor,
|
||||
ignoreSubjects,
|
||||
})
|
||||
return {
|
||||
encoding: 'application/json',
|
||||
|
@ -74,18 +74,18 @@ import * as AppBskyActorGetSuggestions from './types/app/bsky/actor/getSuggestio
|
||||
import * as AppBskyActorPutPreferences from './types/app/bsky/actor/putPreferences'
|
||||
import * as AppBskyActorSearchActors from './types/app/bsky/actor/searchActors'
|
||||
import * as AppBskyActorSearchActorsTypeahead from './types/app/bsky/actor/searchActorsTypeahead'
|
||||
import * as AppBskyFeedDescribeFeedGenerator from './types/app/bsky/feed/describeFeedGenerator'
|
||||
import * as AppBskyFeedGetActorFeeds from './types/app/bsky/feed/getActorFeeds'
|
||||
import * as AppBskyFeedGetAuthorFeed from './types/app/bsky/feed/getAuthorFeed'
|
||||
import * as AppBskyFeedGetFeed from './types/app/bsky/feed/getFeed'
|
||||
import * as AppBskyFeedGetFeedGenerator from './types/app/bsky/feed/getFeedGenerator'
|
||||
import * as AppBskyFeedGetFeedGenerators from './types/app/bsky/feed/getFeedGenerators'
|
||||
import * as AppBskyFeedGetFeedSkeleton from './types/app/bsky/feed/getFeedSkeleton'
|
||||
import * as AppBskyFeedGetLikes from './types/app/bsky/feed/getLikes'
|
||||
import * as AppBskyFeedGetPostThread from './types/app/bsky/feed/getPostThread'
|
||||
import * as AppBskyFeedGetPosts from './types/app/bsky/feed/getPosts'
|
||||
import * as AppBskyFeedGetRepostedBy from './types/app/bsky/feed/getRepostedBy'
|
||||
import * as AppBskyFeedGetSavedFeeds from './types/app/bsky/feed/getSavedFeeds'
|
||||
import * as AppBskyFeedGetTimeline from './types/app/bsky/feed/getTimeline'
|
||||
import * as AppBskyFeedSaveFeed from './types/app/bsky/feed/saveFeed'
|
||||
import * as AppBskyFeedUnsaveFeed from './types/app/bsky/feed/unsaveFeed'
|
||||
import * as AppBskyGraphGetBlocks from './types/app/bsky/graph/getBlocks'
|
||||
import * as AppBskyGraphGetFollowers from './types/app/bsky/graph/getFollowers'
|
||||
import * as AppBskyGraphGetFollows from './types/app/bsky/graph/getFollows'
|
||||
@ -101,6 +101,7 @@ import * as AppBskyNotificationGetUnreadCount from './types/app/bsky/notificatio
|
||||
import * as AppBskyNotificationListNotifications from './types/app/bsky/notification/listNotifications'
|
||||
import * as AppBskyNotificationUpdateSeen from './types/app/bsky/notification/updateSeen'
|
||||
import * as AppBskyUnspeccedGetPopular from './types/app/bsky/unspecced/getPopular'
|
||||
import * as AppBskyUnspeccedGetPopularFeedGenerators from './types/app/bsky/unspecced/getPopularFeedGenerators'
|
||||
|
||||
export const COM_ATPROTO_ADMIN = {
|
||||
DefsTakedown: 'com.atproto.admin.defs#takedown',
|
||||
@ -800,6 +801,16 @@ export class FeedNS {
|
||||
this._server = server
|
||||
}
|
||||
|
||||
describeFeedGenerator<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<
|
||||
AV,
|
||||
AppBskyFeedDescribeFeedGenerator.Handler<ExtractAuth<AV>>
|
||||
>,
|
||||
) {
|
||||
const nsid = 'app.bsky.feed.describeFeedGenerator' // @ts-ignore
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
|
||||
getActorFeeds<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyFeedGetActorFeeds.Handler<ExtractAuth<AV>>>,
|
||||
) {
|
||||
@ -821,6 +832,20 @@ export class FeedNS {
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
|
||||
getFeedGenerator<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyFeedGetFeedGenerator.Handler<ExtractAuth<AV>>>,
|
||||
) {
|
||||
const nsid = 'app.bsky.feed.getFeedGenerator' // @ts-ignore
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
|
||||
getFeedGenerators<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyFeedGetFeedGenerators.Handler<ExtractAuth<AV>>>,
|
||||
) {
|
||||
const nsid = 'app.bsky.feed.getFeedGenerators' // @ts-ignore
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
|
||||
getFeedSkeleton<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyFeedGetFeedSkeleton.Handler<ExtractAuth<AV>>>,
|
||||
) {
|
||||
@ -856,33 +881,12 @@ export class FeedNS {
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
|
||||
getSavedFeeds<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyFeedGetSavedFeeds.Handler<ExtractAuth<AV>>>,
|
||||
) {
|
||||
const nsid = 'app.bsky.feed.getSavedFeeds' // @ts-ignore
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
|
||||
getTimeline<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyFeedGetTimeline.Handler<ExtractAuth<AV>>>,
|
||||
) {
|
||||
const nsid = 'app.bsky.feed.getTimeline' // @ts-ignore
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
|
||||
saveFeed<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyFeedSaveFeed.Handler<ExtractAuth<AV>>>,
|
||||
) {
|
||||
const nsid = 'app.bsky.feed.saveFeed' // @ts-ignore
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
|
||||
unsaveFeed<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<AV, AppBskyFeedUnsaveFeed.Handler<ExtractAuth<AV>>>,
|
||||
) {
|
||||
const nsid = 'app.bsky.feed.unsaveFeed' // @ts-ignore
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
}
|
||||
|
||||
export class GraphNS {
|
||||
@ -1026,6 +1030,16 @@ export class UnspeccedNS {
|
||||
const nsid = 'app.bsky.unspecced.getPopular' // @ts-ignore
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
|
||||
getPopularFeedGenerators<AV extends AuthVerifier>(
|
||||
cfg: ConfigOf<
|
||||
AV,
|
||||
AppBskyUnspeccedGetPopularFeedGenerators.Handler<ExtractAuth<AV>>
|
||||
>,
|
||||
) {
|
||||
const nsid = 'app.bsky.unspecced.getPopularFeedGenerators' // @ts-ignore
|
||||
return this._server.xrpc.method(nsid, cfg)
|
||||
}
|
||||
}
|
||||
|
||||
type ConfigOf<Auth, Handler> =
|
||||
|
@ -856,6 +856,12 @@ export const schemaDict = {
|
||||
subject: {
|
||||
type: 'string',
|
||||
},
|
||||
ignoreSubjects: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
resolved: {
|
||||
type: 'boolean',
|
||||
},
|
||||
@ -1228,12 +1234,12 @@ export const schemaDict = {
|
||||
description: 'Provides the DID of a repo.',
|
||||
parameters: {
|
||||
type: 'params',
|
||||
required: ['handle'],
|
||||
properties: {
|
||||
handle: {
|
||||
type: 'string',
|
||||
format: 'handle',
|
||||
description:
|
||||
"The handle to resolve. If not supplied, will resolve the host's own handle.",
|
||||
description: 'The handle to resolve.',
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1619,6 +1625,7 @@ export const schemaDict = {
|
||||
},
|
||||
rkey: {
|
||||
type: 'string',
|
||||
maxLength: 15,
|
||||
},
|
||||
value: {
|
||||
type: 'unknown',
|
||||
@ -1684,6 +1691,7 @@ export const schemaDict = {
|
||||
rkey: {
|
||||
type: 'string',
|
||||
description: 'The key of the record.',
|
||||
maxLength: 15,
|
||||
},
|
||||
validate: {
|
||||
type: 'boolean',
|
||||
@ -2005,6 +2013,7 @@ export const schemaDict = {
|
||||
rkey: {
|
||||
type: 'string',
|
||||
description: 'The key of the record.',
|
||||
maxLength: 15,
|
||||
},
|
||||
validate: {
|
||||
type: 'boolean',
|
||||
@ -3569,6 +3578,7 @@ export const schemaDict = {
|
||||
refs: [
|
||||
'lex:app.bsky.actor.defs#adultContentPref',
|
||||
'lex:app.bsky.actor.defs#contentLabelPref',
|
||||
'lex:app.bsky.actor.defs#savedFeedsPref',
|
||||
],
|
||||
},
|
||||
},
|
||||
@ -3595,6 +3605,26 @@ export const schemaDict = {
|
||||
},
|
||||
},
|
||||
},
|
||||
savedFeedsPref: {
|
||||
type: 'object',
|
||||
required: ['pinned', 'saved'],
|
||||
properties: {
|
||||
pinned: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
format: 'at-uri',
|
||||
},
|
||||
},
|
||||
saved: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
format: 'at-uri',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyActorGetPreferences: {
|
||||
@ -4329,12 +4359,16 @@ export const schemaDict = {
|
||||
},
|
||||
generatorView: {
|
||||
type: 'object',
|
||||
required: ['uri', 'creator', 'indexedAt'],
|
||||
required: ['uri', 'cid', 'creator', 'displayName', 'indexedAt'],
|
||||
properties: {
|
||||
uri: {
|
||||
type: 'string',
|
||||
format: 'at-uri',
|
||||
},
|
||||
cid: {
|
||||
type: 'string',
|
||||
format: 'cid',
|
||||
},
|
||||
did: {
|
||||
type: 'string',
|
||||
format: 'did',
|
||||
@ -4361,6 +4395,10 @@ export const schemaDict = {
|
||||
avatar: {
|
||||
type: 'string',
|
||||
},
|
||||
likeCount: {
|
||||
type: 'integer',
|
||||
minimum: 0,
|
||||
},
|
||||
viewer: {
|
||||
type: 'ref',
|
||||
ref: 'lex:app.bsky.feed.defs#generatorViewerState',
|
||||
@ -4374,9 +4412,6 @@ export const schemaDict = {
|
||||
generatorViewerState: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
saved: {
|
||||
type: 'boolean',
|
||||
},
|
||||
like: {
|
||||
type: 'string',
|
||||
format: 'at-uri',
|
||||
@ -4409,6 +4444,62 @@ export const schemaDict = {
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyFeedDescribeFeedGenerator: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.feed.describeFeedGenerator',
|
||||
defs: {
|
||||
main: {
|
||||
type: 'query',
|
||||
description:
|
||||
'Returns information about a given feed generator including TOS & offered feed URIs',
|
||||
output: {
|
||||
encoding: 'application/json',
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['did', 'feeds'],
|
||||
properties: {
|
||||
did: {
|
||||
type: 'string',
|
||||
format: 'did',
|
||||
},
|
||||
feeds: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'ref',
|
||||
ref: 'lex:app.bsky.feed.describeFeedGenerator#feed',
|
||||
},
|
||||
},
|
||||
links: {
|
||||
type: 'ref',
|
||||
ref: 'lex:app.bsky.feed.describeFeedGenerator#links',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
feed: {
|
||||
type: 'object',
|
||||
required: ['uri'],
|
||||
properties: {
|
||||
uri: {
|
||||
type: 'string',
|
||||
format: 'at-uri',
|
||||
},
|
||||
},
|
||||
},
|
||||
links: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
privacyPolicy: {
|
||||
type: 'string',
|
||||
},
|
||||
termsOfService: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyFeedGenerator: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.feed.generator',
|
||||
@ -4419,7 +4510,7 @@ export const schemaDict = {
|
||||
key: 'any',
|
||||
record: {
|
||||
type: 'object',
|
||||
required: ['did', 'createdAt'],
|
||||
required: ['did', 'displayName', 'createdAt'],
|
||||
properties: {
|
||||
did: {
|
||||
type: 'string',
|
||||
@ -4427,8 +4518,8 @@ export const schemaDict = {
|
||||
},
|
||||
displayName: {
|
||||
type: 'string',
|
||||
maxGraphemes: 64,
|
||||
maxLength: 640,
|
||||
maxGraphemes: 24,
|
||||
maxLength: 240,
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
@ -4614,6 +4705,85 @@ export const schemaDict = {
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyFeedGetFeedGenerator: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.feed.getFeedGenerator',
|
||||
defs: {
|
||||
main: {
|
||||
type: 'query',
|
||||
description:
|
||||
'Get information about a specific feed offered by a feed generator, such as its online status',
|
||||
parameters: {
|
||||
type: 'params',
|
||||
required: ['feed'],
|
||||
properties: {
|
||||
feed: {
|
||||
type: 'string',
|
||||
format: 'at-uri',
|
||||
},
|
||||
},
|
||||
},
|
||||
output: {
|
||||
encoding: 'application/json',
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['view', 'isOnline', 'isValid'],
|
||||
properties: {
|
||||
view: {
|
||||
type: 'ref',
|
||||
ref: 'lex:app.bsky.feed.defs#generatorView',
|
||||
},
|
||||
isOnline: {
|
||||
type: 'boolean',
|
||||
},
|
||||
isValid: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyFeedGetFeedGenerators: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.feed.getFeedGenerators',
|
||||
defs: {
|
||||
main: {
|
||||
type: 'query',
|
||||
description: 'Get information about a list of feed generators',
|
||||
parameters: {
|
||||
type: 'params',
|
||||
required: ['feeds'],
|
||||
properties: {
|
||||
feeds: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
format: 'at-uri',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
output: {
|
||||
encoding: 'application/json',
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['feeds'],
|
||||
properties: {
|
||||
feeds: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'ref',
|
||||
ref: 'lex:app.bsky.feed.defs#generatorView',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyFeedGetFeedSkeleton: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.feed.getFeedSkeleton',
|
||||
@ -4896,49 +5066,6 @@ export const schemaDict = {
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyFeedGetSavedFeeds: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.feed.getSavedFeeds',
|
||||
defs: {
|
||||
main: {
|
||||
type: 'query',
|
||||
description: "Retrieve a list of the authenticated user's saved feeds",
|
||||
parameters: {
|
||||
type: 'params',
|
||||
properties: {
|
||||
limit: {
|
||||
type: 'integer',
|
||||
minimum: 1,
|
||||
maximum: 100,
|
||||
default: 50,
|
||||
},
|
||||
cursor: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
output: {
|
||||
encoding: 'application/json',
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['feeds'],
|
||||
properties: {
|
||||
cursor: {
|
||||
type: 'string',
|
||||
},
|
||||
feeds: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'ref',
|
||||
ref: 'lex:app.bsky.feed.defs#generatorView',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyFeedGetTimeline: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.feed.getTimeline',
|
||||
@ -5134,52 +5261,6 @@ export const schemaDict = {
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyFeedSaveFeed: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.feed.saveFeed',
|
||||
defs: {
|
||||
main: {
|
||||
type: 'procedure',
|
||||
description: 'Save a 3rd party feed for use across clients',
|
||||
input: {
|
||||
encoding: 'application/json',
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['feed'],
|
||||
properties: {
|
||||
feed: {
|
||||
type: 'string',
|
||||
format: 'at-uri',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyFeedUnsaveFeed: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.feed.unsaveFeed',
|
||||
defs: {
|
||||
main: {
|
||||
type: 'procedure',
|
||||
description: 'Unsave a 3rd party feed',
|
||||
input: {
|
||||
encoding: 'application/json',
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['feed'],
|
||||
properties: {
|
||||
feed: {
|
||||
type: 'string',
|
||||
format: 'at-uri',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyGraphBlock: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.graph.block',
|
||||
@ -6110,6 +6191,32 @@ export const schemaDict = {
|
||||
},
|
||||
},
|
||||
},
|
||||
AppBskyUnspeccedGetPopularFeedGenerators: {
|
||||
lexicon: 1,
|
||||
id: 'app.bsky.unspecced.getPopularFeedGenerators',
|
||||
defs: {
|
||||
main: {
|
||||
type: 'query',
|
||||
description: 'An unspecced view of globally popular feed generators',
|
||||
output: {
|
||||
encoding: 'application/json',
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['feeds'],
|
||||
properties: {
|
||||
feeds: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'ref',
|
||||
ref: 'lex:app.bsky.feed.defs#generatorView',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
export const schemas: LexiconDoc[] = Object.values(schemaDict) as LexiconDoc[]
|
||||
export const lexicons: Lexicons = new Lexicons(schemas)
|
||||
@ -6197,22 +6304,22 @@ export const ids = {
|
||||
AppBskyEmbedRecord: 'app.bsky.embed.record',
|
||||
AppBskyEmbedRecordWithMedia: 'app.bsky.embed.recordWithMedia',
|
||||
AppBskyFeedDefs: 'app.bsky.feed.defs',
|
||||
AppBskyFeedDescribeFeedGenerator: 'app.bsky.feed.describeFeedGenerator',
|
||||
AppBskyFeedGenerator: 'app.bsky.feed.generator',
|
||||
AppBskyFeedGetActorFeeds: 'app.bsky.feed.getActorFeeds',
|
||||
AppBskyFeedGetAuthorFeed: 'app.bsky.feed.getAuthorFeed',
|
||||
AppBskyFeedGetFeed: 'app.bsky.feed.getFeed',
|
||||
AppBskyFeedGetFeedGenerator: 'app.bsky.feed.getFeedGenerator',
|
||||
AppBskyFeedGetFeedGenerators: 'app.bsky.feed.getFeedGenerators',
|
||||
AppBskyFeedGetFeedSkeleton: 'app.bsky.feed.getFeedSkeleton',
|
||||
AppBskyFeedGetLikes: 'app.bsky.feed.getLikes',
|
||||
AppBskyFeedGetPostThread: 'app.bsky.feed.getPostThread',
|
||||
AppBskyFeedGetPosts: 'app.bsky.feed.getPosts',
|
||||
AppBskyFeedGetRepostedBy: 'app.bsky.feed.getRepostedBy',
|
||||
AppBskyFeedGetSavedFeeds: 'app.bsky.feed.getSavedFeeds',
|
||||
AppBskyFeedGetTimeline: 'app.bsky.feed.getTimeline',
|
||||
AppBskyFeedLike: 'app.bsky.feed.like',
|
||||
AppBskyFeedPost: 'app.bsky.feed.post',
|
||||
AppBskyFeedRepost: 'app.bsky.feed.repost',
|
||||
AppBskyFeedSaveFeed: 'app.bsky.feed.saveFeed',
|
||||
AppBskyFeedUnsaveFeed: 'app.bsky.feed.unsaveFeed',
|
||||
AppBskyGraphBlock: 'app.bsky.graph.block',
|
||||
AppBskyGraphDefs: 'app.bsky.graph.defs',
|
||||
AppBskyGraphFollow: 'app.bsky.graph.follow',
|
||||
@ -6235,4 +6342,6 @@ export const ids = {
|
||||
AppBskyNotificationUpdateSeen: 'app.bsky.notification.updateSeen',
|
||||
AppBskyRichtextFacet: 'app.bsky.richtext.facet',
|
||||
AppBskyUnspeccedGetPopular: 'app.bsky.unspecced.getPopular',
|
||||
AppBskyUnspeccedGetPopularFeedGenerators:
|
||||
'app.bsky.unspecced.getPopularFeedGenerators',
|
||||
}
|
||||
|
@ -107,6 +107,7 @@ export function validateViewerState(v: unknown): ValidationResult {
|
||||
export type Preferences = (
|
||||
| AdultContentPref
|
||||
| ContentLabelPref
|
||||
| SavedFeedsPref
|
||||
| { $type: string; [k: string]: unknown }
|
||||
)[]
|
||||
|
||||
@ -144,3 +145,21 @@ export function isContentLabelPref(v: unknown): v is ContentLabelPref {
|
||||
export function validateContentLabelPref(v: unknown): ValidationResult {
|
||||
return lexicons.validate('app.bsky.actor.defs#contentLabelPref', v)
|
||||
}
|
||||
|
||||
export interface SavedFeedsPref {
|
||||
pinned: string[]
|
||||
saved: string[]
|
||||
[k: string]: unknown
|
||||
}
|
||||
|
||||
export function isSavedFeedsPref(v: unknown): v is SavedFeedsPref {
|
||||
return (
|
||||
isObj(v) &&
|
||||
hasProp(v, '$type') &&
|
||||
v.$type === 'app.bsky.actor.defs#savedFeedsPref'
|
||||
)
|
||||
}
|
||||
|
||||
export function validateSavedFeedsPref(v: unknown): ValidationResult {
|
||||
return lexicons.validate('app.bsky.actor.defs#savedFeedsPref', v)
|
||||
}
|
||||
|
@ -188,12 +188,14 @@ export function validateBlockedPost(v: unknown): ValidationResult {
|
||||
|
||||
export interface GeneratorView {
|
||||
uri: string
|
||||
cid: string
|
||||
did?: string
|
||||
creator: AppBskyActorDefs.ProfileView
|
||||
displayName?: string
|
||||
displayName: string
|
||||
description?: string
|
||||
descriptionFacets?: AppBskyRichtextFacet.Main[]
|
||||
avatar?: string
|
||||
likeCount?: number
|
||||
viewer?: GeneratorViewerState
|
||||
indexedAt: string
|
||||
[k: string]: unknown
|
||||
@ -212,7 +214,6 @@ export function validateGeneratorView(v: unknown): ValidationResult {
|
||||
}
|
||||
|
||||
export interface GeneratorViewerState {
|
||||
saved?: boolean
|
||||
like?: string
|
||||
[k: string]: unknown
|
||||
}
|
||||
|
@ -0,0 +1,76 @@
|
||||
/**
|
||||
* 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'
|
||||
|
||||
export interface QueryParams {}
|
||||
|
||||
export type InputSchema = undefined
|
||||
|
||||
export interface OutputSchema {
|
||||
did: string
|
||||
feeds: Feed[]
|
||||
links?: Links
|
||||
[k: string]: unknown
|
||||
}
|
||||
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json'
|
||||
body: OutputSchema
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number
|
||||
message?: string
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
export type Handler<HA extends HandlerAuth = never> = (ctx: {
|
||||
auth: HA
|
||||
params: QueryParams
|
||||
input: HandlerInput
|
||||
req: express.Request
|
||||
res: express.Response
|
||||
}) => Promise<HandlerOutput> | HandlerOutput
|
||||
|
||||
export interface Feed {
|
||||
uri: string
|
||||
[k: string]: unknown
|
||||
}
|
||||
|
||||
export function isFeed(v: unknown): v is Feed {
|
||||
return (
|
||||
isObj(v) &&
|
||||
hasProp(v, '$type') &&
|
||||
v.$type === 'app.bsky.feed.describeFeedGenerator#feed'
|
||||
)
|
||||
}
|
||||
|
||||
export function validateFeed(v: unknown): ValidationResult {
|
||||
return lexicons.validate('app.bsky.feed.describeFeedGenerator#feed', v)
|
||||
}
|
||||
|
||||
export interface Links {
|
||||
privacyPolicy?: string
|
||||
termsOfService?: string
|
||||
[k: string]: unknown
|
||||
}
|
||||
|
||||
export function isLinks(v: unknown): v is Links {
|
||||
return (
|
||||
isObj(v) &&
|
||||
hasProp(v, '$type') &&
|
||||
v.$type === 'app.bsky.feed.describeFeedGenerator#links'
|
||||
)
|
||||
}
|
||||
|
||||
export function validateLinks(v: unknown): ValidationResult {
|
||||
return lexicons.validate('app.bsky.feed.describeFeedGenerator#links', v)
|
||||
}
|
@ -9,7 +9,7 @@ import * as AppBskyRichtextFacet from '../richtext/facet'
|
||||
|
||||
export interface Record {
|
||||
did: string
|
||||
displayName?: string
|
||||
displayName: string
|
||||
description?: string
|
||||
descriptionFacets?: AppBskyRichtextFacet.Main[]
|
||||
avatar?: BlobRef
|
||||
|
@ -7,17 +7,26 @@ import { lexicons } from '../../../../lexicons'
|
||||
import { isObj, hasProp } from '../../../../util'
|
||||
import { CID } from 'multiformats/cid'
|
||||
import { HandlerAuth } from '@atproto/xrpc-server'
|
||||
import * as AppBskyFeedDefs from './defs'
|
||||
|
||||
export interface QueryParams {}
|
||||
|
||||
export interface InputSchema {
|
||||
export interface QueryParams {
|
||||
feed: string
|
||||
}
|
||||
|
||||
export type InputSchema = undefined
|
||||
|
||||
export interface OutputSchema {
|
||||
view: AppBskyFeedDefs.GeneratorView
|
||||
isOnline: boolean
|
||||
isValid: boolean
|
||||
[k: string]: unknown
|
||||
}
|
||||
|
||||
export interface HandlerInput {
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json'
|
||||
body: InputSchema
|
||||
body: OutputSchema
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
@ -25,7 +34,7 @@ export interface HandlerError {
|
||||
message?: string
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | void
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
export type Handler<HA extends HandlerAuth = never> = (ctx: {
|
||||
auth: HA
|
||||
params: QueryParams
|
@ -10,14 +10,12 @@ import { HandlerAuth } from '@atproto/xrpc-server'
|
||||
import * as AppBskyFeedDefs from './defs'
|
||||
|
||||
export interface QueryParams {
|
||||
limit: number
|
||||
cursor?: string
|
||||
feeds: string[]
|
||||
}
|
||||
|
||||
export type InputSchema = undefined
|
||||
|
||||
export interface OutputSchema {
|
||||
cursor?: string
|
||||
feeds: AppBskyFeedDefs.GeneratorView[]
|
||||
[k: string]: unknown
|
||||
}
|
@ -7,17 +7,22 @@ import { lexicons } from '../../../../lexicons'
|
||||
import { isObj, hasProp } from '../../../../util'
|
||||
import { CID } from 'multiformats/cid'
|
||||
import { HandlerAuth } from '@atproto/xrpc-server'
|
||||
import * as AppBskyFeedDefs from '../feed/defs'
|
||||
|
||||
export interface QueryParams {}
|
||||
|
||||
export interface InputSchema {
|
||||
feed: string
|
||||
export type InputSchema = undefined
|
||||
|
||||
export interface OutputSchema {
|
||||
feeds: AppBskyFeedDefs.GeneratorView[]
|
||||
[k: string]: unknown
|
||||
}
|
||||
|
||||
export interface HandlerInput {
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json'
|
||||
body: InputSchema
|
||||
body: OutputSchema
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
@ -25,7 +30,7 @@ export interface HandlerError {
|
||||
message?: string
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | void
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
export type Handler<HA extends HandlerAuth = never> = (ctx: {
|
||||
auth: HA
|
||||
params: QueryParams
|
@ -11,6 +11,7 @@ import * as ComAtprotoAdminDefs from './defs'
|
||||
|
||||
export interface QueryParams {
|
||||
subject?: string
|
||||
ignoreSubjects?: string[]
|
||||
resolved?: boolean
|
||||
actionType?:
|
||||
| 'com.atproto.admin.defs#takedown'
|
||||
|
@ -9,8 +9,8 @@ import { CID } from 'multiformats/cid'
|
||||
import { HandlerAuth } from '@atproto/xrpc-server'
|
||||
|
||||
export interface QueryParams {
|
||||
/** The handle to resolve. If not supplied, will resolve the host's own handle. */
|
||||
handle?: string
|
||||
/** The handle to resolve. */
|
||||
handle: string
|
||||
}
|
||||
|
||||
export type InputSchema = undefined
|
||||
|
@ -81,8 +81,10 @@ export class ModerationService {
|
||||
actionType?: string
|
||||
limit: number
|
||||
cursor?: string
|
||||
ignoreSubjects?: string[]
|
||||
}): Promise<ModerationReportRow[]> {
|
||||
const { subject, resolved, actionType, limit, cursor } = opts
|
||||
const { subject, resolved, actionType, limit, cursor, ignoreSubjects } =
|
||||
opts
|
||||
const { ref } = this.db.db.dynamic
|
||||
let builder = this.db.db.selectFrom('moderation_report')
|
||||
if (subject) {
|
||||
@ -92,6 +94,14 @@ export class ModerationService {
|
||||
.orWhere('subjectUri', '=', subject)
|
||||
})
|
||||
}
|
||||
if (ignoreSubjects?.length) {
|
||||
builder = builder.where((qb) => {
|
||||
return qb
|
||||
.where('subjectDid', 'not in', ignoreSubjects)
|
||||
.where('subjectUri', 'not in', ignoreSubjects)
|
||||
})
|
||||
}
|
||||
|
||||
if (resolved !== undefined) {
|
||||
const resolutionsQuery = this.db.db
|
||||
.selectFrom('moderation_report_resolution')
|
||||
|
@ -6,7 +6,14 @@ export default function (server: Server, ctx: AppContext) {
|
||||
auth: ctx.moderatorVerifier,
|
||||
handler: async ({ params }) => {
|
||||
const { db, services } = ctx
|
||||
const { subject, resolved, actionType, limit = 50, cursor } = params
|
||||
const {
|
||||
subject,
|
||||
resolved,
|
||||
actionType,
|
||||
limit = 50,
|
||||
cursor,
|
||||
ignoreSubjects = [],
|
||||
} = params
|
||||
const moderationService = services.moderation(db)
|
||||
const results = await moderationService.getReports({
|
||||
subject,
|
||||
@ -14,6 +21,7 @@ export default function (server: Server, ctx: AppContext) {
|
||||
actionType,
|
||||
limit,
|
||||
cursor,
|
||||
ignoreSubjects,
|
||||
})
|
||||
return {
|
||||
encoding: 'application/json',
|
||||
|
@ -856,6 +856,12 @@ export const schemaDict = {
|
||||
subject: {
|
||||
type: 'string',
|
||||
},
|
||||
ignoreSubjects: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
resolved: {
|
||||
type: 'boolean',
|
||||
},
|
||||
|
@ -11,6 +11,7 @@ import * as ComAtprotoAdminDefs from './defs'
|
||||
|
||||
export interface QueryParams {
|
||||
subject?: string
|
||||
ignoreSubjects?: string[]
|
||||
resolved?: boolean
|
||||
actionType?:
|
||||
| 'com.atproto.admin.defs#takedown'
|
||||
|
@ -99,8 +99,10 @@ export class ModerationService {
|
||||
actionType?: string
|
||||
limit: number
|
||||
cursor?: string
|
||||
ignoreSubjects?: string[]
|
||||
}): Promise<ModerationReportRow[]> {
|
||||
const { subject, resolved, actionType, limit, cursor } = opts
|
||||
const { subject, resolved, actionType, limit, cursor, ignoreSubjects } =
|
||||
opts
|
||||
const { ref } = this.db.db.dynamic
|
||||
let builder = this.db.db.selectFrom('moderation_report')
|
||||
if (subject) {
|
||||
@ -110,6 +112,15 @@ export class ModerationService {
|
||||
.orWhere('subjectUri', '=', subject)
|
||||
})
|
||||
}
|
||||
|
||||
if (ignoreSubjects?.length) {
|
||||
builder = builder.where((qb) => {
|
||||
return qb
|
||||
.where('subjectDid', 'not in', ignoreSubjects)
|
||||
.where('subjectUri', 'not in', ignoreSubjects)
|
||||
})
|
||||
}
|
||||
|
||||
if (resolved !== undefined) {
|
||||
const resolutionsQuery = this.db.db
|
||||
.selectFrom('moderation_report_resolution')
|
||||
@ -141,6 +152,7 @@ export class ModerationService {
|
||||
.selectAll()
|
||||
builder = builder.whereExists(resolutionActionsQuery)
|
||||
}
|
||||
|
||||
if (cursor) {
|
||||
const cursorNumeric = parseInt(cursor, 10)
|
||||
if (isNaN(cursorNumeric)) {
|
||||
|
@ -120,6 +120,33 @@ describe('pds admin get moderation reports view', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it('ignores subjects when specified.', async () => {
|
||||
// Get all reports and then make another request with a filter to ignore some subject dids
|
||||
// and assert that the reports for those subject dids are ignored in the result set
|
||||
const getDids = (reportsResponse) =>
|
||||
reportsResponse.data.reports
|
||||
.map((report) => report.subject.did)
|
||||
// Not all reports contain a did so we're discarding the undefined values in the mapped array
|
||||
.filter(Boolean)
|
||||
|
||||
const allReports = await agent.api.com.atproto.admin.getModerationReports(
|
||||
{},
|
||||
{ headers: { authorization: adminAuth() } },
|
||||
)
|
||||
|
||||
const ignoreSubjects = getDids(allReports).slice(0, 2)
|
||||
|
||||
const filteredReports =
|
||||
await agent.api.com.atproto.admin.getModerationReports(
|
||||
{ ignoreSubjects },
|
||||
{ headers: { authorization: adminAuth() } },
|
||||
)
|
||||
|
||||
getDids(filteredReports).forEach((resultDid) =>
|
||||
expect(ignoreSubjects).not.toContain(resultDid),
|
||||
)
|
||||
})
|
||||
|
||||
it('gets all moderation reports.', async () => {
|
||||
const result = await agent.api.com.atproto.admin.getModerationReports(
|
||||
{},
|
||||
|
Loading…
x
Reference in New Issue
Block a user