@atproto/ozone 0.1.25 → 0.1.27

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 (158) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/api/index.d.ts.map +1 -1
  3. package/dist/api/index.js +8 -0
  4. package/dist/api/index.js.map +1 -1
  5. package/dist/api/proxied.d.ts.map +1 -1
  6. package/dist/api/proxied.js +30 -0
  7. package/dist/api/proxied.js.map +1 -1
  8. package/dist/api/server/getConfig.d.ts.map +1 -1
  9. package/dist/api/server/getConfig.js +4 -3
  10. package/dist/api/server/getConfig.js.map +1 -1
  11. package/dist/api/team/addMember.d.ts +4 -0
  12. package/dist/api/team/addMember.d.ts.map +1 -0
  13. package/dist/api/team/addMember.js +38 -0
  14. package/dist/api/team/addMember.js.map +1 -0
  15. package/dist/api/team/deleteMember.d.ts +4 -0
  16. package/dist/api/team/deleteMember.d.ts.map +1 -0
  17. package/dist/api/team/deleteMember.js +26 -0
  18. package/dist/api/team/deleteMember.js.map +1 -0
  19. package/dist/api/team/listMembers.d.ts +4 -0
  20. package/dist/api/team/listMembers.d.ts.map +1 -0
  21. package/dist/api/team/listMembers.js +20 -0
  22. package/dist/api/team/listMembers.js.map +1 -0
  23. package/dist/api/team/updateMember.d.ts +4 -0
  24. package/dist/api/team/updateMember.d.ts.map +1 -0
  25. package/dist/api/team/updateMember.js +40 -0
  26. package/dist/api/team/updateMember.js.map +1 -0
  27. package/dist/api/util.d.ts +1 -0
  28. package/dist/api/util.d.ts.map +1 -1
  29. package/dist/api/util.js +10 -1
  30. package/dist/api/util.js.map +1 -1
  31. package/dist/auth-verifier.d.ts +3 -6
  32. package/dist/auth-verifier.d.ts.map +1 -1
  33. package/dist/auth-verifier.js +7 -19
  34. package/dist/auth-verifier.js.map +1 -1
  35. package/dist/context.d.ts +3 -0
  36. package/dist/context.d.ts.map +1 -1
  37. package/dist/context.js +7 -3
  38. package/dist/context.js.map +1 -1
  39. package/dist/db/migrations/20240521T211332580Z-member.d.ts +4 -0
  40. package/dist/db/migrations/20240521T211332580Z-member.d.ts.map +1 -0
  41. package/dist/db/migrations/20240521T211332580Z-member.js +20 -0
  42. package/dist/db/migrations/20240521T211332580Z-member.js.map +1 -0
  43. package/dist/db/migrations/index.d.ts +1 -0
  44. package/dist/db/migrations/index.d.ts.map +1 -1
  45. package/dist/db/migrations/index.js +2 -1
  46. package/dist/db/migrations/index.js.map +1 -1
  47. package/dist/db/schema/index.d.ts +2 -1
  48. package/dist/db/schema/index.d.ts.map +1 -1
  49. package/dist/db/schema/member.d.ts +14 -0
  50. package/dist/db/schema/member.d.ts.map +1 -0
  51. package/dist/db/schema/member.js +5 -0
  52. package/dist/db/schema/member.js.map +1 -0
  53. package/dist/index.d.ts +1 -0
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +25 -0
  56. package/dist/index.js.map +1 -1
  57. package/dist/lexicon/index.d.ts +25 -0
  58. package/dist/lexicon/index.d.ts.map +1 -1
  59. package/dist/lexicon/index.js +54 -1
  60. package/dist/lexicon/index.js.map +1 -1
  61. package/dist/lexicon/lexicons.d.ts +536 -0
  62. package/dist/lexicon/lexicons.d.ts.map +1 -1
  63. package/dist/lexicon/lexicons.js +561 -1
  64. package/dist/lexicon/lexicons.js.map +1 -1
  65. package/dist/lexicon/types/app/bsky/actor/defs.d.ts +5 -0
  66. package/dist/lexicon/types/app/bsky/actor/defs.d.ts.map +1 -1
  67. package/dist/lexicon/types/app/bsky/actor/defs.js.map +1 -1
  68. package/dist/lexicon/types/app/bsky/actor/profile.d.ts +3 -0
  69. package/dist/lexicon/types/app/bsky/actor/profile.d.ts.map +1 -1
  70. package/dist/lexicon/types/app/bsky/actor/profile.js.map +1 -1
  71. package/dist/lexicon/types/app/bsky/graph/defs.d.ts +36 -1
  72. package/dist/lexicon/types/app/bsky/graph/defs.d.ts.map +1 -1
  73. package/dist/lexicon/types/app/bsky/graph/defs.js +23 -1
  74. package/dist/lexicon/types/app/bsky/graph/defs.js.map +1 -1
  75. package/dist/lexicon/types/app/bsky/graph/getActorStarterPacks.d.ts +39 -0
  76. package/dist/lexicon/types/app/bsky/graph/getActorStarterPacks.d.ts.map +1 -0
  77. package/dist/lexicon/types/app/bsky/graph/getActorStarterPacks.js +3 -0
  78. package/dist/lexicon/types/app/bsky/graph/getActorStarterPacks.js.map +1 -0
  79. package/dist/lexicon/types/app/bsky/graph/getStarterPack.d.ts +37 -0
  80. package/dist/lexicon/types/app/bsky/graph/getStarterPack.d.ts.map +1 -0
  81. package/dist/lexicon/types/app/bsky/graph/getStarterPack.js +3 -0
  82. package/dist/lexicon/types/app/bsky/graph/getStarterPack.js.map +1 -0
  83. package/dist/lexicon/types/app/bsky/graph/getStarterPacks.d.ts +36 -0
  84. package/dist/lexicon/types/app/bsky/graph/getStarterPacks.d.ts.map +1 -0
  85. package/dist/lexicon/types/app/bsky/graph/getStarterPacks.js +3 -0
  86. package/dist/lexicon/types/app/bsky/graph/getStarterPacks.js.map +1 -0
  87. package/dist/lexicon/types/app/bsky/graph/starterpack.d.ts +25 -0
  88. package/dist/lexicon/types/app/bsky/graph/starterpack.d.ts.map +1 -0
  89. package/dist/lexicon/types/app/bsky/graph/starterpack.js +27 -0
  90. package/dist/lexicon/types/app/bsky/graph/starterpack.js.map +1 -0
  91. package/dist/lexicon/types/app/bsky/notification/listNotifications.d.ts +2 -2
  92. package/dist/lexicon/types/app/bsky/notification/listNotifications.d.ts.map +1 -1
  93. package/dist/lexicon/types/app/bsky/notification/listNotifications.js.map +1 -1
  94. package/dist/lexicon/types/tools/ozone/team/addMember.d.ts +40 -0
  95. package/dist/lexicon/types/tools/ozone/team/addMember.d.ts.map +1 -0
  96. package/dist/lexicon/types/tools/ozone/team/addMember.js +3 -0
  97. package/dist/lexicon/types/tools/ozone/team/addMember.js.map +1 -0
  98. package/dist/lexicon/types/tools/ozone/team/defs.d.ts +24 -0
  99. package/dist/lexicon/types/tools/ozone/team/defs.d.ts.map +1 -0
  100. package/dist/lexicon/types/tools/ozone/team/defs.js +22 -0
  101. package/dist/lexicon/types/tools/ozone/team/defs.js.map +1 -0
  102. package/dist/lexicon/types/tools/ozone/team/deleteMember.d.ts +30 -0
  103. package/dist/lexicon/types/tools/ozone/team/deleteMember.d.ts.map +1 -0
  104. package/dist/lexicon/types/tools/ozone/team/deleteMember.js +3 -0
  105. package/dist/lexicon/types/tools/ozone/team/deleteMember.js.map +1 -0
  106. package/dist/lexicon/types/tools/ozone/team/listMembers.d.ts +38 -0
  107. package/dist/lexicon/types/tools/ozone/team/listMembers.d.ts.map +1 -0
  108. package/dist/lexicon/types/tools/ozone/team/listMembers.js +3 -0
  109. package/dist/lexicon/types/tools/ozone/team/listMembers.js.map +1 -0
  110. package/dist/lexicon/types/tools/ozone/team/updateMember.d.ts +41 -0
  111. package/dist/lexicon/types/tools/ozone/team/updateMember.d.ts.map +1 -0
  112. package/dist/lexicon/types/tools/ozone/team/updateMember.js +3 -0
  113. package/dist/lexicon/types/tools/ozone/team/updateMember.js.map +1 -0
  114. package/dist/team/index.d.ts +37 -0
  115. package/dist/team/index.d.ts.map +1 -0
  116. package/dist/team/index.js +144 -0
  117. package/dist/team/index.js.map +1 -0
  118. package/package.json +4 -4
  119. package/src/api/index.ts +8 -0
  120. package/src/api/proxied.ts +43 -0
  121. package/src/api/server/getConfig.ts +4 -4
  122. package/src/api/team/addMember.ts +46 -0
  123. package/src/api/team/deleteMember.ts +29 -0
  124. package/src/api/team/listMembers.ts +20 -0
  125. package/src/api/team/updateMember.ts +47 -0
  126. package/src/api/util.ts +15 -0
  127. package/src/auth-verifier.ts +14 -12
  128. package/src/context.ts +9 -3
  129. package/src/db/migrations/20240521T211332580Z-member.ts +17 -0
  130. package/src/db/migrations/index.ts +1 -0
  131. package/src/db/schema/index.ts +3 -1
  132. package/src/db/schema/member.ts +19 -0
  133. package/src/index.ts +36 -0
  134. package/src/lexicon/index.ts +100 -0
  135. package/src/lexicon/lexicons.ts +566 -1
  136. package/src/lexicon/types/app/bsky/actor/defs.ts +5 -0
  137. package/src/lexicon/types/app/bsky/actor/profile.ts +3 -0
  138. package/src/lexicon/types/app/bsky/graph/defs.ts +58 -0
  139. package/src/lexicon/types/app/bsky/graph/getActorStarterPacks.ts +49 -0
  140. package/src/lexicon/types/app/bsky/graph/getStarterPack.ts +47 -0
  141. package/src/lexicon/types/app/bsky/graph/getStarterPacks.ts +46 -0
  142. package/src/lexicon/types/app/bsky/graph/starterpack.ts +50 -0
  143. package/src/lexicon/types/app/bsky/notification/listNotifications.ts +2 -1
  144. package/src/lexicon/types/tools/ozone/team/addMember.ts +53 -0
  145. package/src/lexicon/types/tools/ozone/team/defs.ts +42 -0
  146. package/src/lexicon/types/tools/ozone/team/deleteMember.ts +39 -0
  147. package/src/lexicon/types/tools/ozone/team/listMembers.ts +48 -0
  148. package/src/lexicon/types/tools/ozone/team/updateMember.ts +54 -0
  149. package/src/team/index.ts +213 -0
  150. package/tests/__snapshots__/get-record.test.ts.snap +2 -0
  151. package/tests/__snapshots__/get-repo.test.ts.snap +1 -0
  152. package/tests/__snapshots__/get-starter-pack.test.ts.snap +466 -0
  153. package/tests/__snapshots__/moderation-events.test.ts.snap +1 -0
  154. package/tests/__snapshots__/team.test.ts.snap +688 -0
  155. package/tests/get-config.test.ts +3 -4
  156. package/tests/get-starter-pack.test.ts +104 -0
  157. package/tests/server.test.ts +1 -1
  158. package/tests/team.test.ts +163 -0
