@atproto/pds 0.4.165 → 0.4.166

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 (282) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/account-manager/account-manager.js +2 -2
  3. package/dist/account-manager/account-manager.js.map +1 -1
  4. package/dist/account-manager/helpers/account-device.d.ts +4 -4
  5. package/dist/account-manager/helpers/account.d.ts +1 -1
  6. package/dist/account-manager/helpers/auth.d.ts +1 -1
  7. package/dist/account-manager/helpers/auth.d.ts.map +1 -1
  8. package/dist/account-manager/helpers/auth.js +8 -8
  9. package/dist/account-manager/helpers/auth.js.map +1 -1
  10. package/dist/account-manager/helpers/authorization-request.d.ts +1 -1
  11. package/dist/account-manager/helpers/authorization-request.d.ts.map +1 -1
  12. package/dist/account-manager/helpers/authorization-request.js +16 -8
  13. package/dist/account-manager/helpers/authorization-request.js.map +1 -1
  14. package/dist/account-manager/helpers/token.d.ts +65 -65
  15. package/dist/actor-store/preference/reader.d.ts +2 -2
  16. package/dist/actor-store/preference/reader.d.ts.map +1 -1
  17. package/dist/actor-store/preference/reader.js +2 -2
  18. package/dist/actor-store/preference/reader.js.map +1 -1
  19. package/dist/actor-store/preference/transactor.d.ts +2 -2
  20. package/dist/actor-store/preference/transactor.d.ts.map +1 -1
  21. package/dist/actor-store/preference/transactor.js +5 -5
  22. package/dist/actor-store/preference/transactor.js.map +1 -1
  23. package/dist/actor-store/preference/util.d.ts +4 -2
  24. package/dist/actor-store/preference/util.d.ts.map +1 -1
  25. package/dist/actor-store/preference/util.js +9 -8
  26. package/dist/actor-store/preference/util.js.map +1 -1
  27. package/dist/actor-store/record/reader.d.ts +2 -2
  28. package/dist/api/app/bsky/actor/getPreferences.d.ts.map +1 -1
  29. package/dist/api/app/bsky/actor/getPreferences.js +29 -7
  30. package/dist/api/app/bsky/actor/getPreferences.js.map +1 -1
  31. package/dist/api/app/bsky/actor/getProfile.d.ts.map +1 -1
  32. package/dist/api/app/bsky/actor/getProfile.js +9 -1
  33. package/dist/api/app/bsky/actor/getProfile.js.map +1 -1
  34. package/dist/api/app/bsky/actor/getProfiles.d.ts.map +1 -1
  35. package/dist/api/app/bsky/actor/getProfiles.js +9 -1
  36. package/dist/api/app/bsky/actor/getProfiles.js.map +1 -1
  37. package/dist/api/app/bsky/actor/putPreferences.d.ts.map +1 -1
  38. package/dist/api/app/bsky/actor/putPreferences.js +30 -8
  39. package/dist/api/app/bsky/actor/putPreferences.js.map +1 -1
  40. package/dist/api/app/bsky/feed/getActorLikes.d.ts.map +1 -1
  41. package/dist/api/app/bsky/feed/getActorLikes.js +9 -1
  42. package/dist/api/app/bsky/feed/getActorLikes.js.map +1 -1
  43. package/dist/api/app/bsky/feed/getAuthorFeed.d.ts.map +1 -1
  44. package/dist/api/app/bsky/feed/getAuthorFeed.js +9 -1
  45. package/dist/api/app/bsky/feed/getAuthorFeed.js.map +1 -1
  46. package/dist/api/app/bsky/feed/getFeed.d.ts.map +1 -1
  47. package/dist/api/app/bsky/feed/getFeed.js +8 -1
  48. package/dist/api/app/bsky/feed/getFeed.js.map +1 -1
  49. package/dist/api/app/bsky/feed/getPostThread.d.ts.map +1 -1
  50. package/dist/api/app/bsky/feed/getPostThread.js +8 -1
  51. package/dist/api/app/bsky/feed/getPostThread.js.map +1 -1
  52. package/dist/api/app/bsky/feed/getTimeline.d.ts.map +1 -1
  53. package/dist/api/app/bsky/feed/getTimeline.js +9 -1
  54. package/dist/api/app/bsky/feed/getTimeline.js.map +1 -1
  55. package/dist/api/app/bsky/notification/registerPush.d.ts.map +1 -1
  56. package/dist/api/app/bsky/notification/registerPush.js +16 -4
  57. package/dist/api/app/bsky/notification/registerPush.js.map +1 -1
  58. package/dist/api/com/atproto/identity/getRecommendedDidCredentials.d.ts.map +1 -1
  59. package/dist/api/com/atproto/identity/getRecommendedDidCredentials.js +5 -1
  60. package/dist/api/com/atproto/identity/getRecommendedDidCredentials.js.map +1 -1
  61. package/dist/api/com/atproto/identity/requestPlcOperationSignature.d.ts.map +1 -1
  62. package/dist/api/com/atproto/identity/requestPlcOperationSignature.js +9 -2
  63. package/dist/api/com/atproto/identity/requestPlcOperationSignature.js.map +1 -1
  64. package/dist/api/com/atproto/identity/signPlcOperation.d.ts.map +1 -1
  65. package/dist/api/com/atproto/identity/signPlcOperation.js +9 -1
  66. package/dist/api/com/atproto/identity/signPlcOperation.js.map +1 -1
  67. package/dist/api/com/atproto/identity/submitPlcOperation.d.ts.map +1 -1
  68. package/dist/api/com/atproto/identity/submitPlcOperation.js +5 -1
  69. package/dist/api/com/atproto/identity/submitPlcOperation.js.map +1 -1
  70. package/dist/api/com/atproto/identity/updateHandle.d.ts.map +1 -1
  71. package/dist/api/com/atproto/identity/updateHandle.js +6 -1
  72. package/dist/api/com/atproto/identity/updateHandle.js.map +1 -1
  73. package/dist/api/com/atproto/moderation/createReport.d.ts.map +1 -1
  74. package/dist/api/com/atproto/moderation/createReport.js +8 -3
  75. package/dist/api/com/atproto/moderation/createReport.js.map +1 -1
  76. package/dist/api/com/atproto/repo/applyWrites.d.ts.map +1 -1
  77. package/dist/api/com/atproto/repo/applyWrites.js +25 -19
  78. package/dist/api/com/atproto/repo/applyWrites.js.map +1 -1
  79. package/dist/api/com/atproto/repo/createRecord.d.ts.map +1 -1
  80. package/dist/api/com/atproto/repo/createRecord.js +10 -1
  81. package/dist/api/com/atproto/repo/createRecord.js.map +1 -1
  82. package/dist/api/com/atproto/repo/deleteRecord.d.ts.map +1 -1
  83. package/dist/api/com/atproto/repo/deleteRecord.js +12 -1
  84. package/dist/api/com/atproto/repo/deleteRecord.js.map +1 -1
  85. package/dist/api/com/atproto/repo/importRepo.d.ts.map +1 -1
  86. package/dist/api/com/atproto/repo/importRepo.js +7 -2
  87. package/dist/api/com/atproto/repo/importRepo.js.map +1 -1
  88. package/dist/api/com/atproto/repo/listMissingBlobs.d.ts.map +1 -1
  89. package/dist/api/com/atproto/repo/listMissingBlobs.js +6 -2
  90. package/dist/api/com/atproto/repo/listMissingBlobs.js.map +1 -1
  91. package/dist/api/com/atproto/repo/putRecord.d.ts.map +1 -1
  92. package/dist/api/com/atproto/repo/putRecord.js +17 -11
  93. package/dist/api/com/atproto/repo/putRecord.js.map +1 -1
  94. package/dist/api/com/atproto/repo/uploadBlob.d.ts.map +1 -1
  95. package/dist/api/com/atproto/repo/uploadBlob.js +5 -1
  96. package/dist/api/com/atproto/repo/uploadBlob.js.map +1 -1
  97. package/dist/api/com/atproto/server/activateAccount.d.ts.map +1 -1
  98. package/dist/api/com/atproto/server/activateAccount.js +7 -1
  99. package/dist/api/com/atproto/server/activateAccount.js.map +1 -1
  100. package/dist/api/com/atproto/server/checkAccountStatus.d.ts.map +1 -1
  101. package/dist/api/com/atproto/server/checkAccountStatus.js +5 -1
  102. package/dist/api/com/atproto/server/checkAccountStatus.js.map +1 -1
  103. package/dist/api/com/atproto/server/confirmEmail.d.ts.map +1 -1
  104. package/dist/api/com/atproto/server/confirmEmail.js +6 -1
  105. package/dist/api/com/atproto/server/confirmEmail.js.map +1 -1
  106. package/dist/api/com/atproto/server/createAppPassword.d.ts.map +1 -1
  107. package/dist/api/com/atproto/server/createAppPassword.js +7 -1
  108. package/dist/api/com/atproto/server/createAppPassword.js.map +1 -1
  109. package/dist/api/com/atproto/server/deactivateAccount.d.ts.map +1 -1
  110. package/dist/api/com/atproto/server/deactivateAccount.js +9 -2
  111. package/dist/api/com/atproto/server/deactivateAccount.js.map +1 -1
  112. package/dist/api/com/atproto/server/deleteSession.d.ts.map +1 -1
  113. package/dist/api/com/atproto/server/deleteSession.js +3 -1
  114. package/dist/api/com/atproto/server/deleteSession.js.map +1 -1
  115. package/dist/api/com/atproto/server/getAccountInviteCodes.d.ts.map +1 -1
  116. package/dist/api/com/atproto/server/getAccountInviteCodes.js +8 -1
  117. package/dist/api/com/atproto/server/getAccountInviteCodes.js.map +1 -1
  118. package/dist/api/com/atproto/server/getServiceAuth.d.ts.map +1 -1
  119. package/dist/api/com/atproto/server/getServiceAuth.js +24 -13
  120. package/dist/api/com/atproto/server/getServiceAuth.js.map +1 -1
  121. package/dist/api/com/atproto/server/getSession.d.ts.map +1 -1
  122. package/dist/api/com/atproto/server/getSession.js +12 -19
  123. package/dist/api/com/atproto/server/getSession.js.map +1 -1
  124. package/dist/api/com/atproto/server/listAppPasswords.d.ts.map +1 -1
  125. package/dist/api/com/atproto/server/listAppPasswords.js +6 -1
  126. package/dist/api/com/atproto/server/listAppPasswords.js.map +1 -1
  127. package/dist/api/com/atproto/server/refreshSession.js +1 -1
  128. package/dist/api/com/atproto/server/refreshSession.js.map +1 -1
  129. package/dist/api/com/atproto/server/requestAccountDelete.d.ts.map +1 -1
  130. package/dist/api/com/atproto/server/requestAccountDelete.js +8 -1
  131. package/dist/api/com/atproto/server/requestAccountDelete.js.map +1 -1
  132. package/dist/api/com/atproto/server/requestEmailConfirmation.d.ts.map +1 -1
  133. package/dist/api/com/atproto/server/requestEmailConfirmation.js +6 -1
  134. package/dist/api/com/atproto/server/requestEmailConfirmation.js.map +1 -1
  135. package/dist/api/com/atproto/server/requestEmailUpdate.d.ts.map +1 -1
  136. package/dist/api/com/atproto/server/requestEmailUpdate.js +6 -1
  137. package/dist/api/com/atproto/server/requestEmailUpdate.js.map +1 -1
  138. package/dist/api/com/atproto/server/revokeAppPassword.d.ts.map +1 -1
  139. package/dist/api/com/atproto/server/revokeAppPassword.js +6 -1
  140. package/dist/api/com/atproto/server/revokeAppPassword.js.map +1 -1
  141. package/dist/api/com/atproto/server/updateEmail.d.ts.map +1 -1
  142. package/dist/api/com/atproto/server/updateEmail.js +8 -1
  143. package/dist/api/com/atproto/server/updateEmail.js.map +1 -1
  144. package/dist/api/com/atproto/sync/deprecated/getCheckout.d.ts.map +1 -1
  145. package/dist/api/com/atproto/sync/deprecated/getCheckout.js +7 -2
  146. package/dist/api/com/atproto/sync/deprecated/getCheckout.js.map +1 -1
  147. package/dist/api/com/atproto/sync/deprecated/getHead.d.ts.map +1 -1
  148. package/dist/api/com/atproto/sync/deprecated/getHead.js +7 -2
  149. package/dist/api/com/atproto/sync/deprecated/getHead.js.map +1 -1
  150. package/dist/api/com/atproto/sync/getBlob.d.ts.map +1 -1
  151. package/dist/api/com/atproto/sync/getBlob.js +7 -3
  152. package/dist/api/com/atproto/sync/getBlob.js.map +1 -1
  153. package/dist/api/com/atproto/sync/getBlocks.d.ts.map +1 -1
  154. package/dist/api/com/atproto/sync/getBlocks.js +7 -2
  155. package/dist/api/com/atproto/sync/getBlocks.js.map +1 -1
  156. package/dist/api/com/atproto/sync/getLatestCommit.d.ts.map +1 -1
  157. package/dist/api/com/atproto/sync/getLatestCommit.js +7 -2
  158. package/dist/api/com/atproto/sync/getLatestCommit.js.map +1 -1
  159. package/dist/api/com/atproto/sync/getRecord.d.ts.map +1 -1
  160. package/dist/api/com/atproto/sync/getRecord.js +7 -2
  161. package/dist/api/com/atproto/sync/getRecord.js.map +1 -1
  162. package/dist/api/com/atproto/sync/getRepo.d.ts.map +1 -1
  163. package/dist/api/com/atproto/sync/getRepo.js +7 -3
  164. package/dist/api/com/atproto/sync/getRepo.js.map +1 -1
  165. package/dist/api/com/atproto/sync/listBlobs.d.ts.map +1 -1
  166. package/dist/api/com/atproto/sync/listBlobs.js +7 -3
  167. package/dist/api/com/atproto/sync/listBlobs.js.map +1 -1
  168. package/dist/api/com/atproto/temp/checkSignupQueue.d.ts.map +1 -1
  169. package/dist/api/com/atproto/temp/checkSignupQueue.js +7 -3
  170. package/dist/api/com/atproto/temp/checkSignupQueue.js.map +1 -1
  171. package/dist/auth-output.d.ts +45 -0
  172. package/dist/auth-output.d.ts.map +1 -0
  173. package/dist/auth-output.js +3 -0
  174. package/dist/auth-output.js.map +1 -0
  175. package/dist/auth-scope.d.ts +16 -0
  176. package/dist/auth-scope.d.ts.map +1 -0
  177. package/dist/auth-scope.js +40 -0
  178. package/dist/auth-scope.js.map +1 -0
  179. package/dist/auth-verifier.d.ts +50 -115
  180. package/dist/auth-verifier.d.ts.map +1 -1
  181. package/dist/auth-verifier.js +275 -366
  182. package/dist/auth-verifier.js.map +1 -1
  183. package/dist/config/config.d.ts +2 -1
  184. package/dist/config/config.d.ts.map +1 -1
  185. package/dist/config/config.js +2 -1
  186. package/dist/config/config.js.map +1 -1
  187. package/dist/config/env.d.ts +1 -0
  188. package/dist/config/env.d.ts.map +1 -1
  189. package/dist/config/env.js +3 -1
  190. package/dist/config/env.js.map +1 -1
  191. package/dist/context.d.ts.map +1 -1
  192. package/dist/context.js +5 -5
  193. package/dist/context.js.map +1 -1
  194. package/dist/lexicon/index.d.ts +230 -230
  195. package/dist/lexicon/index.d.ts.map +1 -1
  196. package/dist/lexicon/index.js +687 -687
  197. package/dist/lexicon/index.js.map +1 -1
  198. package/dist/lexicon/lexicons.d.ts +16650 -16650
  199. package/dist/lexicon/lexicons.js +9267 -9267
  200. package/dist/lexicon/lexicons.js.map +1 -1
  201. package/dist/pipethrough.d.ts +5 -3
  202. package/dist/pipethrough.d.ts.map +1 -1
  203. package/dist/pipethrough.js +42 -15
  204. package/dist/pipethrough.js.map +1 -1
  205. package/dist/sequencer/events.d.ts +13 -13
  206. package/dist/util/http.d.ts +7 -0
  207. package/dist/util/http.d.ts.map +1 -0
  208. package/dist/util/http.js +31 -0
  209. package/dist/util/http.js.map +1 -0
  210. package/dist/util/types.d.ts +5 -0
  211. package/dist/util/types.d.ts.map +1 -0
  212. package/dist/util/types.js +3 -0
  213. package/dist/util/types.js.map +1 -0
  214. package/package.json +4 -3
  215. package/src/account-manager/account-manager.ts +1 -1
  216. package/src/account-manager/helpers/auth.ts +1 -1
  217. package/src/account-manager/helpers/authorization-request.ts +8 -4
  218. package/src/actor-store/preference/reader.ts +3 -4
  219. package/src/actor-store/preference/transactor.ts +6 -7
  220. package/src/actor-store/preference/util.ts +15 -5
  221. package/src/api/app/bsky/actor/getPreferences.ts +33 -8
  222. package/src/api/app/bsky/actor/getProfile.ts +9 -1
  223. package/src/api/app/bsky/actor/getProfiles.ts +9 -1
  224. package/src/api/app/bsky/actor/putPreferences.ts +35 -12
  225. package/src/api/app/bsky/feed/getActorLikes.ts +9 -1
  226. package/src/api/app/bsky/feed/getAuthorFeed.ts +9 -1
  227. package/src/api/app/bsky/feed/getFeed.ts +9 -2
  228. package/src/api/app/bsky/feed/getPostThread.ts +8 -1
  229. package/src/api/app/bsky/feed/getTimeline.ts +9 -1
  230. package/src/api/app/bsky/notification/registerPush.ts +16 -5
  231. package/src/api/com/atproto/identity/getRecommendedDidCredentials.ts +5 -1
  232. package/src/api/com/atproto/identity/requestPlcOperationSignature.ts +9 -2
  233. package/src/api/com/atproto/identity/signPlcOperation.ts +9 -1
  234. package/src/api/com/atproto/identity/submitPlcOperation.ts +5 -1
  235. package/src/api/com/atproto/identity/updateHandle.ts +6 -1
  236. package/src/api/com/atproto/moderation/createReport.ts +8 -3
  237. package/src/api/com/atproto/repo/applyWrites.ts +28 -20
  238. package/src/api/com/atproto/repo/createRecord.ts +12 -1
  239. package/src/api/com/atproto/repo/deleteRecord.ts +14 -1
  240. package/src/api/com/atproto/repo/importRepo.ts +9 -2
  241. package/src/api/com/atproto/repo/listMissingBlobs.ts +7 -2
  242. package/src/api/com/atproto/repo/putRecord.ts +18 -10
  243. package/src/api/com/atproto/repo/uploadBlob.ts +6 -2
  244. package/src/api/com/atproto/server/activateAccount.ts +10 -2
  245. package/src/api/com/atproto/server/checkAccountStatus.ts +5 -1
  246. package/src/api/com/atproto/server/confirmEmail.ts +6 -1
  247. package/src/api/com/atproto/server/createAppPassword.ts +9 -1
  248. package/src/api/com/atproto/server/deactivateAccount.ts +11 -2
  249. package/src/api/com/atproto/server/deleteSession.ts +3 -1
  250. package/src/api/com/atproto/server/getAccountInviteCodes.ts +11 -2
  251. package/src/api/com/atproto/server/getServiceAuth.ts +37 -18
  252. package/src/api/com/atproto/server/getSession.ts +20 -27
  253. package/src/api/com/atproto/server/listAppPasswords.ts +8 -1
  254. package/src/api/com/atproto/server/refreshSession.ts +1 -1
  255. package/src/api/com/atproto/server/requestAccountDelete.ts +11 -2
  256. package/src/api/com/atproto/server/requestEmailConfirmation.ts +6 -1
  257. package/src/api/com/atproto/server/requestEmailUpdate.ts +6 -1
  258. package/src/api/com/atproto/server/revokeAppPassword.ts +8 -1
  259. package/src/api/com/atproto/server/updateEmail.ts +11 -2
  260. package/src/api/com/atproto/sync/deprecated/getCheckout.ts +7 -6
  261. package/src/api/com/atproto/sync/deprecated/getHead.ts +7 -6
  262. package/src/api/com/atproto/sync/getBlob.ts +7 -7
  263. package/src/api/com/atproto/sync/getBlocks.ts +7 -6
  264. package/src/api/com/atproto/sync/getLatestCommit.ts +7 -6
  265. package/src/api/com/atproto/sync/getRecord.ts +7 -6
  266. package/src/api/com/atproto/sync/getRepo.ts +7 -7
  267. package/src/api/com/atproto/sync/listBlobs.ts +7 -7
  268. package/src/api/com/atproto/temp/checkSignupQueue.ts +8 -2
  269. package/src/auth-output.ts +51 -0
  270. package/src/auth-scope.ts +40 -0
  271. package/src/auth-verifier.ts +404 -520
  272. package/src/config/config.ts +7 -7
  273. package/src/config/env.ts +5 -1
  274. package/src/context.ts +6 -5
  275. package/src/lexicon/index.ts +1235 -1235
  276. package/src/lexicon/lexicons.ts +9416 -9416
  277. package/src/pipethrough.ts +61 -18
  278. package/src/util/http.ts +31 -0
  279. package/src/util/types.ts +7 -0
  280. package/tests/oauth.test.ts +11 -37
  281. package/tests/preferences.test.ts +7 -3
  282. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1,6 +1,8 @@
