@atproto/ozone 0.1.59 → 0.1.61
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 +14 -0
- package/dist/api/moderation/emitEvent.d.ts.map +1 -1
- package/dist/api/moderation/emitEvent.js +5 -1
- package/dist/api/moderation/emitEvent.js.map +1 -1
- package/dist/api/report/createReport.d.ts.map +1 -1
- package/dist/api/report/createReport.js +2 -1
- package/dist/api/report/createReport.js.map +1 -1
- package/dist/lexicon/index.d.ts +4 -2
- package/dist/lexicon/index.d.ts.map +1 -1
- package/dist/lexicon/index.js +4 -0
- package/dist/lexicon/index.js.map +1 -1
- package/dist/lexicon/lexicons.d.ts +138 -0
- package/dist/lexicon/lexicons.d.ts.map +1 -1
- package/dist/lexicon/lexicons.js +70 -0
- package/dist/lexicon/lexicons.js.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/defs.d.ts +9 -0
- package/dist/lexicon/types/app/bsky/unspecced/defs.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/defs.js +10 -0
- package/dist/lexicon/types/app/bsky/unspecced/defs.js.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/getTrendingTopics.d.ts +39 -0
- package/dist/lexicon/types/app/bsky/unspecced/getTrendingTopics.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/unspecced/getTrendingTopics.js +3 -0
- package/dist/lexicon/types/app/bsky/unspecced/getTrendingTopics.js.map +1 -0
- package/dist/mod-service/index.d.ts +2 -0
- package/dist/mod-service/index.d.ts.map +1 -1
- package/dist/mod-service/index.js +34 -1
- package/dist/mod-service/index.js.map +1 -1
- package/dist/tag-service/index.d.ts +1 -1
- package/dist/tag-service/index.d.ts.map +1 -1
- package/dist/tag-service/index.js +15 -6
- package/dist/tag-service/index.js.map +1 -1
- package/dist/tag-service/util.d.ts +3 -0
- package/dist/tag-service/util.d.ts.map +1 -0
- package/dist/tag-service/util.js +8 -0
- package/dist/tag-service/util.js.map +1 -0
- package/package.json +4 -4
- package/src/api/moderation/emitEvent.ts +6 -1
- package/src/api/report/createReport.ts +2 -1
- package/src/lexicon/index.ts +14 -2
- package/src/lexicon/lexicons.ts +72 -0
- package/src/lexicon/types/app/bsky/unspecced/defs.ts +20 -0
- package/src/lexicon/types/app/bsky/unspecced/getTrendingTopics.ts +49 -0
- package/src/mod-service/index.ts +41 -6
- package/src/tag-service/index.ts +16 -5
- package/src/tag-service/util.ts +5 -0
- package/tests/__snapshots__/get-record.test.ts.snap +4 -0
- package/tests/__snapshots__/get-records.test.ts.snap +2 -0
- package/tests/__snapshots__/get-repo.test.ts.snap +2 -0
- package/tests/__snapshots__/get-repos.test.ts.snap +2 -0
- package/tests/__snapshots__/moderation-events.test.ts.snap +7 -3
- package/tests/__snapshots__/moderation-statuses.test.ts.snap +6 -0
- package/tests/__snapshots__/moderation.test.ts.snap +4 -4
- package/tests/content-tagger.test.ts +29 -0
- package/tests/moderation-status-tags.test.ts +37 -0
- package/tests/report-muting.test.ts +1 -1
- package/tsconfig.build.tsbuildinfo +1 -1
package/src/lexicon/lexicons.ts
CHANGED
|
@@ -9257,6 +9257,24 @@ export const schemaDict = {
|
|
|
9257
9257
|
},
|
|
9258
9258
|
},
|
|
9259
9259
|
},
|
|
9260
|
+
trendingTopic: {
|
|
9261
|
+
type: 'object',
|
|
9262
|
+
required: ['topic', 'link'],
|
|
9263
|
+
properties: {
|
|
9264
|
+
topic: {
|
|
9265
|
+
type: 'string',
|
|
9266
|
+
},
|
|
9267
|
+
displayName: {
|
|
9268
|
+
type: 'string',
|
|
9269
|
+
},
|
|
9270
|
+
description: {
|
|
9271
|
+
type: 'string',
|
|
9272
|
+
},
|
|
9273
|
+
link: {
|
|
9274
|
+
type: 'string',
|
|
9275
|
+
},
|
|
9276
|
+
},
|
|
9277
|
+
},
|
|
9260
9278
|
},
|
|
9261
9279
|
},
|
|
9262
9280
|
AppBskyUnspeccedGetConfig: {
|
|
@@ -9437,6 +9455,56 @@ export const schemaDict = {
|
|
|
9437
9455
|
},
|
|
9438
9456
|
},
|
|
9439
9457
|
},
|
|
9458
|
+
AppBskyUnspeccedGetTrendingTopics: {
|
|
9459
|
+
lexicon: 1,
|
|
9460
|
+
id: 'app.bsky.unspecced.getTrendingTopics',
|
|
9461
|
+
defs: {
|
|
9462
|
+
main: {
|
|
9463
|
+
type: 'query',
|
|
9464
|
+
description: 'Get a list of trending topics',
|
|
9465
|
+
parameters: {
|
|
9466
|
+
type: 'params',
|
|
9467
|
+
properties: {
|
|
9468
|
+
viewer: {
|
|
9469
|
+
type: 'string',
|
|
9470
|
+
format: 'did',
|
|
9471
|
+
description:
|
|
9472
|
+
'DID of the account making the request (not included for public/unauthenticated queries). Used to boost followed accounts in ranking.',
|
|
9473
|
+
},
|
|
9474
|
+
limit: {
|
|
9475
|
+
type: 'integer',
|
|
9476
|
+
minimum: 1,
|
|
9477
|
+
maximum: 25,
|
|
9478
|
+
default: 10,
|
|
9479
|
+
},
|
|
9480
|
+
},
|
|
9481
|
+
},
|
|
9482
|
+
output: {
|
|
9483
|
+
encoding: 'application/json',
|
|
9484
|
+
schema: {
|
|
9485
|
+
type: 'object',
|
|
9486
|
+
required: ['topics', 'suggested'],
|
|
9487
|
+
properties: {
|
|
9488
|
+
topics: {
|
|
9489
|
+
type: 'array',
|
|
9490
|
+
items: {
|
|
9491
|
+
type: 'ref',
|
|
9492
|
+
ref: 'lex:app.bsky.unspecced.defs#trendingTopic',
|
|
9493
|
+
},
|
|
9494
|
+
},
|
|
9495
|
+
suggested: {
|
|
9496
|
+
type: 'array',
|
|
9497
|
+
items: {
|
|
9498
|
+
type: 'ref',
|
|
9499
|
+
ref: 'lex:app.bsky.unspecced.defs#trendingTopic',
|
|
9500
|
+
},
|
|
9501
|
+
},
|
|
9502
|
+
},
|
|
9503
|
+
},
|
|
9504
|
+
},
|
|
9505
|
+
},
|
|
9506
|
+
},
|
|
9507
|
+
},
|
|
9440
9508
|
AppBskyUnspeccedSearchActorsSkeleton: {
|
|
9441
9509
|
lexicon: 1,
|
|
9442
9510
|
id: 'app.bsky.unspecced.searchActorsSkeleton',
|
|
@@ -12430,6 +12498,9 @@ export const schemaDict = {
|
|
|
12430
12498
|
type: 'array',
|
|
12431
12499
|
items: {
|
|
12432
12500
|
type: 'string',
|
|
12501
|
+
maxLength: 25,
|
|
12502
|
+
description:
|
|
12503
|
+
'Items in this array are applied with OR filters. To apply AND filter, put all tags in the same string and separate using && characters',
|
|
12433
12504
|
},
|
|
12434
12505
|
},
|
|
12435
12506
|
excludeTags: {
|
|
@@ -13686,6 +13757,7 @@ export const ids = {
|
|
|
13686
13757
|
'app.bsky.unspecced.getSuggestionsSkeleton',
|
|
13687
13758
|
AppBskyUnspeccedGetTaggedSuggestions:
|
|
13688
13759
|
'app.bsky.unspecced.getTaggedSuggestions',
|
|
13760
|
+
AppBskyUnspeccedGetTrendingTopics: 'app.bsky.unspecced.getTrendingTopics',
|
|
13689
13761
|
AppBskyUnspeccedSearchActorsSkeleton:
|
|
13690
13762
|
'app.bsky.unspecced.searchActorsSkeleton',
|
|
13691
13763
|
AppBskyUnspeccedSearchPostsSkeleton: 'app.bsky.unspecced.searchPostsSkeleton',
|
|
@@ -63,3 +63,23 @@ export function validateSkeletonSearchStarterPack(
|
|
|
63
63
|
v,
|
|
64
64
|
)
|
|
65
65
|
}
|
|
66
|
+
|
|
67
|
+
export interface TrendingTopic {
|
|
68
|
+
topic: string
|
|
69
|
+
displayName?: string
|
|
70
|
+
description?: string
|
|
71
|
+
link: string
|
|
72
|
+
[k: string]: unknown
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function isTrendingTopic(v: unknown): v is TrendingTopic {
|
|
76
|
+
return (
|
|
77
|
+
isObj(v) &&
|
|
78
|
+
hasProp(v, '$type') &&
|
|
79
|
+
v.$type === 'app.bsky.unspecced.defs#trendingTopic'
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function validateTrendingTopic(v: unknown): ValidationResult {
|
|
84
|
+
return lexicons.validate('app.bsky.unspecced.defs#trendingTopic', v)
|
|
85
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
import express from 'express'
|
|
5
|
+
import { ValidationResult, BlobRef } from '@atproto/lexicon'
|
|
6
|
+
import { lexicons } from '../../../../lexicons'
|
|
7
|
+
import { isObj, hasProp } from '../../../../util'
|
|
8
|
+
import { CID } from 'multiformats/cid'
|
|
9
|
+
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
|
|
10
|
+
import * as AppBskyUnspeccedDefs from './defs'
|
|
11
|
+
|
|
12
|
+
export interface QueryParams {
|
|
13
|
+
/** DID of the account making the request (not included for public/unauthenticated queries). Used to boost followed accounts in ranking. */
|
|
14
|
+
viewer?: string
|
|
15
|
+
limit: number
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type InputSchema = undefined
|
|
19
|
+
|
|
20
|
+
export interface OutputSchema {
|
|
21
|
+
topics: AppBskyUnspeccedDefs.TrendingTopic[]
|
|
22
|
+
suggested: AppBskyUnspeccedDefs.TrendingTopic[]
|
|
23
|
+
[k: string]: unknown
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type HandlerInput = undefined
|
|
27
|
+
|
|
28
|
+
export interface HandlerSuccess {
|
|
29
|
+
encoding: 'application/json'
|
|
30
|
+
body: OutputSchema
|
|
31
|
+
headers?: { [key: string]: string }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface HandlerError {
|
|
35
|
+
status: number
|
|
36
|
+
message?: string
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough
|
|
40
|
+
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
41
|
+
auth: HA
|
|
42
|
+
params: QueryParams
|
|
43
|
+
input: HandlerInput
|
|
44
|
+
req: express.Request
|
|
45
|
+
res: express.Response
|
|
46
|
+
}
|
|
47
|
+
export type Handler<HA extends HandlerAuth = never> = (
|
|
48
|
+
ctx: HandlerReqCtx<HA>,
|
|
49
|
+
) => Promise<HandlerOutput> | HandlerOutput
|
package/src/mod-service/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import net from 'node:net'
|
|
2
|
-
import { Insertable, sql } from 'kysely'
|
|
2
|
+
import { Insertable, SelectQueryBuilder, sql } from 'kysely'
|
|
3
3
|
import { CID } from 'multiformats/cid'
|
|
4
4
|
import { AtUri, INVALID_HANDLE } from '@atproto/syntax'
|
|
5
5
|
import { InvalidRequestError } from '@atproto/xrpc-server'
|
|
@@ -791,6 +791,45 @@ export class ModerationService {
|
|
|
791
791
|
return result
|
|
792
792
|
}
|
|
793
793
|
|
|
794
|
+
applyTagFilter = (
|
|
795
|
+
builder: SelectQueryBuilder<any, any, any>,
|
|
796
|
+
tags: string[],
|
|
797
|
+
) => {
|
|
798
|
+
const { ref } = this.db.db.dynamic
|
|
799
|
+
// Build an array of conditions
|
|
800
|
+
const conditions = tags
|
|
801
|
+
.map((tag) => {
|
|
802
|
+
if (tag.includes('&&')) {
|
|
803
|
+
// Split by '&&' for AND logic
|
|
804
|
+
const subTags = tag
|
|
805
|
+
.split('&&')
|
|
806
|
+
// Make sure spaces on either sides of '&&' are trimmed
|
|
807
|
+
.map((subTag) => subTag.trim())
|
|
808
|
+
// Remove empty strings after trimming is applied
|
|
809
|
+
.filter(Boolean)
|
|
810
|
+
|
|
811
|
+
if (!subTags.length) return null
|
|
812
|
+
|
|
813
|
+
return sql`(${sql.join(
|
|
814
|
+
subTags.map(
|
|
815
|
+
(subTag) =>
|
|
816
|
+
sql`${ref('moderation_subject_status.tags')} ? ${subTag}`,
|
|
817
|
+
),
|
|
818
|
+
sql` AND `,
|
|
819
|
+
)})`
|
|
820
|
+
} else {
|
|
821
|
+
// Single tag condition
|
|
822
|
+
return sql`${ref('moderation_subject_status.tags')} ? ${tag}`
|
|
823
|
+
}
|
|
824
|
+
})
|
|
825
|
+
.filter(Boolean)
|
|
826
|
+
|
|
827
|
+
if (!conditions.length) return builder
|
|
828
|
+
|
|
829
|
+
// Combine all conditions with OR
|
|
830
|
+
return builder.where(sql`(${sql.join(conditions, sql` OR `)})`)
|
|
831
|
+
}
|
|
832
|
+
|
|
794
833
|
async getSubjectStatuses({
|
|
795
834
|
includeAllUserRecords,
|
|
796
835
|
cursor,
|
|
@@ -958,11 +997,7 @@ export class ModerationService {
|
|
|
958
997
|
}
|
|
959
998
|
|
|
960
999
|
if (tags.length) {
|
|
961
|
-
builder =
|
|
962
|
-
sql`${ref('moderation_subject_status.tags')} ?| array[${sql.join(
|
|
963
|
-
tags,
|
|
964
|
-
)}]::TEXT[]`,
|
|
965
|
-
)
|
|
1000
|
+
builder = this.applyTagFilter(builder, tags)
|
|
966
1001
|
}
|
|
967
1002
|
|
|
968
1003
|
if (excludeTags.length) {
|
package/src/tag-service/index.ts
CHANGED
|
@@ -22,15 +22,18 @@ export class TagService {
|
|
|
22
22
|
]
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
// Allow the caller to seed the initial tags
|
|
26
|
+
async evaluateForSubject(initialTags?: Iterable<string>) {
|
|
26
27
|
try {
|
|
27
|
-
const tags
|
|
28
|
+
const tags = new Set(initialTags)
|
|
28
29
|
|
|
29
30
|
await Promise.all(
|
|
30
31
|
this.taggers.map(async (tagger) => {
|
|
31
32
|
try {
|
|
32
33
|
const newTags = await tagger.getTags()
|
|
33
|
-
|
|
34
|
+
for (const newTag of newTags) {
|
|
35
|
+
tags.add(newTag)
|
|
36
|
+
}
|
|
34
37
|
} catch (e) {
|
|
35
38
|
// Don't let one tagger error stop the rest from running
|
|
36
39
|
log.error(
|
|
@@ -41,11 +44,19 @@ export class TagService {
|
|
|
41
44
|
}),
|
|
42
45
|
)
|
|
43
46
|
|
|
44
|
-
|
|
47
|
+
// Ensure that before inserting new tags, we discard any tag that may
|
|
48
|
+
// have been evaluated to be added but is already present in the subject
|
|
49
|
+
if (this.subjectStatus?.tags?.length) {
|
|
50
|
+
for (const tag of this.subjectStatus.tags) {
|
|
51
|
+
tags.delete(tag)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (tags.size) {
|
|
45
56
|
await this.moderationService.logEvent({
|
|
46
57
|
event: {
|
|
47
58
|
$type: 'tools.ozone.moderation.defs#modEventTag',
|
|
48
|
-
add: tags,
|
|
59
|
+
add: [...tags],
|
|
49
60
|
remove: [],
|
|
50
61
|
},
|
|
51
62
|
subject: this.subject,
|
|
@@ -46,7 +46,9 @@ Object {
|
|
|
46
46
|
"subjectBlobCids": Array [],
|
|
47
47
|
"subjectRepoHandle": "alice.test",
|
|
48
48
|
"tags": Array [
|
|
49
|
+
"report:spam",
|
|
49
50
|
"lang:en",
|
|
51
|
+
"report:other",
|
|
50
52
|
],
|
|
51
53
|
"takendown": true,
|
|
52
54
|
"updatedAt": "1970-01-01T00:00:00.000Z",
|
|
@@ -150,7 +152,9 @@ Object {
|
|
|
150
152
|
"subjectBlobCids": Array [],
|
|
151
153
|
"subjectRepoHandle": "alice.test",
|
|
152
154
|
"tags": Array [
|
|
155
|
+
"report:spam",
|
|
153
156
|
"lang:en",
|
|
157
|
+
"report:other",
|
|
154
158
|
],
|
|
155
159
|
"takendown": true,
|
|
156
160
|
"updatedAt": "1970-01-01T00:00:00.000Z",
|
|
@@ -35,7 +35,9 @@ Object {
|
|
|
35
35
|
"subjectBlobCids": Array [],
|
|
36
36
|
"subjectRepoHandle": "alice.test",
|
|
37
37
|
"tags": Array [
|
|
38
|
+
"report:misleading",
|
|
38
39
|
"lang:und",
|
|
40
|
+
"report:spam",
|
|
39
41
|
],
|
|
40
42
|
"takendown": false,
|
|
41
43
|
"updatedAt": "1970-01-01T00:00:00.000Z",
|
|
@@ -101,6 +103,7 @@ Array [
|
|
|
101
103
|
"event": Object {
|
|
102
104
|
"$type": "tools.ozone.moderation.defs#modEventTag",
|
|
103
105
|
"add": Array [
|
|
106
|
+
"report:spam",
|
|
104
107
|
"lang:en",
|
|
105
108
|
"lang:i",
|
|
106
109
|
],
|
|
@@ -163,6 +166,7 @@ Array [
|
|
|
163
166
|
"event": Object {
|
|
164
167
|
"$type": "tools.ozone.moderation.defs#modEventTag",
|
|
165
168
|
"add": Array [
|
|
169
|
+
"report:spam",
|
|
166
170
|
"lang:en",
|
|
167
171
|
],
|
|
168
172
|
"remove": Array [],
|
|
@@ -210,7 +214,7 @@ Array [
|
|
|
210
214
|
"isReporterMuted": false,
|
|
211
215
|
"reportType": "com.atproto.moderation.defs#reasonSpam",
|
|
212
216
|
},
|
|
213
|
-
"id":
|
|
217
|
+
"id": 17,
|
|
214
218
|
"subject": Object {
|
|
215
219
|
"$type": "com.atproto.admin.defs#repoRef",
|
|
216
220
|
"did": "user(0)",
|
|
@@ -251,7 +255,7 @@ Array [
|
|
|
251
255
|
"isReporterMuted": false,
|
|
252
256
|
"reportType": "com.atproto.moderation.defs#reasonSpam",
|
|
253
257
|
},
|
|
254
|
-
"id":
|
|
258
|
+
"id": 17,
|
|
255
259
|
"subject": Object {
|
|
256
260
|
"$type": "com.atproto.admin.defs#repoRef",
|
|
257
261
|
"did": "user(0)",
|
|
@@ -292,7 +296,7 @@ Array [
|
|
|
292
296
|
"isReporterMuted": false,
|
|
293
297
|
"reportType": "com.atproto.moderation.defs#reasonSpam",
|
|
294
298
|
},
|
|
295
|
-
"id":
|
|
299
|
+
"id": 17,
|
|
296
300
|
"subject": Object {
|
|
297
301
|
"$type": "com.atproto.admin.defs#repoRef",
|
|
298
302
|
"did": "user(0)",
|
|
@@ -19,6 +19,7 @@ Array [
|
|
|
19
19
|
"subjectBlobCids": Array [],
|
|
20
20
|
"subjectRepoHandle": "bob.test",
|
|
21
21
|
"tags": Array [
|
|
22
|
+
"report:spam",
|
|
22
23
|
"lang:en",
|
|
23
24
|
"lang:i",
|
|
24
25
|
],
|
|
@@ -41,6 +42,7 @@ Array [
|
|
|
41
42
|
"subjectBlobCids": Array [],
|
|
42
43
|
"subjectRepoHandle": "bob.test",
|
|
43
44
|
"tags": Array [
|
|
45
|
+
"report:spam",
|
|
44
46
|
"lang:en",
|
|
45
47
|
"lang:i",
|
|
46
48
|
],
|
|
@@ -69,6 +71,7 @@ Array [
|
|
|
69
71
|
"subjectBlobCids": Array [],
|
|
70
72
|
"subjectRepoHandle": "bob.test",
|
|
71
73
|
"tags": Array [
|
|
74
|
+
"report:spam",
|
|
72
75
|
"lang:en",
|
|
73
76
|
"lang:i",
|
|
74
77
|
],
|
|
@@ -91,6 +94,7 @@ Array [
|
|
|
91
94
|
"subjectBlobCids": Array [],
|
|
92
95
|
"subjectRepoHandle": "bob.test",
|
|
93
96
|
"tags": Array [
|
|
97
|
+
"report:spam",
|
|
94
98
|
"lang:en",
|
|
95
99
|
"lang:i",
|
|
96
100
|
],
|
|
@@ -114,6 +118,7 @@ Array [
|
|
|
114
118
|
"subjectBlobCids": Array [],
|
|
115
119
|
"subjectRepoHandle": "alice.test",
|
|
116
120
|
"tags": Array [
|
|
121
|
+
"report:spam",
|
|
117
122
|
"lang:ha",
|
|
118
123
|
],
|
|
119
124
|
"takendown": false,
|
|
@@ -135,6 +140,7 @@ Array [
|
|
|
135
140
|
"subjectBlobCids": Array [],
|
|
136
141
|
"subjectRepoHandle": "alice.test",
|
|
137
142
|
"tags": Array [
|
|
143
|
+
"report:misleading",
|
|
138
144
|
"lang:und",
|
|
139
145
|
],
|
|
140
146
|
"takendown": false,
|
|
@@ -4,7 +4,7 @@ exports[`moderation reporting creates reports of a DM chat. 1`] = `
|
|
|
4
4
|
Array [
|
|
5
5
|
Object {
|
|
6
6
|
"createdAt": "1970-01-01T00:00:00.000Z",
|
|
7
|
-
"id":
|
|
7
|
+
"id": 14,
|
|
8
8
|
"reasonType": "com.atproto.moderation.defs#reasonSpam",
|
|
9
9
|
"reportedBy": "user(0)",
|
|
10
10
|
"subject": Object {
|
|
@@ -16,7 +16,7 @@ Array [
|
|
|
16
16
|
},
|
|
17
17
|
Object {
|
|
18
18
|
"createdAt": "1970-01-01T00:00:00.000Z",
|
|
19
|
-
"id":
|
|
19
|
+
"id": 16,
|
|
20
20
|
"reason": "defamation",
|
|
21
21
|
"reasonType": "com.atproto.moderation.defs#reasonOther",
|
|
22
22
|
"reportedBy": "user(1)",
|
|
@@ -34,7 +34,7 @@ exports[`moderation reporting creates reports of a record. 1`] = `
|
|
|
34
34
|
Array [
|
|
35
35
|
Object {
|
|
36
36
|
"createdAt": "1970-01-01T00:00:00.000Z",
|
|
37
|
-
"id":
|
|
37
|
+
"id": 7,
|
|
38
38
|
"reasonType": "com.atproto.moderation.defs#reasonSpam",
|
|
39
39
|
"reportedBy": "user(0)",
|
|
40
40
|
"subject": Object {
|
|
@@ -45,7 +45,7 @@ Array [
|
|
|
45
45
|
},
|
|
46
46
|
Object {
|
|
47
47
|
"createdAt": "1970-01-01T00:00:00.000Z",
|
|
48
|
-
"id":
|
|
48
|
+
"id": 9,
|
|
49
49
|
"reason": "defamation",
|
|
50
50
|
"reasonType": "com.atproto.moderation.defs#reasonOther",
|
|
51
51
|
"reportedBy": "user(1)",
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
basicSeed,
|
|
6
6
|
} from '@atproto/dev-env'
|
|
7
7
|
import { REASONSPAM } from '../src/lexicon/types/com/atproto/moderation/defs'
|
|
8
|
+
import { REASONMISLEADING } from '../dist/lexicon/types/com/atproto/moderation/defs'
|
|
8
9
|
|
|
9
10
|
describe('moderation subject content tagging', () => {
|
|
10
11
|
let network: TestNetwork
|
|
@@ -138,4 +139,32 @@ describe('moderation subject content tagging', () => {
|
|
|
138
139
|
expect(imagePostStatus.tags).toContain('embed:image')
|
|
139
140
|
})
|
|
140
141
|
})
|
|
142
|
+
|
|
143
|
+
describe('report tagger', () => {
|
|
144
|
+
it('Adds report reason tag', async () => {
|
|
145
|
+
await Promise.all([
|
|
146
|
+
sc.createReport({
|
|
147
|
+
reasonType: REASONSPAM,
|
|
148
|
+
subject: {
|
|
149
|
+
$type: 'com.atproto.admin.defs#repoRef',
|
|
150
|
+
did: sc.dids.carol,
|
|
151
|
+
},
|
|
152
|
+
reportedBy: sc.dids.alice,
|
|
153
|
+
}),
|
|
154
|
+
sc.createReport({
|
|
155
|
+
reasonType: REASONMISLEADING,
|
|
156
|
+
subject: {
|
|
157
|
+
$type: 'com.atproto.admin.defs#repoRef',
|
|
158
|
+
did: sc.dids.carol,
|
|
159
|
+
},
|
|
160
|
+
reportedBy: sc.dids.alice,
|
|
161
|
+
}),
|
|
162
|
+
])
|
|
163
|
+
|
|
164
|
+
const accountStatus = await getStatus(sc.dids.carol)
|
|
165
|
+
|
|
166
|
+
expect(accountStatus.tags).toContain('report:spam')
|
|
167
|
+
expect(accountStatus.tags).toContain('report:misleading')
|
|
168
|
+
})
|
|
169
|
+
})
|
|
141
170
|
})
|
|
@@ -71,5 +71,42 @@ describe('moderation-status-tags', () => {
|
|
|
71
71
|
'follow-churn',
|
|
72
72
|
)
|
|
73
73
|
})
|
|
74
|
+
|
|
75
|
+
it('allows filtering by tags', async () => {
|
|
76
|
+
await modClient.emitEvent({
|
|
77
|
+
subject: {
|
|
78
|
+
$type: 'com.atproto.admin.defs#repoRef',
|
|
79
|
+
did: sc.dids.alice,
|
|
80
|
+
},
|
|
81
|
+
event: {
|
|
82
|
+
$type: 'tools.ozone.moderation.defs#modEventTag',
|
|
83
|
+
add: ['report:spam', 'lang:ja', 'lang:en'],
|
|
84
|
+
remove: [],
|
|
85
|
+
},
|
|
86
|
+
})
|
|
87
|
+
const [englishAndJapaneseQueue, englishOrJapaneseQueue] =
|
|
88
|
+
await Promise.all([
|
|
89
|
+
modClient.queryStatuses({
|
|
90
|
+
tags: ['lang:ja&&lang:en'],
|
|
91
|
+
}),
|
|
92
|
+
modClient.queryStatuses({
|
|
93
|
+
tags: ['report:ja', 'lang:en'],
|
|
94
|
+
}),
|
|
95
|
+
])
|
|
96
|
+
|
|
97
|
+
// Verify that the queue only contains 1 item with both en and ja tags which is alice's account
|
|
98
|
+
expect(englishAndJapaneseQueue.subjectStatuses.length).toEqual(1)
|
|
99
|
+
expect(englishAndJapaneseQueue.subjectStatuses[0].subject.did).toEqual(
|
|
100
|
+
sc.dids.alice,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
// Verify that when querying for either en or ja tags, both alice and bob are returned
|
|
104
|
+
expect(englishOrJapaneseQueue.subjectStatuses.length).toEqual(2)
|
|
105
|
+
const englishOrJapaneseDids = englishOrJapaneseQueue.subjectStatuses.map(
|
|
106
|
+
({ subject }) => subject.did,
|
|
107
|
+
)
|
|
108
|
+
expect(englishOrJapaneseDids).toContain(sc.dids.alice)
|
|
109
|
+
expect(englishOrJapaneseDids).toContain(sc.dids.bob)
|
|
110
|
+
})
|
|
74
111
|
})
|
|
75
112
|
})
|
|
@@ -69,7 +69,7 @@ describe('report-muting', () => {
|
|
|
69
69
|
})
|
|
70
70
|
|
|
71
71
|
// Verify that a subject status was not created for bob's post since the reporter was muted
|
|
72
|
-
await assertSubjectStatus(bobsPostSubject.uri,
|
|
72
|
+
await assertSubjectStatus(bobsPostSubject.uri, REVIEWNONE)
|
|
73
73
|
// Verify, however, that the event was logged
|
|
74
74
|
await modClient.queryEvents({
|
|
75
75
|
subject: bobsPostSubject.uri,
|