diff --git a/packages/bsky/src/services/moderation/index.ts b/packages/bsky/src/services/moderation/index.ts index 4d86b4fa9b3..99715866d2a 100644 --- a/packages/bsky/src/services/moderation/index.ts +++ b/packages/bsky/src/services/moderation/index.ts @@ -104,12 +104,31 @@ 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) + const ignoreUris: string[] = [] + const ignoreDids: string[] = [] + + ignoreSubjects.forEach((subject) => { + if (subject.startsWith('at://')) { + ignoreUris.push(subject) + } else if (subject.startsWith('did:')) { + ignoreDids.push(subject) + } }) + + if (ignoreDids.length) { + builder = builder.where('subjectDid', 'not in', ignoreDids) + } + if (ignoreUris.length) { + builder = builder.where((qb) => { + // Without the null condition, postgres will ignore all reports where `subjectUri` is null + // which will make all the account reports be ignored as well + return qb + .where('subjectUri', 'not in', ignoreUris) + .orWhere('subjectUri', 'is', null) + }) + } } if (reporters?.length) { diff --git a/packages/pds/src/app-view/api/app/bsky/feed/getTimeline.ts b/packages/pds/src/app-view/api/app/bsky/feed/getTimeline.ts index 3587c3acc7d..dba1b58ece7 100644 --- a/packages/pds/src/app-view/api/app/bsky/feed/getTimeline.ts +++ b/packages/pds/src/app-view/api/app/bsky/feed/getTimeline.ts @@ -26,7 +26,8 @@ export default function (server: Server, ctx: AppContext) { body: res.data, } } - if (ctx.canProxyFeedConstruction(req)) { + + if (ctx.cfg.bskyAppViewEndpoint) { const res = await ctx.appviewAgent.api.app.bsky.unspecced.getTimelineSkeleton( { limit, cursor }, diff --git a/packages/pds/src/services/moderation/index.ts b/packages/pds/src/services/moderation/index.ts index 4a7b3c9eefc..18e3ceb5608 100644 --- a/packages/pds/src/services/moderation/index.ts +++ b/packages/pds/src/services/moderation/index.ts @@ -124,11 +124,29 @@ export class ModerationService { } if (ignoreSubjects?.length) { - builder = builder.where((qb) => { - return qb - .where('subjectDid', 'not in', ignoreSubjects) - .where('subjectUri', 'not in', ignoreSubjects) + const ignoreUris: string[] = [] + const ignoreDids: string[] = [] + + ignoreSubjects.forEach((subject) => { + if (subject.startsWith('at://')) { + ignoreUris.push(subject) + } else if (subject.startsWith('did:')) { + ignoreDids.push(subject) + } }) + + if (ignoreDids.length) { + builder = builder.where('subjectDid', 'not in', ignoreDids) + } + if (ignoreUris.length) { + builder = builder.where((qb) => { + // Without the null condition, postgres will ignore all reports where `subjectUri` is null + // which will make all the account reports be ignored as well + return qb + .where('subjectUri', 'not in', ignoreUris) + .orWhere('subjectUri', 'is', null) + }) + } } if (reporters?.length) { diff --git a/packages/pds/tests/views/admin/get-moderation-reports.test.ts b/packages/pds/tests/views/admin/get-moderation-reports.test.ts index 144a75a9f83..0ef0f92685c 100644 --- a/packages/pds/tests/views/admin/get-moderation-reports.test.ts +++ b/packages/pds/tests/views/admin/get-moderation-reports.test.ts @@ -136,15 +136,40 @@ describe('pds admin get moderation reports view', () => { const ignoreSubjects = getDids(allReports).slice(0, 2) - const filteredReports = + const filteredReportsByDid = await agent.api.com.atproto.admin.getModerationReports( { ignoreSubjects }, { headers: { authorization: adminAuth() } }, ) - getDids(filteredReports).forEach((resultDid) => + // Validate that when ignored by DID, all reports for that DID is ignored + getDids(filteredReportsByDid).forEach((resultDid) => expect(ignoreSubjects).not.toContain(resultDid), ) + + const ignoredAtUriSubjects: string[] = [ + `${ + allReports.data.reports.find(({ subject }) => !!subject.uri)?.subject + ?.uri + }`, + ] + const filteredReportsByAtUri = + await agent.api.com.atproto.admin.getModerationReports( + { + ignoreSubjects: ignoredAtUriSubjects, + }, + { headers: { authorization: adminAuth() } }, + ) + + // Validate that when ignored by at uri, only the reports for that at uri is ignored + expect(filteredReportsByAtUri.data.reports.length).toEqual( + allReports.data.reports.length - 1, + ) + expect( + filteredReportsByAtUri.data.reports + .map(({ subject }) => subject.uri) + .filter(Boolean), + ).not.toContain(ignoredAtUriSubjects[0]) }) it('gets all moderation reports.', async () => {