@atproto/ozone 0.0.9 → 0.0.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.
Files changed (80) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/api/moderation/util.d.ts +1 -1
  3. package/dist/db/index.js +20 -1
  4. package/dist/db/index.js.map +3 -3
  5. package/dist/db/migrations/20240208T213404429Z-add-tags-column-to-moderation-subject.d.ts +3 -0
  6. package/dist/db/migrations/index.d.ts +1 -0
  7. package/dist/db/schema/moderation_event.d.ts +3 -1
  8. package/dist/db/schema/moderation_subject_status.d.ts +1 -0
  9. package/dist/index.js +1458 -596
  10. package/dist/index.js.map +3 -3
  11. package/dist/lexicon/index.d.ts +20 -6
  12. package/dist/lexicon/lexicons.d.ts +449 -110
  13. package/dist/lexicon/types/app/bsky/actor/defs.d.ts +20 -0
  14. package/dist/lexicon/types/com/atproto/admin/defs.d.ts +9 -0
  15. package/dist/lexicon/types/com/atproto/admin/emitModerationEvent.d.ts +1 -1
  16. package/dist/lexicon/types/com/atproto/admin/queryModerationEvents.d.ts +2 -0
  17. package/dist/lexicon/types/com/atproto/admin/queryModerationStatuses.d.ts +2 -0
  18. package/dist/lexicon/types/com/atproto/identity/getRecommendedDidCredentials.d.ts +33 -0
  19. package/dist/lexicon/types/com/atproto/identity/requestPlcOperationSignature.d.ts +19 -0
  20. package/dist/lexicon/types/com/atproto/{temp/transferAccount.d.ts → identity/signPlcOperation.d.ts} +6 -8
  21. package/dist/lexicon/types/com/atproto/identity/submitPlcOperation.d.ts +25 -0
  22. package/dist/lexicon/types/com/atproto/{temp/pushBlob.d.ts → repo/importRepo.d.ts} +1 -2
  23. package/dist/lexicon/types/com/atproto/repo/listMissingBlobs.d.ts +41 -0
  24. package/dist/lexicon/types/com/atproto/server/activateAccount.d.ts +19 -0
  25. package/dist/lexicon/types/com/atproto/server/checkAccountStatus.d.ts +38 -0
  26. package/dist/lexicon/types/com/atproto/server/deactivateAccount.d.ts +25 -0
  27. package/dist/lexicon/types/com/atproto/server/describeServer.d.ts +1 -0
  28. package/dist/lexicon/types/com/atproto/{temp/importRepo.d.ts → server/getServiceAuth.d.ts} +8 -9
  29. package/dist/lexicon/types/com/atproto/sync/subscribeRepos.d.ts +9 -1
  30. package/dist/logger.d.ts +1 -0
  31. package/dist/mod-service/index.d.ts +18 -4
  32. package/dist/mod-service/lang.d.ts +15 -0
  33. package/dist/mod-service/status.d.ts +1 -1
  34. package/dist/mod-service/types.d.ts +1 -1
  35. package/dist/mod-service/views.d.ts +2 -1
  36. package/package.json +6 -6
  37. package/src/api/admin/emitModerationEvent.ts +22 -10
  38. package/src/api/admin/queryModerationEvents.ts +4 -0
  39. package/src/api/admin/queryModerationStatuses.ts +4 -0
  40. package/src/api/moderation/createReport.ts +15 -4
  41. package/src/api/moderation/util.ts +1 -0
  42. package/src/db/migrations/20240208T213404429Z-add-tags-column-to-moderation-subject.ts +31 -0
  43. package/src/db/migrations/index.ts +1 -0
  44. package/src/db/schema/moderation_event.ts +3 -0
  45. package/src/db/schema/moderation_subject_status.ts +1 -0
  46. package/src/lexicon/index.ts +124 -36
  47. package/src/lexicon/lexicons.ts +491 -138
  48. package/src/lexicon/types/app/bsky/actor/defs.ts +59 -0
  49. package/src/lexicon/types/app/bsky/feed/post.ts +1 -1
  50. package/src/lexicon/types/com/atproto/admin/defs.ts +24 -0
  51. package/src/lexicon/types/com/atproto/admin/emitModerationEvent.ts +1 -0
  52. package/src/lexicon/types/com/atproto/admin/queryModerationEvents.ts +4 -0
  53. package/src/lexicon/types/com/atproto/admin/queryModerationStatuses.ts +2 -0
  54. package/src/lexicon/types/com/atproto/identity/getRecommendedDidCredentials.ts +47 -0
  55. package/src/lexicon/types/com/atproto/identity/requestPlcOperationSignature.ts +31 -0
  56. package/src/lexicon/types/com/atproto/{temp/transferAccount.ts → identity/signPlcOperation.ts} +8 -15
  57. package/src/lexicon/types/com/atproto/identity/submitPlcOperation.ts +38 -0
  58. package/src/lexicon/types/com/atproto/{temp/pushBlob.ts → repo/importRepo.ts} +2 -5
  59. package/src/lexicon/types/com/atproto/repo/listMissingBlobs.ts +65 -0
  60. package/src/lexicon/types/com/atproto/server/activateAccount.ts +31 -0
  61. package/src/lexicon/types/com/atproto/server/checkAccountStatus.ts +51 -0
  62. package/src/lexicon/types/com/atproto/server/deactivateAccount.ts +39 -0
  63. package/src/lexicon/types/com/atproto/server/describeServer.ts +1 -0
  64. package/src/lexicon/types/com/atproto/{temp/importRepo.ts → server/getServiceAuth.ts} +10 -9
  65. package/src/lexicon/types/com/atproto/sync/subscribeRepos.ts +24 -3
  66. package/src/logger.ts +2 -0
  67. package/src/mod-service/index.ts +60 -10
  68. package/src/mod-service/lang.ts +82 -0
  69. package/src/mod-service/status.ts +18 -4
  70. package/src/mod-service/types.ts +1 -0
  71. package/src/mod-service/views.ts +21 -2
  72. package/tests/__snapshots__/get-record.test.ts.snap +6 -0
  73. package/tests/__snapshots__/get-repo.test.ts.snap +3 -0
  74. package/tests/__snapshots__/moderation-events.test.ts.snap +45 -4
  75. package/tests/__snapshots__/moderation-statuses.test.ts.snap +59 -3
  76. package/tests/__snapshots__/moderation.test.ts.snap +3 -3
  77. package/tests/get-record.test.ts +0 -8
  78. package/tests/moderation-events.test.ts +57 -5
  79. package/tests/moderation-status-tags.test.ts +92 -0
  80. package/tests/moderation-statuses.test.ts +20 -3