@@ -1,5 +1,6 @@
1
1
  import { TestNetwork, SeedClient, basicSeed } from '@atproto/dev-env'
2
2
  import AtpAgent from '@atproto/api'
3
+ import { TOOLS_OZONE_TEAM } from '../src/lexicon'
3
4
 
4
5
  describe('get-config', () => {
5
6
  let network: TestNetwork
@@ -39,14 +40,12 @@ describe('get-config', () => {
39
40
  )
40
41
  expect(moderatorConfig.chat?.url).toBe(undefined)
41
42
  expect(moderatorConfig.viewer?.role).toEqual(
42
- 'tools.ozone.moderator.defs#modRoleModerator',
43
+ TOOLS_OZONE_TEAM.DefsRoleModerator,
43
44
  )
44
45
  })
45
46
 
46
47
  it('returns the right role for the viewer', async () => {
47
48
  const adminConfig = await getConfig('admin')
48
- expect(adminConfig.viewer?.role).toBe(
49
- 'tools.ozone.moderator.defs#modRoleAdmin',
50
- )
49
+ expect(adminConfig.viewer?.role).toBe(TOOLS_OZONE_TEAM.DefsRoleAdmin)
51
50
  })
52
51
  })
@@ -0,0 +1,104 @@
1
+ import {
2
+ SeedClient,
3
+ TestNetwork,
4
+ basicSeed,
5
+ TestOzone,
6
+ RecordRef,
7
+ } from '@atproto/dev-env'
8
+ import AtpAgent from '@atproto/api'
9
+ import { forSnapshot } from './_util'
10
+ import { TAKEDOWN_LABEL } from '../src/mod-service'
11
+
12
+ describe('admin get starter pack view', () => {
13
+ let network: TestNetwork
14
+ let ozone: TestOzone
15
+ let agent: AtpAgent
16
+ let sc: SeedClient
17
+ let sp1: RecordRef
18
+
19
+ beforeAll(async () => {
20
+ network = await TestNetwork.create({
21
+ dbPostgresSchema: 'ozone_admin_get_starterpack',
22
+ })
23
+ ozone = network.ozone
24
+ AtpAgent.configure({ appLabelers: [ozone.ctx.cfg.service.did] })
25
+ agent = ozone.getClient()
26
+ sc = network.getSeedClient()
27
+ await basicSeed(sc)
28
+ await network.processAll()
29
+ })
30
+
31
+ afterAll(async () => {
32
+ await network.close()
33
+ })
34
+
35
+ beforeAll(async () => {
36
+ const feedgen = await sc.createFeedGen(
37
+ sc.dids.alice,
38
+ 'did:web:example.com',
39
+ "alice's feedgen",
40
+ )
41
+ sp1 = await sc.createStarterPack(
42
+ sc.dids.alice,
43
+ "alice's starter pack",
44
+ [sc.dids.bob, sc.dids.carol, sc.dids.dan],
45
+ [feedgen.uriStr],
46
+ )
47
+ await network.processAll()
48
+ })
49
+
50
+ describe('getStarterPack()', () => {
51
+ it('gets a starterpack by uri', async () => {
52
+ const result = await agent.api.app.bsky.graph.getStarterPack(
53
+ { starterPack: sp1.uriStr },
54
+ { headers: await ozone.modHeaders() },
55
+ )
56
+ expect(forSnapshot(result.data)).toMatchSnapshot()
57
+ })
58
+
59
+ it('gets a starterpack while taken down', async () => {
60
+ // Validate that appview returns starterpacks before takedown
61
+ const appviewAgent = network.bsky.getClient()
62
+ const beforeTakedownFromAppview =
63
+ await appviewAgent.api.app.bsky.graph.getStarterPack(
64
+ { starterPack: sp1.uriStr },
65
+ { headers: await network.serviceHeaders(sc.dids.alice) },
66
+ )
67
+
68
+ expect(
69
+ forSnapshot(beforeTakedownFromAppview.data.starterPack),
70
+ ).toMatchSnapshot()
71
+
72
+ await network.bsky.db.db
73
+ .insertInto('label')
74
+ .values({
75
+ src: ozone.ctx.cfg.service.did,
76
+ uri: sp1.uriStr,
77
+ cid: sp1.cidStr,
78
+ val: TAKEDOWN_LABEL,
79
+ neg: false,
80
+ cts: new Date().toISOString(),
81
+ })
82
+ .execute()
83
+
84
+ const afterTakedownFromOzone =
85
+ await agent.api.app.bsky.graph.getStarterPack(
86
+ { starterPack: sp1.uriStr },
87
+ { headers: await ozone.modHeaders() },
88
+ )
89
+
90
+ // validate that ozone returns starterpacks after takedown
91
+ expect(
92
+ forSnapshot(afterTakedownFromOzone.data.starterPack),
93
+ ).toMatchSnapshot()
94
+
95
+ // validate that appview does not return starterpack after takedown
96
+ await expect(
97
+ appviewAgent.api.app.bsky.graph.getStarterPack(
98
+ { starterPack: sp1.uriStr },
99
+ { headers: await network.serviceHeaders(sc.dids.alice) },
100
+ ),
101
+ ).rejects.toThrow('Starter pack not found')
102
+ })
103
+ })
104
+ })
@@ -54,7 +54,7 @@ describe('server', () => {
54
54
  })
