@atproto/ozone 0.0.16 → 0.0.17-next.0
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/dist/api/moderation/util.d.ts +1 -1
- package/dist/auth-verifier.d.ts +7 -11
- package/dist/config/config.d.ts +1 -0
- package/dist/config/env.d.ts +1 -2
- package/dist/config/secrets.d.ts +0 -2
- package/dist/daemon/event-pusher.d.ts +2 -0
- package/dist/db/index.js.map +1 -1
- package/dist/db/schema/moderation_subject_status.d.ts +2 -2
- package/dist/index.js +821 -1055
- package/dist/index.js.map +3 -3
- package/dist/lexicon/index.d.ts +8 -0
- package/dist/lexicon/lexicons.d.ts +298 -0
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts +23 -1
- package/dist/lexicon/types/app/bsky/embed/record.d.ts +2 -1
- package/dist/lexicon/types/app/bsky/labeler/defs.d.ts +41 -0
- package/dist/lexicon/types/app/bsky/labeler/getServices.d.ts +36 -0
- package/dist/lexicon/types/app/bsky/labeler/service.d.ts +14 -0
- package/dist/lexicon/types/com/atproto/admin/defs.d.ts +2 -1
- package/dist/lexicon/types/com/atproto/label/defs.d.ts +18 -0
- package/dist/mod-service/index.d.ts +2 -2
- package/package.json +5 -4
- package/src/api/admin/createCommunicationTemplate.ts +1 -1
- package/src/api/admin/deleteCommunicationTemplate.ts +1 -1
- package/src/api/admin/emitModerationEvent.ts +6 -2
- package/src/api/admin/getModerationEvent.ts +1 -1
- package/src/api/admin/getRecord.ts +1 -1
- package/src/api/admin/getRepo.ts +1 -1
- package/src/api/admin/listCommunicationTemplates.ts +1 -1
- package/src/api/admin/queryModerationEvents.ts +1 -1
- package/src/api/admin/queryModerationStatuses.ts +1 -1
- package/src/api/admin/searchRepos.ts +1 -1
- package/src/api/admin/updateCommunicationTemplate.ts +1 -1
- package/src/api/admin/util.ts +1 -1
- package/src/api/moderation/createReport.ts +1 -2
- package/src/api/proxied.ts +8 -8
- package/src/api/temp/fetchLabels.ts +1 -1
- package/src/auth-verifier.ts +19 -29
- package/src/config/config.ts +10 -7
- package/src/config/env.ts +2 -4
- package/src/config/secrets.ts +0 -6
- package/src/context.ts +1 -3
- package/src/daemon/context.ts +2 -2
- package/src/daemon/event-pusher.ts +9 -1
- package/src/db/schema/moderation_subject_status.ts +6 -1
- package/src/lexicon/index.ts +23 -0
- package/src/lexicon/lexicons.ts +327 -1
- package/src/lexicon/types/app/bsky/actor/defs.ts +57 -1
- package/src/lexicon/types/app/bsky/embed/record.ts +2 -0
- package/src/lexicon/types/app/bsky/labeler/defs.ts +93 -0
- package/src/lexicon/types/app/bsky/labeler/getServices.ts +51 -0
- package/src/lexicon/types/app/bsky/labeler/service.ts +31 -0
- package/src/lexicon/types/com/atproto/admin/defs.ts +3 -0
- package/src/lexicon/types/com/atproto/label/defs.ts +68 -0
- package/src/mod-service/index.ts +4 -3
- package/src/mod-service/status.ts +42 -26
- package/tests/__snapshots__/get-record.test.ts.snap +4 -4
- package/tests/__snapshots__/get-repo.test.ts.snap +2 -2
- package/tests/communication-templates.test.ts +7 -7
- package/tests/get-record.test.ts +17 -7
- package/tests/get-repo.test.ts +24 -12
- package/tests/moderation-appeals.test.ts +24 -52
- package/tests/moderation-events.test.ts +87 -130
- package/tests/moderation-status-tags.test.ts +16 -31
- package/tests/moderation-statuses.test.ts +125 -58
- package/tests/moderation.test.ts +140 -287
- package/tests/repo-search.test.ts +11 -4
package/tests/moderation.test.ts
CHANGED
|
@@ -4,12 +4,9 @@ import {
|
|
|
4
4
|
RecordRef,
|
|
5
5
|
SeedClient,
|
|
6
6
|
basicSeed,
|
|
7
|
+
ModeratorClient,
|
|
7
8
|
} from '@atproto/dev-env'
|
|
8
|
-
import AtpAgent, {
|
|
9
|
-
ComAtprotoAdminEmitModerationEvent,
|
|
10
|
-
ComAtprotoAdminQueryModerationStatuses,
|
|
11
|
-
ComAtprotoModerationCreateReport,
|
|
12
|
-
} from '@atproto/api'
|
|
9
|
+
import AtpAgent, { ComAtprotoAdminEmitModerationEvent } from '@atproto/api'
|
|
13
10
|
import { AtUri } from '@atproto/syntax'
|
|
14
11
|
import { forSnapshot } from './_util'
|
|
15
12
|
import {
|
|
@@ -19,7 +16,6 @@ import {
|
|
|
19
16
|
} from '../src/lexicon/types/com/atproto/moderation/defs'
|
|
20
17
|
import {
|
|
21
18
|
ModEventLabel,
|
|
22
|
-
ModEventTakedown,
|
|
23
19
|
REVIEWCLOSED,
|
|
24
20
|
REVIEWESCALATED,
|
|
25
21
|
} from '../src/lexicon/types/com/atproto/admin/defs'
|
|
@@ -31,16 +27,6 @@ import {
|
|
|
31
27
|
UNSPECCED_TAKEDOWN_LABEL,
|
|
32
28
|
} from '../src/mod-service/types'
|
|
33
29
|
|
|
34
|
-
type BaseCreateReportParams =
|
|
35
|
-
| { account: string }
|
|
36
|
-
| { content: { uri: string; cid: string } }
|
|
37
|
-
type CreateReportParams = BaseCreateReportParams & {
|
|
38
|
-
author: string
|
|
39
|
-
} & Omit<ComAtprotoModerationCreateReport.InputSchema, 'subject'>
|
|
40
|
-
|
|
41
|
-
type TakedownParams = BaseCreateReportParams &
|
|
42
|
-
Omit<ComAtprotoAdminEmitModerationEvent.InputSchema, 'subject'>
|
|
43
|
-
|
|
44
30
|
describe('moderation', () => {
|
|
45
31
|
let network: TestNetwork
|
|
46
32
|
let ozone: TestOzone
|
|
@@ -49,102 +35,18 @@ describe('moderation', () => {
|
|
|
49
35
|
let bskyAgent: AtpAgent
|
|
50
36
|
let pdsAgent: AtpAgent
|
|
51
37
|
let sc: SeedClient
|
|
38
|
+
let modClient: ModeratorClient
|
|
52
39
|
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
// Set default type to spam
|
|
58
|
-
reasonType: REASONSPAM,
|
|
59
|
-
...rest,
|
|
60
|
-
subject:
|
|
61
|
-
'account' in params
|
|
62
|
-
? {
|
|
63
|
-
$type: 'com.atproto.admin.defs#repoRef',
|
|
64
|
-
did: params.account,
|
|
65
|
-
}
|
|
66
|
-
: {
|
|
67
|
-
$type: 'com.atproto.repo.strongRef',
|
|
68
|
-
uri: params.content.uri,
|
|
69
|
-
cid: params.content.cid,
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
headers: await network.serviceHeaders(
|
|
74
|
-
author,
|
|
75
|
-
network.ozone.ctx.cfg.service.did,
|
|
76
|
-
),
|
|
77
|
-
encoding: 'application/json',
|
|
78
|
-
},
|
|
79
|
-
)
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const performTakedown = async ({
|
|
83
|
-
durationInHours,
|
|
84
|
-
...rest
|
|
85
|
-
}: TakedownParams & Pick<ModEventTakedown, 'durationInHours'>) =>
|
|
86
|
-
agent.api.com.atproto.admin.emitModerationEvent(
|
|
87
|
-
{
|
|
88
|
-
event: {
|
|
89
|
-
$type: 'com.atproto.admin.defs#modEventTakedown',
|
|
90
|
-
durationInHours,
|
|
91
|
-
},
|
|
92
|
-
subject:
|
|
93
|
-
'account' in rest
|
|
94
|
-
? {
|
|
95
|
-
$type: 'com.atproto.admin.defs#repoRef',
|
|
96
|
-
did: rest.account,
|
|
97
|
-
}
|
|
98
|
-
: {
|
|
99
|
-
$type: 'com.atproto.repo.strongRef',
|
|
100
|
-
uri: rest.content.uri,
|
|
101
|
-
cid: rest.content.cid,
|
|
102
|
-
},
|
|
103
|
-
createdBy: 'did:example:admin',
|
|
104
|
-
...rest,
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
encoding: 'application/json',
|
|
108
|
-
headers: ozone.adminAuthHeaders(),
|
|
109
|
-
},
|
|
110
|
-
)
|
|
111
|
-
|
|
112
|
-
const performReverseTakedown = async (params: TakedownParams) =>
|
|
113
|
-
agent.api.com.atproto.admin.emitModerationEvent(
|
|
114
|
-
{
|
|
115
|
-
event: {
|
|
116
|
-
$type: 'com.atproto.admin.defs#modEventReverseTakedown',
|
|
117
|
-
},
|
|
118
|
-
subject:
|
|
119
|
-
'account' in params
|
|
120
|
-
? {
|
|
121
|
-
$type: 'com.atproto.admin.defs#repoRef',
|
|
122
|
-
did: params.account,
|
|
123
|
-
}
|
|
124
|
-
: {
|
|
125
|
-
$type: 'com.atproto.repo.strongRef',
|
|
126
|
-
uri: params.content.uri,
|
|
127
|
-
cid: params.content.cid,
|
|
128
|
-
},
|
|
129
|
-
createdBy: 'did:example:admin',
|
|
130
|
-
...params,
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
encoding: 'application/json',
|
|
134
|
-
headers: ozone.adminAuthHeaders(),
|
|
135
|
-
},
|
|
136
|
-
)
|
|
137
|
-
|
|
138
|
-
const getStatuses = async (
|
|
139
|
-
params: ComAtprotoAdminQueryModerationStatuses.QueryParams,
|
|
140
|
-
) => {
|
|
141
|
-
const { data } = await agent.api.com.atproto.admin.queryModerationStatuses(
|
|
142
|
-
params,
|
|
143
|
-
{ headers: ozone.adminAuthHeaders() },
|
|
144
|
-
)
|
|
40
|
+
const repoSubject = (did: string) => ({
|
|
41
|
+
$type: 'com.atproto.admin.defs#repoRef',
|
|
42
|
+
did,
|
|
43
|
+
})
|
|
145
44
|
|
|
146
|
-
|
|
147
|
-
|
|
45
|
+
const recordSubject = (ref: RecordRef) => ({
|
|
46
|
+
$type: 'com.atproto.repo.strongRef',
|
|
47
|
+
uri: ref.uriStr,
|
|
48
|
+
cid: ref.cidStr,
|
|
49
|
+
})
|
|
148
50
|
|
|
149
51
|
const getLabel = async (uri: string, val: string, neg = false) => {
|
|
150
52
|
return ozone.ctx.db.db
|
|
@@ -170,6 +72,7 @@ describe('moderation', () => {
|
|
|
170
72
|
bskyAgent = network.bsky.getClient()
|
|
171
73
|
pdsAgent = network.pds.getClient()
|
|
172
74
|
sc = network.getSeedClient()
|
|
75
|
+
modClient = network.ozone.getModClient()
|
|
173
76
|
await basicSeed(sc)
|
|
174
77
|
await network.processAll()
|
|
175
78
|
})
|
|
@@ -180,25 +83,25 @@ describe('moderation', () => {
|
|
|
180
83
|
|
|
181
84
|
describe('reporting', () => {
|
|
182
85
|
it('creates reports of a repo.', async () => {
|
|
183
|
-
const
|
|
86
|
+
const reportA = await sc.createReport({
|
|
184
87
|
reasonType: REASONSPAM,
|
|
185
|
-
|
|
186
|
-
|
|
88
|
+
subject: repoSubject(sc.dids.bob),
|
|
89
|
+
reportedBy: sc.dids.alice,
|
|
187
90
|
})
|
|
188
|
-
const
|
|
91
|
+
const reportB = await sc.createReport({
|
|
189
92
|
reasonType: REASONOTHER,
|
|
190
93
|
reason: 'impersonation',
|
|
191
|
-
|
|
192
|
-
|
|
94
|
+
subject: repoSubject(sc.dids.bob),
|
|
95
|
+
reportedBy: sc.dids.carol,
|
|
193
96
|
})
|
|
194
97
|
expect(forSnapshot([reportA, reportB])).toMatchSnapshot()
|
|
195
98
|
})
|
|
196
99
|
|
|
197
100
|
it("allows reporting a repo that doesn't exist.", async () => {
|
|
198
|
-
const promise = createReport({
|
|
101
|
+
const promise = sc.createReport({
|
|
199
102
|
reasonType: REASONSPAM,
|
|
200
|
-
|
|
201
|
-
|
|
103
|
+
subject: repoSubject('did:plc:unknown'),
|
|
104
|
+
reportedBy: sc.dids.alice,
|
|
202
105
|
})
|
|
203
106
|
await expect(promise).resolves.toBeDefined()
|
|
204
107
|
})
|
|
@@ -206,24 +109,16 @@ describe('moderation', () => {
|
|
|
206
109
|
it('creates reports of a record.', async () => {
|
|
207
110
|
const postA = sc.posts[sc.dids.bob][0].ref
|
|
208
111
|
const postB = sc.posts[sc.dids.bob][1].ref
|
|
209
|
-
const
|
|
210
|
-
|
|
112
|
+
const reportA = await sc.createReport({
|
|
113
|
+
reportedBy: sc.dids.alice,
|
|
211
114
|
reasonType: REASONSPAM,
|
|
212
|
-
|
|
213
|
-
$type: 'com.atproto.repo.strongRef',
|
|
214
|
-
uri: postA.uriStr,
|
|
215
|
-
cid: postA.cidStr,
|
|
216
|
-
},
|
|
115
|
+
subject: recordSubject(postA),
|
|
217
116
|
})
|
|
218
|
-
const
|
|
117
|
+
const reportB = await sc.createReport({
|
|
219
118
|
reasonType: REASONOTHER,
|
|
220
119
|
reason: 'defamation',
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
uri: postB.uriStr,
|
|
224
|
-
cid: postB.cidStr,
|
|
225
|
-
},
|
|
226
|
-
author: sc.dids.carol,
|
|
120
|
+
subject: recordSubject(postB),
|
|
121
|
+
reportedBy: sc.dids.carol,
|
|
227
122
|
})
|
|
228
123
|
expect(forSnapshot([reportA, reportB])).toMatchSnapshot()
|
|
229
124
|
})
|
|
@@ -234,26 +129,26 @@ describe('moderation', () => {
|
|
|
234
129
|
const postUriBad = new AtUri(postA.uriStr)
|
|
235
130
|
postUriBad.rkey = 'badrkey'
|
|
236
131
|
|
|
237
|
-
const promiseA = createReport({
|
|
132
|
+
const promiseA = sc.createReport({
|
|
238
133
|
reasonType: REASONSPAM,
|
|
239
|
-
|
|
134
|
+
subject: {
|
|
240
135
|
$type: 'com.atproto.repo.strongRef',
|
|
241
136
|
uri: postUriBad.toString(),
|
|
242
137
|
cid: postA.cidStr,
|
|
243
138
|
},
|
|
244
|
-
|
|
139
|
+
reportedBy: sc.dids.alice,
|
|
245
140
|
})
|
|
246
141
|
await expect(promiseA).resolves.toBeDefined()
|
|
247
142
|
|
|
248
|
-
const promiseB = createReport({
|
|
143
|
+
const promiseB = sc.createReport({
|
|
249
144
|
reasonType: REASONOTHER,
|
|
250
145
|
reason: 'defamation',
|
|
251
|
-
|
|
146
|
+
subject: {
|
|
252
147
|
$type: 'com.atproto.repo.strongRef',
|
|
253
148
|
uri: postB.uri.toString(),
|
|
254
149
|
cid: postA.cidStr, // bad cid
|
|
255
150
|
},
|
|
256
|
-
|
|
151
|
+
reportedBy: sc.dids.carol,
|
|
257
152
|
})
|
|
258
153
|
await expect(promiseB).resolves.toBeDefined()
|
|
259
154
|
})
|
|
@@ -264,29 +159,27 @@ describe('moderation', () => {
|
|
|
264
159
|
const post = sc.posts[sc.dids.bob][1].ref
|
|
265
160
|
|
|
266
161
|
await Promise.all([
|
|
267
|
-
createReport({
|
|
162
|
+
sc.createReport({
|
|
268
163
|
reasonType: REASONSPAM,
|
|
269
|
-
|
|
270
|
-
|
|
164
|
+
subject: repoSubject(sc.dids.bob),
|
|
165
|
+
reportedBy: sc.dids.alice,
|
|
271
166
|
}),
|
|
272
|
-
createReport({
|
|
167
|
+
sc.createReport({
|
|
273
168
|
reasonType: REASONOTHER,
|
|
274
169
|
reason: 'defamation',
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
cid: post.cid.toString(),
|
|
278
|
-
},
|
|
279
|
-
author: sc.dids.carol,
|
|
170
|
+
subject: recordSubject(post),
|
|
171
|
+
reportedBy: sc.dids.carol,
|
|
280
172
|
}),
|
|
281
173
|
])
|
|
282
174
|
|
|
283
|
-
await performTakedown({
|
|
284
|
-
|
|
175
|
+
await modClient.performTakedown({
|
|
176
|
+
subject: repoSubject(sc.dids.bob),
|
|
285
177
|
})
|
|
286
178
|
|
|
287
|
-
const moderationStatusOnBobsAccount =
|
|
288
|
-
|
|
289
|
-
|
|
179
|
+
const moderationStatusOnBobsAccount =
|
|
180
|
+
await modClient.queryModerationStatuses({
|
|
181
|
+
subject: sc.dids.bob,
|
|
182
|
+
})
|
|
290
183
|
|
|
291
184
|
// Validate that subject status is set to review closed and takendown flag is on
|
|
292
185
|
expect(moderationStatusOnBobsAccount.subjectStatuses[0]).toMatchObject({
|
|
@@ -299,8 +192,8 @@ describe('moderation', () => {
|
|
|
299
192
|
})
|
|
300
193
|
|
|
301
194
|
// Cleanup
|
|
302
|
-
await performReverseTakedown({
|
|
303
|
-
|
|
195
|
+
await modClient.performReverseTakedown({
|
|
196
|
+
subject: repoSubject(sc.dids.bob),
|
|
304
197
|
})
|
|
305
198
|
})
|
|
306
199
|
|
|
@@ -311,7 +204,7 @@ describe('moderation', () => {
|
|
|
311
204
|
uri: alicesPostRef.uri.toString(),
|
|
312
205
|
cid: alicesPostRef.cid.toString(),
|
|
313
206
|
}
|
|
314
|
-
await
|
|
207
|
+
await modClient.emitModerationEvent(
|
|
315
208
|
{
|
|
316
209
|
event: {
|
|
317
210
|
$type: 'com.atproto.admin.defs#modEventEscalate',
|
|
@@ -320,13 +213,10 @@ describe('moderation', () => {
|
|
|
320
213
|
subject: alicesPostSubject,
|
|
321
214
|
createdBy: 'did:example:admin',
|
|
322
215
|
},
|
|
323
|
-
|
|
324
|
-
encoding: 'application/json',
|
|
325
|
-
headers: ozone.adminAuthHeaders('triage'),
|
|
326
|
-
},
|
|
216
|
+
'triage',
|
|
327
217
|
)
|
|
328
218
|
|
|
329
|
-
const alicesPostStatus = await
|
|
219
|
+
const alicesPostStatus = await modClient.queryModerationStatuses({
|
|
330
220
|
subject: alicesPostRef.uri.toString(),
|
|
331
221
|
})
|
|
332
222
|
|
|
@@ -344,7 +234,7 @@ describe('moderation', () => {
|
|
|
344
234
|
uri: alicesPostRef.uri.toString(),
|
|
345
235
|
cid: alicesPostRef.cid.toString(),
|
|
346
236
|
}
|
|
347
|
-
await
|
|
237
|
+
await modClient.emitModerationEvent(
|
|
348
238
|
{
|
|
349
239
|
event: {
|
|
350
240
|
$type: 'com.atproto.admin.defs#modEventComment',
|
|
@@ -354,13 +244,10 @@ describe('moderation', () => {
|
|
|
354
244
|
subject: alicesPostSubject,
|
|
355
245
|
createdBy: 'did:example:admin',
|
|
356
246
|
},
|
|
357
|
-
|
|
358
|
-
encoding: 'application/json',
|
|
359
|
-
headers: ozone.adminAuthHeaders('triage'),
|
|
360
|
-
},
|
|
247
|
+
'triage',
|
|
361
248
|
)
|
|
362
249
|
|
|
363
|
-
const alicesPostStatus = await
|
|
250
|
+
const alicesPostStatus = await modClient.queryModerationStatuses({
|
|
364
251
|
subject: alicesPostRef.uri.toString(),
|
|
365
252
|
})
|
|
366
253
|
|
|
@@ -383,17 +270,11 @@ describe('moderation', () => {
|
|
|
383
270
|
},
|
|
384
271
|
createdBy: 'did:example:admin',
|
|
385
272
|
}
|
|
386
|
-
return
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
},
|
|
392
|
-
{
|
|
393
|
-
encoding: 'application/json',
|
|
394
|
-
headers: ozone.adminAuthHeaders(),
|
|
395
|
-
},
|
|
396
|
-
)
|
|
273
|
+
return modClient.emitModerationEvent({
|
|
274
|
+
event,
|
|
275
|
+
...baseAction,
|
|
276
|
+
...overwrites,
|
|
277
|
+
})
|
|
397
278
|
}
|
|
398
279
|
// Validate that subject status is marked as escalated
|
|
399
280
|
await emitModEvent({
|
|
@@ -407,9 +288,10 @@ describe('moderation', () => {
|
|
|
407
288
|
await emitModEvent({
|
|
408
289
|
$type: 'com.atproto.admin.defs#modEventEscalate',
|
|
409
290
|
})
|
|
410
|
-
const alicesPostStatusAfterEscalation =
|
|
411
|
-
|
|
412
|
-
|
|
291
|
+
const alicesPostStatusAfterEscalation =
|
|
292
|
+
await modClient.queryModerationStatuses({
|
|
293
|
+
subject: alicesPostRef.uriStr,
|
|
294
|
+
})
|
|
413
295
|
expect(
|
|
414
296
|
alicesPostStatusAfterEscalation.subjectStatuses[0].reviewState,
|
|
415
297
|
).toEqual(REVIEWESCALATED)
|
|
@@ -425,9 +307,10 @@ describe('moderation', () => {
|
|
|
425
307
|
$type: 'com.atproto.admin.defs#modEventTakedown',
|
|
426
308
|
})
|
|
427
309
|
|
|
428
|
-
const alicesPostStatusAfterTakedown =
|
|
429
|
-
|
|
430
|
-
|
|
310
|
+
const alicesPostStatusAfterTakedown =
|
|
311
|
+
await modClient.queryModerationStatuses({
|
|
312
|
+
subject: alicesPostRef.uriStr,
|
|
313
|
+
})
|
|
431
314
|
expect(alicesPostStatusAfterTakedown.subjectStatuses[0]).toMatchObject({
|
|
432
315
|
reviewState: REVIEWCLOSED,
|
|
433
316
|
takendown: true,
|
|
@@ -436,9 +319,10 @@ describe('moderation', () => {
|
|
|
436
319
|
await emitModEvent({
|
|
437
320
|
$type: 'com.atproto.admin.defs#modEventReverseTakedown',
|
|
438
321
|
})
|
|
439
|
-
const alicesPostStatusAfterRevert =
|
|
440
|
-
|
|
441
|
-
|
|
322
|
+
const alicesPostStatusAfterRevert =
|
|
323
|
+
await modClient.queryModerationStatuses({
|
|
324
|
+
subject: alicesPostRef.uriStr,
|
|
325
|
+
})
|
|
442
326
|
// Validate that after reverting, the status of the subject is reverted to the last status changing event
|
|
443
327
|
expect(alicesPostStatusAfterRevert.subjectStatuses[0]).toMatchObject({
|
|
444
328
|
reviewState: REVIEWCLOSED,
|
|
@@ -598,7 +482,7 @@ describe('moderation', () => {
|
|
|
598
482
|
})
|
|
599
483
|
|
|
600
484
|
it('does not allow triage moderators to label.', async () => {
|
|
601
|
-
const attemptLabel =
|
|
485
|
+
const attemptLabel = modClient.emitModerationEvent(
|
|
602
486
|
{
|
|
603
487
|
event: {
|
|
604
488
|
$type: 'com.atproto.admin.defs#modEventLabel',
|
|
@@ -612,10 +496,7 @@ describe('moderation', () => {
|
|
|
612
496
|
did: sc.dids.bob,
|
|
613
497
|
},
|
|
614
498
|
},
|
|
615
|
-
|
|
616
|
-
encoding: 'application/json',
|
|
617
|
-
headers: network.ozone.adminAuthHeaders('triage'),
|
|
618
|
-
},
|
|
499
|
+
'triage',
|
|
619
500
|
)
|
|
620
501
|
await expect(attemptLabel).rejects.toThrow(
|
|
621
502
|
'Must be a full moderator to label content',
|
|
@@ -623,29 +504,29 @@ describe('moderation', () => {
|
|
|
623
504
|
})
|
|
624
505
|
|
|
625
506
|
it('does not allow take down event on takendown post or reverse takedown on available post.', async () => {
|
|
626
|
-
await performTakedown({
|
|
627
|
-
|
|
507
|
+
await modClient.performTakedown({
|
|
508
|
+
subject: repoSubject(sc.dids.bob),
|
|
628
509
|
})
|
|
629
510
|
await expect(
|
|
630
|
-
performTakedown({
|
|
631
|
-
|
|
511
|
+
modClient.performTakedown({
|
|
512
|
+
subject: repoSubject(sc.dids.bob),
|
|
632
513
|
}),
|
|
633
514
|
).rejects.toThrow('Subject is already taken down')
|
|
634
515
|
|
|
635
516
|
// Cleanup
|
|
636
|
-
await performReverseTakedown({
|
|
637
|
-
|
|
517
|
+
await modClient.performReverseTakedown({
|
|
518
|
+
subject: repoSubject(sc.dids.bob),
|
|
638
519
|
})
|
|
639
520
|
await expect(
|
|
640
|
-
performReverseTakedown({
|
|
641
|
-
|
|
521
|
+
modClient.performReverseTakedown({
|
|
522
|
+
subject: repoSubject(sc.dids.bob),
|
|
642
523
|
}),
|
|
643
524
|
).rejects.toThrow('Subject is not taken down')
|
|
644
525
|
})
|
|
645
526
|
|
|
646
527
|
it('fans out repo takedowns', async () => {
|
|
647
|
-
await performTakedown({
|
|
648
|
-
|
|
528
|
+
await modClient.performTakedown({
|
|
529
|
+
subject: repoSubject(sc.dids.bob),
|
|
649
530
|
})
|
|
650
531
|
await ozone.processAll()
|
|
651
532
|
|
|
@@ -672,7 +553,9 @@ describe('moderation', () => {
|
|
|
672
553
|
expect(takedownLabel1).toBeDefined()
|
|
673
554
|
|
|
674
555
|
// cleanup
|
|
675
|
-
await performReverseTakedown({
|
|
556
|
+
await modClient.performReverseTakedown({
|
|
557
|
+
subject: repoSubject(sc.dids.bob),
|
|
558
|
+
})
|
|
676
559
|
await ozone.processAll()
|
|
677
560
|
|
|
678
561
|
const pdsRes2 = await pdsAgent.api.com.atproto.admin.getSubjectStatus(
|
|
@@ -699,11 +582,10 @@ describe('moderation', () => {
|
|
|
699
582
|
})
|
|
700
583
|
|
|
701
584
|
it('fans out record takedowns', async () => {
|
|
702
|
-
const post = sc.posts[sc.dids.bob][0]
|
|
703
|
-
const uri = post.
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
content: { uri, cid },
|
|
585
|
+
const post = sc.posts[sc.dids.bob][0].ref
|
|
586
|
+
const uri = post.uriStr
|
|
587
|
+
await modClient.performTakedown({
|
|
588
|
+
subject: recordSubject(post),
|
|
707
589
|
})
|
|
708
590
|
await ozone.processAll()
|
|
709
591
|
|
|
@@ -723,7 +605,7 @@ describe('moderation', () => {
|
|
|
723
605
|
expect(takedownLabel1).toBeDefined()
|
|
724
606
|
|
|
725
607
|
// cleanup
|
|
726
|
-
await performReverseTakedown({
|
|
608
|
+
await modClient.performReverseTakedown({ subject: recordSubject(post) })
|
|
727
609
|
await ozone.processAll()
|
|
728
610
|
|
|
729
611
|
const pdsRes2 = await pdsAgent.api.com.atproto.admin.getSubjectStatus(
|
|
@@ -742,7 +624,7 @@ describe('moderation', () => {
|
|
|
742
624
|
})
|
|
743
625
|
|
|
744
626
|
it('allows full moderators to takedown.', async () => {
|
|
745
|
-
await
|
|
627
|
+
await modClient.emitModerationEvent(
|
|
746
628
|
{
|
|
747
629
|
event: {
|
|
748
630
|
$type: 'com.atproto.admin.defs#modEventTakedown',
|
|
@@ -753,10 +635,7 @@ describe('moderation', () => {
|
|
|
753
635
|
did: sc.dids.bob,
|
|
754
636
|
},
|
|
755
637
|
},
|
|
756
|
-
|
|
757
|
-
encoding: 'application/json',
|
|
758
|
-
headers: network.ozone.adminAuthHeaders('moderator'),
|
|
759
|
-
},
|
|
638
|
+
'moderator',
|
|
760
639
|
)
|
|
761
640
|
// cleanup
|
|
762
641
|
await reverse({
|
|
@@ -768,47 +647,42 @@ describe('moderation', () => {
|
|
|
768
647
|
})
|
|
769
648
|
|
|
770
649
|
it('does not allow non-full moderators to takedown.', async () => {
|
|
771
|
-
const attemptTakedownTriage =
|
|
772
|
-
|
|
773
|
-
{
|
|
774
|
-
|
|
775
|
-
$type: 'com.atproto.admin.defs#modEventTakedown',
|
|
776
|
-
},
|
|
777
|
-
createdBy: 'did:example:moderator',
|
|
778
|
-
subject: {
|
|
779
|
-
$type: 'com.atproto.admin.defs#repoRef',
|
|
780
|
-
did: sc.dids.bob,
|
|
781
|
-
},
|
|
650
|
+
const attemptTakedownTriage = modClient.emitModerationEvent(
|
|
651
|
+
{
|
|
652
|
+
event: {
|
|
653
|
+
$type: 'com.atproto.admin.defs#modEventTakedown',
|
|
782
654
|
},
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
655
|
+
createdBy: 'did:example:moderator',
|
|
656
|
+
subject: {
|
|
657
|
+
$type: 'com.atproto.admin.defs#repoRef',
|
|
658
|
+
did: sc.dids.bob,
|
|
786
659
|
},
|
|
787
|
-
|
|
660
|
+
},
|
|
661
|
+
'triage',
|
|
662
|
+
)
|
|
788
663
|
await expect(attemptTakedownTriage).rejects.toThrow(
|
|
789
664
|
'Must be a full moderator to take this type of action',
|
|
790
665
|
)
|
|
791
666
|
})
|
|
792
667
|
|
|
793
668
|
it('automatically reverses actions marked with duration', async () => {
|
|
794
|
-
await createReport({
|
|
669
|
+
await sc.createReport({
|
|
795
670
|
reasonType: REASONSPAM,
|
|
796
|
-
|
|
797
|
-
|
|
671
|
+
subject: repoSubject(sc.dids.bob),
|
|
672
|
+
reportedBy: sc.dids.alice,
|
|
798
673
|
})
|
|
799
|
-
const
|
|
800
|
-
|
|
674
|
+
const action = await modClient.performTakedown({
|
|
675
|
+
subject: repoSubject(sc.dids.bob),
|
|
801
676
|
// Use negative value to set the expiry time in the past so that the action is automatically reversed
|
|
802
677
|
// right away without having to wait n number of hours for a successful assertion
|
|
803
678
|
durationInHours: -1,
|
|
804
679
|
})
|
|
805
680
|
await ozone.processAll()
|
|
806
681
|
|
|
807
|
-
const
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
)
|
|
682
|
+
const statusesAfterTakedown = await modClient.queryModerationStatuses(
|
|
683
|
+
{ subject: sc.dids.bob },
|
|
684
|
+
'moderator',
|
|
685
|
+
)
|
|
812
686
|
|
|
813
687
|
expect(statusesAfterTakedown.subjectStatuses[0]).toMatchObject({
|
|
814
688
|
takendown: true,
|
|
@@ -822,14 +696,11 @@ describe('moderation', () => {
|
|
|
822
696
|
await reverser.findAndRevertDueActions()
|
|
823
697
|
await ozone.processAll()
|
|
824
698
|
|
|
825
|
-
const [
|
|
826
|
-
|
|
699
|
+
const [eventList, statuses] = await Promise.all([
|
|
700
|
+
modClient.queryModerationEvents({ subject: sc.dids.bob }, 'moderator'),
|
|
701
|
+
modClient.queryModerationStatuses(
|
|
827
702
|
{ subject: sc.dids.bob },
|
|
828
|
-
|
|
829
|
-
),
|
|
830
|
-
agent.api.com.atproto.admin.queryModerationStatuses(
|
|
831
|
-
{ subject: sc.dids.bob },
|
|
832
|
-
{ headers: network.ozone.adminAuthHeaders('moderator') },
|
|
703
|
+
'moderator',
|
|
833
704
|
),
|
|
834
705
|
])
|
|
835
706
|
|
|
@@ -873,22 +744,16 @@ describe('moderation', () => {
|
|
|
873
744
|
},
|
|
874
745
|
) {
|
|
875
746
|
const { createLabelVals, negateLabelVals } = opts
|
|
876
|
-
const result = await
|
|
877
|
-
{
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
negateLabelVals,
|
|
882
|
-
},
|
|
883
|
-
createdBy: 'did:example:admin',
|
|
884
|
-
reason: 'Y',
|
|
885
|
-
...opts,
|
|
886
|
-
},
|
|
887
|
-
{
|
|
888
|
-
encoding: 'application/json',
|
|
889
|
-
headers: network.ozone.adminAuthHeaders(),
|
|
747
|
+
const result = await modClient.emitModerationEvent({
|
|
748
|
+
event: {
|
|
749
|
+
$type: 'com.atproto.admin.defs#modEventLabel',
|
|
750
|
+
createLabelVals,
|
|
751
|
+
negateLabelVals,
|
|
890
752
|
},
|
|
891
|
-
|
|
753
|
+
createdBy: 'did:example:admin',
|
|
754
|
+
reason: 'Y',
|
|
755
|
+
...opts,
|
|
756
|
+
})
|
|
892
757
|
return result.data
|
|
893
758
|
}
|
|
894
759
|
|
|
@@ -897,26 +762,20 @@ describe('moderation', () => {
|
|
|
897
762
|
subject: ComAtprotoAdminEmitModerationEvent.InputSchema['subject']
|
|
898
763
|
},
|
|
899
764
|
) {
|
|
900
|
-
await
|
|
901
|
-
{
|
|
902
|
-
|
|
903
|
-
$type: 'com.atproto.admin.defs#modEventReverseTakedown',
|
|
904
|
-
},
|
|
905
|
-
createdBy: 'did:example:admin',
|
|
906
|
-
reason: 'Y',
|
|
907
|
-
...opts,
|
|
908
|
-
},
|
|
909
|
-
{
|
|
910
|
-
encoding: 'application/json',
|
|
911
|
-
headers: network.ozone.adminAuthHeaders(),
|
|
765
|
+
await modClient.emitModerationEvent({
|
|
766
|
+
event: {
|
|
767
|
+
$type: 'com.atproto.admin.defs#modEventReverseTakedown',
|
|
912
768
|
},
|
|
913
|
-
|
|
769
|
+
createdBy: 'did:example:admin',
|
|
770
|
+
reason: 'Y',
|
|
771
|
+
...opts,
|
|
772
|
+
})
|
|
914
773
|
}
|
|
915
774
|
|
|
916
775
|
async function getRecordLabels(uri: string) {
|
|
917
776
|
const result = await agent.api.com.atproto.admin.getRecord(
|
|
918
777
|
{ uri },
|
|
919
|
-
{ headers: network.ozone.
|
|
778
|
+
{ headers: await network.ozone.modHeaders() },
|
|
920
779
|
)
|
|
921
780
|
const labels = result.data.labels ?? []
|
|
922
781
|
return labels.map((l) => l.val)
|
|
@@ -925,7 +784,7 @@ describe('moderation', () => {
|
|
|
925
784
|
async function getRepoLabels(did: string) {
|
|
926
785
|
const result = await agent.api.com.atproto.admin.getRepo(
|
|
927
786
|
{ did },
|
|
928
|
-
{ headers: network.ozone.
|
|
787
|
+
{ headers: await network.ozone.modHeaders() },
|
|
929
788
|
)
|
|
930
789
|
const labels = result.data.labels ?? []
|
|
931
790
|
return labels.map((l) => l.val)
|
|
@@ -951,18 +810,15 @@ describe('moderation', () => {
|
|
|
951
810
|
await fetch(imageUri)
|
|
952
811
|
const cached = await fetch(imageUri)
|
|
953
812
|
expect(cached.headers.get('x-cache')).toEqual('hit')
|
|
954
|
-
await performTakedown({
|
|
955
|
-
|
|
956
|
-
uri: post.ref.uriStr,
|
|
957
|
-
cid: post.ref.cidStr,
|
|
958
|
-
},
|
|
813
|
+
await modClient.performTakedown({
|
|
814
|
+
subject: recordSubject(post.ref),
|
|
959
815
|
subjectBlobCids: [blob.image.ref.toString()],
|
|
960
816
|
})
|
|
961
817
|
await ozone.processAll()
|
|
962
818
|
})
|
|
963
819
|
|
|
964
820
|
it('sets blobCids in moderation status', async () => {
|
|
965
|
-
const { subjectStatuses } = await
|
|
821
|
+
const { subjectStatuses } = await modClient.queryModerationStatuses({
|
|
966
822
|
subject: post.ref.uriStr,
|
|
967
823
|
})
|
|
968
824
|
|
|
@@ -1020,11 +876,8 @@ describe('moderation', () => {
|
|
|
1020
876
|
})
|
|
1021
877
|
|
|
1022
878
|
it('restores blob when action is reversed.', async () => {
|
|
1023
|
-
await performReverseTakedown({
|
|
1024
|
-
|
|
1025
|
-
uri: post.ref.uriStr,
|
|
1026
|
-
cid: post.ref.cidStr,
|
|
1027
|
-
},
|
|
879
|
+
await modClient.performReverseTakedown({
|
|
880
|
+
subject: recordSubject(post.ref),
|
|
1028
881
|
subjectBlobCids: [blob.image.ref.toString()],
|
|
1029
882
|
})
|
|
1030
883
|
|