diff --git a/packages/bsky/src/auto-moderator/index.ts b/packages/bsky/src/auto-moderator/index.ts index 851d3289e89..956301f34b5 100644 --- a/packages/bsky/src/auto-moderator/index.ts +++ b/packages/bsky/src/auto-moderator/index.ts @@ -20,7 +20,7 @@ import { } from '../lexicon/types/com/atproto/moderation/defs' export class AutoModerator { - public pushAgent?: AtpAgent + public pushAgent: AtpAgent public imageFlagger?: ImageFlagger public textFlagger?: TextFlagger public imgLabeler?: ImgLabeler @@ -66,7 +66,6 @@ export class AutoModerator { const { text, imgs } = getFieldsFromRecord(obj, uri) await Promise.all([ this.labelRecord(uri, cid, text, imgs).catch((err) => { - console.log('ERR: ', err) log.error( { err, uri: uri.toString(), record: obj }, 'failed to label record', @@ -140,7 +139,7 @@ export class AutoModerator { uri: subject.uri.toString(), cid: subject.cid.toString(), } - await this.pushAgent?.api.com.atproto.moderation.createReport({ + await this.pushAgent.api.com.atproto.moderation.createReport({ reasonType: REASONOTHER, reason: `Automatically flagged for possible slurs: ${matches.join(', ')}`, subject: formattedSubject, @@ -199,7 +198,7 @@ export class AutoModerator { 'hard takedown of record (and blobs) based on auto-matching', ) - await this.pushAgent?.com.atproto.moderation.createReport({ + await this.pushAgent.com.atproto.moderation.createReport({ reportedBy: this.ctx.cfg.labelerDid, reasonType: REASONVIOLATION, subject: { @@ -210,7 +209,7 @@ export class AutoModerator { reason: reportReason, }) - await this.pushAgent?.com.atproto.admin.emitModerationEvent({ + await this.pushAgent.com.atproto.admin.emitModerationEvent({ event: { $type: 'com.atproto.admin.defs#modEventTakedown', comment: takedownReason, @@ -228,7 +227,7 @@ export class AutoModerator { async pushLabels(uri: AtUri, cid: CID, labels: string[]): Promise { if (labels.length < 1) return - await this.pushAgent?.com.atproto.admin.emitModerationEvent({ + await this.pushAgent.com.atproto.admin.emitModerationEvent({ event: { $type: 'com.atproto.admin.defs#modEventLabel', comment: '[AutoModerator]: Applying labels', diff --git a/packages/dev-env/src/network.ts b/packages/dev-env/src/network.ts index 080099175ae..612132a009b 100644 --- a/packages/dev-env/src/network.ts +++ b/packages/dev-env/src/network.ts @@ -62,10 +62,11 @@ export class TestNetwork extends TestNetworkNoAppView { redisHost, modServiceUrl: `http://localhost:${ozonePort}`, modServiceDid: ozoneDid, + ...params.bsky, indexer: { + ...params.bsky?.indexer, moderationPushUrl: `http://admin:${ADMIN_PASSWORD}@localhost:${ozonePort}`, }, - ...params.bsky, }) const pds = await TestPds.create({ diff --git a/packages/pds/tests/moderation.test.ts b/packages/pds/tests/moderation.test.ts index 39c4fa69057..6a2f30066d4 100644 --- a/packages/pds/tests/moderation.test.ts +++ b/packages/pds/tests/moderation.test.ts @@ -20,26 +20,29 @@ describe('moderation', () => { let blobSubject: RepoBlobRef let blobRef: ImageRef - const appviewDid = 'did:example:appview' - const altAppviewDid = 'did:example:alt' - let appviewKey: Secp256k1Keypair + const modServiceDid = 'did:example:mod' + const altModDid = 'did:example:alt' + let modServiceKey: Secp256k1Keypair + let pdsDid: string beforeAll(async () => { network = await TestNetworkNoAppView.create({ dbPostgresSchema: 'moderation', pds: { - bskyAppViewDid: appviewDid, + modServiceDid, }, }) - appviewKey = await Secp256k1Keypair.create() + pdsDid = network.pds.ctx.cfg.service.did + + modServiceKey = await Secp256k1Keypair.create() const origResolve = network.pds.ctx.idResolver.did.resolveAtprotoKey network.pds.ctx.idResolver.did.resolveAtprotoKey = async ( did: string, forceRefresh?: boolean, ) => { - if (did === appviewDid || did === altAppviewDid) { - return appviewKey.did() + if (did === modServiceDid || did === altModDid) { + return modServiceKey.did() } return origResolve(did, forceRefresh) } @@ -323,9 +326,9 @@ describe('moderation', () => { describe('auth', () => { it('allows service auth requests from the configured appview did', async () => { const headers = await createServiceAuthHeaders({ - iss: appviewDid, - aud: repoSubject.did, - keypair: appviewKey, + iss: modServiceDid, + aud: pdsDid, + keypair: modServiceKey, }) await agent.api.com.atproto.admin.updateSubjectStatus( { @@ -350,9 +353,9 @@ describe('moderation', () => { it('does not allow requests from another did', async () => { const headers = await createServiceAuthHeaders({ - iss: altAppviewDid, - aud: repoSubject.did, - keypair: appviewKey, + iss: altModDid, + aud: pdsDid, + keypair: modServiceKey, }) const attempt = agent.api.com.atproto.admin.updateSubjectStatus( { @@ -372,8 +375,8 @@ describe('moderation', () => { it('does not allow requests with a bad signature', async () => { const badKey = await Secp256k1Keypair.create() const headers = await createServiceAuthHeaders({ - iss: appviewDid, - aud: repoSubject.did, + iss: modServiceDid, + aud: pdsDid, keypair: badKey, }) const attempt = agent.api.com.atproto.admin.updateSubjectStatus( @@ -391,12 +394,12 @@ describe('moderation', () => { ) }) - it('does not allow requests with a bad signature', async () => { + it('does not allow requests with a bad aud', async () => { // repo subject is bob, so we set alice as the audience const headers = await createServiceAuthHeaders({ - iss: appviewDid, + iss: modServiceDid, aud: sc.dids.alice, - keypair: appviewKey, + keypair: modServiceKey, }) const attempt = agent.api.com.atproto.admin.updateSubjectStatus( { @@ -409,7 +412,7 @@ describe('moderation', () => { }, ) await expect(attempt).rejects.toThrow( - 'jwt audience does not match account did', + 'jwt audience does not match service did', ) }) })