@atproto/ozone 0.1.139 → 0.1.141

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 (106) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/api/moderation/emitEvent.d.ts.map +1 -1
  3. package/dist/api/moderation/emitEvent.js +3 -0
  4. package/dist/api/moderation/emitEvent.js.map +1 -1
  5. package/dist/api/report/createReport.d.ts.map +1 -1
  6. package/dist/api/report/createReport.js +7 -5
  7. package/dist/api/report/createReport.js.map +1 -1
  8. package/dist/api/util.d.ts +2 -3
  9. package/dist/api/util.d.ts.map +1 -1
  10. package/dist/api/util.js +7 -17
  11. package/dist/api/util.js.map +1 -1
  12. package/dist/config/config.d.ts +1 -0
  13. package/dist/config/config.d.ts.map +1 -1
  14. package/dist/config/config.js +1 -0
  15. package/dist/config/config.js.map +1 -1
  16. package/dist/config/env.d.ts +1 -0
  17. package/dist/config/env.d.ts.map +1 -1
  18. package/dist/config/env.js +1 -0
  19. package/dist/config/env.js.map +1 -1
  20. package/dist/context.d.ts +3 -0
  21. package/dist/context.d.ts.map +1 -1
  22. package/dist/context.js +6 -0
  23. package/dist/context.js.map +1 -1
  24. package/dist/db/migrations/20250718T150931000Z-update-appeal-reason-stats.d.ts +5 -0
  25. package/dist/db/migrations/20250718T150931000Z-update-appeal-reason-stats.d.ts.map +1 -0
  26. package/dist/db/migrations/20250718T150931000Z-update-appeal-reason-stats.js +228 -0
  27. package/dist/db/migrations/20250718T150931000Z-update-appeal-reason-stats.js.map +1 -0
  28. package/dist/db/migrations/index.d.ts +1 -0
  29. package/dist/db/migrations/index.d.ts.map +1 -1
  30. package/dist/db/migrations/index.js +2 -1
  31. package/dist/db/migrations/index.js.map +1 -1
  32. package/dist/lexicon/index.d.ts +60 -0
  33. package/dist/lexicon/index.d.ts.map +1 -1
  34. package/dist/lexicon/index.js +83 -1
  35. package/dist/lexicon/index.js.map +1 -1
  36. package/dist/lexicon/lexicons.d.ts +758 -16
  37. package/dist/lexicon/lexicons.d.ts.map +1 -1
  38. package/dist/lexicon/lexicons.js +485 -7
  39. package/dist/lexicon/lexicons.js.map +1 -1
  40. package/dist/lexicon/types/app/bsky/bookmark/createBookmark.d.ts +16 -0
  41. package/dist/lexicon/types/app/bsky/bookmark/createBookmark.d.ts.map +1 -0
  42. package/dist/lexicon/types/app/bsky/bookmark/createBookmark.js +7 -0
  43. package/dist/lexicon/types/app/bsky/bookmark/createBookmark.js.map +1 -0
  44. package/dist/lexicon/types/app/bsky/bookmark/defs.d.ts +25 -0
  45. package/dist/lexicon/types/app/bsky/bookmark/defs.d.ts.map +1 -0
  46. package/dist/lexicon/types/app/bsky/bookmark/defs.js +25 -0
  47. package/dist/lexicon/types/app/bsky/bookmark/defs.js.map +1 -0
  48. package/dist/lexicon/types/app/bsky/bookmark/deleteBookmark.d.ts +15 -0
  49. package/dist/lexicon/types/app/bsky/bookmark/deleteBookmark.d.ts.map +1 -0
  50. package/dist/lexicon/types/app/bsky/bookmark/deleteBookmark.js +7 -0
  51. package/dist/lexicon/types/app/bsky/bookmark/deleteBookmark.js.map +1 -0
  52. package/dist/lexicon/types/app/bsky/bookmark/getBookmarks.d.ts +24 -0
  53. package/dist/lexicon/types/app/bsky/bookmark/getBookmarks.d.ts.map +1 -0
  54. package/dist/lexicon/types/app/bsky/bookmark/getBookmarks.js +7 -0
  55. package/dist/lexicon/types/app/bsky/bookmark/getBookmarks.js.map +1 -0
  56. package/dist/lexicon/types/app/bsky/feed/defs.d.ts +2 -0
  57. package/dist/lexicon/types/app/bsky/feed/defs.d.ts.map +1 -1
  58. package/dist/lexicon/types/app/bsky/feed/defs.js.map +1 -1
  59. package/dist/lexicon/types/com/atproto/moderation/defs.d.ts +8 -8
  60. package/dist/lexicon/types/com/atproto/moderation/defs.d.ts.map +1 -1
  61. package/dist/lexicon/types/com/atproto/moderation/defs.js +7 -7
  62. package/dist/lexicon/types/com/atproto/moderation/defs.js.map +1 -1
  63. package/dist/lexicon/types/com/atproto/temp/dereferenceScope.d.ts +24 -0
  64. package/dist/lexicon/types/com/atproto/temp/dereferenceScope.d.ts.map +1 -0
  65. package/dist/lexicon/types/com/atproto/temp/dereferenceScope.js +7 -0
  66. package/dist/lexicon/types/com/atproto/temp/dereferenceScope.js.map +1 -0
  67. package/dist/lexicon/types/tools/ozone/report/defs.d.ts +92 -0
  68. package/dist/lexicon/types/tools/ozone/report/defs.d.ts.map +1 -0
  69. package/dist/lexicon/types/tools/ozone/report/defs.js +98 -0
  70. package/dist/lexicon/types/tools/ozone/report/defs.js.map +1 -0
  71. package/dist/mod-service/profile.d.ts +15 -0
  72. package/dist/mod-service/profile.d.ts.map +1 -0
  73. package/dist/mod-service/profile.js +135 -0
  74. package/dist/mod-service/profile.js.map +1 -0
  75. package/dist/mod-service/status.d.ts.map +1 -1
  76. package/dist/mod-service/status.js +18 -17
  77. package/dist/mod-service/status.js.map +1 -1
  78. package/dist/tag-service/util.d.ts.map +1 -1
  79. package/dist/tag-service/util.js +7 -1
  80. package/dist/tag-service/util.js.map +1 -1
  81. package/package.json +9 -9
  82. package/src/api/moderation/emitEvent.ts +4 -0
  83. package/src/api/report/createReport.ts +9 -9
  84. package/src/api/util.ts +7 -28
  85. package/src/config/config.ts +3 -1
  86. package/src/config/env.ts +2 -0
  87. package/src/context.ts +14 -0
  88. package/src/db/migrations/20250718T150931000Z-update-appeal-reason-stats.ts +311 -0
  89. package/src/db/migrations/index.ts +1 -0
  90. package/src/lexicon/index.ts +131 -0
  91. package/src/lexicon/lexicons.ts +503 -7
  92. package/src/lexicon/types/app/bsky/bookmark/createBookmark.ts +35 -0
  93. package/src/lexicon/types/app/bsky/bookmark/defs.ts +54 -0
  94. package/src/lexicon/types/app/bsky/bookmark/deleteBookmark.ts +34 -0
  95. package/src/lexicon/types/app/bsky/bookmark/getBookmarks.ts +42 -0
  96. package/src/lexicon/types/app/bsky/feed/defs.ts +2 -0
  97. package/src/lexicon/types/com/atproto/moderation/defs.ts +52 -7
  98. package/src/lexicon/types/com/atproto/temp/dereferenceScope.ts +42 -0
  99. package/src/lexicon/types/tools/ozone/report/defs.ts +154 -0
  100. package/src/mod-service/profile.ts +143 -0
  101. package/src/mod-service/status.ts +3 -2
  102. package/src/tag-service/util.ts +9 -1
  103. package/tests/__snapshots__/report-reason.test.ts.snap +14 -0
  104. package/tests/report-reason.test.ts +154 -0
  105. package/tsconfig.build.tsbuildinfo +1 -1
  106. package/tsconfig.tests.tsbuildinfo +1 -1
