@atproto/ozone 0.0.9 → 0.0.10
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 +9 -0
- package/dist/api/moderation/util.d.ts +1 -1
- package/dist/db/index.js +20 -1
- package/dist/db/index.js.map +3 -3
- package/dist/db/migrations/20240208T213404429Z-add-tags-column-to-moderation-subject.d.ts +3 -0
- package/dist/db/migrations/index.d.ts +1 -0
- package/dist/db/schema/moderation_event.d.ts +3 -1
- package/dist/db/schema/moderation_subject_status.d.ts +1 -0
- package/dist/index.js +318 -51
- package/dist/index.js.map +3 -3
- package/dist/lexicon/lexicons.d.ts +57 -0
- package/dist/lexicon/types/com/atproto/admin/defs.d.ts +9 -0
- package/dist/lexicon/types/com/atproto/admin/emitModerationEvent.d.ts +1 -1
- package/dist/lexicon/types/com/atproto/admin/queryModerationEvents.d.ts +2 -0
- package/dist/lexicon/types/com/atproto/admin/queryModerationStatuses.d.ts +2 -0
- package/dist/logger.d.ts +1 -0
- package/dist/mod-service/index.d.ts +18 -4
- package/dist/mod-service/lang.d.ts +15 -0
- package/dist/mod-service/status.d.ts +1 -1
- package/dist/mod-service/types.d.ts +1 -1
- package/dist/mod-service/views.d.ts +2 -1
- package/package.json +6 -6
- package/src/api/admin/emitModerationEvent.ts +22 -10
- package/src/api/admin/queryModerationEvents.ts +4 -0
- package/src/api/admin/queryModerationStatuses.ts +4 -0
- package/src/api/moderation/createReport.ts +15 -4
- package/src/api/moderation/util.ts +1 -0
- package/src/db/migrations/20240208T213404429Z-add-tags-column-to-moderation-subject.ts +31 -0
- package/src/db/migrations/index.ts +1 -0
- package/src/db/schema/moderation_event.ts +3 -0
- package/src/db/schema/moderation_subject_status.ts +1 -0
- package/src/lexicon/lexicons.ts +62 -0
- package/src/lexicon/types/com/atproto/admin/defs.ts +24 -0
- package/src/lexicon/types/com/atproto/admin/emitModerationEvent.ts +1 -0
- package/src/lexicon/types/com/atproto/admin/queryModerationEvents.ts +4 -0
- package/src/lexicon/types/com/atproto/admin/queryModerationStatuses.ts +2 -0
- package/src/logger.ts +2 -0
- package/src/mod-service/index.ts +60 -10
- package/src/mod-service/lang.ts +82 -0
- package/src/mod-service/status.ts +18 -4
- package/src/mod-service/types.ts +1 -0
- package/src/mod-service/views.ts +21 -2
- package/tests/__snapshots__/get-record.test.ts.snap +6 -0
- package/tests/__snapshots__/get-repo.test.ts.snap +3 -0
- package/tests/__snapshots__/moderation-events.test.ts.snap +45 -4
- package/tests/__snapshots__/moderation-statuses.test.ts.snap +59 -3
- package/tests/__snapshots__/moderation.test.ts.snap +3 -3
- package/tests/get-record.test.ts +0 -8
- package/tests/moderation-events.test.ts +57 -5
- package/tests/moderation-status-tags.test.ts +92 -0
- package/tests/moderation-statuses.test.ts +20 -3
|
@@ -31,6 +31,10 @@ export interface QueryParams {
|
|
|
31
31
|
addedLabels?: string[]
|
|
32
32
|
/** If specified, only events where all of these labels were removed are returned */
|
|
33
33
|
removedLabels?: string[]
|
|
34
|
+
/** If specified, only events where all of these tags were added are returned */
|
|
35
|
+
addedTags?: string[]
|
|
36
|
+
/** If specified, only events where all of these tags were removed are returned */
|
|
37
|
+
removedTags?: string[]
|
|
34
38
|
reportTypes?: string[]
|
|
35
39
|
cursor?: string
|
|
36
40
|
}
|
package/src/logger.ts
CHANGED
|
@@ -5,6 +5,8 @@ export const dbLogger: ReturnType<typeof subsystemLogger> =
|
|
|
5
5
|
subsystemLogger('ozone:db')
|
|
6
6
|
export const httpLogger: ReturnType<typeof subsystemLogger> =
|
|
7
7
|
subsystemLogger('ozone')
|
|
8
|
+
export const langLogger: ReturnType<typeof subsystemLogger> =
|
|
9
|
+
subsystemLogger('ozone:lang')
|
|
8
10
|
|
|
9
11
|
export const loggerMiddleware = pinoHttp({
|
|
10
12
|
logger: httpLogger,
|
package/src/mod-service/index.ts
CHANGED
|
@@ -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<
|
|
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(
|
|
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
|
|
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
|
|
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<
|
|
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
|
|
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
|
|
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
|
-
|
|
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 =
|
package/src/mod-service/types.ts
CHANGED
package/src/mod-service/views.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
},
|
|
@@ -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":
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
45
|
+
"id": 5,
|
|
46
46
|
"reason": "impersonation",
|
|
47
47
|
"reasonType": "com.atproto.moderation.defs#reasonOther",
|
|
48
48
|
"reportedBy": "user(2)",
|
package/tests/get-record.test.ts
CHANGED
|
@@ -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,
|