1
1
  import { AppContext } from '../../../../context'
2
2
  import { Server } from '../../../../lexicon'
3
+ import { ids } from '../../../../lexicon/lexicons'
3
4
  import { OutputSchema } from '../../../../lexicon/types/app/bsky/actor/getProfiles'
5
+ import { computeProxyTo } from '../../../../pipethrough'
4
6
  import {
5
7
  LocalRecords,
6
8
  LocalViewer,
@@ -11,7 +13,13 @@ export default function (server: Server, ctx: AppContext) {
11
13
  if (!ctx.bskyAppView) return
12
14
 
13
15
  server.app.bsky.actor.getProfiles({
14
- auth: ctx.authVerifier.accessStandard(),
16
+ auth: ctx.authVerifier.authorization({
17
+ authorize: (permissions, { req }) => {
18
+ const lxm = ids.AppBskyActorGetProfiles
19
+ const aud = computeProxyTo(ctx, req, lxm)
20
+ permissions.assertRpc({ aud, lxm })
21
+ },
22
+ }),
15
23
  handler: async (reqCtx) => {
16
24
  return pipethroughReadAfterWrite(ctx, reqCtx, getProfilesMunge)
17
25
  },
@@ -1,30 +1,53 @@
1
1
  import { InvalidRequestError } from '@atproto/xrpc-server'
2
2
  import { AccountPreference } from '../../../../actor-store/preference/reader'
3
+ import { isAccessFull } from '../../../../auth-scope'
3
4
  import { AppContext } from '../../../../context'
4
5
  import { Server } from '../../../../lexicon'
6
+ import { ids } from '../../../../lexicon/lexicons'
7
+ import { computeProxyTo, pipethrough } from '../../../../pipethrough'
5
8
 
6
9
  export default function (server: Server, ctx: AppContext) {
7
- if (!ctx.bskyAppView) return
10
+ const { bskyAppView } = ctx
11
+ if (!bskyAppView) return
8
12
 
9
13
  server.app.bsky.actor.putPreferences({
10
- auth: ctx.authVerifier.accessStandard({ checkTakedown: true }),
11
- handler: async ({ auth, input }) => {
12
- const { preferences } = input.body
13
- const requester = auth.credentials.did
14
+ auth: ctx.authVerifier.authorization({
15
+ checkTakedown: true,
16
+ authorize: (permissions, { req }) => {
17
+ const lxm = ids.AppBskyActorPutPreferences
18
+ const aud = computeProxyTo(ctx, req, lxm)
19
+ permissions.assertRpc({ aud, lxm })
20
+ },
21
+ }),
22
+ handler: async ({ req, auth, input }) => {
23
+ const { did } = auth.credentials
24
+
25
+ // If the request has a proxy header different from the bsky app view,
26
+ // we need to proxy the request to the requested app view.
27
+ // @TODO This behavior should not be implemented as part of the XRPC framework
28
+ const lxm = ids.AppBskyActorPutPreferences
29
+ const aud = computeProxyTo(ctx, req, lxm)
30
+ if (aud !== `${bskyAppView.did}#bsky_appview`) {
31
+ return pipethrough(ctx, req, { iss: did, aud, lxm })
32
+ }
33
+
14
34
  const checkedPreferences: AccountPreference[] = []
15
- for (const pref of preferences) {
35
+ for (const pref of input.body.preferences) {
16
36
  if (typeof pref.$type === 'string') {
17
37
  checkedPreferences.push(pref as AccountPreference)
18
38
  } else {
19
39
  throw new InvalidRequestError('Preference is missing a $type')
20
40
  }
21
41
  }
22
- await ctx.actorStore.transact(requester, async (actorTxn) => {
23
- await actorTxn.pref.putPreferences(
24
- checkedPreferences,
25
- 'app.bsky',
26
- auth.credentials.scope,
27
- )
42
+
43
+ const hasAccessFull =
44
+ auth.credentials.type === 'access' &&
45
+ isAccessFull(auth.credentials.scope)
46
+
47
+ await ctx.actorStore.transact(did, async (actorTxn) => {
48
+ await actorTxn.pref.putPreferences(checkedPreferences, 'app.bsky', {
49
+ hasAccessFull,
50
+ })
28
51
  })
29
52
  },
30
53
  })
@@ -1,6 +1,8 @@
1
1
  import { AppContext } from '../../../../context'
2
2
  import { Server } from '../../../../lexicon'
3
+ import { ids } from '../../../../lexicon/lexicons'
3
4
  import { OutputSchema } from '../../../../lexicon/types/app/bsky/feed/getActorLikes'
5
+ import { computeProxyTo } from '../../../../pipethrough'
4
6
  import {
5
7
  LocalRecords,
6
8
  LocalViewer,
@@ -11,7 +13,13 @@ export default function (server: Server, ctx: AppContext) {
11
13
  if (!ctx.bskyAppView) return
12
14
 
13
15
  server.app.bsky.feed.getActorLikes({
14
- auth: ctx.authVerifier.accessStandard(),
16
+ auth: ctx.authVerifier.authorization({
17
+ authorize: (permissions, { req }) => {
18
+ const lxm = ids.AppBskyFeedGetActorLikes
19
+ const aud = computeProxyTo(ctx, req, lxm)
20
+ permissions.assertRpc({ aud, lxm })
21
+ },
22
+ }),
15
23
  handler: async (reqCtx) => {
16
24
  return pipethroughReadAfterWrite(ctx, reqCtx, getAuthorMunge)
17
25
  },
@@ -1,7 +1,9 @@
1
1
  import { AppContext } from '../../../../context'
2
2
  import { Server } from '../../../../lexicon'
3
+ import { ids } from '../../../../lexicon/lexicons'
3
4
  import { isReasonRepost } from '../../../../lexicon/types/app/bsky/feed/defs'
4
5
  import { OutputSchema } from '../../../../lexicon/types/app/bsky/feed/getAuthorFeed'
6
+ import { computeProxyTo } from '../../../../pipethrough'
5
7
  import {
6
8
  LocalRecords,
7
9
  LocalViewer,
@@ -12,7 +14,13 @@ export default function (server: Server, ctx: AppContext) {
12
14
  if (!ctx.bskyAppView) return
13
15
 
14
16
  server.app.bsky.feed.getAuthorFeed({
15
- auth: ctx.authVerifier.accessStandard(),
17
+ auth: ctx.authVerifier.authorization({
18
+ authorize: (permissions, { req }) => {
19
+ const lxm = ids.AppBskyFeedGetAuthorFeed
20
+ const aud = computeProxyTo(ctx, req, lxm)
21
+ permissions.assertRpc({ aud, lxm })
22
+ },
23
+ }),
16
24
  handler: async (reqCtx) => {
17
25
  return pipethroughReadAfterWrite(ctx, reqCtx, getAuthorMunge)
18
26
  },
@@ -3,14 +3,21 @@ import { AtUri } from '@atproto/syntax'
3
3
  import { AppContext } from '../../../../context'
4
4
  import { Server } from '../../../../lexicon'
5
5
  import { ids } from '../../../../lexicon/lexicons'
6
- import { pipethrough } from '../../../../pipethrough'
6
+ import { computeProxyTo, pipethrough } from '../../../../pipethrough'
7
7
 
8
8
  export default function (server: Server, ctx: AppContext) {
9
9
  const { bskyAppView } = ctx
10
10
  if (!bskyAppView) return
11
11
 
12
12
  server.app.bsky.feed.getFeed({
13
- auth: ctx.authVerifier.accessStandard(),
13
+ auth: ctx.authVerifier.authorization({
14
+ authorize: (permissions, { req }) => {
15
+ const lxm = ids.AppBskyFeedGetFeed
16
+ const aud = computeProxyTo(ctx, req, lxm)
17
+ permissions.assertRpc({ aud, lxm })
18
+ permissions.assertRpc({ aud, lxm: ids.AppBskyFeedGetFeedSkeleton })
19
+ },
20
+ }),
14
21
  handler: async ({ params, auth, req }) => {
15
22
  const requester = auth.credentials.did
16
23
 
@@ -14,6 +14,7 @@ import {
14
14
  } from '../../../../lexicon/types/app/bsky/feed/getPostThread'
15
15
  import { Record as PostRecord } from '../../../../lexicon/types/app/bsky/feed/post'
16
16
  import { $Typed } from '../../../../lexicon/util'
17
+ import { computeProxyTo } from '../../../../pipethrough'
17
18
  import {
18
19
  LocalRecords,
19
20
  LocalViewer,
@@ -28,7 +29,13 @@ export default function (server: Server, ctx: AppContext) {
28
29
  if (!ctx.bskyAppView) return
29
30
 
30
31
  server.app.bsky.feed.getPostThread({
31
- auth: ctx.authVerifier.accessStandard(),
32
+ auth: ctx.authVerifier.authorization({
33
+ authorize: (permissions, { req }) => {
34
+ const lxm = ids.AppBskyFeedGetPostThread
35
+ const aud = computeProxyTo(ctx, req, lxm)
36
+ permissions.assertRpc({ aud, lxm })
37
+ },
38
+ }),
32
39
  handler: async (reqCtx) => {
33
40
  try {
34
41
  return await pipethroughReadAfterWrite(ctx, reqCtx, getPostThreadMunge)
@@ -1,6 +1,8 @@
1
1
  import { AppContext } from '../../../../context'
2
2
  import { Server } from '../../../../lexicon'
3
+ import { ids } from '../../../../lexicon/lexicons'
3
4
  import { OutputSchema } from '../../../../lexicon/types/app/bsky/feed/getTimeline'
5
+ import { computeProxyTo } from '../../../../pipethrough'
4
6
  import {
5
7
  LocalRecords,
6
8
  LocalViewer,
@@ -11,7 +13,13 @@ export default function (server: Server, ctx: AppContext) {
11
13
  if (!ctx.bskyAppView) return
12
14
 
13
15
  server.app.bsky.feed.getTimeline({
14
- auth: ctx.authVerifier.accessStandard(),
16
+ auth: ctx.authVerifier.authorization({
17
+ authorize: (permissions, { req }) => {
18
+ const lxm = ids.AppBskyFeedGetTimeline
19
+ const aud = computeProxyTo(ctx, req, lxm)
20
+ permissions.assertRpc({ aud, lxm })
21
+ },
22
+ }),
15
23
  handler: async (reqCtx) => {
16
24
  return pipethroughReadAfterWrite(ctx, reqCtx, getTimelineMunge)
17
25
  },
@@ -1,7 +1,7 @@
1
1
  import { AtpAgent } from '@atproto/api'
2
2
  import { getNotif } from '@atproto/identity'
3
3
  import { InvalidRequestError } from '@atproto/xrpc-server'
4
- import { AuthScope } from '../../../../auth-verifier'
4
+ import { AuthScope } from '../../../../auth-scope'
5
5
  import { AppContext } from '../../../../context'
6
6
  import { Server } from '../../../../lexicon'
7
7
  import { ids } from '../../../../lexicon/lexicons'
@@ -12,14 +12,25 @@ export default function (server: Server, ctx: AppContext) {
12
12
  if (!bskyAppView) return
13
13
 
14
14
  server.app.bsky.notification.registerPush({
15
- auth: ctx.authVerifier.accessStandard({
15
+ auth: ctx.authVerifier.authorization({
16
16
  additional: [AuthScope.SignupQueued],
17
+ authorize: () => {
18
+ // @NOTE this endpoint predates generic service proxying but we want to
19
+ // map the permission to the "RPC" scope for consistency. However, since
20
+ // the service info is only available in the request body, we can't
21
+ // assert permissions here.
22
+ },
17
23
  }),
18
24
  handler: async ({ auth, input }) => {
19
25
  const { serviceDid } = input.body
20
- const {
21
- credentials: { did },
22
- } = auth
26
+ const { did } = auth.credentials
27
+
28
+ if (auth.credentials.type === 'oauth') {
29
+ auth.credentials.permissions.assertRpc({
30
+ aud: `${serviceDid}#bsky_notif`,
31
+ lxm: ids.AppBskyNotificationRegisterPush,
32
+ })
33
+ }
23
34
 
24
35
  const authHeaders = await ctx.serviceAuthHeaders(
25
36
  did,
@@ -3,7 +3,11 @@ import { Server } from '../../../../lexicon'
3
3
 
4
4
  export default function (server: Server, ctx: AppContext) {
5
5
  server.com.atproto.identity.getRecommendedDidCredentials({
6
- auth: ctx.authVerifier.accessStandard(),
6
+ auth: ctx.authVerifier.authorization({
7
+ authorize: () => {
8
+ // always allow
9
+ },
10
+ }),
7
11
  handler: async ({ auth }) => {
8
12
  const requester = auth.credentials.did
9
13
  const signingKey = await ctx.actorStore.keypair(requester)
@@ -1,12 +1,19 @@
1
1
  import { InvalidRequestError } from '@atproto/xrpc-server'
2
- import { AuthScope } from '../../../../auth-verifier'
2
+ import { ACCESS_FULL, AuthScope } from '../../../../auth-scope'
3
3
  import { AppContext } from '../../../../context'
4
4
  import { Server } from '../../../../lexicon'
5
5
  import { ids } from '../../../../lexicon/lexicons'
6
6
 
7
7
  export default function (server: Server, ctx: AppContext) {
8
8
  server.com.atproto.identity.requestPlcOperationSignature({
9
- auth: ctx.authVerifier.accessFull({ additional: [AuthScope.Takendown] }),
9
+ auth: ctx.authVerifier.authorization({
10
+ // @NOTE Reflect any change in signPlcOperation
11
+ scopes: ACCESS_FULL,
12
+ additional: [AuthScope.Takendown],
13
+ authorize: (permissions) => {
14
+ permissions.assertIdentity({ attr: '*' })
15
+ },
16
+ }),
10
17
  handler: async ({ auth, req }) => {
11
18
  if (ctx.entrywayAgent) {
12
19
  await ctx.entrywayAgent.com.atproto.identity.requestPlcOperationSignature(
@@ -1,6 +1,7 @@
1
1
  import * as plc from '@did-plc/lib'
2
2
  import { check } from '@atproto/common'
3
3
  import { InvalidRequestError } from '@atproto/xrpc-server'
4
+ import { ACCESS_FULL, AuthScope } from '../../../../auth-scope'
4
5
  import { AppContext } from '../../../../context'
5
6
  import { Server } from '../../../../lexicon'
6
7
  import { ids } from '../../../../lexicon/lexicons'
@@ -8,7 +9,14 @@ import { resultPassthru } from '../../../proxy'
8
9
 
9
10
  export default function (server: Server, ctx: AppContext) {
10
11
  server.com.atproto.identity.signPlcOperation({
11
- auth: ctx.authVerifier.accessFull(),
12
+ auth: ctx.authVerifier.authorization({
13
+ // @NOTE Should match auth rules from requestPlcOperationSignature
14
+ scopes: ACCESS_FULL,
15
+ additional: [AuthScope.Takendown],
16
+ authorize: (permissions) => {
17
+ permissions.assertIdentity({ attr: '*' })
18
+ },
19
+ }),
12
20
  handler: async ({ auth, input, req }) => {
13
21
  if (ctx.entrywayAgent) {
14
22
  return resultPassthru(
@@ -7,7 +7,11 @@ import { httpLogger as log } from '../../../../logger'
7
7
 
8
8
  export default function (server: Server, ctx: AppContext) {
9
9
  server.com.atproto.identity.submitPlcOperation({
10
- auth: ctx.authVerifier.accessStandard(),
10
+ auth: ctx.authVerifier.authorization({
11
+ authorize: (permissions) => {
12
+ permissions.assertIdentity({ attr: '*' })
13
+ },
14
+ }),
11
15
  handler: async ({ auth, input }) => {
12
16
  const requester = auth.credentials.did
13
17
  const op = input.body.operation
@@ -7,7 +7,12 @@ import { httpLogger } from '../../../../logger'
7
7
 
8
8
  export default function (server: Server, ctx: AppContext) {
9
9
  server.com.atproto.identity.updateHandle({
10
- auth: ctx.authVerifier.accessStandard({ checkTakedown: true }),
10
+ auth: ctx.authVerifier.authorization({
11
+ checkTakedown: true,
12
+ authorize: (permissions) => {
13
+ permissions.assertIdentity({ attr: 'handle' })
14
+ },
15
+ }),
11
16
  rateLimit: [
12
17
  {
13
18
  durationMs: 5 * MINUTE,
@@ -1,14 +1,19 @@
1
1
  import { AtpAgent } from '@atproto/api'
2
- import { AuthScope } from '../../../../auth-verifier'
2
+ import { AuthScope } from '../../../../auth-scope'
3
3
  import { AppContext } from '../../../../context'
4
4
  import { Server } from '../../../../lexicon'
5
5
  import { ids } from '../../../../lexicon/lexicons'
6
- import { parseProxyInfo } from '../../../../pipethrough'
6
+ import { computeProxyTo, parseProxyInfo } from '../../../../pipethrough'
7
7
 
8
8
  export default function (server: Server, ctx: AppContext) {
9
9
  server.com.atproto.moderation.createReport({
10
- auth: ctx.authVerifier.accessStandard({
10
+ auth: ctx.authVerifier.authorization({
11
11
  additional: [AuthScope.Takendown],
12
+ authorize: (permissions, { req }) => {
13
+ const lxm = ids.ComAtprotoModerationCreateReport
14
+ const aud = computeProxyTo(ctx, req, lxm)
15
+ permissions.assertRpc({ aud, lxm })
16
+ },
12
17
  }),
13
18
  handler: async ({ auth, input, req }) => {
14
19
  const { url, did: aud } = await parseProxyInfo(
@@ -38,10 +38,14 @@ const ratelimitPoints = ({ input }: { input: HandlerInput }) => {
38
38
 
39
39
  export default function (server: Server, ctx: AppContext) {
40
40
  server.com.atproto.repo.applyWrites({
41
- auth: ctx.authVerifier.accessStandard({
41
+ auth: ctx.authVerifier.authorization({
42
42
  checkTakedown: true,
43
43
  checkDeactivated: true,
44
+ authorize: () => {
45
+ // Performed in the handler as it is based on the request body
46
+ },
44
47
  }),
48
+
45
49
  rateLimit: [
46
50
  {
47
51
  name: 'repo-write-hour',
@@ -56,31 +60,35 @@ export default function (server: Server, ctx: AppContext) {
56
60
  ],
57
61
 
58
62
  handler: async ({ input, auth }) => {
59
- const tx = input.body
60
- const { repo, validate, swapCommit } = tx
61
- const account = await ctx.accountManager.getAccount(repo, {
62
- includeDeactivated: true,
63
- })
64
-
65
- if (!account) {
66
- throw new InvalidRequestError(`Could not find repo: ${repo}`)
67
- } else if (account.deactivatedAt) {
68
- throw new InvalidRequestError('Account is deactivated')
69
- }
63
+ const { repo, validate, swapCommit, writes } = input.body
70
64
 
71
- const did = account.did
72
- if (did !== auth.credentials.did) {
65
+ const { did } = auth.credentials
66
+ if (repo !== did) {
73
67
  throw new AuthRequiredError()
74
68
  }
75
- if (tx.writes.length > 200) {
69
+ if (writes.length > 200) {
76
70
  throw new InvalidRequestError('Too many writes. Max: 200')
77
71
  }
78
72
 
73
+ // Verify permission of every unique "action" / "collection" pair
74
+ if (auth.credentials.type === 'oauth') {
75
+ // @NOTE Unlike "importRepo", we do not require "action" = "*" here.
76
+ for (const [action, collections] of [
77
+ ['create', new Set(writes.filter(isCreate).map((w) => w.collection))],
78
+ ['update', new Set(writes.filter(isUpdate).map((w) => w.collection))],
79
+ ['delete', new Set(writes.filter(isDelete).map((w) => w.collection))],
80
+ ] as const) {
81
+ for (const collection of collections) {
82
+ auth.credentials.permissions.assertRepo({ action, collection })
83
+ }
84
+ }
85
+ }
86
+
79
87
  // @NOTE should preserve order of ts.writes for final use in response
80
- let writes: PreparedWrite[]
88
+ let preparedWrites: PreparedWrite[]
81
89
  try {
82
- writes = await Promise.all(
83
- tx.writes.map((write) => {
90
+ preparedWrites = await Promise.all(
91
+ writes.map(async (write) => {
84
92
  if (isCreate(write)) {
85
93
  return prepareCreate({
86
94
  did,
@@ -121,7 +129,7 @@ export default function (server: Server, ctx: AppContext) {
121
129
 
122
130
  const commit = await ctx.actorStore.transact(did, async (actorTxn) => {
123
131
  const commit = await actorTxn.repo
124
- .processWrites(writes, swapCommitCid)
132
+ .processWrites(preparedWrites, swapCommitCid)
125
133
  .catch((err) => {
126
134
  if (err instanceof BadCommitSwapError) {
127
135
  throw new InvalidRequestError(err.message, 'InvalidSwap')
@@ -150,7 +158,7 @@ export default function (server: Server, ctx: AppContext) {
150
158
  cid: commit.cid.toString(),
151
159
  rev: commit.rev,
152
160
  },
153
- results: writes.map(writeToOutputResult),
161
+ results: preparedWrites.map(writeToOutputResult),
154
162
  },
155
163
  }
156
164
  },
@@ -14,9 +14,12 @@ import {
14
14
 
15
15
  export default function (server: Server, ctx: AppContext) {
16
16
  server.com.atproto.repo.createRecord({
17
- auth: ctx.authVerifier.accessStandard({
17
+ auth: ctx.authVerifier.authorization({
18
18
  checkTakedown: true,
19
19
  checkDeactivated: true,
20
+ authorize: () => {
21
+ // Performed in the handler as it requires the request body
22
+ },
20
23
  }),
21
24
  rateLimit: [
22
25
  {
@@ -33,6 +36,14 @@ export default function (server: Server, ctx: AppContext) {
33
36
  handler: async ({ input, auth }) => {
34
37
  const { repo, collection, rkey, record, swapCommit, validate } =
35
38
  input.body
39
+
40
+ if (auth.credentials.type === 'oauth') {
41
+ auth.credentials.permissions.assertRepo({
42
+ action: 'create',
43
+ collection,
44
+ })
45
+ }
46
+
36
47
  const account = await ctx.accountManager.getAccount(repo, {
37
48
  includeDeactivated: true,
38
49
  })
@@ -11,9 +11,12 @@ import {
11
11
 
12
12
  export default function (server: Server, ctx: AppContext) {
13
13
  server.com.atproto.repo.deleteRecord({
14
- auth: ctx.authVerifier.accessStandard({
14
+ auth: ctx.authVerifier.authorization({
15
15
  checkTakedown: true,
16
16
  checkDeactivated: true,
17
+ authorize: () => {
18
+ // Performed in the handler as it requires the request body
19
+ },
17
20
  }),
18
21
  rateLimit: [
19
22
  {
@@ -29,6 +32,16 @@ export default function (server: Server, ctx: AppContext) {
29
32
  ],
30
33
  handler: async ({ input, auth }) => {
31
34
  const { repo, collection, rkey, swapCommit, swapRecord } = input.body
35
+
36
+ // We can't compute permissions based on the request payload ("input") in
37
+ // the 'auth' phase, so we do it here.
38
+ if (auth.credentials.type === 'oauth') {
39
+ auth.credentials.permissions.assertRepo({
40
+ action: 'delete',
41
+ collection,
42
+ })
43
+ }
44
+
32
45
  const account = await ctx.accountManager.getAccount(repo, {
33
46
  includeDeactivated: true,
34
47
  })
@@ -12,19 +12,26 @@ import {
12
12
  import { AtUri } from '@atproto/syntax'
13
13
  import { InvalidRequestError } from '@atproto/xrpc-server'
14
14
  import { ActorStoreTransactor } from '../../../../actor-store/actor-store-transactor'
15
+ import { ACCESS_FULL } from '../../../../auth-scope'
15
16
  import { AppContext } from '../../../../context'
16
17
  import { Server } from '../../../../lexicon'
17
18
 
18
19
  export default function (server: Server, ctx: AppContext) {
19
20
  server.com.atproto.repo.importRepo({
20
- auth: ctx.authVerifier.accessFull({
21
+ auth: ctx.authVerifier.authorization({
21
22
  checkTakedown: true,
23
+ scopes: ACCESS_FULL,
24
+ authorize: (permissions) => {
25
+ permissions.assertAccount({ attr: 'repo', action: 'manage' })
26
+ },
22
27
  }),
23
28
  handler: async ({ input, auth }) => {
24
- const did = auth.credentials.did
25
29
  if (!ctx.cfg.service.acceptingImports) {
26
30
  throw new InvalidRequestError('Service is not accepting repo imports')
27
31
  }
32
+
33
+ const { did } = auth.credentials
34
+
28
35
  await ctx.actorStore.transact(did, (store) =>
29
36
  importRepo(store, input.body),
30
37
  )
@@ -3,10 +3,15 @@ import { Server } from '../../../../lexicon'
3
3
 
4
4
  export default function (server: Server, ctx: AppContext) {
5
5
  server.com.atproto.repo.listMissingBlobs({
6
- auth: ctx.authVerifier.accessStandard(),
6
+ auth: ctx.authVerifier.authorization({
7
+ authorize: () => {
8
+ // always allow
9
+ },
10
+ }),
7
11
  handler: async ({ auth, params }) => {
8
- const did = auth.credentials.did
12
+ const { did } = auth.credentials
9
13
  const { limit, cursor } = params
14
+
10
15
  const blobs = await ctx.actorStore.read(did, (store) =>
11
16
  store.repo.blob.listMissingBlobs({ limit, cursor }),
12
17
  )
@@ -20,9 +20,12 @@ import {
20
20
 
21
21
  export default function (server: Server, ctx: AppContext) {
22
22
  server.com.atproto.repo.putRecord({
23
- auth: ctx.authVerifier.accessStandard({
23
+ auth: ctx.authVerifier.authorization({
24
24
  checkTakedown: true,
25
25
  checkDeactivated: true,
26
+ authorize: () => {
27
+ // Performed in the handler as it requires the request body
28
+ },
26
29
  }),
27
30
  rateLimit: [
28
31
  {
@@ -46,17 +49,22 @@ export default function (server: Server, ctx: AppContext) {
46
49
  swapCommit,
47
50
  swapRecord,
48
51
  } = input.body
49
- const account = await ctx.accountManager.getAccount(repo, {
50
- includeDeactivated: true,
51
- })
52
52
 
53
- if (!account) {
54
- throw new InvalidRequestError(`Could not find repo: ${repo}`)
55
- } else if (account.deactivatedAt) {
56
- throw new InvalidRequestError('Account is deactivated')
53
+ // We can't compute permissions based on the request payload ("input") in
54
+ // the 'auth' phase, so we do it here.
55
+ if (auth.credentials.type === 'oauth') {
56
+ auth.credentials.permissions.assertRepo({
57
+ action: 'create',
58
+ collection,
59
+ })
60
+ auth.credentials.permissions.assertRepo({
61
+ action: 'update',
62
+ collection,
63
+ })
57
64
  }
58
- const did = account.did
59
- if (did !== auth.credentials.did) {
65
+
66
+ const { did } = auth.credentials
67
+ if (did !== repo) {
60
68
  throw new AuthRequiredError()
61
69
  }
62
70
 
@@ -1,13 +1,17 @@
1
1
  import { DAY } from '@atproto/common'
2
- import { UpstreamTimeoutError } from '@atproto/xrpc-server'
2
+ import { UpstreamTimeoutError, parseReqEncoding } from '@atproto/xrpc-server'
3
3
  import { BlobMetadata } from '../../../../actor-store/blob/transactor'
4
4
  import { AppContext } from '../../../../context'
5
5
  import { Server } from '../../../../lexicon'
6
6
 
7
7
  export default function (server: Server, ctx: AppContext) {
8
8
  server.com.atproto.repo.uploadBlob({
9
- auth: ctx.authVerifier.accessOrUserServiceAuth({
9
+ auth: ctx.authVerifier.authorizationOrUserServiceAuth({
10
10
  checkTakedown: true,
11
+ authorize: (permissions, { req }) => {
12
+ const encoding = parseReqEncoding(req)
13
+ permissions.assertBlob({ mime: encoding })
14
+ },
11
15
  }),
12
16
  rateLimit: {
13
17
  durationMs: DAY,
@@ -1,12 +1,20 @@
1
1
  import { INVALID_HANDLE } from '@atproto/syntax'
2
- import { InvalidRequestError } from '@atproto/xrpc-server'
2
+ import { ForbiddenError, InvalidRequestError } from '@atproto/xrpc-server'
3
+ import { ACCESS_FULL } from '../../../../auth-scope'
3
4
  import { AppContext } from '../../../../context'
4
5
  import { Server } from '../../../../lexicon'
5
6
  import { assertValidDidDocumentForService } from './util'
6
7
 
7
8
  export default function (server: Server, ctx: AppContext) {
8
9
  server.com.atproto.server.activateAccount({
9
- auth: ctx.authVerifier.accessFull(),
10
+ auth: ctx.authVerifier.authorization({
11
+ scopes: ACCESS_FULL,
12
+ authorize: () => {
13
+ throw new ForbiddenError(
14
+ 'OAuth credentials are not supported for this endpoint',
15
+ )
16
+ },
17
+ }),
10
18
  handler: async ({ req, auth }) => {
11
19
  // in the case of entryway, the full flow is activateAccount (PDS) -> activateAccount (Entryway) -> updateSubjectStatus(PDS)
12
20
  if (ctx.entrywayAgent) {