@atproto/ozone 0.0.16 → 0.0.17-next.1

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.
Files changed (157) hide show
  1. package/dist/api/util.d.ts +10 -0
  2. package/dist/auth-verifier.d.ts +8 -12
  3. package/dist/communication-service/template.d.ts +2 -2
  4. package/dist/config/config.d.ts +6 -0
  5. package/dist/config/env.d.ts +3 -2
  6. package/dist/config/secrets.d.ts +0 -2
  7. package/dist/context.d.ts +6 -0
  8. package/dist/daemon/blob-diverter.d.ts +26 -0
  9. package/dist/daemon/event-pusher.d.ts +6 -0
  10. package/dist/daemon/index.d.ts +1 -0
  11. package/dist/db/index.js +21 -1
  12. package/dist/db/index.js.map +3 -3
  13. package/dist/db/migrations/20240228T003647759Z-add-label-sigs.d.ts +3 -0
  14. package/dist/db/migrations/index.d.ts +1 -0
  15. package/dist/db/schema/index.d.ts +2 -1
  16. package/dist/db/schema/label.d.ts +4 -0
  17. package/dist/db/schema/moderation_event.d.ts +1 -1
  18. package/dist/db/schema/moderation_subject_status.d.ts +2 -2
  19. package/dist/db/schema/signing_key.d.ts +9 -0
  20. package/dist/index.js +10400 -10313
  21. package/dist/index.js.map +3 -3
  22. package/dist/lexicon/index.d.ts +55 -27
  23. package/dist/lexicon/lexicons.d.ts +5046 -4757
  24. package/dist/lexicon/types/app/bsky/actor/defs.d.ts +23 -1
  25. package/dist/lexicon/types/app/bsky/embed/record.d.ts +2 -1
  26. package/dist/lexicon/types/app/bsky/feed/defs.d.ts +1 -0
  27. package/dist/lexicon/types/app/bsky/graph/defs.d.ts +3 -0
  28. package/dist/lexicon/types/app/bsky/labeler/defs.d.ts +41 -0
  29. package/dist/lexicon/types/app/bsky/labeler/getServices.d.ts +36 -0
  30. package/dist/lexicon/types/app/bsky/labeler/service.d.ts +14 -0
  31. package/dist/lexicon/types/com/atproto/admin/defs.d.ts +0 -304
  32. package/dist/lexicon/types/com/atproto/label/defs.d.ts +23 -0
  33. package/dist/lexicon/types/{com/atproto/admin/createCommunicationTemplate.d.ts → tools/ozone/communication/createTemplate.d.ts} +2 -2
  34. package/dist/lexicon/types/tools/ozone/communication/defs.d.ts +14 -0
  35. package/dist/lexicon/types/{com/atproto/admin/listCommunicationTemplates.d.ts → tools/ozone/communication/listTemplates.d.ts} +2 -2
  36. package/dist/lexicon/types/{com/atproto/admin/updateCommunicationTemplate.d.ts → tools/ozone/communication/updateTemplate.d.ts} +2 -2
  37. package/dist/lexicon/types/tools/ozone/moderation/defs.d.ts +269 -0
  38. package/dist/lexicon/types/{com/atproto/admin/emitModerationEvent.d.ts → tools/ozone/moderation/emitEvent.d.ts} +5 -4
  39. package/dist/lexicon/types/{com/atproto/admin/getModerationEvent.d.ts → tools/ozone/moderation/getEvent.d.ts} +2 -2
  40. package/dist/lexicon/types/{com/atproto/admin → tools/ozone/moderation}/getRecord.d.ts +2 -2
  41. package/dist/lexicon/types/{com/atproto/admin → tools/ozone/moderation}/getRepo.d.ts +2 -2
  42. package/dist/lexicon/types/{com/atproto/admin/queryModerationEvents.d.ts → tools/ozone/moderation/queryEvents.d.ts} +2 -2
  43. package/dist/lexicon/types/{com/atproto/admin/queryModerationStatuses.d.ts → tools/ozone/moderation/queryStatuses.d.ts} +2 -2
  44. package/dist/lexicon/types/{com/atproto/admin → tools/ozone/moderation}/searchRepos.d.ts +2 -2
  45. package/dist/mod-service/index.d.ts +16 -15
  46. package/dist/mod-service/subject.d.ts +1 -1
  47. package/dist/mod-service/types.d.ts +2 -2
  48. package/dist/mod-service/util.d.ts +6 -0
  49. package/dist/mod-service/views.d.ts +9 -3
  50. package/dist/sequencer/sequencer.d.ts +6 -4
  51. package/dist/util.d.ts +2 -0
  52. package/package.json +9 -8
  53. package/src/api/{admin/createCommunicationTemplate.ts → communication/createTemplate.ts} +2 -2
  54. package/src/api/{admin/deleteCommunicationTemplate.ts → communication/deleteTemplate.ts} +2 -2
  55. package/src/api/{admin/listCommunicationTemplates.ts → communication/listTemplates.ts} +2 -2
  56. package/src/api/{admin/updateCommunicationTemplate.ts → communication/updateTemplate.ts} +2 -2
  57. package/src/api/index.ts +21 -21
  58. package/src/api/{temp → label}/fetchLabels.ts +5 -3
  59. package/src/api/label/queryLabels.ts +4 -2
  60. package/src/api/moderation/emitEvent.ts +218 -0
  61. package/src/api/{admin/getModerationEvent.ts → moderation/getEvent.ts} +2 -2
  62. package/src/api/{admin → moderation}/getRecord.ts +3 -3
  63. package/src/api/{admin → moderation}/getRepo.ts +3 -3
  64. package/src/api/{admin/queryModerationEvents.ts → moderation/queryEvents.ts} +3 -3
  65. package/src/api/{admin/queryModerationStatuses.ts → moderation/queryStatuses.ts} +3 -3
  66. package/src/api/{admin → moderation}/searchRepos.ts +2 -2
  67. package/src/api/proxied.ts +8 -8
  68. package/src/api/{moderation → report}/createReport.ts +2 -3
  69. package/src/api/util.ts +119 -0
  70. package/src/auth-verifier.ts +20 -30
  71. package/src/communication-service/template.ts +2 -2
  72. package/src/config/config.ts +24 -7
  73. package/src/config/env.ts +6 -4
  74. package/src/config/secrets.ts +0 -6
  75. package/src/context.ts +36 -12
  76. package/src/daemon/blob-diverter.ts +150 -0
  77. package/src/daemon/context.ts +11 -7
  78. package/src/daemon/event-pusher.ts +58 -15
  79. package/src/daemon/index.ts +1 -0
  80. package/src/db/migrations/20240228T003647759Z-add-label-sigs.ts +25 -0
  81. package/src/db/migrations/index.ts +1 -0
  82. package/src/db/schema/index.ts +2 -0
  83. package/src/db/schema/label.ts +3 -0
  84. package/src/db/schema/moderation_event.ts +11 -11
  85. package/src/db/schema/moderation_subject_status.ts +7 -2
  86. package/src/db/schema/signing_key.ts +10 -0
  87. package/src/lexicon/index.ts +200 -137
  88. package/src/lexicon/lexicons.ts +6310 -6012
  89. package/src/lexicon/types/app/bsky/actor/defs.ts +57 -1
  90. package/src/lexicon/types/app/bsky/embed/record.ts +2 -0
  91. package/src/lexicon/types/app/bsky/feed/defs.ts +1 -0
  92. package/src/lexicon/types/app/bsky/graph/defs.ts +3 -0
  93. package/src/lexicon/types/app/bsky/labeler/defs.ts +93 -0
  94. package/src/lexicon/types/app/bsky/labeler/getServices.ts +51 -0
  95. package/src/lexicon/types/app/bsky/labeler/service.ts +31 -0
  96. package/src/lexicon/types/com/atproto/admin/defs.ts +0 -694
  97. package/src/lexicon/types/com/atproto/label/defs.ts +78 -0
  98. package/src/lexicon/types/{com/atproto/admin/createCommunicationTemplate.ts → tools/ozone/communication/createTemplate.ts} +2 -2
  99. package/src/lexicon/types/tools/ozone/communication/defs.ts +35 -0
  100. package/src/lexicon/types/{com/atproto/admin/listCommunicationTemplates.ts → tools/ozone/communication/listTemplates.ts} +2 -2
  101. package/src/lexicon/types/{com/atproto/admin/updateCommunicationTemplate.ts → tools/ozone/communication/updateTemplate.ts} +2 -2
  102. package/src/lexicon/types/tools/ozone/moderation/defs.ts +641 -0
  103. package/src/lexicon/types/{com/atproto/admin/emitModerationEvent.ts → tools/ozone/moderation/emitEvent.ts} +15 -14
  104. package/src/lexicon/types/{com/atproto/admin/getModerationEvent.ts → tools/ozone/moderation/getEvent.ts} +2 -2
  105. package/src/lexicon/types/{com/atproto/admin → tools/ozone/moderation}/getRecord.ts +2 -2
  106. package/src/lexicon/types/{com/atproto/admin → tools/ozone/moderation}/getRepo.ts +2 -2
  107. package/src/lexicon/types/{com/atproto/admin/queryModerationEvents.ts → tools/ozone/moderation/queryEvents.ts} +3 -3
  108. package/src/lexicon/types/{com/atproto/admin/queryModerationStatuses.ts → tools/ozone/moderation/queryStatuses.ts} +2 -2
  109. package/src/lexicon/types/{com/atproto/admin → tools/ozone/moderation}/searchRepos.ts +2 -2
  110. package/src/mod-service/index.ts +46 -50
  111. package/src/mod-service/lang.ts +1 -1
  112. package/src/mod-service/status.ts +60 -41
  113. package/src/mod-service/subject.ts +1 -1
  114. package/src/mod-service/types.ts +10 -10
  115. package/src/mod-service/util.ts +49 -5
  116. package/src/mod-service/views.ts +45 -18
  117. package/src/sequencer/sequencer.ts +12 -11
  118. package/src/util.ts +21 -0
  119. package/tests/__snapshots__/blob-divert.test.ts.snap +22 -0
  120. package/tests/__snapshots__/get-record.test.ts.snap +14 -6
  121. package/tests/__snapshots__/get-repo.test.ts.snap +7 -3
  122. package/tests/__snapshots__/moderation-events.test.ts.snap +8 -8
  123. package/tests/__snapshots__/moderation-statuses.test.ts.snap +6 -6
  124. package/tests/_util.ts +5 -0
  125. package/tests/blob-divert.test.ts +87 -0
  126. package/tests/communication-templates.test.ts +33 -37
  127. package/tests/db.test.ts +6 -6
  128. package/tests/get-record.test.ts +22 -12
  129. package/tests/get-repo.test.ts +33 -21
  130. package/tests/moderation-appeals.test.ts +39 -67
  131. package/tests/moderation-events.test.ts +99 -142
  132. package/tests/moderation-status-tags.test.ts +20 -37
  133. package/tests/moderation-statuses.test.ts +132 -65
  134. package/tests/moderation.test.ts +147 -301
  135. package/tests/query-labels.test.ts +86 -10
  136. package/tests/repo-search.test.ts +18 -11
  137. package/tests/sequencer.test.ts +6 -3
  138. package/dist/api/admin/util.d.ts +0 -5
  139. package/dist/api/moderation/util.d.ts +0 -4
  140. package/src/api/admin/emitModerationEvent.ts +0 -170
  141. package/src/api/admin/util.ts +0 -54
  142. package/src/api/moderation/util.ts +0 -67
  143. /package/dist/api/{admin/createCommunicationTemplate.d.ts → communication/createTemplate.d.ts} +0 -0
  144. /package/dist/api/{admin/deleteCommunicationTemplate.d.ts → communication/deleteTemplate.d.ts} +0 -0
  145. /package/dist/api/{admin/emitModerationEvent.d.ts → communication/listTemplates.d.ts} +0 -0
  146. /package/dist/api/{admin/getModerationEvent.d.ts → communication/updateTemplate.d.ts} +0 -0
  147. /package/dist/api/{temp → label}/fetchLabels.d.ts +0 -0
  148. /package/dist/api/{admin/getRecord.d.ts → moderation/emitEvent.d.ts} +0 -0
  149. /package/dist/api/{admin/getRepo.d.ts → moderation/getEvent.d.ts} +0 -0
  150. /package/dist/api/{admin/listCommunicationTemplates.d.ts → moderation/getRecord.d.ts} +0 -0
  151. /package/dist/api/{admin/queryModerationEvents.d.ts → moderation/getRepo.d.ts} +0 -0
  152. /package/dist/api/{admin/queryModerationStatuses.d.ts → moderation/queryEvents.d.ts} +0 -0
  153. /package/dist/api/{admin/searchRepos.d.ts → moderation/queryStatuses.d.ts} +0 -0
  154. /package/dist/api/{admin/updateCommunicationTemplate.d.ts → moderation/searchRepos.d.ts} +0 -0
  155. /package/dist/api/{moderation → report}/createReport.d.ts +0 -0
  156. /package/dist/lexicon/types/{com/atproto/admin/deleteCommunicationTemplate.d.ts → tools/ozone/communication/deleteTemplate.d.ts} +0 -0
  157. /package/src/lexicon/types/{com/atproto/admin/deleteCommunicationTemplate.ts → tools/ozone/communication/deleteTemplate.ts} +0 -0