@@ -0,0 +1,34 @@
1
+ /**
2
+ * GENERATED CODE - DO NOT MODIFY
3
+ */
4
+ import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+ import { CID } from 'multiformats/cid'
6
+ import { validate as _validate } from '../../../../lexicons'
7
+ import {
8
+ type $Typed,
9
+ is$typed as _is$typed,
10
+ type OmitKey,
11
+ } from '../../../../util'
12
+
13
+ const is$typed = _is$typed,
14
+ validate = _validate
15
+ const id = 'app.bsky.bookmark.deleteBookmark'
16
+
17
+ export type QueryParams = {}
18
+
19
+ export interface InputSchema {
20
+ uri: string
21
+ }
22
+
23
+ export interface HandlerInput {
24
+ encoding: 'application/json'
25
+ body: InputSchema
26
+ }
27
+
28
+ export interface HandlerError {
29
+ status: number
30
+ message?: string
31
+ error?: 'UnsupportedCollection'
32
+ }
33
+
34
+ export type HandlerOutput = HandlerError | void
@@ -0,0 +1,42 @@
1
+ /**
2
+ * GENERATED CODE - DO NOT MODIFY
3
+ */
4
+ import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+ import { CID } from 'multiformats/cid'
6
+ import { validate as _validate } from '../../../../lexicons'
7
+ import {
8
+ type $Typed,
9
+ is$typed as _is$typed,
10
+ type OmitKey,
11
+ } from '../../../../util'
12
+ import type * as AppBskyBookmarkDefs from './defs.js'
13
+
14
+ const is$typed = _is$typed,
15
+ validate = _validate
16
+ const id = 'app.bsky.bookmark.getBookmarks'
17
+
18
+ export type QueryParams = {
19
+ limit: number
20
+ cursor?: string
21
+ }
22
+ export type InputSchema = undefined
23
+
24
+ export interface OutputSchema {
25
+ cursor?: string
26
+ bookmarks: AppBskyBookmarkDefs.BookmarkView[]
27
+ }
28
+
29
+ export type HandlerInput = void
30
+
31
+ export interface HandlerSuccess {
32
+ encoding: 'application/json'
33
+ body: OutputSchema
34
+ headers?: { [key: string]: string }
35
+ }
36
+
37
+ export interface HandlerError {
38
+ status: number
39
+ message?: string
40
+ }
41
+
42
+ export type HandlerOutput = HandlerError | HandlerSuccess
@@ -36,6 +36,7 @@ export interface PostView {
36
36
  | $Typed<AppBskyEmbedRecord.View>
37
37
  | $Typed<AppBskyEmbedRecordWithMedia.View>
38
38
  | { $type: string }
39
+ bookmarkCount?: number
39
40
  replyCount?: number
40
41
  repostCount?: number
41
42
  likeCount?: number
@@ -61,6 +62,7 @@ export interface ViewerState {
61
62
  $type?: 'app.bsky.feed.defs#viewerState'
62
63
  repost?: string
63
64
  like?: string
65
+ bookmarked?: boolean
64
66
  threadMuted?: boolean
65
67
  replyDisabled?: boolean
66
68
  embeddingDisabled?: boolean
@@ -22,21 +22,66 @@ export type ReasonType =
22
22
  | 'com.atproto.moderation.defs#reasonRude'
23
23
  | 'com.atproto.moderation.defs#reasonOther'
24
24
  | 'com.atproto.moderation.defs#reasonAppeal'
25
+ | 'tools.ozone.report.defs#reasonAppeal'
26
+ | 'tools.ozone.report.defs#reasonViolenceAnimalWelfare'
27
+ | 'tools.ozone.report.defs#reasonViolenceThreats'
28
+ | 'tools.ozone.report.defs#reasonViolenceGraphicContent'
29
+ | 'tools.ozone.report.defs#reasonViolenceSelfHarm'
30
+ | 'tools.ozone.report.defs#reasonViolenceGlorification'
31
+ | 'tools.ozone.report.defs#reasonViolenceExtremistContent'
32
+ | 'tools.ozone.report.defs#reasonViolenceTrafficking'
33
+ | 'tools.ozone.report.defs#reasonViolenceOther'
34
+ | 'tools.ozone.report.defs#reasonSexualAbuseContent'
35
+ | 'tools.ozone.report.defs#reasonSexualNCII'
36
+ | 'tools.ozone.report.defs#reasonSexualSextortion'
37
+ | 'tools.ozone.report.defs#reasonSexualDeepfake'
38
+ | 'tools.ozone.report.defs#reasonSexualAnimal'
39
+ | 'tools.ozone.report.defs#reasonSexualUnlabeled'
40
+ | 'tools.ozone.report.defs#reasonSexualOther'
41
+ | 'tools.ozone.report.defs#reasonChildSafetyCSAM'
42
+ | 'tools.ozone.report.defs#reasonChildSafetyGroom'
43
+ | 'tools.ozone.report.defs#reasonChildSafetyMinorPrivacy'
44
+ | 'tools.ozone.report.defs#reasonChildSafetyEndangerment'
45
+ | 'tools.ozone.report.defs#reasonChildSafetyHarassment'
46
+ | 'tools.ozone.report.defs#reasonChildSafetyPromotion'
47
+ | 'tools.ozone.report.defs#reasonChildSafetyOther'
48
+ | 'tools.ozone.report.defs#reasonHarassmentTroll'
49
+ | 'tools.ozone.report.defs#reasonHarassmentTargeted'
50
+ | 'tools.ozone.report.defs#reasonHarassmentHateSpeech'
51
+ | 'tools.ozone.report.defs#reasonHarassmentDoxxing'
52
+ | 'tools.ozone.report.defs#reasonHarassmentOther'
53
+ | 'tools.ozone.report.defs#reasonMisleadingBot'
54
+ | 'tools.ozone.report.defs#reasonMisleadingImpersonation'
55
+ | 'tools.ozone.report.defs#reasonMisleadingSpam'
56
+ | 'tools.ozone.report.defs#reasonMisleadingScam'
57
+ | 'tools.ozone.report.defs#reasonMisleadingSyntheticContent'
58
+ | 'tools.ozone.report.defs#reasonMisleadingMisinformation'
59
+ | 'tools.ozone.report.defs#reasonMisleadingOther'
60
+ | 'tools.ozone.report.defs#reasonRuleSiteSecurity'
61
+ | 'tools.ozone.report.defs#reasonRuleStolenContent'
62
+ | 'tools.ozone.report.defs#reasonRuleProhibitedSales'
63
+ | 'tools.ozone.report.defs#reasonRuleBanEvasion'
64
+ | 'tools.ozone.report.defs#reasonRuleOther'
65
+ | 'tools.ozone.report.defs#reasonCivicElectoralProcess'
66
+ | 'tools.ozone.report.defs#reasonCivicDisclosure'
67
+ | 'tools.ozone.report.defs#reasonCivicInterference'
68
+ | 'tools.ozone.report.defs#reasonCivicMisinformation'
69
+ | 'tools.ozone.report.defs#reasonCivicImpersonation'
25
70
  | (string & {})
26
71
 
27
- /** Spam: frequent unwanted promotion, replies, mentions */
72
+ /** Spam: frequent unwanted promotion, replies, mentions. Prefer new lexicon definition `tools.ozone.report.defs#reasonMisleadingSpam`. */
28
73
  export const REASONSPAM = `${id}#reasonSpam`
29
- /** Direct violation of server rules, laws, terms of service */
74
+ /** Direct violation of server rules, laws, terms of service. Prefer new lexicon definition `tools.ozone.report.defs#reasonRuleOther`. */
30
75
  export const REASONVIOLATION = `${id}#reasonViolation`
31
- /** Misleading identity, affiliation, or content */
76
+ /** Misleading identity, affiliation, or content. Prefer new lexicon definition `tools.ozone.report.defs#reasonMisleadingOther`. */
32
77
  export const REASONMISLEADING = `${id}#reasonMisleading`
33
- /** Unwanted or mislabeled sexual content */
78
+ /** Unwanted or mislabeled sexual content. Prefer new lexicon definition `tools.ozone.report.defs#reasonSexualUnlabeled`. */
34
79
  export const REASONSEXUAL = `${id}#reasonSexual`
35
- /** Rude, harassing, explicit, or otherwise unwelcoming behavior */
80
+ /** Rude, harassing, explicit, or otherwise unwelcoming behavior. Prefer new lexicon definition `tools.ozone.report.defs#reasonHarassmentOther`. */
36
81
  export const REASONRUDE = `${id}#reasonRude`
37
- /** Other: reports not falling under another report category */
82
+ /** Reports not falling under another report category. Prefer new lexicon definition `tools.ozone.report.defs#reasonRuleOther`. */
38
83
  export const REASONOTHER = `${id}#reasonOther`
39
- /** Appeal: appeal a previously taken moderation action */
84
+ /** Appeal a previously taken moderation action */
40
85
  export const REASONAPPEAL = `${id}#reasonAppeal`
41
86
 
42
87
  /** Tag describing a type of subject that might be reported. */
@@ -0,0 +1,42 @@
1
+ /**
2
+ * GENERATED CODE - DO NOT MODIFY
3
+ */
4
+ import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+ import { CID } from 'multiformats/cid'
6
+ import { validate as _validate } from '../../../../lexicons'
7
+ import {
8
+ type $Typed,
9
+ is$typed as _is$typed,
10
+ type OmitKey,
11
+ } from '../../../../util'
12
+
13
+ const is$typed = _is$typed,
14
+ validate = _validate
15
+ const id = 'com.atproto.temp.dereferenceScope'
16
+
17
+ export type QueryParams = {
18
+ /** The scope reference (starts with 'ref:') */
19
+ scope: string
20
+ }
21
+ export type InputSchema = undefined
22
+
23
+ export interface OutputSchema {
24
+ /** The full oauth permission scope */
25
+ scope: string
26
+ }
27
+
28
+ export type HandlerInput = void
29
+
30
+ export interface HandlerSuccess {
31
+ encoding: 'application/json'
32
+ body: OutputSchema
33
+ headers?: { [key: string]: string }
34
+ }
35
+
36
+ export interface HandlerError {
37
+ status: number
38
+ message?: string
39
+ error?: 'InvalidScopeReference'
40
+ }
41
+
42
+ export type HandlerOutput = HandlerError | HandlerSuccess
@@ -0,0 +1,154 @@
1
+ /**
2
+ * GENERATED CODE - DO NOT MODIFY
3
+ */
4
+ import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+ import { CID } from 'multiformats/cid'
6
+ import { validate as _validate } from '../../../../lexicons'
7
+ import {
8
+ type $Typed,
9
+ is$typed as _is$typed,
10
+ type OmitKey,
11
+ } from '../../../../util'
12
+
13
+ const is$typed = _is$typed,
14
+ validate = _validate
15
+ const id = 'tools.ozone.report.defs'
16
+
17
+ export type ReasonType =
18
+ | 'tools.ozone.report.defs#reasonAppeal'
19
+ | 'tools.ozone.report.defs#reasonViolenceAnimalWelfare'
20
+ | 'tools.ozone.report.defs#reasonViolenceThreats'
21
+ | 'tools.ozone.report.defs#reasonViolenceGraphicContent'
22
+ | 'tools.ozone.report.defs#reasonViolenceSelfHarm'
23
+ | 'tools.ozone.report.defs#reasonViolenceGlorification'
24
+ | 'tools.ozone.report.defs#reasonViolenceExtremistContent'
25
+ | 'tools.ozone.report.defs#reasonViolenceTrafficking'
26
+ | 'tools.ozone.report.defs#reasonViolenceOther'
27
+ | 'tools.ozone.report.defs#reasonSexualAbuseContent'
28
+ | 'tools.ozone.report.defs#reasonSexualNCII'
29
+ | 'tools.ozone.report.defs#reasonSexualSextortion'
30
+ | 'tools.ozone.report.defs#reasonSexualDeepfake'
31
+ | 'tools.ozone.report.defs#reasonSexualAnimal'
32
+ | 'tools.ozone.report.defs#reasonSexualUnlabeled'
33
+ | 'tools.ozone.report.defs#reasonSexualOther'
34
+ | 'tools.ozone.report.defs#reasonChildSafetyCSAM'
35
+ | 'tools.ozone.report.defs#reasonChildSafetyGroom'
36
+ | 'tools.ozone.report.defs#reasonChildSafetyMinorPrivacy'
37
+ | 'tools.ozone.report.defs#reasonChildSafetyEndangerment'
38
+ | 'tools.ozone.report.defs#reasonChildSafetyHarassment'
39
+ | 'tools.ozone.report.defs#reasonChildSafetyPromotion'
40
+ | 'tools.ozone.report.defs#reasonChildSafetyOther'
41
+ | 'tools.ozone.report.defs#reasonHarassmentTroll'
42
+ | 'tools.ozone.report.defs#reasonHarassmentTargeted'
43
+ | 'tools.ozone.report.defs#reasonHarassmentHateSpeech'
44
+ | 'tools.ozone.report.defs#reasonHarassmentDoxxing'
45
+ | 'tools.ozone.report.defs#reasonHarassmentOther'
46
+ | 'tools.ozone.report.defs#reasonMisleadingBot'
47
+ | 'tools.ozone.report.defs#reasonMisleadingImpersonation'
48
+ | 'tools.ozone.report.defs#reasonMisleadingSpam'
49
+ | 'tools.ozone.report.defs#reasonMisleadingScam'
50
+ | 'tools.ozone.report.defs#reasonMisleadingSyntheticContent'
51
+ | 'tools.ozone.report.defs#reasonMisleadingMisinformation'
52
+ | 'tools.ozone.report.defs#reasonMisleadingOther'
53
+ | 'tools.ozone.report.defs#reasonRuleSiteSecurity'
54
+ | 'tools.ozone.report.defs#reasonRuleStolenContent'
55
+ | 'tools.ozone.report.defs#reasonRuleProhibitedSales'
56
+ | 'tools.ozone.report.defs#reasonRuleBanEvasion'
57
+ | 'tools.ozone.report.defs#reasonRuleOther'
58
+ | 'tools.ozone.report.defs#reasonCivicElectoralProcess'
59
+ | 'tools.ozone.report.defs#reasonCivicDisclosure'
60
+ | 'tools.ozone.report.defs#reasonCivicInterference'
61
+ | 'tools.ozone.report.defs#reasonCivicMisinformation'
62
+ | 'tools.ozone.report.defs#reasonCivicImpersonation'
63
+ | (string & {})
64
+
65
+ /** Appeal a previously taken moderation action */
66
+ export const REASONAPPEAL = `${id}#reasonAppeal`
67
+ /** Animal welfare violations */
68
+ export const REASONVIOLENCEANIMALWELFARE = `${id}#reasonViolenceAnimalWelfare`
69
+ /** Threats or incitement */
70
+ export const REASONVIOLENCETHREATS = `${id}#reasonViolenceThreats`
71
+ /** Graphic violent content */
72
+ export const REASONVIOLENCEGRAPHICCONTENT = `${id}#reasonViolenceGraphicContent`
73
+ /** Self harm */
74
+ export const REASONVIOLENCESELFHARM = `${id}#reasonViolenceSelfHarm`
75
+ /** Glorification of violence */
76
+ export const REASONVIOLENCEGLORIFICATION = `${id}#reasonViolenceGlorification`
77
+ /** Extremist content. These reports will be sent only be sent to the application's Moderation Authority. */
78
+ export const REASONVIOLENCEEXTREMISTCONTENT = `${id}#reasonViolenceExtremistContent`
79
+ /** Human trafficking */
80
+ export const REASONVIOLENCETRAFFICKING = `${id}#reasonViolenceTrafficking`
81
+ /** Other violent content */
82
+ export const REASONVIOLENCEOTHER = `${id}#reasonViolenceOther`
83
+ /** Adult sexual abuse content */
84
+ export const REASONSEXUALABUSECONTENT = `${id}#reasonSexualAbuseContent`
85
+ /** Non-consensual intimate imagery */
86
+ export const REASONSEXUALNCII = `${id}#reasonSexualNCII`
87
+ /** Sextortion */
88
+ export const REASONSEXUALSEXTORTION = `${id}#reasonSexualSextortion`
89
+ /** Deepfake adult content */
90
+ export const REASONSEXUALDEEPFAKE = `${id}#reasonSexualDeepfake`
91
+ /** Animal sexual abuse */
92
+ export const REASONSEXUALANIMAL = `${id}#reasonSexualAnimal`
93
+ /** Unlabelled adult content */
94
+ export const REASONSEXUALUNLABELED = `${id}#reasonSexualUnlabeled`
95
+ /** Other sexual violence content */
96
+ export const REASONSEXUALOTHER = `${id}#reasonSexualOther`
97
+ /** Child sexual abuse material (CSAM). These reports will be sent only be sent to the application's Moderation Authority. */
98
+ export const REASONCHILDSAFETYCSAM = `${id}#reasonChildSafetyCSAM`
99
+ /** Grooming or predatory behavior. These reports will be sent only be sent to the application's Moderation Authority. */
100
+ export const REASONCHILDSAFETYGROOM = `${id}#reasonChildSafetyGroom`
101
+ /** Privacy violation involving a minor */
102
+ export const REASONCHILDSAFETYMINORPRIVACY = `${id}#reasonChildSafetyMinorPrivacy`
103
+ /** Child endangerment. These reports will be sent only be sent to the application's Moderation Authority. */
104
+ export const REASONCHILDSAFETYENDANGERMENT = `${id}#reasonChildSafetyEndangerment`
105
+ /** Harassment or bullying of minors */
106
+ export const REASONCHILDSAFETYHARASSMENT = `${id}#reasonChildSafetyHarassment`
107
+ /** Promotion of child exploitation. These reports will be sent only be sent to the application's Moderation Authority. */
108
+ export const REASONCHILDSAFETYPROMOTION = `${id}#reasonChildSafetyPromotion`
109
+ /** Other child safety. These reports will be sent only be sent to the application's Moderation Authority. */
110
+ export const REASONCHILDSAFETYOTHER = `${id}#reasonChildSafetyOther`
111
+ /** Trolling */
112
+ export const REASONHARASSMENTTROLL = `${id}#reasonHarassmentTroll`
113
+ /** Targeted harassment */
114
+ export const REASONHARASSMENTTARGETED = `${id}#reasonHarassmentTargeted`
115
+ /** Hate speech */
116
+ export const REASONHARASSMENTHATESPEECH = `${id}#reasonHarassmentHateSpeech`
117
+ /** Doxxing */
118
+ export const REASONHARASSMENTDOXXING = `${id}#reasonHarassmentDoxxing`
119
+ /** Other harassing or hateful content */
120
+ export const REASONHARASSMENTOTHER = `${id}#reasonHarassmentOther`
121
+ /** Fake account or bot */
122
+ export const REASONMISLEADINGBOT = `${id}#reasonMisleadingBot`
123
+ /** Impersonation */
124
+ export const REASONMISLEADINGIMPERSONATION = `${id}#reasonMisleadingImpersonation`
125
+ /** Spam */
126
+ export const REASONMISLEADINGSPAM = `${id}#reasonMisleadingSpam`
127
+ /** Scam */
128
+ export const REASONMISLEADINGSCAM = `${id}#reasonMisleadingScam`
129
+ /** Unlabelled gen-AI or synthetic content */
130
+ export const REASONMISLEADINGSYNTHETICCONTENT = `${id}#reasonMisleadingSyntheticContent`
131
+ /** Harmful false claims */
132
+ export const REASONMISLEADINGMISINFORMATION = `${id}#reasonMisleadingMisinformation`
133
+ /** Other misleading content */
134
+ export const REASONMISLEADINGOTHER = `${id}#reasonMisleadingOther`
135
+ /** Hacking or system attacks */
136
+ export const REASONRULESITESECURITY = `${id}#reasonRuleSiteSecurity`
137
+ /** Stolen content */
138
+ export const REASONRULESTOLENCONTENT = `${id}#reasonRuleStolenContent`
139
+ /** Promoting or selling prohibited items or services */
140
+ export const REASONRULEPROHIBITEDSALES = `${id}#reasonRuleProhibitedSales`
141
+ /** Banned user returning */
142
+ export const REASONRULEBANEVASION = `${id}#reasonRuleBanEvasion`
143
+ /** Other */
144
+ export const REASONRULEOTHER = `${id}#reasonRuleOther`
145
+ /** Electoral process violations */
146
+ export const REASONCIVICELECTORALPROCESS = `${id}#reasonCivicElectoralProcess`
147
+ /** Disclosure & transparency violations */
148
+ export const REASONCIVICDISCLOSURE = `${id}#reasonCivicDisclosure`
149
+ /** Voter intimidation or interference */
150
+ export const REASONCIVICINTERFERENCE = `${id}#reasonCivicInterference`
151
+ /** Election misinformation */
152
+ export const REASONCIVICMISINFORMATION = `${id}#reasonCivicMisinformation`
153
+ /** Impersonation of electoral officials/entities */
154
+ export const REASONCIVICIMPERSONATION = `${id}#reasonCivicImpersonation`
@@ -0,0 +1,143 @@
1
+ import AtpAgent, { AppBskyLabelerDefs } from '@atproto/api'
2
+ import { InvalidRequestError } from '@atproto/xrpc-server'
3
+ import { OzoneConfig } from '../config'
4
+ import {
5
+ REASONAPPEAL,
6
+ REASONMISLEADING,
7
+ REASONRUDE,
8
+ REASONSEXUAL,
9
+ REASONSPAM,
10
+ REASONVIOLATION,
11
+ } from '../lexicon/types/com/atproto/moderation/defs'
12
+ import { httpLogger } from '../logger'
13
+
14
+ // Reverse mapping from new ozone namespaced reason types to old com.atproto namespaced reason types
15
+ export const NEW_TO_OLD_REASON_MAPPING: Record<string, string> = {
16
+ 'tools.ozone.report.defs#reasonMisleadingSpam': REASONSPAM,
17
+ 'tools.ozone.report.defs#reasonRuleOther': REASONVIOLATION,
18
+ 'tools.ozone.report.defs#reasonMisleadingOther': REASONMISLEADING,
19
+ 'tools.ozone.report.defs#reasonSexualUnlabeled': REASONSEXUAL,
20
+ 'tools.ozone.report.defs#reasonHarassmentOther': REASONRUDE,
21
+ 'tools.ozone.report.defs#reasonAppeal': REASONAPPEAL,
22
+ // Map all violence-related reasons to REASONVIOLATION
23
+ 'tools.ozone.report.defs#reasonViolenceAnimalWelfare': REASONVIOLATION,
24
+ 'tools.ozone.report.defs#reasonViolenceThreats': REASONVIOLATION,
25
+ 'tools.ozone.report.defs#reasonViolenceGraphicContent': REASONVIOLATION,
26
+ 'tools.ozone.report.defs#reasonViolenceSelfHarm': REASONVIOLATION,
27
+ 'tools.ozone.report.defs#reasonViolenceGlorification': REASONVIOLATION,
28
+ 'tools.ozone.report.defs#reasonViolenceExtremistContent': REASONVIOLATION,
29
+ 'tools.ozone.report.defs#reasonViolenceTrafficking': REASONVIOLATION,
30
+ 'tools.ozone.report.defs#reasonViolenceOther': REASONVIOLATION,
31
+ // Map all sexual-related reasons to REASONSEXUAL
32
+ 'tools.ozone.report.defs#reasonSexualAbuseContent': REASONSEXUAL,
33
+ 'tools.ozone.report.defs#reasonSexualNCII': REASONSEXUAL,
34
+ 'tools.ozone.report.defs#reasonSexualSextortion': REASONSEXUAL,
35
+ 'tools.ozone.report.defs#reasonSexualDeepfake': REASONSEXUAL,
36
+ 'tools.ozone.report.defs#reasonSexualAnimal': REASONSEXUAL,
37
+ 'tools.ozone.report.defs#reasonSexualOther': REASONSEXUAL,
38
+ // Map all child safety reasons to REASONVIOLATION
39
+ 'tools.ozone.report.defs#reasonChildSafetyCSAM': REASONVIOLATION,
40
+ 'tools.ozone.report.defs#reasonChildSafetyGroom': REASONVIOLATION,
41
+ 'tools.ozone.report.defs#reasonChildSafetyMinorPrivacy': REASONVIOLATION,
42
+ 'tools.ozone.report.defs#reasonChildSafetyEndangerment': REASONVIOLATION,
43
+ 'tools.ozone.report.defs#reasonChildSafetyHarassment': REASONVIOLATION,
44
+ 'tools.ozone.report.defs#reasonChildSafetyPromotion': REASONVIOLATION,
45
+ 'tools.ozone.report.defs#reasonChildSafetyOther': REASONVIOLATION,
46
+ // Map all harassment reasons to REASONRUDE
47
+ 'tools.ozone.report.defs#reasonHarassmentTroll': REASONRUDE,
48
+ 'tools.ozone.report.defs#reasonHarassmentTargeted': REASONRUDE,
49
+ 'tools.ozone.report.defs#reasonHarassmentHateSpeech': REASONRUDE,
50
+ 'tools.ozone.report.defs#reasonHarassmentDoxxing': REASONRUDE,
51
+ // Map all misleading reasons to REASONMISLEADING
52
+ 'tools.ozone.report.defs#reasonMisleadingBot': REASONMISLEADING,
53
+ 'tools.ozone.report.defs#reasonMisleadingImpersonation': REASONMISLEADING,
54
+ 'tools.ozone.report.defs#reasonMisleadingScam': REASONMISLEADING,
55
+ 'tools.ozone.report.defs#reasonMisleadingSyntheticContent': REASONMISLEADING,
56
+ 'tools.ozone.report.defs#reasonMisleadingMisinformation': REASONMISLEADING,
57
+ // Map all rule-related reasons to REASONVIOLATION
58
+ 'tools.ozone.report.defs#reasonRuleSiteSecurity': REASONVIOLATION,
59
+ 'tools.ozone.report.defs#reasonRuleStolenContent': REASONVIOLATION,
60
+ 'tools.ozone.report.defs#reasonRuleProhibitedSales': REASONVIOLATION,
61
+ 'tools.ozone.report.defs#reasonRuleBanEvasion': REASONVIOLATION,
62
+ // Map all civic reasons to REASONMISLEADING
63
+ 'tools.ozone.report.defs#reasonCivicElectoralProcess': REASONMISLEADING,
64
+ 'tools.ozone.report.defs#reasonCivicDisclosure': REASONMISLEADING,
65
+ 'tools.ozone.report.defs#reasonCivicInterference': REASONMISLEADING,
66
+ 'tools.ozone.report.defs#reasonCivicMisinformation': REASONMISLEADING,
67
+ 'tools.ozone.report.defs#reasonCivicImpersonation': REASONMISLEADING,
68
+ }
69
+
70
+ interface CacheEntry {
71
+ profile: AppBskyLabelerDefs.LabelerViewDetailed | null
72
+ timestamp: number
73
+ }
74
+
75
+ export type ModerationServiceProfileCreator = () => ModerationServiceProfile
76
+
77
+ export class ModerationServiceProfile {
78
+ private cache: CacheEntry | null = null
79
+ private CACHE_TTL: number
80
+
81
+ constructor(
82
+ private cfg: OzoneConfig,
83
+ private appviewAgent: AtpAgent,
84
+ cacheTTL?: number,
85
+ ) {
86
+ this.CACHE_TTL = cacheTTL || cfg.service.serviceRecordCacheTTL
87
+ }
88
+
89
+ static creator(
90
+ cfg: OzoneConfig,
91
+ appviewAgent: AtpAgent,
92
+ ): ModerationServiceProfileCreator {
93
+ return () => new ModerationServiceProfile(cfg, appviewAgent)
94
+ }
95
+
96
+ async getProfile() {
97
+ const now = Date.now()
98
+
99
+ if (!this.cache || now - this.cache.timestamp > this.CACHE_TTL) {
100
+ try {
101
+ const { data } = await this.appviewAgent.app.bsky.labeler.getServices({
102
+ dids: [this.cfg.service.did],
103
+ detailed: true,
104
+ })
105
+
106
+ if (AppBskyLabelerDefs.isLabelerViewDetailed(data.views?.[0])) {
107
+ this.cache = {
108
+ profile: data.views[0],
109
+ timestamp: now,
110
+ }
111
+ }
112
+ } catch (e) {
113
+ // On error, fail open
114
+ httpLogger.error(`Failed to fetch labeler profile: ${e?.['message']}`)
115
+ }
116
+ }
117
+
118
+ return this.cache?.profile || null
119
+ }
120
+
121
+ async validateReasonType(reasonType: string): Promise<string> {
122
+ const profile = await this.getProfile()
123
+
124
+ if (!Array.isArray(profile?.reasonTypes)) {
125
+ return reasonType
126
+ }
127
+
128
+ const supportedReasonTypes = profile.reasonTypes
129
+
130
+ // Check if the reason type is directly supported
131
+ if (supportedReasonTypes.includes(reasonType)) {
132
+ return reasonType
133
+ }
134
+
135
+ // Allow new reason types only if they map to a supported old reason type
136
+ const mappedOldReason = NEW_TO_OLD_REASON_MAPPING[reasonType]
137
+ if (mappedOldReason && supportedReasonTypes.includes(mappedOldReason)) {
138
+ return reasonType
139
+ }
140
+
141
+ throw new InvalidRequestError(`Invalid reason type: ${reasonType}`)
142
+ }
143
+ }
@@ -2,10 +2,10 @@
2
2
 
3
3
  import { HOUR } from '@atproto/common'
4
4
  import { AtUri } from '@atproto/syntax'
5
+ import { isAppealReport } from '../api/util'
5
6
  import { Database } from '../db'
6
7
  import { DatabaseSchema } from '../db/schema'
7
8
  import { jsonb } from '../db/types'
8
- import { REASONAPPEAL } from '../lexicon/types/com/atproto/moderation/defs'
9
9
  import {
10
10
  REVIEWCLOSED,
11
11
  REVIEWESCALATED,
@@ -341,7 +341,8 @@ export const adjustModerationSubjectStatus = async (
341
341
 
342
342
  const isAppealEvent =
343
343
  action === 'tools.ozone.moderation.defs#modEventReport' &&
344
- meta?.reportType === REASONAPPEAL
344
+ meta?.reportType &&
345
+ isAppealReport(`${meta.reportType}`)
345
346
 
346
347
  const subjectStatus = getSubjectStatusForModerationEvent({
347
348
  currentStatus,
@@ -1,5 +1,13 @@
1
1
  import { ReasonType } from '../lexicon/types/com/atproto/moderation/defs'
2
2
 
3
3
  export const getTagForReport = (reasonType: ReasonType) => {
4
- return `report:${reasonType.replace('com.atproto.moderation.defs#reason', '').toLowerCase()}`
4
+ const reasonWithoutPrefix = reasonType
5
+ .replace('com.atproto.moderation.defs#reason', '')
6
+ .replace('tools.ozone.report.defs#reason', '')
7
+
8
+ const kebabCase = reasonWithoutPrefix
9
+ .replace(/([a-z])([A-Z])/g, '$1-$2')
10
+ .toLowerCase()
11
+
12
+ return `report:${kebabCase}`
5
13
  }
@@ -0,0 +1,14 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`report reason createReport only passes for allowed reason types 1`] = `
4
+ Object {
5
+ "createdAt": "1970-01-01T00:00:00.000Z",
6
+ "id": 1,
7
+ "reasonType": "tools.ozone.report.defs#reasonHarassmentTroll",
8
+ "reportedBy": "user(0)",
9
+ "subject": Object {
10
+ "$type": "com.atproto.admin.defs#repoRef",
11
+ "did": "user(1)",
12
+ },
13
+ }
14
+ `;