@@ -12,6 +12,7 @@ import {
12
12
  isModEventReport,
13
13
  isModEventTakedown,
14
14
  isModEventEmail,
15
+ isModEventTag,
15
16
  RepoRef,
16
17
  RepoBlobRef,
17
18
  } from '../lexicon/types/com/atproto/admin/defs'
@@ -103,6 +104,8 @@ export class ModerationService {
103
104
  createdBefore?: string
104
105
  addedLabels: string[]
105
106
  removedLabels: string[]
107
+ addedTags: string[]
108
+ removedTags: string[]
106
109
  reportTypes?: string[]
107
110
  }): Promise<{ cursor?: string; events: ModerationEventRow[] }> {
108
111
  const {
@@ -119,8 +122,11 @@ export class ModerationService {
119
122
  createdBefore,
120
123
  addedLabels,
121
124
  removedLabels,
125
+ addedTags,
126
+ removedTags,
122
127
  reportTypes,
123
128
  } = opts
129
+ const { ref } = this.db.db.dynamic
124
130
  let builder = this.db.db.selectFrom('moderation_event').selectAll()
125
131
  if (subject) {
126
132
  builder = builder.where((qb) => {
@@ -178,11 +184,18 @@ export class ModerationService {
178
184
  builder = builder.where('negateLabelVals', 'ilike', `%${label}%`)
179
185
  })
180
186
  }
187
+ if (addedTags.length) {
188
+ builder = builder.where(sql`${ref('addedTags')} @> ${jsonb(addedTags)}`)
189
+ }
190
+ if (removedTags.length) {
191
+ builder = builder.where(
192
+ sql`${ref('removedTags')} @> ${jsonb(removedTags)}`,
193
+ )
194
+ }
181
195
  if (reportTypes?.length) {
182
196
  builder = builder.where(sql`meta->>'reportType'`, 'in', reportTypes)
183
197
  }
184
198
 
185
- const { ref } = this.db.db.dynamic
186
199
  const keyset = new TimeIdKeyset(
187
200
  ref(`moderation_event.createdAt`),
188
201
  ref('moderation_event.id'),
@@ -238,7 +251,10 @@ export class ModerationService {
238
251
  subject: ModSubject
239
252
  createdBy: string
240
253
  createdAt?: Date
241
- }): Promise<ModerationEventRow> {
254
+ }): Promise<{
255
+ event: ModerationEventRow
256
+ subjectStatus: ModerationSubjectStatusRow | null
257
+ }> {
242
258
  this.db.assertTransaction()
243
259
  const { event, subject, createdBy, createdAt = new Date() } = info
244
260
 
@@ -253,6 +269,9 @@ export class ModerationService {
253
269
 
254
270
  const meta: Record<string, string | boolean> = {}
255
271
 
272
+ const addedTags = isModEventTag(event) ? jsonb(event.add) : null
273
+ const removedTags = isModEventTag(event) ? jsonb(event.remove) : null
274
+
256
275
  if (isModEventReport(event)) {
257
276
  meta.reportType = event.reportType
258
277
  }
@@ -276,6 +295,8 @@ export class ModerationService {
276
295
  createdBy,
277
296
  createLabelVals,
278
297
  negateLabelVals,
298
+ addedTags,
299
+ removedTags,
279
300
  durationInHours: event.durationInHours
280
301
  ? Number(event.durationInHours)
281
302
  : null,
@@ -294,9 +315,13 @@ export class ModerationService {
294
315
  .returningAll()
295
316
  .executeTakeFirstOrThrow()
296
317
 
297
- await adjustModerationSubjectStatus(this.db, modEvent, subject.blobCids)
318
+ const subjectStatus = await adjustModerationSubjectStatus(
319
+ this.db,
320
+ modEvent,
321
+ subject.blobCids,
322
+ )
298
323
 
299
- return modEvent
324
+ return { event: modEvent, subjectStatus }
300
325
  }
301
326
 
302
327
  async getLastReversibleEventForSubject(subject: ReversalSubject) {
@@ -376,7 +401,7 @@ export class ModerationService {
376
401
  const isRevertingTakedown =
377
402
  action === 'com.atproto.admin.defs#modEventTakedown'
378
403
  this.db.assertTransaction()
379
- const result = await this.logEvent({
404
+ const { event } = await this.logEvent({
380
405
  event: {
381
406
  $type: isRevertingTakedown
382
407
  ? 'com.atproto.admin.defs#modEventReverseTakedown'
@@ -396,7 +421,7 @@ export class ModerationService {
396
421
  }
397
422
  }
398
423
 
399
- return result
424
+ return event
400
425
  }
401
426
 
402
427
  async takedownRepo(
@@ -613,7 +638,10 @@ export class ModerationService {
613
638
  subject: ModSubject
614
639
  reportedBy: string
615
640
  createdAt?: Date
616
- }): Promise<ModerationEventRow> {
641
+ }): Promise<{
642
+ event: ModerationEventRow
643
+ subjectStatus: ModerationSubjectStatusRow | null
644
+ }> {
617
645
  const {
618
646
  reasonType,
619
647
  reason,
@@ -622,7 +650,7 @@ export class ModerationService {
622
650
  subject,
623
651
  } = info
624
652
 
625
- const event = await this.logEvent({
653
+ const result = await this.logEvent({
626
654
  event: {
627
655
  $type: 'com.atproto.admin.defs#modEventReport',
628
656
  reportType: reasonType,
@@ -633,7 +661,7 @@ export class ModerationService {
633
661
  createdAt,
634
662
  })
635
663
 
636
- return event
664
+ return result
637
665
  }
638
666
 
639
667
  async getSubjectStatuses({
@@ -652,6 +680,8 @@ export class ModerationService {
652
680
  lastReviewedBy,
653
681
  sortField,
654
682
  subject,
683
+ tags,
684
+ excludeTags,
655
685
  }: {
656
686
  cursor?: string
657
687
  limit?: number
@@ -668,8 +698,11 @@ export class ModerationService {
668
698
  sortDirection: 'asc' | 'desc'
669
699
  lastReviewedBy?: string
670
700
  sortField: 'lastReviewedAt' | 'lastReportedAt'
701
+ tags: string[]
702
+ excludeTags: string[]
671
703
  }) {
672
704
  let builder = this.db.db.selectFrom('moderation_subject_status').selectAll()
705
+ const { ref } = this.db.db.dynamic
673
706
 
674
707
  if (subject) {
675
708
  const subjectInfo = getStatusIdentifierFromSubject(subject)
@@ -731,7 +764,24 @@ export class ModerationService {
731
764
  )
732
765
  }
733
766
 
734
- const { ref } = this.db.db.dynamic
767
+ if (tags.length) {
768
+ builder = builder.where(
769
+ sql`${ref('moderation_subject_status.tags')} @> ${jsonb(tags)}`,
770
+ )
771
+ }
772
+
773
+ if (excludeTags.length) {
774
+ builder = builder.where((qb) =>
775
+ qb
776
+ .where(
777
+ sql`NOT(${ref('moderation_subject_status.tags')} @> ${jsonb(
778
+ excludeTags,
779
+ )})`,
780
+ )
781
+ .orWhere('tags', 'is', null),
782
+ )
783
+ }
784
+
735
785
  const keyset = new StatusKeyset(
736
786
  ref(`moderation_subject_status.${sortField}`),
737
787
  ref('moderation_subject_status.id'),
@@ -0,0 +1,82 @@
1
+ import { ModerationService } from '.'
2
+ import { ModSubject } from './subject'
3
+ import { ModerationSubjectStatusRow } from './types'
4
+ import { langLogger as log } from '../logger'
5
+
6
+ export class ModerationLangService {
7
+ constructor(private moderationService: ModerationService) {}
8
+
9
+ async tagSubjectWithLang({
10
+ subject,
11
+ subjectStatus,
12
+ createdBy,
13
+ }: {
14
+ subject: ModSubject
15
+ createdBy: string
16
+ subjectStatus: ModerationSubjectStatusRow | null
17
+ }) {
18
+ if (
19
+ subjectStatus &&
20
+ !subjectStatus.tags?.find((tag) => tag.includes('lang:'))
21
+ ) {
22
+ try {
23
+ const recordLangs = await this.getRecordLang({
24
+ subject,
25
+ })
26
+ await this.moderationService.logEvent({
27
+ event: {
28
+ $type: 'com.atproto.admin.defs#modEventTag',
29
+ add: recordLangs
30
+ ? recordLangs.map((lang) => `lang:${lang}`)
31
+ : ['lang:und'],
32
+ remove: [],
33
+ },
34
+ subject,
35
+ createdBy,
36
+ })
37
+ } catch (err) {
38
+ log.error({ subject, err }, 'Error getting record langs')
39
+ }
40
+ }
41
+ }
42
+
43
+ async getRecordLang({
44
+ subject,
45
+ }: {
46
+ subject: ModSubject
47
+ }): Promise<string[] | null> {
48
+ const isRecord = subject.isRecord()
49
+ const langs = new Set<string>()
50
+
51
+ if (
52
+ subject.isRepo() ||
53
+ (isRecord && subject.uri.endsWith('/app.bsky.actor.profile/self'))
54
+ ) {
55
+ const feed = await this.moderationService.views.fetchAuthorFeed(
56
+ subject.did,
57
+ )
58
+ feed.forEach((item) => {
59
+ const itemLangs = item.post.record['langs'] as string[] | null
60
+ if (itemLangs?.length) {
61
+ // Pick the first fragment of the lang code so that instead of `en-US` and `en-GB` we get `en`
62
+ itemLangs.forEach((lang) => langs.add(lang.split('-')[0]))
63
+ }
64
+ })
65
+ }
66
+
67
+ if (isRecord) {
68
+ const recordByUri = await this.moderationService.views.fetchRecords([
69
+ subject,
70
+ ])
71
+ const record = recordByUri.get(subject.uri)
72
+ const recordLang = record?.value.langs as string[] | null
73
+ if (recordLang?.length) {
74
+ recordLang
75
+ .map((lang) => lang.split('-')[0])
76
+ .forEach((lang) => langs.add(lang))
77
+ }
78
+ }
79
+
80
+ return langs.size > 0 ? Array.from(langs) : null
81
+ }
82
+ }
@@ -10,7 +10,6 @@ import {
10
10
  } from '../lexicon/types/com/atproto/admin/defs'
11
11
  import { ModerationEventRow, ModerationSubjectStatusRow } from './types'
12
12
  import { HOUR } from '@atproto/common'
13
- import { sql } from 'kysely'
14
13
  import { REASONAPPEAL } from '../lexicon/types/com/atproto/moderation/defs'
15
14
  import { jsonb } from '../db/types'
16
15
 
@@ -83,6 +82,8 @@ const getSubjectStatusForModerationEvent = ({
83
82
  lastReviewedBy: createdBy,
84
83
  lastReviewedAt: createdAt,
85
84
  }
85
+ case 'com.atproto.admin.defs#modEventTag':
86
+ return { tags: [] }
86
87
  case 'com.atproto.admin.defs#modEventResolveAppeal':
87
88
  return {
88
89
  appealed: false,
@@ -107,6 +108,8 @@ export const adjustModerationSubjectStatus = async (
107
108
  subjectCid,
108
109
  createdBy,
109
110
  meta,
111
+ addedTags,
112
+ removedTags,
110
113
  comment,
111
114
  createdAt,
112
115
  } = moderationEvent
@@ -191,6 +194,18 @@ export const adjustModerationSubjectStatus = async (
191
194
  subjectStatus.comment = comment
192
195
  }
193
196
 
197
+ if (action === 'com.atproto.admin.defs#modEventTag') {
198
+ let tags = currentStatus?.tags || []
199
+ if (addedTags?.length) {
200
+ tags = tags.concat(addedTags)
201
+ }
202
+ if (removedTags?.length) {
203
+ tags = tags.filter((tag) => !removedTags.includes(tag))
204
+ }
205
+ newStatus.tags = jsonb([...new Set(tags)]) as unknown as string[]
206
+ subjectStatus.tags = newStatus.tags
207
+ }
208
+
194
209
  if (blobCids?.length) {
195
210
  const newBlobCids = jsonb(
196
211
  blobCids,
@@ -206,7 +221,6 @@ export const adjustModerationSubjectStatus = async (
206
221
  ...newStatus,
207
222
  createdAt: now,
208
223
  updatedAt: now,
209
- // TODO: Need to get the types right here.
210
224
  } as ModerationSubjectStatusRow)
211
225
  .onConflict((oc) =>
212
226
  oc.constraint('moderation_status_unique_idx').doUpdateSet({
@@ -215,8 +229,8 @@ export const adjustModerationSubjectStatus = async (
215
229
  }),
216
230
  )
217
231
 
218
- const status = await insertQuery.executeTakeFirst()
219
- return status
232
+ const status = await insertQuery.returningAll().executeTakeFirst()
233
+ return status || null
220
234
  }
221
235
 
222
236
  type ModerationSubjectStatusFilter =
@@ -30,6 +30,7 @@ export type ModEventType =
30
30
  | ComAtprotoAdminDefs.ModEventReport
31
31
  | ComAtprotoAdminDefs.ModEventMute
32
32
  | ComAtprotoAdminDefs.ModEventReverseTakedown
33
+ | ComAtprotoAdminDefs.ModEventTag
33
34
 
34
35
  export const UNSPECCED_TAKEDOWN_LABEL = '!unspecced-takedown'
35
36
 
@@ -1,6 +1,6 @@
1
1
  import { sql } from 'kysely'
2
2
  import { AtUri, INVALID_HANDLE, normalizeDatetimeAlways } from '@atproto/syntax'
3
- import AtpAgent from '@atproto/api'
3
+ import AtpAgent, { AppBskyFeedDefs } from '@atproto/api'
4
4
  import { dedupeStrs } from '@atproto/common'
5
5
  import { BlobRef } from '@atproto/lexicon'
6
6
  import { Database } from '../db'
@@ -163,6 +163,11 @@ export class ModerationViews {
163
163
  eventView.event.sticky = true
164
164
  }
165
165
 
166
+ if (event.action === 'com.atproto.admin.defs#modEventTag') {
167
+ eventView.event.add = event.addedTags || []
168
+ eventView.event.remove = event.removedTags || []
169
+ }
170
+
166
171
  return eventView
167
172
  }
168
173
 
@@ -217,7 +222,7 @@ export class ModerationViews {
217
222
  subjects.map(async (subject) => {
218
223
  const uri = new AtUri(subject.uri)
219
224
  try {
220
- return await this.appviewAgent.api.com.atproto.repo.getRecord(
225
+ const record = await this.appviewAgent.api.com.atproto.repo.getRecord(
221
226
  {
222
227
  repo: uri.hostname,
223
228
  collection: uri.collection,
@@ -226,6 +231,7 @@ export class ModerationViews {
226
231
  },
227
232
  auth,
228
233
  )
234
+ return record
229
235
  } catch {
230
236
  return null
231
237
  }
@@ -473,9 +479,22 @@ export class ModerationViews {
473
479
  appealed: status.appealed ?? undefined,
474
480
  subjectRepoHandle: status.handle ?? undefined,
475
481
  subjectBlobCids: status.blobCids || [],
482
+ tags: status.tags || [],
476
483
  subject: subjectFromStatusRow(status).lex(),
477
484
  }
478
485
  }
486
+
487
+ async fetchAuthorFeed(
488
+ actor: string,
489
+ ): Promise<AppBskyFeedDefs.FeedViewPost[]> {
490
+ const auth = await this.appviewAuth()
491
+ if (!auth) return []
492
+ const {
493
+ data: { feed },
494
+ } = await this.appviewAgent.api.app.bsky.feed.getAuthorFeed({ actor }, auth)
495
+
496
+ return feed
497
+ }
479
498
  }
480
499
 
481
500
  type RecordSubject = { uri: string; cid?: string }
@@ -39,6 +39,9 @@ Object {
39
39
  },
40
40
  "subjectBlobCids": Array [],
41
41
  "subjectRepoHandle": "alice.test",
42
+ "tags": Array [
43
+ "lang:und",
44
+ ],
42
45
  "takendown": true,
43
46
  "updatedAt": "1970-01-01T00:00:00.000Z",
44
47
  },
@@ -133,6 +136,9 @@ Object {
133
136
  },
134
137
  "subjectBlobCids": Array [],
135
138
  "subjectRepoHandle": "alice.test",
139
+ "tags": Array [
140
+ "lang:und",
141
+ ],
136
142
  "takendown": true,
137
143
  "updatedAt": "1970-01-01T00:00:00.000Z",
138
144
  },
@@ -31,6 +31,9 @@ Object {
31
31
  },
32
32
  "subjectBlobCids": Array [],
33
33
  "subjectRepoHandle": "alice.test",
34
+ "tags": Array [
35
+ "lang:und",
36
+ ],
34
37
  "takendown": true,
35
38
  "updatedAt": "1970-01-01T00:00:00.000Z",
36
39
  },
@@ -37,6 +37,9 @@ Object {
37
37
  },
38
38
  "subjectBlobCids": Array [],
39
39
  "subjectRepoHandle": "alice.test",
40
+ "tags": Array [
41
+ "lang:und",
42
+ ],
40
43
  "takendown": false,
41
44
  "updatedAt": "1970-01-01T00:00:00.000Z",
42
45
  },
@@ -98,7 +101,26 @@ Array [
98
101
  "comment": "X",
99
102
  "reportType": "com.atproto.moderation.defs#reasonSpam",
100
103
  },
101
- "id": 9,
104
+ "id": 13,
105
+ "subject": Object {
106
+ "$type": "com.atproto.admin.defs#repoRef",
107
+ "did": "user(0)",
108
+ },
109
+ "subjectBlobCids": Array [],
110
+ "subjectHandle": "bob.test",
111
+ },
112
+ Object {
113
+ "createdAt": "1970-01-01T00:00:00.000Z",
114
+ "createdBy": "user(2)",
115
+ "event": Object {
116
+ "$type": "com.atproto.admin.defs#modEventTag",
117
+ "add": Array [
118
+ "lang:en",
119
+ "lang:i",
120
+ ],
121
+ "remove": Array [],
122
+ },
123
+ "id": 8,
102
124
  "subject": Object {
103
125
  "$type": "com.atproto.admin.defs#repoRef",
104
126
  "did": "user(0)",
@@ -115,7 +137,7 @@ Array [
115
137
  "comment": "X",
116
138
  "reportType": "com.atproto.moderation.defs#reasonSpam",
117
139
  },
118
- "id": 5,
140
+ "id": 7,
119
141
  "subject": Object {
120
142
  "$type": "com.atproto.admin.defs#repoRef",
121
143
  "did": "user(0)",
@@ -137,7 +159,26 @@ Array [
137
159
  "comment": "X",
138
160
  "reportType": "com.atproto.moderation.defs#reasonSpam",
139
161
  },
140
- "id": 8,
162
+ "id": 12,
163
+ "subject": Object {
164
+ "$type": "com.atproto.repo.strongRef",
165
+ "cid": "cids(0)",
166
+ "uri": "record(0)",
167
+ },
168
+ "subjectBlobCids": Array [],
169
+ "subjectHandle": "alice.test",
170
+ },
171
+ Object {
172
+ "createdAt": "1970-01-01T00:00:00.000Z",
173
+ "createdBy": "user(1)",
174
+ "event": Object {
175
+ "$type": "com.atproto.admin.defs#modEventTag",
176
+ "add": Array [
177
+ "lang:und",
178
+ ],
179
+ "remove": Array [],
180
+ },
181
+ "id": 6,
141
182
  "subject": Object {
142
183
  "$type": "com.atproto.repo.strongRef",
143
184
  "cid": "cids(0)",
@@ -155,7 +196,7 @@ Array [
155
196
  "comment": "X",
156
197
  "reportType": "com.atproto.moderation.defs#reasonSpam",
157
198
  },
158
- "id": 4,
199
+ "id": 5,
159
200
  "subject": Object {
160
201
  "$type": "com.atproto.repo.strongRef",
161
202
  "cid": "cids(0)",
@@ -1,10 +1,52 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
+ exports[`moderation-statuses query statuses returns statuses filtered by subject language 1`] = `
4
+ Array [
5
+ Object {
6
+ "createdAt": "1970-01-01T00:00:00.000Z",
7
+ "id": 7,
8
+ "lastReportedAt": "1970-01-01T00:00:00.000Z",
9
+ "reviewState": "com.atproto.admin.defs#reviewOpen",
10
+ "subject": Object {
11
+ "$type": "com.atproto.repo.strongRef",
12
+ "cid": "cids(0)",
13
+ "uri": "record(0)",
14
+ },
15
+ "subjectBlobCids": Array [],
16
+ "subjectRepoHandle": "bob.test",
17
+ "tags": Array [
18
+ "lang:en",
19
+ "lang:i",
20
+ ],
21
+ "takendown": false,
22
+ "updatedAt": "1970-01-01T00:00:00.000Z",
23
+ },
24
+ Object {
25
+ "createdAt": "1970-01-01T00:00:00.000Z",
26
+ "id": 5,
27
+ "lastReportedAt": "1970-01-01T00:00:00.000Z",
28
+ "reviewState": "com.atproto.admin.defs#reviewOpen",
29
+ "subject": Object {
30
+ "$type": "com.atproto.admin.defs#repoRef",
31
+ "did": "user(0)",
32
+ },
33
+ "subjectBlobCids": Array [],
34
+ "subjectRepoHandle": "bob.test",
35
+ "tags": Array [
36
+ "lang:en",
37
+ "lang:i",
38
+ ],
39
+ "takendown": false,
40
+ "updatedAt": "1970-01-01T00:00:00.000Z",
41
+ },
42
+ ]
43
+ `;
44
+
3
45
  exports[`moderation-statuses query statuses returns statuses for subjects that received moderation events 1`] = `
4
46
  Array [
5
47
  Object {
6
48
  "createdAt": "1970-01-01T00:00:00.000Z",
7
- "id": 4,
49
+ "id": 7,
8
50
  "lastReportedAt": "1970-01-01T00:00:00.000Z",
9
51
  "reviewState": "com.atproto.admin.defs#reviewOpen",
10
52
  "subject": Object {
@@ -14,12 +56,16 @@ Array [
14
56
  },
15
57
  "subjectBlobCids": Array [],
16
58
  "subjectRepoHandle": "bob.test",
59
+ "tags": Array [
60
+ "lang:en",
61
+ "lang:i",
62
+ ],
17
63
  "takendown": false,
18
64
  "updatedAt": "1970-01-01T00:00:00.000Z",
19
65
  },
20
66
  Object {
21
67
  "createdAt": "1970-01-01T00:00:00.000Z",
22
- "id": 3,
68
+ "id": 5,
23
69
  "lastReportedAt": "1970-01-01T00:00:00.000Z",
24
70
  "reviewState": "com.atproto.admin.defs#reviewOpen",
25
71
  "subject": Object {
@@ -28,12 +74,16 @@ Array [
28
74
  },
29
75
  "subjectBlobCids": Array [],
30
76
  "subjectRepoHandle": "bob.test",
77
+ "tags": Array [
78
+ "lang:en",
79
+ "lang:i",
80
+ ],
31
81
  "takendown": false,
32
82
  "updatedAt": "1970-01-01T00:00:00.000Z",
33
83
  },
34
84
  Object {
35
85
  "createdAt": "1970-01-01T00:00:00.000Z",
36
- "id": 2,
86
+ "id": 3,
37
87
  "lastReportedAt": "1970-01-01T00:00:00.000Z",
38
88
  "reviewState": "com.atproto.admin.defs#reviewOpen",
39
89
  "subject": Object {
@@ -43,6 +93,9 @@ Array [
43
93
  },
44
94
  "subjectBlobCids": Array [],
45
95
  "subjectRepoHandle": "alice.test",
96
+ "tags": Array [
97
+ "lang:und",
98
+ ],
46
99
  "takendown": false,
47
100
  "updatedAt": "1970-01-01T00:00:00.000Z",
48
101
  },
@@ -57,6 +110,9 @@ Array [
57
110
  },
58
111
  "subjectBlobCids": Array [],
59
112
  "subjectRepoHandle": "alice.test",
113
+ "tags": Array [
114
+ "lang:und",
115
+ ],
60
116
  "takendown": false,
61
117
  "updatedAt": "1970-01-01T00:00:00.000Z",
62
118
  },
@@ -4,7 +4,7 @@ exports[`moderation reporting creates reports of a record. 1`] = `
4
4
  Array [
5
5
  Object {
6
6
  "createdAt": "1970-01-01T00:00:00.000Z",
7
- "id": 6,
7
+ "id": 7,
8
8
  "reasonType": "com.atproto.moderation.defs#reasonSpam",
9
9
  "reportedBy": "user(0)",
10
10
  "subject": Object {
@@ -15,7 +15,7 @@ Array [
15
15
  },
16
16
  Object {
17
17
  "createdAt": "1970-01-01T00:00:00.000Z",
18
- "id": 7,
18
+ "id": 9,
19
19
  "reason": "defamation",
20
20
  "reasonType": "com.atproto.moderation.defs#reasonOther",
21
21
  "reportedBy": "user(1)",
@@ -42,7 +42,7 @@ Array [
42
42
  },
43
43
  Object {
44
44
  "createdAt": "1970-01-01T00:00:00.000Z",
45
- "id": 4,
45
+ "id": 5,
46
46
  "reason": "impersonation",
47
47
  "reasonType": "com.atproto.moderation.defs#reasonOther",
48
48
  "reportedBy": "user(2)",
@@ -27,14 +27,6 @@ describe('admin get record view', () => {
27
27
  })
28
28
 
29
29
  beforeAll(async () => {
30
- await sc.emitModerationEvent({
31
- event: { $type: 'com.atproto.admin.defs#modEventFlag' },
32
- subject: {
33
- $type: 'com.atproto.repo.strongRef',
34
- uri: sc.posts[sc.dids.alice][0].ref.uriStr,
35
- cid: sc.posts[sc.dids.alice][0].ref.cidStr,
36
- },
37
- })
38
30
  await sc.createReport({
39
31
  reportedBy: sc.dids.bob,
40
32
  reasonType: REASONSPAM,