@@ -1,11 +1,13 @@
1
1
  import assert from 'node:assert'
2
2
  import EventEmitter, { once } from 'node:events'
3
+ import {
4
+ TestNetwork,
5
+ SeedClient,
6
+ basicSeed,
7
+ ModeratorClient,
8
+ } from '@atproto/dev-env'
9
+ import { ToolsOzoneModerationDefs } from '@atproto/api'
3
10
  import Mail from 'nodemailer/lib/mailer'
4
- import { TestNetwork, SeedClient, basicSeed } from '@atproto/dev-env'
5
- import AtpAgent, {
6
- ComAtprotoAdminDefs,
7
- ComAtprotoAdminEmitModerationEvent,
8
- } from '@atproto/api'
9
11
  import { forSnapshot } from './_util'
10
12
  import {
11
13
  REASONAPPEAL,
@@ -15,23 +17,8 @@ import {
15
17
 
16
18
  describe('moderation-events', () => {
17
19
  let network: TestNetwork
18
- let agent: AtpAgent
19
- let pdsAgent: AtpAgent
20
20
  let sc: SeedClient
21
-
22
- const emitModerationEvent = async (
23
- eventData: ComAtprotoAdminEmitModerationEvent.InputSchema,
24
- ) => {
25
- return pdsAgent.api.com.atproto.admin.emitModerationEvent(eventData, {
26
- encoding: 'application/json',
27
- headers: network.ozone.adminAuthHeaders('moderator'),
28
- })
29
- }
30
-
31
- const queryModerationEvents = (eventQuery) =>
32
- agent.api.com.atproto.admin.queryModerationEvents(eventQuery, {
33
- headers: network.ozone.adminAuthHeaders('moderator'),
34
- })
21
+ let modClient: ModeratorClient
35
22
 
36
23
  const seedEvents = async () => {
37
24
  const bobsAccount = {
@@ -54,25 +41,19 @@ describe('moderation-events', () => {
54
41
  }
55
42
 
56
43
  for (let i = 0; i < 4; i++) {
57
- await emitModerationEvent({
58
- event: {
59
- $type: 'com.atproto.admin.defs#modEventReport',
60
- reportType: i % 2 ? REASONSPAM : REASONMISLEADING,
61
- comment: 'X',
62
- },
44
+ await sc.createReport({
45
+ reasonType: i % 2 ? REASONSPAM : REASONMISLEADING,
46
+ reason: 'X',
63
47
  // Report bob's account by alice and vice versa
64
48
  subject: i % 2 ? bobsAccount : alicesAccount,
65
- createdBy: i % 2 ? sc.dids.alice : sc.dids.bob,
49
+ reportedBy: i % 2 ? sc.dids.alice : sc.dids.bob,
66
50
  })
67
- await emitModerationEvent({
68
- event: {
69
- $type: 'com.atproto.admin.defs#modEventReport',
70
- reportType: REASONSPAM,
71
- comment: 'X',
72
- },
51
+ await sc.createReport({
52
+ reasonType: REASONSPAM,
53
+ reason: 'X',
73
54
  // Report bob's post by alice and vice versa
74
55
  subject: i % 2 ? bobsPost : alicesPost,
75
- createdBy: i % 2 ? sc.dids.alice : sc.dids.bob,
56
+ reportedBy: i % 2 ? sc.dids.alice : sc.dids.bob,
76
57
  })
77
58
  }
78
59
  }
@@ -81,9 +62,8 @@ describe('moderation-events', () => {
81
62
  network = await TestNetwork.create({
82
63
  dbPostgresSchema: 'ozone_moderation_events',
83
64
  })
84
- agent = network.ozone.getClient()
85
- pdsAgent = network.pds.getClient()
86
65
  sc = network.getSeedClient()
66
+ modClient = network.ozone.getModClient()
87
67
  await basicSeed(sc)
88
68
  await network.processAll()
89
69
  await seedEvents()
@@ -96,16 +76,16 @@ describe('moderation-events', () => {
96
76
  describe('query events', () => {
97
77
  it('returns all events for record or repo', async () => {
98
78
  const [bobsEvents, alicesPostEvents] = await Promise.all([
99
- queryModerationEvents({
79
+ modClient.queryEvents({
100
80
  subject: sc.dids.bob,
101
81
  }),
102
- queryModerationEvents({
82
+ modClient.queryEvents({
103
83
  subject: sc.posts[sc.dids.alice][0].ref.uriStr,
104
84
  }),
105
85
  ])
106
86
 
107
- expect(forSnapshot(bobsEvents.data.events)).toMatchSnapshot()
108
- expect(forSnapshot(alicesPostEvents.data.events)).toMatchSnapshot()
87
+ expect(forSnapshot(bobsEvents.events)).toMatchSnapshot()
88
+ expect(forSnapshot(alicesPostEvents.events)).toMatchSnapshot()
109
89
  })
110
90
 
111
91
  it('filters events by types', async () => {
@@ -114,66 +94,64 @@ describe('moderation-events', () => {
114
94
  did: sc.dids.alice,
115
95
  }
116
96
  await Promise.all([
117
- emitModerationEvent({
97
+ modClient.emitEvent({
118
98
  event: {
119
- $type: 'com.atproto.admin.defs#modEventComment',
99
+ $type: 'tools.ozone.moderation.defs#modEventComment',
120
100
  comment: 'X',
121
101
  },
122
102
  subject: alicesAccount,
123
- createdBy: 'did:plc:moderator',
124
103
  }),
125
- emitModerationEvent({
104
+ modClient.emitEvent({
126
105
  event: {
127
- $type: 'com.atproto.admin.defs#modEventEscalate',
106
+ $type: 'tools.ozone.moderation.defs#modEventEscalate',
128
107
  comment: 'X',
129
108
  },
130
109
  subject: alicesAccount,
131
- createdBy: 'did:plc:moderator',
132
110
  }),
133
111
  ])
134
112
  const [allEvents, reportEvents] = await Promise.all([
135
- queryModerationEvents({
113
+ modClient.queryEvents({
136
114
  subject: sc.dids.alice,
137
115
  }),
138
- queryModerationEvents({
116
+ modClient.queryEvents({
139
117
  subject: sc.dids.alice,
140
- types: ['com.atproto.admin.defs#modEventReport'],
118
+ types: ['tools.ozone.moderation.defs#modEventReport'],
141
119
  }),
142
120
  ])
143
121
 
144
- expect(allEvents.data.events.length).toBeGreaterThan(
145
- reportEvents.data.events.length,
122
+ expect(allEvents.events.length).toBeGreaterThan(
123
+ reportEvents.events.length,
146
124
  )
147
125
  expect(
148
- [...new Set(reportEvents.data.events.map((e) => e.event.$type))].length,
126
+ [...new Set(reportEvents.events.map((e) => e.event.$type))].length,
149
127
  ).toEqual(1)
150
128
 
151
129
  expect(
152
- [...new Set(allEvents.data.events.map((e) => e.event.$type))].length,
130
+ [...new Set(allEvents.events.map((e) => e.event.$type))].length,
153
131
  ).toEqual(4)
154
132
  })
155
133
 
156
134
  it('returns events for all content by user', async () => {
157
135
  const [forAccount, forPost] = await Promise.all([
158
- queryModerationEvents({
136
+ modClient.queryEvents({
159
137
  subject: sc.dids.bob,
160
138
  includeAllUserRecords: true,
161
139
  }),
162
- queryModerationEvents({
140
+ modClient.queryEvents({
163
141
  subject: sc.posts[sc.dids.bob][0].ref.uriStr,
164
142
  includeAllUserRecords: true,
165
143
  }),
166
144
  ])
167
145
 
168
- expect(forAccount.data.events.length).toEqual(forPost.data.events.length)
146
+ expect(forAccount.events.length).toEqual(forPost.events.length)
169
147
  // Save events are returned from both requests
170
- expect(forPost.data.events.map(({ id }) => id).sort()).toEqual(
171
- forAccount.data.events.map(({ id }) => id).sort(),
148
+ expect(forPost.events.map(({ id }) => id).sort()).toEqual(
149
+ forAccount.events.map(({ id }) => id).sort(),
172
150
  )
173
151
  })
174
152
 
175
153
  it('returns paginated list of events with cursor', async () => {
176
- const allEvents = await queryModerationEvents({
154
+ const allEvents = await modClient.queryEvents({
177
155
  subject: sc.dids.bob,
178
156
  includeAllUserRecords: true,
179
157
  })
@@ -182,19 +160,19 @@ describe('moderation-events', () => {
182
160
  sortDirection: 'asc' | 'desc' = 'desc',
183
161
  ) => {
184
162
  let defaultCursor: undefined | string = undefined
185
- const events: ComAtprotoAdminDefs.ModEventView[] = []
163
+ const events: ToolsOzoneModerationDefs.ModEventView[] = []
186
164
  let count = 0
187
165
  do {
188
166
  // get 1 event at a time and check we get all events
189
- const { data } = await queryModerationEvents({
167
+ const res = await modClient.queryEvents({
190
168
  limit: 1,
191
169
  subject: sc.dids.bob,
192
170
  includeAllUserRecords: true,
193
171
  cursor: defaultCursor,
194
172
  sortDirection,
195
173
  })
196
- events.push(...data.events)
197
- defaultCursor = data.cursor
174
+ events.push(...res.events)
175
+ defaultCursor = res.cursor
198
176
  count++
199
177
  // The count is a circuit breaker to prevent infinite loop in case of failing test
200
178
  } while (defaultCursor && count < 10)
@@ -205,51 +183,53 @@ describe('moderation-events', () => {
205
183
  const defaultEvents = await getPaginatedEvents()
206
184
  const reversedEvents = await getPaginatedEvents('asc')
207
185
 
208
- expect(allEvents.data.events.length).toEqual(6)
209
- expect(defaultEvents.length).toEqual(allEvents.data.events.length)
210
- expect(reversedEvents.length).toEqual(allEvents.data.events.length)
186
+ expect(allEvents.events.length).toEqual(6)
187
+ expect(defaultEvents.length).toEqual(allEvents.events.length)
188
+ expect(reversedEvents.length).toEqual(allEvents.events.length)
211
189
  // First event in the reversed list is the last item in the default list
212
- expect(reversedEvents[0].id).toEqual(defaultEvents[5].id)
190
+ expect(reversedEvents[0].id).toEqual(
191
+ defaultEvents[defaultEvents.length - 1].id,
192
+ )
213
193
  })
214
194
 
215
195
  it('returns report events matching reportType filters', async () => {
216
196
  const [spamEvents, misleadingEvents] = await Promise.all([
217
- queryModerationEvents({
197
+ modClient.queryEvents({
218
198
  reportTypes: [REASONSPAM],
219
199
  }),
220
- queryModerationEvents({
200
+ modClient.queryEvents({
221
201
  reportTypes: [REASONMISLEADING, REASONAPPEAL],
222
202
  }),
223
203
  ])
224
204
 
225
- expect(misleadingEvents.data.events.length).toEqual(2)
226
- expect(spamEvents.data.events.length).toEqual(6)
205
+ expect(misleadingEvents.events.length).toEqual(2)
206
+ expect(spamEvents.events.length).toEqual(6)
227
207
  })
228
208
 
229
209
  it('returns events matching keyword in comment', async () => {
230
210
  const [eventsWithX, eventsWithTest, eventsWithComment] =
231
211
  await Promise.all([
232
- queryModerationEvents({
212
+ modClient.queryEvents({
233
213
  comment: 'X',
234
214
  }),
235
- queryModerationEvents({
215
+ modClient.queryEvents({
236
216
  comment: 'test',
237
217
  }),
238
- queryModerationEvents({
218
+ modClient.queryEvents({
239
219
  hasComment: true,
240
220
  }),
241
221
  ])
242
222
 
243
- expect(eventsWithX.data.events.length).toEqual(10)
244
- expect(eventsWithTest.data.events.length).toEqual(0)
245
- expect(eventsWithComment.data.events.length).toEqual(10)
223
+ expect(eventsWithX.events.length).toEqual(10)
224
+ expect(eventsWithTest.events.length).toEqual(0)
225
+ expect(eventsWithComment.events.length).toEqual(10)
246
226
  })
247
227
 
248
228
  it('returns events matching filter params for labels', async () => {
249
229
  const [negatedLabelEvent, createdLabelEvent] = await Promise.all([
250
- emitModerationEvent({
230
+ modClient.emitEvent({
251
231
  event: {
252
- $type: 'com.atproto.admin.defs#modEventLabel',
232
+ $type: 'tools.ozone.moderation.defs#modEventLabel',
253
233
  comment: 'X',
254
234
  negateLabelVals: ['L1', 'L2'],
255
235
  createLabelVals: [],
@@ -259,11 +239,10 @@ describe('moderation-events', () => {
259
239
  $type: 'com.atproto.admin.defs#repoRef',
260
240
  did: sc.dids.alice,
261
241
  },
262
- createdBy: sc.dids.bob,
263
242
  }),
264
- emitModerationEvent({
243
+ modClient.emitEvent({
265
244
  event: {
266
- $type: 'com.atproto.admin.defs#modEventLabel',
245
+ $type: 'tools.ozone.moderation.defs#modEventLabel',
267
246
  comment: 'X',
268
247
  createLabelVals: ['L1', 'L2'],
269
248
  negateLabelVals: [],
@@ -273,36 +252,31 @@ describe('moderation-events', () => {
273
252
  $type: 'com.atproto.admin.defs#repoRef',
274
253
  did: sc.dids.bob,
275
254
  },
276
- createdBy: sc.dids.alice,
277
255
  }),
278
256
  ])
279
257
  const [withTwoLabels, withoutTwoLabels, withOneLabel, withoutOneLabel] =
280
258
  await Promise.all([
281
- queryModerationEvents({
259
+ modClient.queryEvents({
282
260
  addedLabels: ['L1', 'L3'],
283
261
  }),
284
- queryModerationEvents({
262
+ modClient.queryEvents({
285
263
  removedLabels: ['L1', 'L2'],
286
264
  }),
287
- queryModerationEvents({
265
+ modClient.queryEvents({
288
266
  addedLabels: ['L1'],
289
267
  }),
290
- queryModerationEvents({
268
+ modClient.queryEvents({
291
269
  removedLabels: ['L2'],
292
270
  }),
293
271
  ])
294
272
 
295
273
  // Verify that when querying for events where 2 different labels were added
296
274
  // events where all of the labels from the list was added are returned
297
- expect(withTwoLabels.data.events.length).toEqual(0)
298
- expect(negatedLabelEvent.data.id).toEqual(
299
- withoutTwoLabels.data.events[0].id,
300
- )
275
+ expect(withTwoLabels.events.length).toEqual(0)
276
+ expect(negatedLabelEvent.id).toEqual(withoutTwoLabels.events[0].id)
301
277
 
302
- expect(createdLabelEvent.data.id).toEqual(withOneLabel.data.events[0].id)
303
- expect(negatedLabelEvent.data.id).toEqual(
304
- withoutOneLabel.data.events[0].id,
305
- )
278
+ expect(createdLabelEvent.id).toEqual(withOneLabel.events[0].id)
279
+ expect(negatedLabelEvent.id).toEqual(withoutOneLabel.events[0].id)
306
280
  })
307
281
  it('returns events matching filter params for tags', async () => {
308
282
  const tagEvent = async ({
@@ -312,9 +286,9 @@ describe('moderation-events', () => {
312
286
  add: string[]
313
287
  remove: string[]
314
288
  }) =>
315
- emitModerationEvent({
289
+ modClient.emitEvent({
316
290
  event: {
317
- $type: 'com.atproto.admin.defs#modEventTag',
291
+ $type: 'tools.ozone.moderation.defs#modEventTag',
318
292
  comment: 'X',
319
293
  add,
320
294
  remove,
@@ -323,43 +297,35 @@ describe('moderation-events', () => {
323
297
  $type: 'com.atproto.admin.defs#repoRef',
324
298
  did: sc.dids.carol,
325
299
  },
326
- createdBy: sc.dids.bob,
327
300
  })
328
301
  const addEvent = await tagEvent({ add: ['L1', 'L2'], remove: [] })
329
302
  const addAndRemoveEvent = await tagEvent({ add: ['L3'], remove: ['L2'] })
330
303
  const [addFinder, addAndRemoveFinder, _removeFinder] = await Promise.all([
331
- queryModerationEvents({
304
+ modClient.queryEvents({
332
305
  addedTags: ['L1'],
333
306
  }),
334
- queryModerationEvents({
307
+ modClient.queryEvents({
335
308
  addedTags: ['L3'],
336
309
  removedTags: ['L2'],
337
310
  }),
338
- queryModerationEvents({
311
+ modClient.queryEvents({
339
312
  removedTags: ['L2'],
340
313
  }),
341
314
  ])
342
315
 
343
- expect(addFinder.data.events.length).toEqual(1)
344
- expect(addEvent.data.id).toEqual(addFinder.data.events[0].id)
316
+ expect(addFinder.events.length).toEqual(1)
317
+ expect(addEvent.id).toEqual(addFinder.events[0].id)
345
318
 
346
- expect(addAndRemoveEvent.data.id).toEqual(
347
- addAndRemoveFinder.data.events[0].id,
348
- )
349
- expect(addAndRemoveEvent.data.id).toEqual(
350
- addAndRemoveFinder.data.events[0].id,
351
- )
352
- expect(addAndRemoveEvent.data.event.add).toEqual(['L3'])
353
- expect(addAndRemoveEvent.data.event.remove).toEqual(['L2'])
319
+ expect(addAndRemoveEvent.id).toEqual(addAndRemoveFinder.events[0].id)
320
+ expect(addAndRemoveEvent.id).toEqual(addAndRemoveFinder.events[0].id)
321
+ expect(addAndRemoveEvent.event.add).toEqual(['L3'])
322
+ expect(addAndRemoveEvent.event.remove).toEqual(['L2'])
354
323
  })
355
324
  })
356
325
 
357
326
  describe('get event', () => {
358
327
  it('gets an event by specific id', async () => {
359
- const { data } = await pdsAgent.api.com.atproto.admin.getModerationEvent(
360
- { id: 1 },
361
- { headers: network.ozone.adminAuthHeaders('moderator') },
362
- )
328
+ const data = await modClient.getEvent(1)
363
329
  expect(forSnapshot(data)).toMatchSnapshot()
364
330
  })
365
331
  })
@@ -368,9 +334,9 @@ describe('moderation-events', () => {
368
334
  it('are tracked on takedown event', async () => {
369
335
  const post = sc.posts[sc.dids.carol][0]
370
336
  assert(post.images.length > 1)
371
- await emitModerationEvent({
337
+ await modClient.emitEvent({
372
338
  event: {
373
- $type: 'com.atproto.admin.defs#modEventTakedown',
339
+ $type: 'tools.ozone.moderation.defs#modEventTakedown',
374
340
  },
375
341
  subject: {
376
342
  $type: 'com.atproto.repo.strongRef',
@@ -378,20 +344,15 @@ describe('moderation-events', () => {
378
344
  cid: post.ref.cidStr,
379
345
  },
380
346
  subjectBlobCids: [post.images[0].image.ref.toString()],
381
- createdBy: sc.dids.alice,
382
347
  })
383
- const { data: result } =
384
- await pdsAgent.api.com.atproto.admin.queryModerationEvents(
385
- {
386
- subject: post.ref.uriStr,
387
- types: ['com.atproto.admin.defs#modEventTakedown'],
388
- },
389
- { headers: network.ozone.adminAuthHeaders('moderator') },
390
- )
348
+ const result = await modClient.queryEvents({
349
+ subject: post.ref.uriStr,
350
+ types: ['tools.ozone.moderation.defs#modEventTakedown'],
351
+ })
391
352
  expect(result.events[0]).toMatchObject({
392
- createdBy: sc.dids.alice,
353
+ createdBy: network.ozone.moderatorAccnt.did,
393
354
  event: {
394
- $type: 'com.atproto.admin.defs#modEventTakedown',
355
+ $type: 'tools.ozone.moderation.defs#modEventTakedown',
395
356
  },
396
357
  subjectBlobCids: [post.images[0].image.ref.toString()],
397
358
  })
@@ -399,26 +360,23 @@ describe('moderation-events', () => {
399
360
 
400
361
  it("are tracked on reverse-takedown event even if they aren't specified", async () => {
401
362
  const post = sc.posts[sc.dids.carol][0]
402
- await emitModerationEvent({
363
+ await modClient.emitEvent({
403
364
  event: {
404
- $type: 'com.atproto.admin.defs#modEventReverseTakedown',
365
+ $type: 'tools.ozone.moderation.defs#modEventReverseTakedown',
405
366
  },
406
367
  subject: {
407
368
  $type: 'com.atproto.repo.strongRef',
408
369
  uri: post.ref.uriStr,
409
370
  cid: post.ref.cidStr,
410
371
  },
411
- createdBy: sc.dids.alice,
412
372
  })
413
- const { data: result } =
414
- await pdsAgent.api.com.atproto.admin.queryModerationEvents(
415
- { subject: post.ref.uriStr },
416
- { headers: network.ozone.adminAuthHeaders('moderator') },
417
- )
373
+ const result = await modClient.queryEvents({
374
+ subject: post.ref.uriStr,
375
+ })
418
376
  expect(result.events[0]).toMatchObject({
419
- createdBy: sc.dids.alice,
377
+ createdBy: network.ozone.moderatorAccnt.did,
420
378
  event: {
421
- $type: 'com.atproto.admin.defs#modEventReverseTakedown',
379
+ $type: 'tools.ozone.moderation.defs#modEventReverseTakedown',
422
380
  },
423
381
  subjectBlobCids: [post.images[0].image.ref.toString()],
424
382
  })
@@ -450,9 +408,9 @@ describe('moderation-events', () => {
450
408
 
451
409
  it('sends email via pds.', async () => {
452
410
  const mail = await getMailFrom(
453
- emitModerationEvent({
411
+ modClient.emitEvent({
454
412
  event: {
455
- $type: 'com.atproto.admin.defs#modEventEmail',
413
+ $type: 'tools.ozone.moderation.defs#modEventEmail',
456
414
  comment: 'Reaching out to Alice',
457
415
  subjectLine: 'Hello',
458
416
  content: 'Hey Alice, how are you?',
@@ -461,7 +419,6 @@ describe('moderation-events', () => {
461
419
  $type: 'com.atproto.admin.defs#repoRef',
462
420
  did: sc.dids.alice,
463
421
  },
464
- createdBy: sc.dids.bob,
465
422
  }),
466
423
  )
467
424
  expect(mail).toEqual({
@@ -1,32 +1,22 @@
1
- import { TestNetwork, SeedClient, basicSeed } from '@atproto/dev-env'
2
- import AtpAgent from '@atproto/api'
1
+ import {
2
+ TestNetwork,
3
+ SeedClient,
4
+ basicSeed,
5
+ ModeratorClient,
6
+ } from '@atproto/dev-env'
3
7
  import { REASONSPAM } from '../src/lexicon/types/com/atproto/moderation/defs'
4
8
 
5
9
  describe('moderation-status-tags', () => {
6
10
  let network: TestNetwork
7
- let agent: AtpAgent
8
- let pdsAgent: AtpAgent
9
11
  let sc: SeedClient
10
-
11
- const emitModerationEvent = async (eventData) => {
12
- return pdsAgent.api.com.atproto.admin.emitModerationEvent(eventData, {
13
- encoding: 'application/json',
14
- headers: network.bsky.adminAuthHeaders('moderator'),
15
- })
16
- }
17
-
18
- const queryModerationStatuses = (statusQuery) =>
19
- agent.api.com.atproto.admin.queryModerationStatuses(statusQuery, {
20
- headers: network.bsky.adminAuthHeaders('moderator'),
21
- })
12
+ let modClient: ModeratorClient
22
13
 
23
14
  beforeAll(async () => {
24
15
  network = await TestNetwork.create({
25
16
  dbPostgresSchema: 'ozone_moderation_status_tags',
26
17
  })
27
- agent = network.ozone.getClient()
28
- pdsAgent = network.pds.getClient()
29
18
  sc = network.getSeedClient()
19
+ modClient = network.ozone.getModClient()
30
20
  await basicSeed(sc)
31
21
  await network.processAll()
32
22
  })
@@ -41,43 +31,36 @@ describe('moderation-status-tags', () => {
41
31
  $type: 'com.atproto.admin.defs#repoRef',
42
32
  did: sc.dids.bob,
43
33
  }
44
- await emitModerationEvent({
34
+ await sc.createReport({
35
+ reasonType: REASONSPAM,
36
+ reason: 'X',
45
37
  subject: bobsAccount,
46
- event: {
47
- $type: 'com.atproto.admin.defs#modEventReport',
48
- comment: 'X',
49
- reportType: REASONSPAM,
50
- },
51
- createdBy: sc.dids.alice,
38
+ reportedBy: sc.dids.alice,
52
39
  })
53
- await emitModerationEvent({
40
+ await modClient.emitEvent({
54
41
  subject: bobsAccount,
55
42
  event: {
56
- $type: 'com.atproto.admin.defs#modEventTag',
43
+ $type: 'tools.ozone.moderation.defs#modEventTag',
57
44
  add: ['interaction-churn'],
58
45
  remove: [],
59
46
  },
60
- createdBy: sc.dids.alice,
61
47
  })
62
- const { data: statusAfterInteractionTag } = await queryModerationStatuses(
63
- {
64
- subject: bobsAccount.did,
65
- },
66
- )
48
+ const statusAfterInteractionTag = await modClient.queryStatuses({
49
+ subject: bobsAccount.did,
50
+ })
67
51
  expect(statusAfterInteractionTag.subjectStatuses[0].tags).toContain(
68
52
  'interaction-churn',
69
53
  )
70
54
 
71
- await emitModerationEvent({
55
+ await modClient.emitEvent({
72
56
  subject: bobsAccount,
73
57
  event: {
74
- $type: 'com.atproto.admin.defs#modEventTag',
58
+ $type: 'tools.ozone.moderation.defs#modEventTag',
75
59
  remove: ['interaction-churn'],
76
60
  add: ['follow-churn'],
77
61
  },
78
- createdBy: sc.dids.alice,
79
62
  })
80
- const { data: statusAfterFollowTag } = await queryModerationStatuses({
63
+ const statusAfterFollowTag = await modClient.queryStatuses({
81
64
  subject: bobsAccount.did,
82
65
  })
83
66