@atproto/ozone 0.2.8 → 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 +33 -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,488 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AtpAgent,
|
|
3
|
-
ToolsOzoneModerationListScheduledActions,
|
|
4
|
-
} from '@atproto/api'
|
|
5
|
-
import { HOUR, MINUTE } from '@atproto/common'
|
|
6
|
-
import { SeedClient, TestNetwork, basicSeed } from '@atproto/dev-env'
|
|
7
|
-
import { ModEventTakedown } from '../dist/lexicon/types/tools/ozone/moderation/defs.js'
|
|
8
|
-
import { ids } from '../src/lexicon/lexicons.js'
|
|
9
|
-
import { ProtectedTagSettingKey } from '../src/setting/constants.js'
|
|
10
|
-
|
|
11
|
-
describe('scheduled action processor', () => {
|
|
12
|
-
let network: TestNetwork
|
|
13
|
-
let adminAgent: AtpAgent
|
|
14
|
-
let sc: SeedClient
|
|
15
|
-
|
|
16
|
-
const getAdminHeaders = async (route: string) => {
|
|
17
|
-
return {
|
|
18
|
-
headers: await network.ozone.modHeaders(route, 'admin'),
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const scheduleTestAction = async (
|
|
23
|
-
subject: string,
|
|
24
|
-
scheduling: any,
|
|
25
|
-
emailData?: { emailSubject?: string; emailContent?: string },
|
|
26
|
-
) => {
|
|
27
|
-
return await adminAgent.tools.ozone.moderation.scheduleAction(
|
|
28
|
-
{
|
|
29
|
-
action: {
|
|
30
|
-
$type: 'tools.ozone.moderation.scheduleAction#takedown',
|
|
31
|
-
comment: 'Test scheduled takedown',
|
|
32
|
-
policies: ['spam'],
|
|
33
|
-
severityLevel: 'sev-1',
|
|
34
|
-
strikeCount: 1,
|
|
35
|
-
...emailData,
|
|
36
|
-
},
|
|
37
|
-
subjects: [subject],
|
|
38
|
-
createdBy: 'did:plc:moderator',
|
|
39
|
-
scheduling,
|
|
40
|
-
},
|
|
41
|
-
await getAdminHeaders(ids.ToolsOzoneModerationScheduleAction),
|
|
42
|
-
)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const getScheduledActions = async (
|
|
46
|
-
statuses: ToolsOzoneModerationListScheduledActions.InputSchema['statuses'],
|
|
47
|
-
subjects?: string[],
|
|
48
|
-
) => {
|
|
49
|
-
const { data } =
|
|
50
|
-
await adminAgent.tools.ozone.moderation.listScheduledActions(
|
|
51
|
-
{ subjects, statuses },
|
|
52
|
-
await getAdminHeaders(ids.ToolsOzoneModerationListScheduledActions),
|
|
53
|
-
)
|
|
54
|
-
return data.actions
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const getModerationEvents = async (subject: string, types?: string[]) => {
|
|
58
|
-
const { data } = await adminAgent.tools.ozone.moderation.queryEvents(
|
|
59
|
-
{ subject, types },
|
|
60
|
-
await getAdminHeaders(ids.ToolsOzoneModerationQueryEvents),
|
|
61
|
-
)
|
|
62
|
-
return data.events
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
beforeAll(async () => {
|
|
66
|
-
network = await TestNetwork.create({
|
|
67
|
-
dbPostgresSchema: 'ozone_scheduled_action_processor_test',
|
|
68
|
-
})
|
|
69
|
-
adminAgent = network.ozone.getAgent()
|
|
70
|
-
sc = network.getSeedClient()
|
|
71
|
-
await basicSeed(sc)
|
|
72
|
-
await network.processAll()
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
afterAll(async () => {
|
|
76
|
-
await network?.close()
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
describe('findAndExecuteScheduledActions', () => {
|
|
80
|
-
it('processes actions scheduled for immediate execution', async () => {
|
|
81
|
-
const testSubject = sc.dids.alice
|
|
82
|
-
|
|
83
|
-
const pastTime = new Date(Date.now() - 1000).toISOString()
|
|
84
|
-
await scheduleTestAction(
|
|
85
|
-
testSubject,
|
|
86
|
-
{ executeAt: pastTime },
|
|
87
|
-
{
|
|
88
|
-
emailSubject: 'Test Email Subject',
|
|
89
|
-
emailContent: 'Test Email Content',
|
|
90
|
-
},
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
const pendingActions = await getScheduledActions(
|
|
94
|
-
['pending'],
|
|
95
|
-
[testSubject],
|
|
96
|
-
)
|
|
97
|
-
expect(pendingActions.length).toBe(1)
|
|
98
|
-
|
|
99
|
-
await network.ozone.daemon.ctx.scheduledActionProcessor.findAndExecuteScheduledActions()
|
|
100
|
-
|
|
101
|
-
const executedActions = await getScheduledActions(
|
|
102
|
-
['executed'],
|
|
103
|
-
[testSubject],
|
|
104
|
-
)
|
|
105
|
-
expect(executedActions.length).toBe(1)
|
|
106
|
-
expect(executedActions[0].status).toBe('executed')
|
|
107
|
-
expect(executedActions[0].executionEventId).toBeDefined()
|
|
108
|
-
|
|
109
|
-
const modEvents = await getModerationEvents(testSubject, [
|
|
110
|
-
'tools.ozone.moderation.defs#modEventTakedown',
|
|
111
|
-
'tools.ozone.moderation.defs#modEventEmail',
|
|
112
|
-
])
|
|
113
|
-
expect(modEvents.length).toBe(2)
|
|
114
|
-
const takedownEvent = modEvents.find(
|
|
115
|
-
(e) => e.event.$type === 'tools.ozone.moderation.defs#modEventTakedown',
|
|
116
|
-
)
|
|
117
|
-
const emailEvent = modEvents.find(
|
|
118
|
-
(e) => e.event.$type === 'tools.ozone.moderation.defs#modEventEmail',
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
expect(takedownEvent?.event['comment']).toBeDefined()
|
|
122
|
-
|
|
123
|
-
expect(emailEvent?.event['subjectLine']).toBe('Test Email Subject')
|
|
124
|
-
expect(emailEvent?.event['content']).toBe('Test Email Content')
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
it('skips actions scheduled for future execution', async () => {
|
|
128
|
-
const testSubject = sc.dids.bob
|
|
129
|
-
|
|
130
|
-
// Schedule an action for future execution (1 hour from now)
|
|
131
|
-
const futureTime = new Date(Date.now() + HOUR).toISOString()
|
|
132
|
-
await scheduleTestAction(testSubject, { executeAt: futureTime })
|
|
133
|
-
|
|
134
|
-
// Process scheduled actions
|
|
135
|
-
await network.ozone.daemon.ctx.scheduledActionProcessor.findAndExecuteScheduledActions()
|
|
136
|
-
|
|
137
|
-
// Verify action is still pending
|
|
138
|
-
const pendingActions = await getScheduledActions(
|
|
139
|
-
['pending'],
|
|
140
|
-
[testSubject],
|
|
141
|
-
)
|
|
142
|
-
expect(pendingActions.length).toBe(1)
|
|
143
|
-
|
|
144
|
-
const executedActions = await getScheduledActions(
|
|
145
|
-
['executed'],
|
|
146
|
-
[testSubject],
|
|
147
|
-
)
|
|
148
|
-
expect(executedActions.length).toBe(0)
|
|
149
|
-
})
|
|
150
|
-
|
|
151
|
-
it('skips randomized actions before executeAfter time', async () => {
|
|
152
|
-
const testSubject = 'did:plc:future_randomized'
|
|
153
|
-
|
|
154
|
-
// Schedule an action with future executeAfter
|
|
155
|
-
const futureAfter = new Date(Date.now() + 30 * MINUTE).toISOString()
|
|
156
|
-
const futureUntil = new Date(Date.now() + HOUR).toISOString()
|
|
157
|
-
await scheduleTestAction(testSubject, {
|
|
158
|
-
executeAfter: futureAfter,
|
|
159
|
-
executeUntil: futureUntil,
|
|
160
|
-
})
|
|
161
|
-
|
|
162
|
-
// Process scheduled actions
|
|
163
|
-
await network.ozone.daemon.ctx.scheduledActionProcessor.findAndExecuteScheduledActions()
|
|
164
|
-
|
|
165
|
-
// Verify action is still pending
|
|
166
|
-
const pendingActions = await getScheduledActions(
|
|
167
|
-
['pending'],
|
|
168
|
-
[testSubject],
|
|
169
|
-
)
|
|
170
|
-
expect(pendingActions.length).toBe(1)
|
|
171
|
-
})
|
|
172
|
-
|
|
173
|
-
it('always executes randomized actions past executeUntil deadline', async () => {
|
|
174
|
-
const testSubject = 'did:plc:overdue_randomized'
|
|
175
|
-
|
|
176
|
-
// Schedule an action that's past its deadline
|
|
177
|
-
const pastAfter = new Date(Date.now() - HOUR).toISOString()
|
|
178
|
-
const pastUntil = new Date(Date.now() - 30 * MINUTE).toISOString()
|
|
179
|
-
await scheduleTestAction(testSubject, {
|
|
180
|
-
executeAfter: pastAfter,
|
|
181
|
-
executeUntil: pastUntil,
|
|
182
|
-
})
|
|
183
|
-
|
|
184
|
-
// Process scheduled actions
|
|
185
|
-
await network.ozone.daemon.ctx.scheduledActionProcessor.findAndExecuteScheduledActions()
|
|
186
|
-
|
|
187
|
-
// Verify action is executed (should always execute past deadline)
|
|
188
|
-
const executedActions = await getScheduledActions(
|
|
189
|
-
['executed'],
|
|
190
|
-
[testSubject],
|
|
191
|
-
)
|
|
192
|
-
expect(executedActions.length).toBe(1)
|
|
193
|
-
expect(executedActions[0].status).toBe('executed')
|
|
194
|
-
})
|
|
195
|
-
})
|
|
196
|
-
|
|
197
|
-
describe('executeScheduledAction', () => {
|
|
198
|
-
it('handles takedown actions with all properties', async () => {
|
|
199
|
-
const testSubject = 'did:plc:detailed_takedown'
|
|
200
|
-
|
|
201
|
-
// Schedule a detailed takedown action
|
|
202
|
-
await adminAgent.tools.ozone.moderation.scheduleAction(
|
|
203
|
-
{
|
|
204
|
-
action: {
|
|
205
|
-
$type: 'tools.ozone.moderation.scheduleAction#takedown',
|
|
206
|
-
comment: 'Detailed takedown test',
|
|
207
|
-
durationInHours: 24,
|
|
208
|
-
acknowledgeAccountSubjects: true,
|
|
209
|
-
policies: ['spam', 'harassment'],
|
|
210
|
-
},
|
|
211
|
-
subjects: [testSubject],
|
|
212
|
-
createdBy: 'did:plc:moderator',
|
|
213
|
-
scheduling: {
|
|
214
|
-
executeAt: new Date(Date.now() - 1000).toISOString(),
|
|
215
|
-
},
|
|
216
|
-
modTool: { name: 'test-tool' },
|
|
217
|
-
},
|
|
218
|
-
await getAdminHeaders(ids.ToolsOzoneModerationScheduleAction),
|
|
219
|
-
)
|
|
220
|
-
|
|
221
|
-
// Process the action
|
|
222
|
-
await network.ozone.daemon.ctx.scheduledActionProcessor.findAndExecuteScheduledActions()
|
|
223
|
-
|
|
224
|
-
// Verify the moderation event has all properties
|
|
225
|
-
const modEvents = await getModerationEvents(testSubject, [
|
|
226
|
-
'tools.ozone.moderation.defs#modEventTakedown',
|
|
227
|
-
'tools.ozone.moderation.defs#modEventEmail',
|
|
228
|
-
])
|
|
229
|
-
// No email was sent
|
|
230
|
-
expect(modEvents.length).toBe(1)
|
|
231
|
-
|
|
232
|
-
const takedownEvent = modEvents[0].event as ModEventTakedown
|
|
233
|
-
expect(takedownEvent.comment).toContain('[SCHEDULED_ACTION]')
|
|
234
|
-
expect(takedownEvent.comment).toContain('Detailed takedown test')
|
|
235
|
-
expect(takedownEvent.durationInHours).toBe(24)
|
|
236
|
-
expect(takedownEvent.acknowledgeAccountSubjects).toBe(true)
|
|
237
|
-
expect(takedownEvent.policies).toEqual(['spam', 'harassment'])
|
|
238
|
-
})
|
|
239
|
-
|
|
240
|
-
it('marks action as failed when moderation event creation fails', async () => {
|
|
241
|
-
const testSubject = 'did:plc:invalid_subject'
|
|
242
|
-
|
|
243
|
-
await scheduleTestAction(testSubject, {
|
|
244
|
-
executeAt: new Date(Date.now() - 1000).toISOString(),
|
|
245
|
-
})
|
|
246
|
-
|
|
247
|
-
const pendingActions = await getScheduledActions(
|
|
248
|
-
['pending'],
|
|
249
|
-
[testSubject],
|
|
250
|
-
)
|
|
251
|
-
expect(pendingActions.length).toBe(1)
|
|
252
|
-
const actionId = pendingActions[0].id
|
|
253
|
-
|
|
254
|
-
// Manually update the action type to trigger error in processing
|
|
255
|
-
await network.ozone.ctx.db.db
|
|
256
|
-
.updateTable('scheduled_action')
|
|
257
|
-
.set({ action: 'unknown' })
|
|
258
|
-
.where('id', '=', actionId)
|
|
259
|
-
.execute()
|
|
260
|
-
|
|
261
|
-
await network.ozone.daemon.ctx.scheduledActionProcessor.executeScheduledAction(
|
|
262
|
-
actionId,
|
|
263
|
-
)
|
|
264
|
-
|
|
265
|
-
const failedActions = await getScheduledActions(['failed'], [testSubject])
|
|
266
|
-
expect(failedActions.length).toBe(1)
|
|
267
|
-
expect(failedActions[0].status).toBe('failed')
|
|
268
|
-
expect(failedActions[0].lastFailureReason).toBeDefined()
|
|
269
|
-
})
|
|
270
|
-
|
|
271
|
-
it('skips actions that are no longer pending', async () => {
|
|
272
|
-
const testSubject = 'did:plc:already_processed'
|
|
273
|
-
|
|
274
|
-
// Schedule and then cancel an action
|
|
275
|
-
await scheduleTestAction(testSubject, {
|
|
276
|
-
executeAt: new Date(Date.now() - 1000).toISOString(),
|
|
277
|
-
})
|
|
278
|
-
|
|
279
|
-
await adminAgent.tools.ozone.moderation.cancelScheduledActions(
|
|
280
|
-
{ subjects: [testSubject] },
|
|
281
|
-
await getAdminHeaders(ids.ToolsOzoneModerationCancelScheduledActions),
|
|
282
|
-
)
|
|
283
|
-
|
|
284
|
-
const cancelledActions = await getScheduledActions(
|
|
285
|
-
['cancelled'],
|
|
286
|
-
[testSubject],
|
|
287
|
-
)
|
|
288
|
-
expect(cancelledActions.length).toBe(1)
|
|
289
|
-
const actionId = cancelledActions[0].id
|
|
290
|
-
|
|
291
|
-
await network.ozone.daemon.ctx.scheduledActionProcessor.executeScheduledAction(
|
|
292
|
-
actionId,
|
|
293
|
-
)
|
|
294
|
-
|
|
295
|
-
const modEvents = await getModerationEvents(testSubject)
|
|
296
|
-
const takedownEvents = modEvents.filter(
|
|
297
|
-
(e) => e.event.$type === 'tools.ozone.moderation.defs#modEventTakedown',
|
|
298
|
-
)
|
|
299
|
-
expect(takedownEvents.length).toBe(0)
|
|
300
|
-
})
|
|
301
|
-
|
|
302
|
-
it('processes multiple actions in batch', async () => {
|
|
303
|
-
const subjects = ['did:plc:batch1', 'did:plc:batch2', 'did:plc:batch3']
|
|
304
|
-
const pastTime = new Date(Date.now() - 1000).toISOString()
|
|
305
|
-
|
|
306
|
-
for (const subject of subjects) {
|
|
307
|
-
await scheduleTestAction(subject, { executeAt: pastTime })
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
await network.ozone.daemon.ctx.scheduledActionProcessor.findAndExecuteScheduledActions()
|
|
311
|
-
|
|
312
|
-
const executedActions = await getScheduledActions(['executed'], subjects)
|
|
313
|
-
expect(executedActions.length).toBe(3)
|
|
314
|
-
|
|
315
|
-
for (const subject of subjects) {
|
|
316
|
-
const modEvents = await getModerationEvents(subject, [
|
|
317
|
-
'tools.ozone.moderation.defs#modEventTakedown',
|
|
318
|
-
])
|
|
319
|
-
expect(modEvents.length).toBe(1)
|
|
320
|
-
}
|
|
321
|
-
})
|
|
322
|
-
})
|
|
323
|
-
|
|
324
|
-
describe('takedown validation checks', () => {
|
|
325
|
-
it('fails when trying to takedown an already taken down account', async () => {
|
|
326
|
-
const testSubject = 'did:plc:already_takendown'
|
|
327
|
-
|
|
328
|
-
// takedown the account manually
|
|
329
|
-
await adminAgent.tools.ozone.moderation.emitEvent(
|
|
330
|
-
{
|
|
331
|
-
subject: {
|
|
332
|
-
$type: 'com.atproto.admin.defs#repoRef',
|
|
333
|
-
did: testSubject,
|
|
334
|
-
},
|
|
335
|
-
event: {
|
|
336
|
-
$type: 'tools.ozone.moderation.defs#modEventTakedown',
|
|
337
|
-
comment: 'Manual takedown first',
|
|
338
|
-
},
|
|
339
|
-
createdBy: adminAgent.session?.did || 'did:plc:admin',
|
|
340
|
-
},
|
|
341
|
-
await getAdminHeaders(ids.ToolsOzoneModerationEmitEvent),
|
|
342
|
-
)
|
|
343
|
-
|
|
344
|
-
// Schedule a takedown for the already taken down account
|
|
345
|
-
await scheduleTestAction(testSubject, {
|
|
346
|
-
executeAt: new Date(Date.now() - 1000).toISOString(),
|
|
347
|
-
})
|
|
348
|
-
|
|
349
|
-
// Process the scheduled action
|
|
350
|
-
await network.ozone.daemon.ctx.scheduledActionProcessor.findAndExecuteScheduledActions()
|
|
351
|
-
|
|
352
|
-
// Verify the scheduled action failed
|
|
353
|
-
const failedActions = await getScheduledActions(['failed'], [testSubject])
|
|
354
|
-
expect(failedActions.length).toBe(1)
|
|
355
|
-
expect(failedActions[0].status).toBe('failed')
|
|
356
|
-
expect(failedActions[0].lastFailureReason).toContain(
|
|
357
|
-
'Account is already taken down',
|
|
358
|
-
)
|
|
359
|
-
})
|
|
360
|
-
|
|
361
|
-
it('enforces protected tag restrictions when account has protected tags', async () => {
|
|
362
|
-
const testSubject = 'did:plc:protected_tag_test'
|
|
363
|
-
|
|
364
|
-
// add the protected tag to the account
|
|
365
|
-
await adminAgent.tools.ozone.moderation.emitEvent(
|
|
366
|
-
{
|
|
367
|
-
subject: {
|
|
368
|
-
$type: 'com.atproto.admin.defs#repoRef',
|
|
369
|
-
did: testSubject,
|
|
370
|
-
},
|
|
371
|
-
event: {
|
|
372
|
-
$type: 'tools.ozone.moderation.defs#modEventTag',
|
|
373
|
-
add: ['vip'],
|
|
374
|
-
remove: [],
|
|
375
|
-
},
|
|
376
|
-
createdBy: adminAgent.session?.did || 'did:plc:admin',
|
|
377
|
-
},
|
|
378
|
-
await getAdminHeaders(ids.ToolsOzoneModerationEmitEvent),
|
|
379
|
-
)
|
|
380
|
-
|
|
381
|
-
// add protected tag setting for the instance and make that tag actionable by a mod only
|
|
382
|
-
await adminAgent.tools.ozone.setting.upsertOption(
|
|
383
|
-
{
|
|
384
|
-
key: ProtectedTagSettingKey,
|
|
385
|
-
scope: 'instance',
|
|
386
|
-
managerRole: 'tools.ozone.team.defs#roleAdmin',
|
|
387
|
-
value: { vip: { moderators: [sc.dids.alice] } },
|
|
388
|
-
},
|
|
389
|
-
await getAdminHeaders(ids.ToolsOzoneSettingUpsertOption),
|
|
390
|
-
)
|
|
391
|
-
|
|
392
|
-
// Schedule a takedown action created by a non-admin moderator
|
|
393
|
-
await adminAgent.tools.ozone.moderation.scheduleAction(
|
|
394
|
-
{
|
|
395
|
-
action: {
|
|
396
|
-
$type: 'tools.ozone.moderation.scheduleAction#takedown',
|
|
397
|
-
comment: 'Test protected tag enforcement',
|
|
398
|
-
},
|
|
399
|
-
subjects: [testSubject],
|
|
400
|
-
createdBy: 'did:plc:non_admin_moderator', // Non-admin creator
|
|
401
|
-
scheduling: {
|
|
402
|
-
executeAt: new Date(Date.now() - 1000).toISOString(),
|
|
403
|
-
},
|
|
404
|
-
},
|
|
405
|
-
await getAdminHeaders(ids.ToolsOzoneModerationScheduleAction),
|
|
406
|
-
)
|
|
407
|
-
|
|
408
|
-
// Process the scheduled action
|
|
409
|
-
await network.ozone.daemon.ctx.scheduledActionProcessor.findAndExecuteScheduledActions()
|
|
410
|
-
|
|
411
|
-
// Verify the scheduled action failed due to protected tag restrictions
|
|
412
|
-
const failedActions = await getScheduledActions(['failed'], [testSubject])
|
|
413
|
-
expect(failedActions.length).toBe(1)
|
|
414
|
-
expect(failedActions[0].status).toBe('failed')
|
|
415
|
-
expect(failedActions[0].lastFailureReason).toContain('tag')
|
|
416
|
-
|
|
417
|
-
// Clean up protected tags setting
|
|
418
|
-
await adminAgent.tools.ozone.setting.removeOptions(
|
|
419
|
-
{
|
|
420
|
-
keys: [ProtectedTagSettingKey],
|
|
421
|
-
scope: 'instance',
|
|
422
|
-
},
|
|
423
|
-
await getAdminHeaders(ids.ToolsOzoneSettingRemoveOptions),
|
|
424
|
-
)
|
|
425
|
-
})
|
|
426
|
-
|
|
427
|
-
it('allows takedown of accounts with protected tags when created by authorized user', async () => {
|
|
428
|
-
const testSubject = 'did:plc:authorized_protected_tag_test'
|
|
429
|
-
|
|
430
|
-
// Set up protected tags configuration allowing admins
|
|
431
|
-
await adminAgent.tools.ozone.setting.upsertOption(
|
|
432
|
-
{
|
|
433
|
-
key: ProtectedTagSettingKey,
|
|
434
|
-
scope: 'instance',
|
|
435
|
-
managerRole: 'tools.ozone.team.defs#roleAdmin',
|
|
436
|
-
value: { vip: { roles: ['tools.ozone.team.defs#roleAdmin'] } },
|
|
437
|
-
},
|
|
438
|
-
await getAdminHeaders(ids.ToolsOzoneSettingUpsertOption),
|
|
439
|
-
)
|
|
440
|
-
|
|
441
|
-
// Add a protected tag to the account
|
|
442
|
-
await adminAgent.tools.ozone.moderation.emitEvent(
|
|
443
|
-
{
|
|
444
|
-
subject: {
|
|
445
|
-
$type: 'com.atproto.admin.defs#repoRef',
|
|
446
|
-
did: testSubject,
|
|
447
|
-
},
|
|
448
|
-
event: {
|
|
449
|
-
$type: 'tools.ozone.moderation.defs#modEventTag',
|
|
450
|
-
add: ['vip'],
|
|
451
|
-
remove: [],
|
|
452
|
-
},
|
|
453
|
-
createdBy: adminAgent.session?.did || 'did:plc:admin',
|
|
454
|
-
},
|
|
455
|
-
await getAdminHeaders(ids.ToolsOzoneModerationEmitEvent),
|
|
456
|
-
)
|
|
457
|
-
|
|
458
|
-
await adminAgent.tools.ozone.moderation.scheduleAction(
|
|
459
|
-
{
|
|
460
|
-
action: {
|
|
461
|
-
$type: 'tools.ozone.moderation.scheduleAction#takedown',
|
|
462
|
-
comment: 'Admin takedown of protected account',
|
|
463
|
-
},
|
|
464
|
-
subjects: [testSubject],
|
|
465
|
-
createdBy: network.ozone.ctx.cfg.service.did,
|
|
466
|
-
scheduling: {
|
|
467
|
-
executeAt: new Date(Date.now() - 1000).toISOString(),
|
|
468
|
-
},
|
|
469
|
-
},
|
|
470
|
-
await getAdminHeaders(ids.ToolsOzoneModerationScheduleAction),
|
|
471
|
-
)
|
|
472
|
-
|
|
473
|
-
await network.ozone.daemon.ctx.scheduledActionProcessor.findAndExecuteScheduledActions()
|
|
474
|
-
|
|
475
|
-
const executedActions = await getScheduledActions(
|
|
476
|
-
['executed'],
|
|
477
|
-
[testSubject],
|
|
478
|
-
)
|
|
479
|
-
expect(executedActions.length).toBe(1)
|
|
480
|
-
expect(executedActions[0].status).toBe('executed')
|
|
481
|
-
|
|
482
|
-
const modEvents = await getModerationEvents(testSubject, [
|
|
483
|
-
'tools.ozone.moderation.defs#modEventTakedown',
|
|
484
|
-
])
|
|
485
|
-
expect(modEvents.length).toBe(1)
|
|
486
|
-
})
|
|
487
|
-
})
|
|
488
|
-
})
|