55
55
 
56
56
  it('healthcheck fails when database is unavailable.', async () => {
57
- // destory sequencer to release connection that would prevent the db from closing
57
+ // destroy sequencer to release connection that would prevent the db from closing
58
58
  await ozone.ctx.sequencer.destroy()
59
59
  await ozone.ctx.db.close()
60
60
  let error: AxiosError
@@ -0,0 +1,163 @@
1
+ import { SeedClient, TestNetwork, basicSeed } from '@atproto/dev-env'
2
+ import AtpAgent from '@atproto/api'
3
+ import { forSnapshot } from './_util'
4
+
5
+ describe('team management', () => {
6
+ let network: TestNetwork
7
+ let adminAgent: AtpAgent
8
+ let triageAgent: AtpAgent
9
+ let sc: SeedClient
10
+
11
+ beforeAll(async () => {
12
+ network = await TestNetwork.create({
13
+ dbPostgresSchema: 'ozone_team_test',
14
+ })
15
+ adminAgent = network.pds.getClient()
16
+ sc = network.getSeedClient()
17
+ await basicSeed(sc)
18
+ await network.processAll()
19
+
20
+ await network.ozone.addAdminDid(sc.dids.alice)
21
+ await network.ozone.addModeratorDid(sc.dids.bob)
22
+ await network.ozone.addTriageDid(sc.dids.carol)
23
+ await adminAgent.login({
24
+ identifier: sc.accounts[sc.dids.alice].handle,
25
+ password: sc.accounts[sc.dids.alice].password,
26
+ })
27
+ triageAgent = network.pds.getClient()
28
+ await triageAgent.login({
29
+ identifier: sc.accounts[sc.dids.carol].handle,
30
+ password: sc.accounts[sc.dids.carol].password,
31
+ })
32
+ })
33
+
34
+ afterAll(async () => {
35
+ await network.close()
36
+ })
37
+
38
+ describe('listMembers', () => {
39
+ it('allows all members to list all members', async () => {
40
+ const [{ data: forAdmin }, { data: forTriage }] = await Promise.all([
41
+ adminAgent.api.tools.ozone.team.listMembers({}),
42
+ triageAgent.api.tools.ozone.team.listMembers({}),
43
+ ])
44
+ expect(forSnapshot(forAdmin.members)).toMatchSnapshot()
45
+ expect(forSnapshot(forTriage.members)).toMatchSnapshot()
46
+ // Validate that the list looks the same to both admin and triage members
47
+
48
+ expect(forAdmin.members.length).toEqual(forTriage.members.length)
49
+ })
50
+ })
51
+ describe('listMembers', () => {
52
+ it('allows all members to list all members', async () => {
53
+ const [{ data: forAdmin }, { data: forTriage }] = await Promise.all([
54
+ adminAgent.api.tools.ozone.team.listMembers({}),
55
+ triageAgent.api.tools.ozone.team.listMembers({}),
56
+ ])
57
+ expect(forSnapshot(forAdmin.members)).toMatchSnapshot()
58
+ expect(forSnapshot(forTriage.members)).toMatchSnapshot()
59
+ // Validate that the list looks the same to both admin and triage members
60
+
61
+ expect(forAdmin.members.length).toEqual(forTriage.members.length)
62
+ })
63
+ })
64
+ describe('addMember', () => {
65
+ const newMemberData = {
66
+ did: 'did:plc:newMember',
67
+ role: 'tools.ozone.team.defs#roleAdmin',
68
+ disabled: false,
69
+ }
70
+ it('only allows admins to add member', async () => {
71
+ await expect(
72
+ triageAgent.api.tools.ozone.team.addMember(newMemberData),
73
+ ).rejects.toThrow('Must be an admin to add a member')
74
+ const { data: newMember } =
75
+ await adminAgent.api.tools.ozone.team.addMember(newMemberData)
76
+ expect(forSnapshot(newMember)).toMatchSnapshot()
77
+ })
78
+ it('throws error when trying to add existing member', async () => {
79
+ await expect(
80
+ adminAgent.api.tools.ozone.team.addMember(newMemberData),
81
+ ).rejects.toThrow('member already exists')
82
+ })
83
+ })
84
+ describe('deleteMember', () => {
85
+ it('only allows admins to delete members', async () => {
86
+ const {
87
+ data: { members: initialMembers },
88
+ } = await adminAgent.api.tools.ozone.team.listMembers({})
89
+ await expect(
90
+ triageAgent.api.tools.ozone.team.deleteMember({
91
+ did: sc.dids.bob,
92
+ }),
93
+ ).rejects.toThrow('Must be an admin to delete a member')
94
+
95
+ await adminAgent.api.tools.ozone.team.deleteMember({
96
+ did: sc.dids.bob,
97
+ })
98
+ const {
99
+ data: { members: membersAfterDelete },
100
+ } = await adminAgent.api.tools.ozone.team.listMembers({})
101
+
102
+ expect(membersAfterDelete.length).toEqual(initialMembers.length - 1)
103
+ expect(membersAfterDelete.map(({ did }) => did)).not.toContain(
104
+ sc.dids.bob,
105
+ )
106
+ })
107
+
108
+ it('throws error when trying to remove non-existent member', async () => {
109
+ await expect(
110
+ adminAgent.api.tools.ozone.team.deleteMember({
111
+ did: 'did:plc:test',
112
+ }),
113
+ ).rejects.toThrow('member not found')
114
+ })
115
+ })
116
+ describe('updateMember', () => {
117
+ it('allows admins to update member', async () => {
118
+ const getCarol = async () => {
119
+ const {
120
+ data: { members },
121
+ } = await adminAgent.api.tools.ozone.team.listMembers({})
122
+
123
+ return members.find(({ did }) => did === sc.dids.carol)
124
+ }
125
+ await expect(
126
+ triageAgent.api.tools.ozone.team.updateMember({
127
+ disabled: false,
128
+ did: sc.dids.carol,
129
+ role: 'tools.ozone.team.defs#roleAdmin',
130
+ }),
131
+ ).rejects.toThrow('Must be an admin to update a member')
132
+
133
+ await adminAgent.api.tools.ozone.team.updateMember({
134
+ did: sc.dids.carol,
135
+ role: 'tools.ozone.team.defs#roleAdmin',
136
+ })
137
+ const carolAfterRoleChange = await getCarol()
138
+ expect(carolAfterRoleChange?.role).toEqual(
139
+ 'tools.ozone.team.defs#roleAdmin',
140
+ )
141
+ // Verify that params that we didn't send did not get updated
142
+ expect(carolAfterRoleChange?.disabled).toEqual(false)
143
+
144
+ await adminAgent.api.tools.ozone.team.updateMember({
145
+ did: sc.dids.carol,
146
+ disabled: true,
147
+ })
148
+ const carolAfterDisable = await getCarol()
149
+ expect(carolAfterDisable?.disabled).toEqual(true)
150
+ // Verify that params that we didn't send did not get updated
151
+ expect(carolAfterDisable?.role).toEqual('tools.ozone.team.defs#roleAdmin')
152
+ })
153
+ it('throws error when trying to update non-existent member', async () => {
154
+ await expect(
155
+ adminAgent.api.tools.ozone.team.updateMember({
156
+ disabled: false,
157
+ did: 'did:plc:test',
158
+ role: 'tools.ozone.team.defs#roleAdmin',
159
+ }),
160
+ ).rejects.toThrow('member not found')
161
+ })
162
+ })
163
+ })