@atproto/ozone 0.1.58 → 0.1.59

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.
@@ -7,6 +7,8 @@ import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server';
7
7
  import * as AppBskyActorDefs from '../actor/defs';
8
8
  import * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs';
9
9
  export interface QueryParams {
10
+ /** Notification reasons to include in response. */
11
+ reasons?: string[];
10
12
  limit: number;
11
13
  priority?: boolean;
12
14
  cursor?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"listNotifications.d.ts","sourceRoot":"","sources":["../../../../../../src/lexicon/types/app/bsky/notification/listNotifications.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,OAAO,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,gBAAgB,EAAW,MAAM,kBAAkB,CAAA;AAI5D,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACtE,OAAO,KAAK,gBAAgB,MAAM,eAAe,CAAA;AACjD,OAAO,KAAK,mBAAmB,MAAM,iCAAiC,CAAA;AAEtE,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,MAAM,WAAW,GAAG,SAAS,CAAA;AAEnC,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,aAAa,EAAE,YAAY,EAAE,CAAA;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED,MAAM,MAAM,YAAY,GAAG,SAAS,CAAA;AAEpC,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,IAAI,EAAE,YAAY,CAAA;IAClB,OAAO,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,cAAc,GAAG,kBAAkB,CAAA;AAC9E,MAAM,MAAM,aAAa,CAAC,EAAE,SAAS,WAAW,GAAG,KAAK,IAAI;IAC1D,IAAI,EAAE,EAAE,CAAA;IACR,MAAM,EAAE,WAAW,CAAA;IACnB,KAAK,EAAE,YAAY,CAAA;IACnB,GAAG,EAAE,OAAO,CAAC,OAAO,CAAA;IACpB,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAA;CACtB,CAAA;AACD,MAAM,MAAM,OAAO,CAAC,EAAE,SAAS,WAAW,GAAG,KAAK,IAAI,CACpD,GAAG,EAAE,aAAa,CAAC,EAAE,CAAC,KACnB,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,CAAA;AAE3C,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,gBAAgB,CAAC,WAAW,CAAA;IACpC,6GAA6G;IAC7G,MAAM,EACF,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,OAAO,GACP,OAAO,GACP,oBAAoB,GACpB,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,MAAM,EAAE,EAAE,CAAA;IACV,MAAM,EAAE,OAAO,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,mBAAmB,CAAC,KAAK,EAAE,CAAA;IACpC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,YAAY,CAM5D;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAKjE"}
1
+ {"version":3,"file":"listNotifications.d.ts","sourceRoot":"","sources":["../../../../../../src/lexicon/types/app/bsky/notification/listNotifications.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,OAAO,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,gBAAgB,EAAW,MAAM,kBAAkB,CAAA;AAI5D,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACtE,OAAO,KAAK,gBAAgB,MAAM,eAAe,CAAA;AACjD,OAAO,KAAK,mBAAmB,MAAM,iCAAiC,CAAA;AAEtE,MAAM,WAAW,WAAW;IAC1B,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,MAAM,WAAW,GAAG,SAAS,CAAA;AAEnC,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,aAAa,EAAE,YAAY,EAAE,CAAA;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED,MAAM,MAAM,YAAY,GAAG,SAAS,CAAA;AAEpC,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,IAAI,EAAE,YAAY,CAAA;IAClB,OAAO,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,cAAc,GAAG,kBAAkB,CAAA;AAC9E,MAAM,MAAM,aAAa,CAAC,EAAE,SAAS,WAAW,GAAG,KAAK,IAAI;IAC1D,IAAI,EAAE,EAAE,CAAA;IACR,MAAM,EAAE,WAAW,CAAA;IACnB,KAAK,EAAE,YAAY,CAAA;IACnB,GAAG,EAAE,OAAO,CAAC,OAAO,CAAA;IACpB,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAA;CACtB,CAAA;AACD,MAAM,MAAM,OAAO,CAAC,EAAE,SAAS,WAAW,GAAG,KAAK,IAAI,CACpD,GAAG,EAAE,aAAa,CAAC,EAAE,CAAC,KACnB,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,CAAA;AAE3C,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,gBAAgB,CAAC,WAAW,CAAA;IACpC,6GAA6G;IAC7G,MAAM,EACF,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,OAAO,GACP,OAAO,GACP,oBAAoB,GACpB,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,MAAM,EAAE,EAAE,CAAA;IACV,MAAM,EAAE,OAAO,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,mBAAmB,CAAC,KAAK,EAAE,CAAA;IACpC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,YAAY,CAM5D;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAKjE"}
@@ -1 +1 @@
1
- {"version":3,"file":"listNotifications.js","sourceRoot":"","sources":["../../../../../../src/lexicon/types/app/bsky/notification/listNotifications.ts"],"names":[],"mappings":";;AA4EA,wCAMC;AAED,oDAKC;AApFD,mDAA+C;AAC/C,2CAAiD;AAsEjD,SAAgB,cAAc,CAAC,CAAU;IACvC,OAAO,CACL,IAAA,YAAK,EAAC,CAAC,CAAC;QACR,IAAA,cAAO,EAAC,CAAC,EAAE,OAAO,CAAC;QACnB,CAAC,CAAC,KAAK,KAAK,sDAAsD,CACnE,CAAA;AACH,CAAC;AAED,SAAgB,oBAAoB,CAAC,CAAU;IAC7C,OAAO,mBAAQ,CAAC,QAAQ,CACtB,sDAAsD,EACtD,CAAC,CACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"listNotifications.js","sourceRoot":"","sources":["../../../../../../src/lexicon/types/app/bsky/notification/listNotifications.ts"],"names":[],"mappings":";;AA8EA,wCAMC;AAED,oDAKC;AAtFD,mDAA+C;AAC/C,2CAAiD;AAwEjD,SAAgB,cAAc,CAAC,CAAU;IACvC,OAAO,CACL,IAAA,YAAK,EAAC,CAAC,CAAC;QACR,IAAA,cAAO,EAAC,CAAC,EAAE,OAAO,CAAC;QACnB,CAAC,CAAC,KAAK,KAAK,sDAAsD,CACnE,CAAA;AACH,CAAC;AAED,SAAgB,oBAAoB,CAAC,CAAU;IAC7C,OAAO,mBAAQ,CAAC,QAAQ,CACtB,sDAAsD,EACtD,CAAC,CACF,CAAA;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/ozone",
3
- "version": "0.1.58",
3
+ "version": "0.1.59",
4
4
  "license": "MIT",
5
5
  "description": "Backend service for moderating the Bluesky network.",
6
6
  "keywords": [
@@ -32,14 +32,14 @@
32
32
  "structured-headers": "^1.0.1",
33
33
  "typed-emitter": "^2.1.0",
34
34
  "uint8arrays": "3.0.0",
35
- "@atproto/api": "^0.13.19",
36
- "@atproto/common": "^0.4.4",
35
+ "@atproto/api": "^0.13.20",
36
+ "@atproto/common": "^0.4.5",
37
37
  "@atproto/crypto": "^0.4.2",
38
38
  "@atproto/identity": "^0.4.3",
39
- "@atproto/lexicon": "^0.4.3",
39
+ "@atproto/lexicon": "^0.4.4",
40
40
  "@atproto/syntax": "^0.3.1",
41
- "@atproto/xrpc": "^0.6.4",
42
- "@atproto/xrpc-server": "^0.7.3"
41
+ "@atproto/xrpc": "^0.6.5",
42
+ "@atproto/xrpc-server": "^0.7.4"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@did-plc/server": "^0.0.1",
@@ -52,8 +52,8 @@
52
52
  "jest": "^28.1.2",
53
53
  "ts-node": "^10.8.2",
54
54
  "typescript": "^5.6.3",
55
- "@atproto/lex-cli": "^0.5.2",
56
- "@atproto/pds": "^0.4.75"
55
+ "@atproto/lex-cli": "^0.5.3",
56
+ "@atproto/pds": "^0.4.76"
57
57
  },
58
58
  "scripts": {
59
59
  "codegen": "lex gen-server --yes ./src/lexicon ../../lexicons/com/atproto/*/* ../../lexicons/app/bsky/*/* ../../lexicons/chat/bsky/*/* ../../lexicons/tools/ozone/*/*",
@@ -99,49 +99,7 @@ const handleModerationEvent = async ({
99
99
  )
100
100
 
101
101
  if (protectedTags) {
102
- status.tags.forEach((tag) => {
103
- if (!Object.hasOwn(protectedTags, tag)) return
104
- if (
105
- protectedTags[tag]['moderators'] &&
106
- !protectedTags[tag]['moderators'].includes(createdBy)
107
- ) {
108
- throw new InvalidRequestError(
109
- `Not allowed to action on protected tag: ${tag}`,
110
- )
111
- }
112
- if (protectedTags[tag]['roles']) {
113
- if (
114
- auth.credentials.isAdmin &&
115
- !protectedTags[tag]['roles'].includes(
116
- 'tools.ozone.team.defs#roleAdmin',
117
- )
118
- ) {
119
- throw new InvalidRequestError(
120
- `Not allowed to action on protected tag: ${tag}`,
121
- )
122
- }
123
- if (
124
- auth.credentials.isModerator &&
125
- !protectedTags[tag]['roles'].includes(
126
- 'tools.ozone.team.defs#roleModerator',
127
- )
128
- ) {
129
- throw new InvalidRequestError(
130
- `Not allowed to action on protected tag: ${tag}`,
131
- )
132
- }
133
- if (
134
- auth.credentials.isTriage &&
135
- !protectedTags[tag]['roles'].includes(
136
- 'tools.ozone.team.defs#roleTriage',
137
- )
138
- ) {
139
- throw new InvalidRequestError(
140
- `Not allowed to action on protected tag: ${tag}`,
141
- )
142
- }
143
- }
144
- })
102
+ assertProtectedTagAction(protectedTags, status.tags, createdBy, auth)
145
103
  }
146
104
  }
147
105
 
@@ -291,6 +249,68 @@ export default function (server: Server, ctx: AppContext) {
291
249
  })
292
250
  }
293
251
 
252
+ const assertProtectedTagAction = (
253
+ protectedTags: ProtectedTagSetting,
254
+ subjectTags: string[],
255
+ actionAuthor: string,
256
+ auth: ModeratorOutput | AdminTokenOutput,
257
+ ) => {
258
+ subjectTags.forEach((tag) => {
259
+ if (!Object.hasOwn(protectedTags, tag)) return
260
+ if (
261
+ protectedTags[tag]['moderators'] &&
262
+ !protectedTags[tag]['moderators'].includes(actionAuthor)
263
+ ) {
264
+ throw new InvalidRequestError(
265
+ `Not allowed to action on protected tag: ${tag}`,
266
+ )
267
+ }
268
+
269
+ if (protectedTags[tag]['roles']) {
270
+ if (auth.credentials.isAdmin) {
271
+ if (
272
+ protectedTags[tag]['roles'].includes(
273
+ 'tools.ozone.team.defs#roleAdmin',
274
+ )
275
+ ) {
276
+ return
277
+ }
278
+ throw new InvalidRequestError(
279
+ `Not allowed to action on protected tag: ${tag}`,
280
+ )
281
+ }
282
+
283
+ if (auth.credentials.isModerator) {
284
+ if (
285
+ protectedTags[tag]['roles'].includes(
286
+ 'tools.ozone.team.defs#roleModerator',
287
+ )
288
+ ) {
289
+ return
290
+ }
291
+
292
+ throw new InvalidRequestError(
293
+ `Not allowed to action on protected tag: ${tag}`,
294
+ )
295
+ }
296
+
297
+ if (auth.credentials.isTriage) {
298
+ if (
299
+ protectedTags[tag]['roles'].includes(
300
+ 'tools.ozone.team.defs#roleTriage',
301
+ )
302
+ ) {
303
+ return
304
+ }
305
+
306
+ throw new InvalidRequestError(
307
+ `Not allowed to action on protected tag: ${tag}`,
308
+ )
309
+ }
310
+ }
311
+ })
312
+ }
313
+
294
314
  const assertTagAuth = async (
295
315
  settingService: SettingService,
296
316
  serviceDid: string,
@@ -8944,6 +8944,15 @@ export const schemaDict = {
8944
8944
  parameters: {
8945
8945
  type: 'params',
8946
8946
  properties: {
8947
+ reasons: {
8948
+ description: 'Notification reasons to include in response.',
8949
+ type: 'array',
8950
+ items: {
8951
+ type: 'string',
8952
+ description:
8953
+ 'A reason that matches the reason property of #notification.',
8954
+ },
8955
+ },
8947
8956
  limit: {
8948
8957
  type: 'integer',
8949
8958
  minimum: 1,
@@ -11,6 +11,8 @@ import * as AppBskyActorDefs from '../actor/defs'
11
11
  import * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs'
12
12
 
13
13
  export interface QueryParams {
14
+ /** Notification reasons to include in response. */
15
+ reasons?: string[]
14
16
  limit: number
15
17
  priority?: boolean
16
18
  cursor?: string
@@ -19,7 +19,7 @@ import {
19
19
  import { isRepoRef } from '../src/lexicon/types/com/atproto/admin/defs'
20
20
  import { ComAtprotoRepoStrongRef } from '@atproto/api'
21
21
 
22
- describe('moderation', () => {
22
+ describe('acknowledge all subjects of account', () => {
23
23
  let network: TestNetwork
24
24
  let sc: SeedClient
25
25
  let modClient: ModeratorClient
@@ -0,0 +1,71 @@
1
+ import {
2
+ TestNetwork,
3
+ SeedClient,
4
+ basicSeed,
5
+ ModeratorClient,
6
+ } from '@atproto/dev-env'
7
+ import { ids } from '../src/lexicon/lexicons'
8
+
9
+ describe('get profiles through ozone', () => {
10
+ let network: TestNetwork
11
+ let sc: SeedClient
12
+ let modClient: ModeratorClient
13
+
14
+ const repoSubject = (did: string) => ({
15
+ $type: 'com.atproto.admin.defs#repoRef',
16
+ did,
17
+ })
18
+
19
+ beforeAll(async () => {
20
+ network = await TestNetwork.create({
21
+ dbPostgresSchema: 'ozone_get_profiles',
22
+ })
23
+ sc = network.getSeedClient()
24
+ modClient = network.ozone.getModClient()
25
+ await basicSeed(sc)
26
+ await network.processAll()
27
+ })
28
+
29
+ afterAll(async () => {
30
+ await network.close()
31
+ })
32
+
33
+ it('allows getting profiles by dids for takendown accounts.', async () => {
34
+ const getProfiles = async (actors: string[]) => {
35
+ const { data } = await modClient.agent.app.bsky.actor.getProfiles(
36
+ { actors },
37
+ {
38
+ headers: await network.ozone.modHeaders(
39
+ 'app.bsky.actor.getProfiles',
40
+ 'admin',
41
+ ),
42
+ },
43
+ )
44
+
45
+ return data.profiles
46
+ }
47
+ const profilesBefore = await getProfiles([sc.dids.bob, sc.dids.carol])
48
+
49
+ await modClient.performTakedown({
50
+ subject: repoSubject(sc.dids.bob),
51
+ })
52
+
53
+ const profilesAfterFromOzone = await getProfiles([
54
+ sc.dids.bob,
55
+ sc.dids.carol,
56
+ ])
57
+
58
+ const appviewAgent = network.bsky.getClient()
59
+ const {
60
+ data: { profiles: profilesFromAppview },
61
+ } = await appviewAgent.app.bsky.actor.getProfiles({
62
+ actors: [sc.dids.bob, sc.dids.carol],
63
+ })
64
+
65
+ expect(profilesBefore.length).toEqual(profilesAfterFromOzone.length)
66
+ expect(
67
+ profilesAfterFromOzone.find((p) => p.did === sc.dids.bob),
68
+ ).toBeTruthy()
69
+ expect(profilesFromAppview.find((p) => p.did === sc.dids.bob)).toBeFalsy()
70
+ })
71
+ })
@@ -145,6 +145,22 @@ describe('protected-tags', () => {
145
145
  },
146
146
  }),
147
147
  ).rejects.toThrow(/Can not manage tag vip/gi)
148
+
149
+ // Verify that since admins are configured to manage this tag, admin actions go through
150
+ const removeTag = await modClient.emitEvent(
151
+ {
152
+ subject: {
153
+ $type: 'com.atproto.admin.defs#repoRef',
154
+ did: sc.dids.bob,
155
+ },
156
+ event: {
157
+ $type: 'tools.ozone.moderation.defs#modEventTakedown',
158
+ },
159
+ },
160
+ 'admin',
161
+ )
162
+
163
+ expect(removeTag.id).toBeTruthy()
148
164
  })
149
165
  it('only allows configured moderators to add/remove protected tags', async () => {
150
166
  await modClient.upsertSettingOption({
@@ -1 +1 @@
1
- {"root":["./tests/3p-labeler.test.ts","./tests/_util.ts","./tests/ack-all-subjects-of-account.test.ts","./tests/blob-divert.test.ts","./tests/communication-templates.test.ts","./tests/content-tagger.test.ts","./tests/db.test.ts","./tests/get-config.test.ts","./tests/get-lists.test.ts","./tests/get-record.test.ts","./tests/get-records.test.ts","./tests/get-repo.test.ts","./tests/get-repos.test.ts","./tests/get-starter-pack.test.ts","./tests/moderation-appeals.test.ts","./tests/moderation-events.test.ts","./tests/moderation-status-tags.test.ts","./tests/moderation-statuses.test.ts","./tests/moderation.test.ts","./tests/protected-tags.test.ts","./tests/query-labels.test.ts","./tests/record-and-account-events.test.ts","./tests/repo-search.test.ts","./tests/report-muting.test.ts","./tests/sequencer.test.ts","./tests/server.test.ts","./tests/sets.test.ts","./tests/settings.test.ts","./tests/team.test.ts"],"version":"5.6.3"}
1
+ {"root":["./tests/3p-labeler.test.ts","./tests/_util.ts","./tests/ack-all-subjects-of-account.test.ts","./tests/blob-divert.test.ts","./tests/communication-templates.test.ts","./tests/content-tagger.test.ts","./tests/db.test.ts","./tests/get-config.test.ts","./tests/get-lists.test.ts","./tests/get-profiles.test.ts","./tests/get-record.test.ts","./tests/get-records.test.ts","./tests/get-repo.test.ts","./tests/get-repos.test.ts","./tests/get-starter-pack.test.ts","./tests/moderation-appeals.test.ts","./tests/moderation-events.test.ts","./tests/moderation-status-tags.test.ts","./tests/moderation-statuses.test.ts","./tests/moderation.test.ts","./tests/protected-tags.test.ts","./tests/query-labels.test.ts","./tests/record-and-account-events.test.ts","./tests/repo-search.test.ts","./tests/report-muting.test.ts","./tests/sequencer.test.ts","./tests/server.test.ts","./tests/sets.test.ts","./tests/settings.test.ts","./tests/team.test.ts"],"version":"5.6.3"}