@atproto/ozone 0.2.9 → 0.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/package.json +25 -21
- package/bin/migration-create.ts +0 -38
- package/jest.config.cjs +0 -22
- package/src/api/chat/getActorMetadata.ts +0 -23
- package/src/api/chat/getConvo.ts +0 -23
- package/src/api/chat/getConvoMembers.ts +0 -23
- package/src/api/chat/getConvos.ts +0 -23
- package/src/api/chat/getMessageContext.ts +0 -42
- package/src/api/chat/index.ts +0 -16
- package/src/api/communication/createTemplate.ts +0 -51
- package/src/api/communication/deleteTemplate.ts +0 -23
- package/src/api/communication/listTemplates.ts +0 -31
- package/src/api/communication/updateTemplate.ts +0 -51
- package/src/api/health.ts +0 -27
- package/src/api/index.ts +0 -146
- package/src/api/label/fetchLabels.ts +0 -32
- package/src/api/label/queryLabels.ts +0 -57
- package/src/api/label/subscribeLabels.ts +0 -25
- package/src/api/moderation/cancelScheduledActions.ts +0 -72
- package/src/api/moderation/emitEvent.ts +0 -475
- package/src/api/moderation/getAccountTimeline.ts +0 -160
- package/src/api/moderation/getEvent.ts +0 -19
- package/src/api/moderation/getRecord.ts +0 -40
- package/src/api/moderation/getRecords.ts +0 -50
- package/src/api/moderation/getRepo.ts +0 -34
- package/src/api/moderation/getReporterStats.ts +0 -18
- package/src/api/moderation/getRepos.ts +0 -41
- package/src/api/moderation/getSubjects.ts +0 -101
- package/src/api/moderation/listScheduledActions.ts +0 -45
- package/src/api/moderation/queryEvents.ts +0 -72
- package/src/api/moderation/queryStatuses.ts +0 -23
- package/src/api/moderation/scheduleAction.ts +0 -129
- package/src/api/moderation/searchRepos.ts +0 -46
- package/src/api/moderation/util.ts +0 -96
- package/src/api/proxied.ts +0 -327
- package/src/api/queue/assignModerator.ts +0 -31
- package/src/api/queue/createQueue.ts +0 -62
- package/src/api/queue/deleteQueue.ts +0 -56
- package/src/api/queue/getAssignments.ts +0 -19
- package/src/api/queue/listQueues.ts +0 -39
- package/src/api/queue/routeReports.ts +0 -44
- package/src/api/queue/unassignModerator.ts +0 -26
- package/src/api/queue/updateQueue.ts +0 -54
- package/src/api/report/assignModerator.ts +0 -36
- package/src/api/report/createActivity.ts +0 -57
- package/src/api/report/createReport.ts +0 -93
- package/src/api/report/getAssignments.ts +0 -20
- package/src/api/report/getHistoricalStats.ts +0 -41
- package/src/api/report/getLatestReport.ts +0 -44
- package/src/api/report/getLiveStats.ts +0 -26
- package/src/api/report/getReport.ts +0 -55
- package/src/api/report/listActivities.ts +0 -37
- package/src/api/report/queryActivities.ts +0 -64
- package/src/api/report/queryReports.ts +0 -44
- package/src/api/report/reassignQueue.ts +0 -68
- package/src/api/report/refreshStats.ts +0 -27
- package/src/api/report/unassignModerator.ts +0 -21
- package/src/api/safelink/addRule.ts +0 -48
- package/src/api/safelink/queryEvents.ts +0 -32
- package/src/api/safelink/queryRules.ts +0 -58
- package/src/api/safelink/removeRule.ts +0 -42
- package/src/api/safelink/updateRule.ts +0 -48
- package/src/api/server/getConfig.ts +0 -35
- package/src/api/set/addValues.ts +0 -28
- package/src/api/set/deleteSet.ts +0 -34
- package/src/api/set/deleteValues.ts +0 -31
- package/src/api/set/getValues.ts +0 -42
- package/src/api/set/querySets.ts +0 -36
- package/src/api/set/upsertSet.ts +0 -38
- package/src/api/setting/listOptions.ts +0 -44
- package/src/api/setting/removeOptions.ts +0 -64
- package/src/api/setting/upsertOption.ts +0 -156
- package/src/api/team/addMember.ts +0 -51
- package/src/api/team/deleteMember.ts +0 -29
- package/src/api/team/listMembers.ts +0 -20
- package/src/api/team/updateMember.ts +0 -47
- package/src/api/util.ts +0 -265
- package/src/api/verification/grantVerifications.ts +0 -90
- package/src/api/verification/listVerifications.ts +0 -44
- package/src/api/verification/revokeVerifications.ts +0 -43
- package/src/api/well-known.ts +0 -46
- package/src/assignment/index.ts +0 -728
- package/src/auth-verifier.ts +0 -227
- package/src/background.ts +0 -183
- package/src/communication-service/template.ts +0 -110
- package/src/communication-service/util.ts +0 -8
- package/src/config/config.ts +0 -211
- package/src/config/env.ts +0 -95
- package/src/config/index.ts +0 -3
- package/src/config/secrets.ts +0 -17
- package/src/context.ts +0 -399
- package/src/daemon/blob-diverter.ts +0 -186
- package/src/daemon/context.ts +0 -247
- package/src/daemon/event-pusher.ts +0 -363
- package/src/daemon/event-reverser.ts +0 -128
- package/src/daemon/index.ts +0 -33
- package/src/daemon/job-cursor.ts +0 -33
- package/src/daemon/materialized-view-refresher.ts +0 -33
- package/src/daemon/queue-router.ts +0 -101
- package/src/daemon/scheduled-action-processor.ts +0 -304
- package/src/daemon/stats-computer.ts +0 -101
- package/src/daemon/strike-expiry-processor.ts +0 -95
- package/src/daemon/team-profile-synchronizer.ts +0 -15
- package/src/daemon/verification-listener.ts +0 -169
- package/src/db/index.ts +0 -203
- package/src/db/migrations/20231219T205730722Z-init.ts +0 -170
- package/src/db/migrations/20240116T085607200Z-communication-template.ts +0 -23
- package/src/db/migrations/20240201T051104136Z-mod-event-blobs.ts +0 -15
- package/src/db/migrations/20240208T213404429Z-add-tags-column-to-moderation-subject.ts +0 -31
- package/src/db/migrations/20240228T003647759Z-add-label-sigs.ts +0 -25
- package/src/db/migrations/20240408T192432676Z-mute-reporting.ts +0 -15
- package/src/db/migrations/20240506T225055595Z-message-subject.ts +0 -21
- package/src/db/migrations/20240521T211332580Z-member.ts +0 -17
- package/src/db/migrations/20240814T003647759Z-event-created-at-index.ts +0 -13
- package/src/db/migrations/20240903T205730722Z-add-template-lang.ts +0 -12
- package/src/db/migrations/20240904T205730722Z-add-subject-did-index.ts +0 -13
- package/src/db/migrations/20241001T205730722Z-subject-status-review-state-index.ts +0 -15
- package/src/db/migrations/20241008T205730722Z-sets.ts +0 -53
- package/src/db/migrations/20241018T205730722Z-setting.ts +0 -27
- package/src/db/migrations/20241026T205730722Z-add-hosting-status-to-subject-status.ts +0 -57
- package/src/db/migrations/20241220T144630860Z-stats-materialized-views.ts +0 -215
- package/src/db/migrations/20250204T003647759Z-add-subject-priority-score.ts +0 -22
- package/src/db/migrations/20250211T003647759Z-add-reporter-stats-index.ts +0 -38
- package/src/db/migrations/20250211T132135150Z-moderation-event-message-partial-idx.ts +0 -26
- package/src/db/migrations/20250221T132135150Z-member-details.ts +0 -14
- package/src/db/migrations/20250404T201720309Z-subject-status-sort-idxs.ts +0 -18
- package/src/db/migrations/20250415T201720309Z-verification.ts +0 -34
- package/src/db/migrations/20250417T201720309Z-firehose-cursor.ts +0 -16
- package/src/db/migrations/20250609T110704000Z-safelink.ts +0 -53
- package/src/db/migrations/20250618T180246000Z-add-mod-tool-to-moderation-event.ts +0 -18
- package/src/db/migrations/20250701T000000000Z-add-age-assurance-state.ts +0 -25
- package/src/db/migrations/20250715T000000000Z-add-mod-event-external-id.ts +0 -15
- package/src/db/migrations/20250718T150931000Z-update-appeal-reason-stats.ts +0 -310
- package/src/db/migrations/20250813T000000000Z-mod-tool-batch-id-index.ts +0 -14
- package/src/db/migrations/20250923T000000000Z-scheduled-actions.ts +0 -56
- package/src/db/migrations/20251008T120000000Z-add-strike-system.ts +0 -87
- package/src/db/migrations/20260210T154806448Z-mod-event-created-by-indexes.ts +0 -22
- package/src/db/migrations/20260219T164523000Z-create-report-table.ts +0 -155
- package/src/db/migrations/20260219T165302248Z-moderator-assignment.ts +0 -42
- package/src/db/migrations/20260225T000000000Z-add-report-queue-table.ts +0 -41
- package/src/db/migrations/20260313T000000000Z-add-report-activity-table.ts +0 -48
- package/src/db/migrations/20260318T152058935Z-add-report-stat.ts +0 -35
- package/src/db/migrations/20260428T000000000Z-add-expiring-tag-table.ts +0 -32
- package/src/db/migrations/20260513T202941104Z-add-subject-convo-id.ts +0 -114
- package/src/db/migrations/20260602T120000000Z-add-report-activity-created-index.ts +0 -17
- package/src/db/migrations/index.ts +0 -44
- package/src/db/migrations/provider.ts +0 -26
- package/src/db/pagination.ts +0 -335
- package/src/db/schema/account_events_stats.ts +0 -16
- package/src/db/schema/account_record_events_stats.ts +0 -15
- package/src/db/schema/account_record_status_stats.ts +0 -15
- package/src/db/schema/account_strike.ts +0 -13
- package/src/db/schema/blob_push_event.ts +0 -21
- package/src/db/schema/communication_template.ts +0 -19
- package/src/db/schema/expiring_tag.ts +0 -18
- package/src/db/schema/firehose_cursor.ts +0 -13
- package/src/db/schema/index.ts +0 -60
- package/src/db/schema/job_cursor.ts +0 -13
- package/src/db/schema/label.ts +0 -22
- package/src/db/schema/member.ts +0 -22
- package/src/db/schema/moderation_event.ts +0 -61
- package/src/db/schema/moderation_subject_status.ts +0 -52
- package/src/db/schema/moderator_assignment.ts +0 -16
- package/src/db/schema/ozone_set.ts +0 -24
- package/src/db/schema/record_events_stats.ts +0 -15
- package/src/db/schema/record_push_event.ts +0 -21
- package/src/db/schema/repo_push_event.ts +0 -19
- package/src/db/schema/report.ts +0 -28
- package/src/db/schema/report_activity.ts +0 -22
- package/src/db/schema/report_queue.ts +0 -21
- package/src/db/schema/report_stat.ts +0 -27
- package/src/db/schema/safelink.ts +0 -39
- package/src/db/schema/scheduled-action.ts +0 -25
- package/src/db/schema/setting.ts +0 -24
- package/src/db/schema/signing_key.ts +0 -10
- package/src/db/schema/verification.ts +0 -21
- package/src/db/types.ts +0 -24
- package/src/error.ts +0 -12
- package/src/image-invalidator.ts +0 -7
- package/src/index.ts +0 -154
- package/src/jetstream/service.ts +0 -107
- package/src/logger.ts +0 -29
- package/src/mod-service/expiring-tags.ts +0 -104
- package/src/mod-service/index.ts +0 -1842
- package/src/mod-service/profile.ts +0 -139
- package/src/mod-service/report.ts +0 -429
- package/src/mod-service/status.ts +0 -549
- package/src/mod-service/strike.ts +0 -96
- package/src/mod-service/subject.ts +0 -311
- package/src/mod-service/types.ts +0 -96
- package/src/mod-service/util.ts +0 -99
- package/src/mod-service/views.ts +0 -912
- package/src/queue/service.ts +0 -603
- package/src/report/activity.ts +0 -281
- package/src/report/handle-report-update.ts +0 -209
- package/src/report/reassign.ts +0 -109
- package/src/report/stats.ts +0 -852
- package/src/report/views.ts +0 -239
- package/src/safelink/service.ts +0 -304
- package/src/scheduled-action/service.ts +0 -281
- package/src/scheduled-action/types.ts +0 -17
- package/src/sequencer/index.ts +0 -2
- package/src/sequencer/outbox.ts +0 -123
- package/src/sequencer/sequencer.ts +0 -147
- package/src/set/service.ts +0 -230
- package/src/setting/constants.ts +0 -3
- package/src/setting/service.ts +0 -148
- package/src/setting/types.ts +0 -3
- package/src/setting/validators.ts +0 -333
- package/src/tag-service/content-tagger.ts +0 -30
- package/src/tag-service/embed-tagger.ts +0 -70
- package/src/tag-service/index.ts +0 -70
- package/src/tag-service/language-data.ts +0 -561
- package/src/tag-service/language-tagger.ts +0 -101
- package/src/tag-service/util.ts +0 -13
- package/src/team/index.ts +0 -296
- package/src/util.ts +0 -230
- package/src/verification/issuer.ts +0 -146
- package/src/verification/service.ts +0 -208
- package/src/verification/util.ts +0 -53
- package/test.env +0 -2
- package/tests/3p-labeler.test.ts +0 -288
- package/tests/__snapshots__/account-strikes.test.ts.snap +0 -159
- package/tests/__snapshots__/age-assurance.test.ts.snap +0 -66
- package/tests/__snapshots__/blob-divert.test.ts.snap +0 -219
- package/tests/__snapshots__/get-account-timeline.test.ts.snap +0 -36
- package/tests/__snapshots__/get-record.test.ts.snap +0 -271
- package/tests/__snapshots__/get-records.test.ts.snap +0 -175
- package/tests/__snapshots__/get-repo.test.ts.snap +0 -91
- package/tests/__snapshots__/get-repos.test.ts.snap +0 -127
- package/tests/__snapshots__/get-starter-pack.test.ts.snap +0 -535
- package/tests/__snapshots__/get-subjects.test.ts.snap +0 -529
- package/tests/__snapshots__/moderation-events.test.ts.snap +0 -347
- package/tests/__snapshots__/moderation-statuses.test.ts.snap +0 -276
- package/tests/__snapshots__/moderation.test.ts.snap +0 -85
- package/tests/__snapshots__/report-reason.test.ts.snap +0 -14
- package/tests/__snapshots__/safelink.test.ts.snap +0 -179
- package/tests/__snapshots__/scheduled-action.test.ts.snap +0 -61
- package/tests/__snapshots__/sets.test.ts.snap +0 -46
- package/tests/__snapshots__/settings.test.ts.snap +0 -52
- package/tests/__snapshots__/team.test.ts.snap +0 -374
- package/tests/__snapshots__/verification-listener.test.ts.snap +0 -152
- package/tests/__snapshots__/verification.test.ts.snap +0 -302
- package/tests/_util.ts +0 -242
- package/tests/account-strikes.test.ts +0 -184
- package/tests/ack-all-subjects-of-account.test.ts +0 -177
- package/tests/age-assurance.test.ts +0 -372
- package/tests/blob-divert.test.ts +0 -106
- package/tests/communication-templates.test.ts +0 -149
- package/tests/content-tagger.test.ts +0 -170
- package/tests/db.test.ts +0 -184
- package/tests/expiring-label.test.ts +0 -72
- package/tests/expiring-tags.test.ts +0 -232
- package/tests/get-account-timeline.test.ts +0 -85
- package/tests/get-config.test.ts +0 -55
- package/tests/get-lists.test.ts +0 -111
- package/tests/get-profiles.test.ts +0 -70
- package/tests/get-record.test.ts +0 -130
- package/tests/get-records.test.ts +0 -91
- package/tests/get-repo.test.ts +0 -171
- package/tests/get-report.test.ts +0 -136
- package/tests/get-reporter-stats.test.ts +0 -132
- package/tests/get-repos.test.ts +0 -91
- package/tests/get-starter-pack.test.ts +0 -115
- package/tests/get-subjects.test.ts +0 -81
- package/tests/mod-tool.test.ts +0 -268
- package/tests/moderation-appeals.test.ts +0 -260
- package/tests/moderation-events.test.ts +0 -756
- package/tests/moderation-status-tags.test.ts +0 -140
- package/tests/moderation-statuses.test.ts +0 -495
- package/tests/moderation.test.ts +0 -992
- package/tests/protected-tags.test.ts +0 -218
- package/tests/query-labels.test.ts +0 -238
- package/tests/query-reports.test.ts +0 -608
- package/tests/queue-assignment.test.ts +0 -428
- package/tests/queue-router.test.ts +0 -306
- package/tests/queues.test.ts +0 -690
- package/tests/record-and-account-events.test.ts +0 -197
- package/tests/repo-search.test.ts +0 -136
- package/tests/report-action.test.ts +0 -308
- package/tests/report-activity.test.ts +0 -711
- package/tests/report-assignment.test.ts +0 -517
- package/tests/report-muting.test.ts +0 -100
- package/tests/report-reason.test.ts +0 -154
- package/tests/report-reassign-queue.test.ts +0 -340
- package/tests/report-routing.test.ts +0 -245
- package/tests/report-stats.test.ts +0 -545
- package/tests/revoke-account-credentials.test.ts +0 -54
- package/tests/safelink.test.ts +0 -534
- package/tests/scheduled-action-processor.test.ts +0 -488
- package/tests/scheduled-action.test.ts +0 -334
- package/tests/sequencer.test.ts +0 -227
- package/tests/server.test.ts +0 -62
- package/tests/sets.test.ts +0 -246
- package/tests/settings.test.ts +0 -308
- package/tests/strike-expiry-processor.test.ts +0 -299
- package/tests/subject-priority-score.test.ts +0 -96
- package/tests/takedown.test.ts +0 -105
- package/tests/team.test.ts +0 -216
- package/tests/verification-listener.test.ts +0 -129
- package/tests/verification.test.ts +0 -186
- package/tsconfig.build.json +0 -9
- package/tsconfig.build.tsbuildinfo +0 -1
- package/tsconfig.json +0 -7
- package/tsconfig.tests.json +0 -8
|
@@ -1,306 +0,0 @@
|
|
|
1
|
-
import AtpAgent from '@atproto/api'
|
|
2
|
-
import {
|
|
3
|
-
ModeratorClient,
|
|
4
|
-
SeedClient,
|
|
5
|
-
TestNetwork,
|
|
6
|
-
basicSeed,
|
|
7
|
-
} from '@atproto/dev-env'
|
|
8
|
-
import { ids } from '../src/lexicon/lexicons.js'
|
|
9
|
-
|
|
10
|
-
const REASON_SPAM = 'com.atproto.moderation.defs#reasonSpam'
|
|
11
|
-
const REASON_THREAT = 'tools.ozone.report.defs#reasonViolenceThreats'
|
|
12
|
-
const REASON_MISLEADING = 'com.atproto.moderation.defs#reasonMisleading'
|
|
13
|
-
|
|
14
|
-
describe('queue-router', () => {
|
|
15
|
-
let network: TestNetwork
|
|
16
|
-
let agent: AtpAgent
|
|
17
|
-
let sc: SeedClient
|
|
18
|
-
let modClient: ModeratorClient
|
|
19
|
-
|
|
20
|
-
const modHeaders = (nsid: string) => network.ozone.modHeaders(nsid, 'admin')
|
|
21
|
-
|
|
22
|
-
const createQueue = async (input: {
|
|
23
|
-
name: string
|
|
24
|
-
subjectTypes: string[]
|
|
25
|
-
reportTypes: string[]
|
|
26
|
-
collection?: string
|
|
27
|
-
}) => {
|
|
28
|
-
const { data } = await agent.tools.ozone.queue.createQueue(input, {
|
|
29
|
-
encoding: 'application/json',
|
|
30
|
-
headers: await modHeaders(ids.ToolsOzoneQueueCreateQueue),
|
|
31
|
-
})
|
|
32
|
-
return data.queue
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const deleteQueue = async (queueId: number) => {
|
|
36
|
-
await agent.tools.ozone.queue.deleteQueue(
|
|
37
|
-
{ queueId },
|
|
38
|
-
{
|
|
39
|
-
encoding: 'application/json',
|
|
40
|
-
headers: await modHeaders(ids.ToolsOzoneQueueDeleteQueue),
|
|
41
|
-
},
|
|
42
|
-
)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Creates a report event (account-level) directly via modClient for a given DID + reason
|
|
46
|
-
const reportAccount = async (did: string, reportType: string) => {
|
|
47
|
-
await modClient.emitEvent({
|
|
48
|
-
event: {
|
|
49
|
-
$type: 'tools.ozone.moderation.defs#modEventReport',
|
|
50
|
-
reportType,
|
|
51
|
-
comment: 'automated test report',
|
|
52
|
-
},
|
|
53
|
-
subject: { $type: 'com.atproto.admin.defs#repoRef', did },
|
|
54
|
-
})
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Creates a record-level report event via modClient
|
|
58
|
-
const reportRecord = async (uri: string, cid: string, reportType: string) => {
|
|
59
|
-
await modClient.emitEvent({
|
|
60
|
-
event: {
|
|
61
|
-
$type: 'tools.ozone.moderation.defs#modEventReport',
|
|
62
|
-
reportType,
|
|
63
|
-
comment: 'automated test report',
|
|
64
|
-
},
|
|
65
|
-
subject: { $type: 'com.atproto.repo.strongRef', uri, cid },
|
|
66
|
-
})
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Returns the most recent report for a subject using the queryReports API.
|
|
70
|
-
// Pass a DID for account subjects or an at:// URI for record subjects.
|
|
71
|
-
const queryLatestReportForSubject = async (
|
|
72
|
-
subjectOrUri: string,
|
|
73
|
-
status: 'open' | 'closed' | 'escalated' | 'queued' | 'assigned' = 'queued',
|
|
74
|
-
) => {
|
|
75
|
-
const { reports } = await modClient.queryReports({
|
|
76
|
-
status,
|
|
77
|
-
subject: subjectOrUri,
|
|
78
|
-
})
|
|
79
|
-
return reports[0]
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
beforeAll(async () => {
|
|
83
|
-
network = await TestNetwork.create({
|
|
84
|
-
dbPostgresSchema: 'ozone_queue_router',
|
|
85
|
-
})
|
|
86
|
-
agent = network.ozone.getAgent()
|
|
87
|
-
sc = network.getSeedClient()
|
|
88
|
-
modClient = network.ozone.getModClient()
|
|
89
|
-
await basicSeed(sc)
|
|
90
|
-
await network.processAll()
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
afterAll(async () => {
|
|
94
|
-
await network?.close()
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
it('inserts report rows with no queue assignment when no queues are configured', async () => {
|
|
98
|
-
// This test intentionally runs before any queues are created. The daemon
|
|
99
|
-
// still inserts the report row (with queueId = -1) so the invariant
|
|
100
|
-
// "every modEventReport has a corresponding report row" holds.
|
|
101
|
-
await reportAccount(sc.dids.alice, REASON_SPAM)
|
|
102
|
-
|
|
103
|
-
await network.ozone.daemon.ctx.queueRouter.routeReports()
|
|
104
|
-
|
|
105
|
-
// Cursor advances past the processed event
|
|
106
|
-
const cursor = await network.ozone.daemon.ctx.queueRouter.getCursor()
|
|
107
|
-
expect(cursor).not.toBeNull()
|
|
108
|
-
expect(cursor!).toBeGreaterThan(0)
|
|
109
|
-
|
|
110
|
-
// Report row exists with no queue (queueId = -1 surfaces as undefined)
|
|
111
|
-
const report = await queryLatestReportForSubject(sc.dids.alice, 'open')
|
|
112
|
-
expect(report).toBeDefined()
|
|
113
|
-
expect(report.queue).toBeUndefined()
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
describe('with queues configured', () => {
|
|
117
|
-
let spamAccountQueueId: number
|
|
118
|
-
let threatAccountQueueId: number
|
|
119
|
-
let spamPostQueueId: number
|
|
120
|
-
|
|
121
|
-
beforeAll(async () => {
|
|
122
|
-
const [spamAccountQueue, threatAccountQueue, spamPostQueue] =
|
|
123
|
-
await Promise.all([
|
|
124
|
-
createQueue({
|
|
125
|
-
name: 'QR: Spam Accounts',
|
|
126
|
-
subjectTypes: ['account'],
|
|
127
|
-
reportTypes: [REASON_SPAM],
|
|
128
|
-
}),
|
|
129
|
-
createQueue({
|
|
130
|
-
name: 'QR: Threat Accounts',
|
|
131
|
-
subjectTypes: ['account'],
|
|
132
|
-
reportTypes: [REASON_THREAT],
|
|
133
|
-
}),
|
|
134
|
-
createQueue({
|
|
135
|
-
name: 'QR: Spam Posts',
|
|
136
|
-
subjectTypes: ['record'],
|
|
137
|
-
reportTypes: [REASON_SPAM],
|
|
138
|
-
collection: 'app.bsky.feed.post',
|
|
139
|
-
}),
|
|
140
|
-
])
|
|
141
|
-
spamAccountQueueId = spamAccountQueue.id
|
|
142
|
-
threatAccountQueueId = threatAccountQueue.id
|
|
143
|
-
spamPostQueueId = spamPostQueue.id
|
|
144
|
-
})
|
|
145
|
-
|
|
146
|
-
afterAll(async () => {
|
|
147
|
-
await Promise.all([
|
|
148
|
-
deleteQueue(spamAccountQueueId).catch(() => {}),
|
|
149
|
-
deleteQueue(threatAccountQueueId).catch(() => {}),
|
|
150
|
-
deleteQueue(spamPostQueueId).catch(() => {}),
|
|
151
|
-
])
|
|
152
|
-
})
|
|
153
|
-
|
|
154
|
-
it('routes an account report to the matching queue', async () => {
|
|
155
|
-
await reportAccount(sc.dids.bob, REASON_SPAM)
|
|
156
|
-
|
|
157
|
-
const beforeRouting = new Date()
|
|
158
|
-
await network.ozone.daemon.ctx.queueRouter.routeReports()
|
|
159
|
-
|
|
160
|
-
const report = await queryLatestReportForSubject(sc.dids.bob)
|
|
161
|
-
expect(report).toBeDefined()
|
|
162
|
-
expect(report.queue?.id).toBe(spamAccountQueueId)
|
|
163
|
-
expect(new Date(report.queuedAt!).getTime()).toBeGreaterThanOrEqual(
|
|
164
|
-
beforeRouting.getTime(),
|
|
165
|
-
)
|
|
166
|
-
})
|
|
167
|
-
|
|
168
|
-
it('routes a record report to the matching queue with collection filter', async () => {
|
|
169
|
-
const alicePost = sc.posts[sc.dids.alice][0]
|
|
170
|
-
const postUri = alicePost.ref.uriStr
|
|
171
|
-
const postCid = alicePost.ref.cidStr
|
|
172
|
-
|
|
173
|
-
await reportRecord(postUri, postCid, REASON_SPAM)
|
|
174
|
-
|
|
175
|
-
const beforeRouting = new Date()
|
|
176
|
-
await network.ozone.daemon.ctx.queueRouter.routeReports()
|
|
177
|
-
|
|
178
|
-
const report = await queryLatestReportForSubject(postUri)
|
|
179
|
-
expect(report).toBeDefined()
|
|
180
|
-
expect(report.queue?.id).toBe(spamPostQueueId)
|
|
181
|
-
expect(new Date(report.queuedAt!).getTime()).toBeGreaterThanOrEqual(
|
|
182
|
-
beforeRouting.getTime(),
|
|
183
|
-
)
|
|
184
|
-
})
|
|
185
|
-
|
|
186
|
-
it('routes a record report to a queue with null collection (matches all)', async () => {
|
|
187
|
-
// Create a catch-all record queue with no collection filter
|
|
188
|
-
const catchAllQueue = await createQueue({
|
|
189
|
-
name: 'QR: All Records Threat',
|
|
190
|
-
subjectTypes: ['record'],
|
|
191
|
-
reportTypes: [REASON_THREAT],
|
|
192
|
-
})
|
|
193
|
-
|
|
194
|
-
// Use a different post than the collection-filter test to avoid subject overlap
|
|
195
|
-
const bobPost = sc.posts[sc.dids.bob][0]
|
|
196
|
-
const postUri = bobPost.ref.uriStr
|
|
197
|
-
const postCid = bobPost.ref.cidStr
|
|
198
|
-
|
|
199
|
-
await reportRecord(postUri, postCid, REASON_THREAT)
|
|
200
|
-
await network.ozone.daemon.ctx.queueRouter.routeReports()
|
|
201
|
-
|
|
202
|
-
const report = await queryLatestReportForSubject(postUri)
|
|
203
|
-
expect(report).toBeDefined()
|
|
204
|
-
expect(report.queue?.id).toBe(catchAllQueue.id)
|
|
205
|
-
|
|
206
|
-
// Clean up
|
|
207
|
-
await deleteQueue(catchAllQueue.id)
|
|
208
|
-
})
|
|
209
|
-
|
|
210
|
-
it('sets queueId to -1 for reports with no matching queue', async () => {
|
|
211
|
-
// REASON_MISLEADING has no configured queue
|
|
212
|
-
await reportAccount(sc.dids.carol, REASON_MISLEADING)
|
|
213
|
-
|
|
214
|
-
await network.ozone.daemon.ctx.queueRouter.routeReports()
|
|
215
|
-
|
|
216
|
-
const report = await queryLatestReportForSubject(sc.dids.carol, 'open')
|
|
217
|
-
expect(report).toBeDefined()
|
|
218
|
-
expect(report.queue).toBeUndefined()
|
|
219
|
-
expect(report.queuedAt).toBeUndefined()
|
|
220
|
-
})
|
|
221
|
-
|
|
222
|
-
it('skips unmatched reports (queueId = -1)', async () => {
|
|
223
|
-
// The previous test already set carol's report to queueId = -1 (REASON_MISLEADING)
|
|
224
|
-
const report = await queryLatestReportForSubject(sc.dids.carol, 'open')
|
|
225
|
-
expect(report).toBeDefined()
|
|
226
|
-
expect(report.queue).toBeUndefined() // queueId = -1
|
|
227
|
-
|
|
228
|
-
// Run the routing again
|
|
229
|
-
await network.ozone.daemon.ctx.queueRouter.routeReports()
|
|
230
|
-
|
|
231
|
-
const reportAfter = await queryLatestReportForSubject(
|
|
232
|
-
sc.dids.carol,
|
|
233
|
-
'open',
|
|
234
|
-
)
|
|
235
|
-
expect(reportAfter.queue).toBeUndefined() // still unmatched, was skipped
|
|
236
|
-
expect(reportAfter.id).toBe(report.id) // same report, unchanged
|
|
237
|
-
})
|
|
238
|
-
|
|
239
|
-
it('advances cursor so already-processed events are skipped on subsequent runs', async () => {
|
|
240
|
-
await reportAccount(sc.dids.dan, REASON_THREAT)
|
|
241
|
-
|
|
242
|
-
await network.ozone.daemon.ctx.queueRouter.routeReports()
|
|
243
|
-
|
|
244
|
-
const report = await queryLatestReportForSubject(sc.dids.dan)
|
|
245
|
-
expect(report).toBeDefined()
|
|
246
|
-
expect(report.queue?.id).toBe(threatAccountQueueId)
|
|
247
|
-
|
|
248
|
-
const cursorAfterFirst =
|
|
249
|
-
await network.ozone.daemon.ctx.queueRouter.getCursor()
|
|
250
|
-
expect(cursorAfterFirst).not.toBeNull()
|
|
251
|
-
|
|
252
|
-
// Delete the report row to simulate an unprocessed state — there is no
|
|
253
|
-
// API surface for this, so a direct DB write is necessary. The cursor
|
|
254
|
-
// (which points at the moderation_event id) stays past this event, so
|
|
255
|
-
// the daemon must not re-insert.
|
|
256
|
-
await network.ozone.daemon.ctx.db.db
|
|
257
|
-
.deleteFrom('report')
|
|
258
|
-
.where('id', '=', report.id)
|
|
259
|
-
.execute()
|
|
260
|
-
|
|
261
|
-
// A second run must not reprocess the event because its id is below the cursor
|
|
262
|
-
await network.ozone.daemon.ctx.queueRouter.routeReports()
|
|
263
|
-
|
|
264
|
-
const reportAfterSecondRun = await queryLatestReportForSubject(
|
|
265
|
-
sc.dids.dan,
|
|
266
|
-
)
|
|
267
|
-
// No report row should have been re-inserted
|
|
268
|
-
expect(reportAfterSecondRun).toBeUndefined()
|
|
269
|
-
|
|
270
|
-
// Cursor unchanged — second run found nothing past it
|
|
271
|
-
const cursorAfterSecond =
|
|
272
|
-
await network.ozone.daemon.ctx.queueRouter.getCursor()
|
|
273
|
-
expect(cursorAfterSecond).toBe(cursorAfterFirst)
|
|
274
|
-
})
|
|
275
|
-
|
|
276
|
-
it('skips disabled queues when routing', async () => {
|
|
277
|
-
// Disable the threat queue and create the report concurrently
|
|
278
|
-
await Promise.all([
|
|
279
|
-
agent.tools.ozone.queue.updateQueue(
|
|
280
|
-
{ queueId: threatAccountQueueId, enabled: false },
|
|
281
|
-
{
|
|
282
|
-
encoding: 'application/json',
|
|
283
|
-
headers: await modHeaders(ids.ToolsOzoneQueueUpdateQueue),
|
|
284
|
-
},
|
|
285
|
-
),
|
|
286
|
-
reportAccount(sc.dids.alice, REASON_THREAT),
|
|
287
|
-
])
|
|
288
|
-
|
|
289
|
-
await network.ozone.daemon.ctx.queueRouter.routeReports()
|
|
290
|
-
|
|
291
|
-
const report = await queryLatestReportForSubject(sc.dids.alice, 'open')
|
|
292
|
-
expect(report).toBeDefined()
|
|
293
|
-
// Threat queue is disabled, so no match → queue is absent
|
|
294
|
-
expect(report.queue).toBeUndefined()
|
|
295
|
-
|
|
296
|
-
// Re-enable the queue for subsequent tests
|
|
297
|
-
await agent.tools.ozone.queue.updateQueue(
|
|
298
|
-
{ queueId: threatAccountQueueId, enabled: true },
|
|
299
|
-
{
|
|
300
|
-
encoding: 'application/json',
|
|
301
|
-
headers: await modHeaders(ids.ToolsOzoneQueueUpdateQueue),
|
|
302
|
-
},
|
|
303
|
-
)
|
|
304
|
-
})
|
|
305
|
-
})
|
|
306
|
-
})
|