@atproto/pds 0.5.11 → 0.5.14

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 (322) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/dist/api/app/bsky/notification/index.d.ts.map +1 -1
  3. package/dist/api/app/bsky/notification/index.js +2 -0
  4. package/dist/api/app/bsky/notification/index.js.map +1 -1
  5. package/dist/api/app/bsky/notification/unregisterPush.d.ts +4 -0
  6. package/dist/api/app/bsky/notification/unregisterPush.d.ts.map +1 -0
  7. package/dist/api/app/bsky/notification/unregisterPush.js +48 -0
  8. package/dist/api/app/bsky/notification/unregisterPush.js.map +1 -0
  9. package/package.json +42 -38
  10. package/build.templates.cjs +0 -22
  11. package/example.env +0 -42
  12. package/jest.config.cjs +0 -27
  13. package/src/account-manager/account-manager.ts +0 -916
  14. package/src/account-manager/db/index.ts +0 -21
  15. package/src/account-manager/db/migrations/001-init.ts +0 -115
  16. package/src/account-manager/db/migrations/002-account-deactivation.ts +0 -17
  17. package/src/account-manager/db/migrations/003-privileged-app-passwords.ts +0 -12
  18. package/src/account-manager/db/migrations/004-oauth.ts +0 -122
  19. package/src/account-manager/db/migrations/005-oauth-account-management.ts +0 -136
  20. package/src/account-manager/db/migrations/006-oauth-permission-sets.ts +0 -20
  21. package/src/account-manager/db/migrations/007-lexicon-failures-index.ts +0 -14
  22. package/src/account-manager/db/migrations/index.ts +0 -17
  23. package/src/account-manager/db/schema/account-device.ts +0 -14
  24. package/src/account-manager/db/schema/account.ts +0 -16
  25. package/src/account-manager/db/schema/actor.ts +0 -17
  26. package/src/account-manager/db/schema/app-password.ts +0 -13
  27. package/src/account-manager/db/schema/authorization-request.ts +0 -30
  28. package/src/account-manager/db/schema/authorized-client.ts +0 -23
  29. package/src/account-manager/db/schema/device.ts +0 -18
  30. package/src/account-manager/db/schema/email-token.ts +0 -19
  31. package/src/account-manager/db/schema/index.ts +0 -43
  32. package/src/account-manager/db/schema/invite-code.ts +0 -24
  33. package/src/account-manager/db/schema/lexicon.ts +0 -15
  34. package/src/account-manager/db/schema/refresh-token.ts +0 -11
  35. package/src/account-manager/db/schema/repo-root.ts +0 -12
  36. package/src/account-manager/db/schema/token.ts +0 -38
  37. package/src/account-manager/db/schema/used-refresh-token.ts +0 -13
  38. package/src/account-manager/helpers/account-device.ts +0 -63
  39. package/src/account-manager/helpers/account.ts +0 -355
  40. package/src/account-manager/helpers/auth.ts +0 -222
  41. package/src/account-manager/helpers/authorization-request.ts +0 -90
  42. package/src/account-manager/helpers/authorized-client.ts +0 -75
  43. package/src/account-manager/helpers/device.ts +0 -47
  44. package/src/account-manager/helpers/email-token.ts +0 -87
  45. package/src/account-manager/helpers/invite.ts +0 -263
  46. package/src/account-manager/helpers/lexicon.ts +0 -67
  47. package/src/account-manager/helpers/password.ts +0 -136
  48. package/src/account-manager/helpers/repo.ts +0 -24
  49. package/src/account-manager/helpers/scrypt.ts +0 -53
  50. package/src/account-manager/helpers/token.ts +0 -158
  51. package/src/account-manager/helpers/used-refresh-token.ts +0 -30
  52. package/src/account-manager/oauth-store.ts +0 -880
  53. package/src/account-manager/scope-reference-getter.ts +0 -106
  54. package/src/actor-store/actor-store-reader.ts +0 -45
  55. package/src/actor-store/actor-store-resources.ts +0 -8
  56. package/src/actor-store/actor-store-transactor.ts +0 -31
  57. package/src/actor-store/actor-store-writer.ts +0 -17
  58. package/src/actor-store/actor-store.ts +0 -210
  59. package/src/actor-store/blob/reader.ts +0 -160
  60. package/src/actor-store/blob/transactor.ts +0 -383
  61. package/src/actor-store/db/index.ts +0 -20
  62. package/src/actor-store/db/migrations/001-init.ts +0 -105
  63. package/src/actor-store/db/migrations/index.ts +0 -5
  64. package/src/actor-store/db/schema/account-pref.ts +0 -11
  65. package/src/actor-store/db/schema/backlink.ts +0 -9
  66. package/src/actor-store/db/schema/blob.ts +0 -14
  67. package/src/actor-store/db/schema/index.ts +0 -23
  68. package/src/actor-store/db/schema/record-blob.ts +0 -8
  69. package/src/actor-store/db/schema/record.ts +0 -14
  70. package/src/actor-store/db/schema/repo-block.ts +0 -10
  71. package/src/actor-store/db/schema/repo-root.ts +0 -10
  72. package/src/actor-store/migrate.ts +0 -39
  73. package/src/actor-store/preference/reader.ts +0 -48
  74. package/src/actor-store/preference/transactor.ts +0 -55
  75. package/src/actor-store/preference/util.ts +0 -39
  76. package/src/actor-store/record/reader.ts +0 -374
  77. package/src/actor-store/record/transactor.ts +0 -111
  78. package/src/actor-store/repo/reader.ts +0 -31
  79. package/src/actor-store/repo/sql-repo-reader.ts +0 -150
  80. package/src/actor-store/repo/sql-repo-transactor.ts +0 -105
  81. package/src/actor-store/repo/transactor.ts +0 -227
  82. package/src/api/app/bsky/actor/getPreferences.ts +0 -57
  83. package/src/api/app/bsky/actor/getProfile.ts +0 -41
  84. package/src/api/app/bsky/actor/getProfiles.ts +0 -51
  85. package/src/api/app/bsky/actor/index.ts +0 -13
  86. package/src/api/app/bsky/actor/putPreferences.ts +0 -62
  87. package/src/api/app/bsky/feed/getActorLikes.ts +0 -63
  88. package/src/api/app/bsky/feed/getAuthorFeed.ts +0 -84
  89. package/src/api/app/bsky/feed/getFeed.ts +0 -47
  90. package/src/api/app/bsky/feed/getPostThread.ts +0 -251
  91. package/src/api/app/bsky/feed/getTimeline.ts +0 -50
  92. package/src/api/app/bsky/feed/index.ts +0 -15
  93. package/src/api/app/bsky/index.ts +0 -11
  94. package/src/api/app/bsky/notification/index.ts +0 -7
  95. package/src/api/app/bsky/notification/registerPush.ts +0 -71
  96. package/src/api/app/bsky/util/resolver.ts +0 -20
  97. package/src/api/com/atproto/admin/deleteAccount.ts +0 -22
  98. package/src/api/com/atproto/admin/disableAccountInvites.ts +0 -18
  99. package/src/api/com/atproto/admin/disableInviteCodes.ts +0 -21
  100. package/src/api/com/atproto/admin/enableAccountInvites.ts +0 -18
  101. package/src/api/com/atproto/admin/getAccountInfo.ts +0 -32
  102. package/src/api/com/atproto/admin/getAccountInfos.ts +0 -34
  103. package/src/api/com/atproto/admin/getInviteCodes.ts +0 -126
  104. package/src/api/com/atproto/admin/getSubjectStatus.ts +0 -76
  105. package/src/api/com/atproto/admin/index.ts +0 -31
  106. package/src/api/com/atproto/admin/sendEmail.ts +0 -47
  107. package/src/api/com/atproto/admin/updateAccountEmail.ts +0 -32
  108. package/src/api/com/atproto/admin/updateAccountHandle.ts +0 -47
  109. package/src/api/com/atproto/admin/updateAccountPassword.ts +0 -34
  110. package/src/api/com/atproto/admin/updateSubjectStatus.ts +0 -68
  111. package/src/api/com/atproto/admin/util.ts +0 -66
  112. package/src/api/com/atproto/identity/getRecommendedDidCredentials.ts +0 -50
  113. package/src/api/com/atproto/identity/index.ts +0 -17
  114. package/src/api/com/atproto/identity/requestPlcOperationSignature.ts +0 -59
  115. package/src/api/com/atproto/identity/resolveHandle.ts +0 -50
  116. package/src/api/com/atproto/identity/signPlcOperation.ts +0 -85
  117. package/src/api/com/atproto/identity/submitPlcOperation.ts +0 -65
  118. package/src/api/com/atproto/identity/updateHandle.ts +0 -66
  119. package/src/api/com/atproto/index.ts +0 -19
  120. package/src/api/com/atproto/moderation/createReport.ts +0 -41
  121. package/src/api/com/atproto/moderation/index.ts +0 -7
  122. package/src/api/com/atproto/repo/applyWrites.ts +0 -226
  123. package/src/api/com/atproto/repo/createRecord.ts +0 -143
  124. package/src/api/com/atproto/repo/deleteRecord.ts +0 -122
  125. package/src/api/com/atproto/repo/describeRepo.ts +0 -43
  126. package/src/api/com/atproto/repo/getRecord.ts +0 -40
  127. package/src/api/com/atproto/repo/importRepo.ts +0 -101
  128. package/src/api/com/atproto/repo/index.ts +0 -25
  129. package/src/api/com/atproto/repo/listMissingBlobs.ts +0 -29
  130. package/src/api/com/atproto/repo/listRecords.ts +0 -36
  131. package/src/api/com/atproto/repo/putRecord.ts +0 -211
  132. package/src/api/com/atproto/repo/uploadBlob.ts +0 -60
  133. package/src/api/com/atproto/server/activateAccount.ts +0 -37
  134. package/src/api/com/atproto/server/checkAccountStatus.ts +0 -51
  135. package/src/api/com/atproto/server/confirmEmail.ts +0 -39
  136. package/src/api/com/atproto/server/createAccount.ts +0 -327
  137. package/src/api/com/atproto/server/createAppPassword.ts +0 -53
  138. package/src/api/com/atproto/server/createInviteCode.ts +0 -38
  139. package/src/api/com/atproto/server/createInviteCodes.ts +0 -42
  140. package/src/api/com/atproto/server/createSession.ts +0 -97
  141. package/src/api/com/atproto/server/deactivateAccount.ts +0 -41
  142. package/src/api/com/atproto/server/deleteAccount.ts +0 -85
  143. package/src/api/com/atproto/server/deleteSession.ts +0 -23
  144. package/src/api/com/atproto/server/describeServer.ts +0 -29
  145. package/src/api/com/atproto/server/getAccountInviteCodes.ts +0 -142
  146. package/src/api/com/atproto/server/getServiceAuth.ts +0 -111
  147. package/src/api/com/atproto/server/getSession.ts +0 -80
  148. package/src/api/com/atproto/server/index.ts +0 -55
  149. package/src/api/com/atproto/server/listAppPasswords.ts +0 -45
  150. package/src/api/com/atproto/server/refreshSession.ts +0 -72
  151. package/src/api/com/atproto/server/requestAccountDelete.ts +0 -66
  152. package/src/api/com/atproto/server/requestEmailConfirmation.ts +0 -68
  153. package/src/api/com/atproto/server/requestEmailUpdate.ts +0 -86
  154. package/src/api/com/atproto/server/requestPasswordReset.ts +0 -52
  155. package/src/api/com/atproto/server/reserveSigningKey.ts +0 -15
  156. package/src/api/com/atproto/server/resetPassword.ts +0 -50
  157. package/src/api/com/atproto/server/revokeAppPassword.ts +0 -42
  158. package/src/api/com/atproto/server/updateEmail.ts +0 -52
  159. package/src/api/com/atproto/server/util.ts +0 -136
  160. package/src/api/com/atproto/sync/deprecated/getCheckout.ts +0 -27
  161. package/src/api/com/atproto/sync/deprecated/getHead.ts +0 -33
  162. package/src/api/com/atproto/sync/getBlob.ts +0 -61
  163. package/src/api/com/atproto/sync/getBlocks.ts +0 -37
  164. package/src/api/com/atproto/sync/getLatestCommit.ts +0 -33
  165. package/src/api/com/atproto/sync/getRecord.ts +0 -49
  166. package/src/api/com/atproto/sync/getRepo.ts +0 -75
  167. package/src/api/com/atproto/sync/getRepoStatus.ts +0 -34
  168. package/src/api/com/atproto/sync/index.ts +0 -27
  169. package/src/api/com/atproto/sync/listBlobs.ts +0 -33
  170. package/src/api/com/atproto/sync/listRepos.ts +0 -74
  171. package/src/api/com/atproto/sync/subscribeRepos.ts +0 -73
  172. package/src/api/com/atproto/sync/util.ts +0 -37
  173. package/src/api/com/atproto/temp/checkSignupQueue.ts +0 -34
  174. package/src/api/com/atproto/temp/index.ts +0 -7
  175. package/src/api/index.ts +0 -10
  176. package/src/api/proxy.ts +0 -44
  177. package/src/app-view.ts +0 -24
  178. package/src/auth-output.ts +0 -52
  179. package/src/auth-routes.ts +0 -64
  180. package/src/auth-scope.ts +0 -40
  181. package/src/auth-verifier.ts +0 -668
  182. package/src/background.ts +0 -65
  183. package/src/basic-routes.ts +0 -52
  184. package/src/bsky-app-view.ts +0 -33
  185. package/src/config/config.ts +0 -553
  186. package/src/config/env.ts +0 -167
  187. package/src/config/index.ts +0 -3
  188. package/src/config/secrets.ts +0 -54
  189. package/src/context.ts +0 -523
  190. package/src/crawlers.ts +0 -46
  191. package/src/db/cast.ts +0 -52
  192. package/src/db/db.ts +0 -140
  193. package/src/db/index.ts +0 -4
  194. package/src/db/migrator.ts +0 -40
  195. package/src/db/pagination.ts +0 -132
  196. package/src/db/tables/moderation.ts +0 -80
  197. package/src/db/util.ts +0 -108
  198. package/src/did-cache/db/index.ts +0 -21
  199. package/src/did-cache/db/migrations.ts +0 -17
  200. package/src/did-cache/db/schema.ts +0 -9
  201. package/src/did-cache/index.ts +0 -131
  202. package/src/disk-blobstore.ts +0 -172
  203. package/src/error.ts +0 -19
  204. package/src/handle/explicit-slurs.ts +0 -22
  205. package/src/handle/index.ts +0 -49
  206. package/src/handle/reserved.ts +0 -1059
  207. package/src/image/image-url-builder.ts +0 -16
  208. package/src/index.ts +0 -189
  209. package/src/lexicons.ts +0 -4
  210. package/src/logger.ts +0 -35
  211. package/src/mailer/index.ts +0 -111
  212. package/src/mailer/moderation.ts +0 -33
  213. package/src/mailer/templates/confirm-email.d.ts +0 -4
  214. package/src/mailer/templates/confirm-email.hbs +0 -158
  215. package/src/mailer/templates/delete-account.d.ts +0 -4
  216. package/src/mailer/templates/delete-account.hbs +0 -156
  217. package/src/mailer/templates/plc-operation.d.ts +0 -4
  218. package/src/mailer/templates/plc-operation.hbs +0 -153
  219. package/src/mailer/templates/reset-password.d.ts +0 -4
  220. package/src/mailer/templates/reset-password.hbs +0 -154
  221. package/src/mailer/templates/update-email.d.ts +0 -4
  222. package/src/mailer/templates/update-email.hbs +0 -153
  223. package/src/mailer/templates.ts +0 -17
  224. package/src/pipethrough.ts +0 -716
  225. package/src/rate-limits.ts +0 -59
  226. package/src/read-after-write/index.ts +0 -3
  227. package/src/read-after-write/types.ts +0 -35
  228. package/src/read-after-write/util.ts +0 -101
  229. package/src/read-after-write/viewer.ts +0 -290
  230. package/src/redis.ts +0 -25
  231. package/src/repo/index.ts +0 -2
  232. package/src/repo/prepare.ts +0 -266
  233. package/src/repo/types.ts +0 -65
  234. package/src/scripts/README.md +0 -40
  235. package/src/scripts/index.ts +0 -20
  236. package/src/scripts/publish-identity.ts +0 -60
  237. package/src/scripts/rebuild-repo.ts +0 -119
  238. package/src/scripts/rotate-keys.ts +0 -146
  239. package/src/scripts/sequencer-recovery/index.ts +0 -23
  240. package/src/scripts/sequencer-recovery/recoverer.ts +0 -297
  241. package/src/scripts/sequencer-recovery/recovery-db.ts +0 -65
  242. package/src/scripts/sequencer-recovery/repair-repos.ts +0 -49
  243. package/src/scripts/sequencer-recovery/user-queues.ts +0 -44
  244. package/src/scripts/util.ts +0 -7
  245. package/src/sequencer/db/index.ts +0 -21
  246. package/src/sequencer/db/migrations/001-init.ts +0 -35
  247. package/src/sequencer/db/migrations/index.ts +0 -5
  248. package/src/sequencer/db/schema.ts +0 -19
  249. package/src/sequencer/events.ts +0 -199
  250. package/src/sequencer/index.ts +0 -3
  251. package/src/sequencer/outbox.ts +0 -123
  252. package/src/sequencer/sequencer.ts +0 -290
  253. package/src/util/compression.ts +0 -16
  254. package/src/util/debug.ts +0 -10
  255. package/src/util/http.ts +0 -31
  256. package/src/util/types.ts +0 -7
  257. package/src/well-known.ts +0 -30
  258. package/test.env +0 -2
  259. package/tests/__snapshots__/takedown-appeal.test.ts.snap +0 -43
  260. package/tests/_oauth_client_assets_middleware.ts +0 -23
  261. package/tests/_puppeteer.ts +0 -147
  262. package/tests/_types.d.ts +0 -16
  263. package/tests/_util.ts +0 -191
  264. package/tests/account-deactivation.test.ts +0 -204
  265. package/tests/account-deletion.test.ts +0 -300
  266. package/tests/account-manager.test.ts +0 -462
  267. package/tests/account-migration.test.ts +0 -221
  268. package/tests/account-status.test.ts +0 -206
  269. package/tests/account.test.ts +0 -595
  270. package/tests/app-passwords.test.ts +0 -262
  271. package/tests/auth.test.ts +0 -405
  272. package/tests/blob-deletes.test.ts +0 -204
  273. package/tests/create-post.test.ts +0 -79
  274. package/tests/crud.test.ts +0 -1595
  275. package/tests/db.test.ts +0 -170
  276. package/tests/email-confirmation.test.ts +0 -227
  277. package/tests/entryway-mock.ts +0 -323
  278. package/tests/entryway.test.ts +0 -145
  279. package/tests/file-uploads.test.ts +0 -301
  280. package/tests/get-service-auth.test.ts +0 -81
  281. package/tests/handle-validation.test.ts +0 -56
  282. package/tests/handles.test.ts +0 -274
  283. package/tests/invite-codes.test.ts +0 -367
  284. package/tests/invites-admin.test.ts +0 -252
  285. package/tests/moderation.test.ts +0 -280
  286. package/tests/moderator-auth.test.ts +0 -177
  287. package/tests/oauth.test.ts +0 -334
  288. package/tests/plc-operations.test.ts +0 -239
  289. package/tests/preferences.test.ts +0 -352
  290. package/tests/proxied/__snapshots__/admin.test.ts.snap +0 -516
  291. package/tests/proxied/__snapshots__/feedgen.test.ts.snap +0 -215
  292. package/tests/proxied/__snapshots__/views.test.ts.snap +0 -4456
  293. package/tests/proxied/admin.test.ts +0 -340
  294. package/tests/proxied/feedgen.test.ts +0 -66
  295. package/tests/proxied/notif.test.ts +0 -85
  296. package/tests/proxied/procedures.test.ts +0 -175
  297. package/tests/proxied/proxy-catchall.test.ts +0 -256
  298. package/tests/proxied/proxy-header.test.ts +0 -239
  299. package/tests/proxied/proxy-oauth-aud.test.ts +0 -182
  300. package/tests/proxied/read-after-write.test.ts +0 -382
  301. package/tests/proxied/views.test.ts +0 -608
  302. package/tests/races.test.ts +0 -89
  303. package/tests/rate-limits.test.ts +0 -70
  304. package/tests/recovery.test.ts +0 -180
  305. package/tests/seeds/basic.ts +0 -165
  306. package/tests/seeds/follows.ts +0 -57
  307. package/tests/seeds/likes.ts +0 -14
  308. package/tests/seeds/reposts.ts +0 -18
  309. package/tests/seeds/thread.ts +0 -40
  310. package/tests/seeds/users-bulk.ts +0 -246
  311. package/tests/seeds/users.ts +0 -67
  312. package/tests/sequencer.test.ts +0 -251
  313. package/tests/server.test.ts +0 -151
  314. package/tests/sync/invertible-ops.test.ts +0 -99
  315. package/tests/sync/list.test.ts +0 -43
  316. package/tests/sync/subscribe-repos.test.ts +0 -672
  317. package/tests/sync/sync.test.ts +0 -316
  318. package/tests/takedown-appeal.test.ts +0 -166
  319. package/tsconfig.build.json +0 -9
  320. package/tsconfig.build.tsbuildinfo +0 -1
  321. package/tsconfig.json +0 -7
  322. package/tsconfig.tests.json +0 -8
@@ -1,68 +0,0 @@
1
- import { DAY, HOUR } from '@atproto/common'
2
- import {
3
- MethodAuthVerifier,
4
- MethodRateLimit,
5
- Server,
6
- } from '@atproto/xrpc-server'
7
- import { AccessOutput, OAuthOutput } from '../../../../auth-output.js'
8
- import { AppContext } from '../../../../context.js'
9
- import { com } from '../../../../lexicons/index.js'
10
-
11
- // Exposed as a utility to ensure auth in confirmEmail and requestEmailConfirmation
12
- export function requestEmailConfirmationAuth(
13
- ctx: AppContext,
14
- ): MethodAuthVerifier<AccessOutput | OAuthOutput> {
15
- return ctx.authVerifier.authorization({
16
- checkTakedown: true,
17
- authorize: (permissions) => {
18
- permissions.assertAccount({ attr: 'email', action: 'manage' })
19
- },
20
- })
21
- }
22
-
23
- const rateLimit: MethodRateLimit<AccessOutput | OAuthOutput> = [
24
- {
25
- durationMs: DAY,
26
- points: 15,
27
- calcKey: ({ auth }) => auth.credentials.did,
28
- },
29
- {
30
- durationMs: HOUR,
31
- points: 5,
32
- calcKey: ({ auth }) => auth.credentials.did,
33
- },
34
- ]
35
-
36
- export default function (server: Server, ctx: AppContext) {
37
- const { entrywayClient } = ctx
38
-
39
- const auth = requestEmailConfirmationAuth(ctx)
40
-
41
- if (entrywayClient) {
42
- server.add(com.atproto.server.requestEmailConfirmation, {
43
- auth,
44
- rateLimit,
45
- handler: async ({ auth, req }) => {
46
- const { headers } = await ctx.entrywayAuthHeaders(
47
- req,
48
- auth.credentials.did,
49
- com.atproto.server.requestEmailConfirmation.$lxm,
50
- )
51
-
52
- await entrywayClient.xrpc(com.atproto.server.requestEmailConfirmation, {
53
- headers,
54
- })
55
- },
56
- })
57
- } else {
58
- server.add(com.atproto.server.requestEmailConfirmation, {
59
- auth,
60
- rateLimit,
61
- handler: async ({ auth }) => {
62
- const did = auth.credentials.did
63
- const locale = undefined // @TODO get the locale somehow
64
- await ctx.accountManager.requestEmailConfirmation(did, { locale })
65
- },
66
- })
67
- }
68
- }
@@ -1,86 +0,0 @@
1
- import { DAY, HOUR } from '@atproto/common'
2
- import {
3
- ForbiddenError,
4
- MethodAuthVerifier,
5
- MethodRateLimit,
6
- Server,
7
- } from '@atproto/xrpc-server'
8
- import { AccessOutput, OAuthOutput } from '../../../../auth-output.js'
9
- import { ACCESS_FULL } from '../../../../auth-scope.js'
10
- import { AppContext } from '../../../../context.js'
11
- import { com } from '../../../../lexicons/index.js'
12
-
13
- // Exposed as a utility to ensure auth in updateEmail and requestEmailUpdate
14
- // stay consistent.
15
- export function requestEmailUpdateAuth(
16
- ctx: AppContext,
17
- ): MethodAuthVerifier<AccessOutput | OAuthOutput> {
18
- return ctx.authVerifier.authorization({
19
- checkTakedown: true,
20
- scopes: ACCESS_FULL,
21
- authorize: () => {
22
- throw new ForbiddenError(
23
- 'Use the account manager interface to update email address associated with an account',
24
- )
25
- },
26
- })
27
- }
28
-
29
- const rateLimit: MethodRateLimit<AccessOutput | OAuthOutput> = [
30
- {
31
- durationMs: DAY,
32
- points: 15,
33
- calcKey: ({ auth }) => auth.credentials.did,
34
- },
35
- {
36
- durationMs: HOUR,
37
- points: 5,
38
- calcKey: ({ auth }) => auth.credentials.did,
39
- },
40
- ]
41
-
42
- export default function (server: Server, ctx: AppContext) {
43
- const { entrywayClient } = ctx
44
-
45
- const auth = requestEmailUpdateAuth(ctx)
46
-
47
- if (entrywayClient) {
48
- server.add(com.atproto.server.requestEmailUpdate, {
49
- rateLimit,
50
- auth,
51
- handler: async ({ auth, req }) => {
52
- const { headers } = await ctx.entrywayAuthHeaders(
53
- req,
54
- auth.credentials.did,
55
- com.atproto.server.requestEmailUpdate.$lxm,
56
- )
57
-
58
- return entrywayClient.xrpc(com.atproto.server.requestEmailUpdate, {
59
- headers,
60
- })
61
- },
62
- })
63
- } else {
64
- server.add(com.atproto.server.requestEmailUpdate, {
65
- rateLimit,
66
- auth,
67
- handler: async ({ auth }) => {
68
- const did = auth.credentials.did
69
-
70
- // @TODO get the locale somehow (either by adding a field in the request
71
- // body, or by using the `Accept-Language` header).
72
- const locale = undefined
73
-
74
- const { tokenRequired } = await ctx.accountManager.requestEmailUpdate(
75
- did,
76
- { locale },
77
- )
78
-
79
- return {
80
- encoding: 'application/json' as const,
81
- body: { tokenRequired },
82
- }
83
- },
84
- })
85
- }
86
- }
@@ -1,52 +0,0 @@
1
- import { DAY, HOUR } from '@atproto/common'
2
- import { InvalidRequestError, Server } from '@atproto/xrpc-server'
3
- import { AppContext } from '../../../../context.js'
4
- import { com } from '../../../../lexicons/index.js'
5
-
6
- export default function (server: Server, ctx: AppContext) {
7
- const { entrywayClient } = ctx
8
-
9
- server.add(com.atproto.server.requestPasswordReset, {
10
- rateLimit: [
11
- {
12
- durationMs: DAY,
13
- points: 50,
14
- },
15
- {
16
- durationMs: HOUR,
17
- points: 15,
18
- },
19
- ],
20
- handler: async ({ input: { body }, req }) => {
21
- const email = body.email.toLowerCase()
22
-
23
- const account = await ctx.accountManager.getAccountByEmail(email, {
24
- includeDeactivated: true,
25
- includeTakenDown: true,
26
- })
27
-
28
- if (account?.email) {
29
- const token = await ctx.accountManager.createEmailToken(
30
- account.did,
31
- 'reset_password',
32
- )
33
- await ctx.mailer.sendResetPassword(
34
- { handle: account.handle ?? account.email, token },
35
- { to: account.email },
36
- )
37
- return
38
- }
39
-
40
- if (entrywayClient) {
41
- const { headers } = ctx.entrywayPassthruHeaders(req)
42
- await entrywayClient.xrpc(com.atproto.server.requestPasswordReset, {
43
- headers,
44
- body,
45
- })
46
- return
47
- }
48
-
49
- throw new InvalidRequestError('account does not have an email address')
50
- },
51
- })
52
- }
@@ -1,15 +0,0 @@
1
- import { Server } from '@atproto/xrpc-server'
2
- import { AppContext } from '../../../../context.js'
3
- import { com } from '../../../../lexicons/index.js'
4
-
5
- export default function (server: Server, ctx: AppContext) {
6
- server.add(com.atproto.server.reserveSigningKey, {
7
- handler: async ({ input }) => {
8
- const signingKey = await ctx.actorStore.reserveKeypair(input.body.did)
9
- return {
10
- encoding: 'application/json' as const,
11
- body: { signingKey },
12
- }
13
- },
14
- })
15
- }
@@ -1,50 +0,0 @@
1
- import { MINUTE } from '@atproto/common'
2
- import {
3
- InvalidRequestError,
4
- MethodRateLimit,
5
- Server,
6
- } from '@atproto/xrpc-server'
7
- import { NEW_PASSWORD_MAX_LENGTH } from '../../../../account-manager/helpers/scrypt.js'
8
- import { AppContext } from '../../../../context.js'
9
- import { com } from '../../../../lexicons/index.js'
10
-
11
- export default function (server: Server, ctx: AppContext) {
12
- const { entrywayClient } = ctx
13
-
14
- const rateLimit: MethodRateLimit<
15
- void,
16
- com.atproto.server.resetPassword.$Params,
17
- com.atproto.server.resetPassword.$Input
18
- > = [
19
- {
20
- durationMs: 5 * MINUTE,
21
- points: 50,
22
- },
23
- ]
24
-
25
- if (entrywayClient) {
26
- server.add(com.atproto.server.resetPassword, {
27
- rateLimit,
28
- handler: async ({ input: { body }, req }) => {
29
- const { headers } = ctx.entrywayPassthruHeaders(req)
30
- await entrywayClient.xrpc(com.atproto.server.resetPassword, {
31
- headers,
32
- body,
33
- })
34
- },
35
- })
36
- } else {
37
- server.add(com.atproto.server.resetPassword, {
38
- rateLimit,
39
- handler: async ({ input: { body } }) => {
40
- const { token, password } = body
41
-
42
- if (password.length > NEW_PASSWORD_MAX_LENGTH) {
43
- throw new InvalidRequestError('Invalid password length.')
44
- }
45
-
46
- await ctx.accountManager.resetPassword({ token, password })
47
- },
48
- })
49
- }
50
- }
@@ -1,42 +0,0 @@
1
- import { ForbiddenError, Server } from '@atproto/xrpc-server'
2
- import { AppContext } from '../../../../context.js'
3
- import { com } from '../../../../lexicons/index.js'
4
-
5
- export default function (server: Server, ctx: AppContext) {
6
- const { entrywayClient } = ctx
7
-
8
- const auth = ctx.authVerifier.authorization({
9
- authorize: () => {
10
- throw new ForbiddenError(
11
- 'OAuth credentials are not supported for this endpoint',
12
- )
13
- },
14
- })
15
-
16
- if (entrywayClient) {
17
- server.add(com.atproto.server.revokeAppPassword, {
18
- auth,
19
- handler: async ({ auth, input: { body }, req }) => {
20
- const { headers } = await ctx.entrywayAuthHeaders(
21
- req,
22
- auth.credentials.did,
23
- com.atproto.server.revokeAppPassword.$lxm,
24
- )
25
-
26
- await entrywayClient.xrpc(com.atproto.server.revokeAppPassword, {
27
- headers,
28
- body,
29
- })
30
- },
31
- })
32
- } else {
33
- server.add(com.atproto.server.revokeAppPassword, {
34
- auth,
35
- handler: async ({ auth, input: { body } }) => {
36
- const requester = auth.credentials.did
37
-
38
- await ctx.accountManager.revokeAppPassword(requester, body.name)
39
- },
40
- })
41
- }
42
- }
@@ -1,52 +0,0 @@
1
- import { InvalidRequestError, Server } from '@atproto/xrpc-server'
2
- import { UserAlreadyExistsError } from '../../../../account-manager/helpers/account.js'
3
- import { AppContext } from '../../../../context.js'
4
- import { com } from '../../../../lexicons/index.js'
5
- import { requestEmailUpdateAuth } from './requestEmailUpdate.js'
6
-
7
- export default function (server: Server, ctx: AppContext) {
8
- const { entrywayClient } = ctx
9
-
10
- // @NOTE Ensure that both endpoints use the same authentication logic
11
- const auth = requestEmailUpdateAuth(ctx)
12
-
13
- if (entrywayClient) {
14
- server.add(com.atproto.server.updateEmail, {
15
- auth,
16
- handler: async ({ auth, input: { body }, req }) => {
17
- const { headers } = await ctx.entrywayAuthHeaders(
18
- req,
19
- auth.credentials.did,
20
- com.atproto.server.updateEmail.$lxm,
21
- )
22
-
23
- await entrywayClient.xrpc(com.atproto.server.updateEmail, {
24
- headers,
25
- body,
26
- })
27
- },
28
- })
29
- } else {
30
- server.add(com.atproto.server.updateEmail, {
31
- auth,
32
- handler: async ({ auth, input: { body } }) => {
33
- const did = auth.credentials.did
34
- const { token, email } = body
35
-
36
- // @TODO get the locale somehow (either by adding a field in the request
37
- // body, or by using the `Accept-Language` header).
38
- const locale = undefined
39
-
40
- try {
41
- await ctx.accountManager.updateEmail(did, email, token, { locale })
42
- } catch (cause) {
43
- if (cause instanceof UserAlreadyExistsError) {
44
- throw new InvalidRequestError(cause.message, undefined, { cause })
45
- }
46
-
47
- throw cause
48
- }
49
- },
50
- })
51
- }
52
- }
@@ -1,136 +0,0 @@
1
- import * as plc from '@did-plc/lib'
2
- import { getPdsEndpoint, getSigningDidKey } from '@atproto/common'
3
- import * as crypto from '@atproto/crypto'
4
- import { DidDocument, IdResolver } from '@atproto/identity'
5
- import { InvalidRequestError } from '@atproto/xrpc-server'
6
- import { ActorStore } from '../../../../actor-store/actor-store.js'
7
- import { ServerConfig } from '../../../../config/index.js'
8
- import { httpLogger } from '../../../../logger.js'
9
-
10
- // generate an invite code preceded by the hostname
11
- // with '.'s replaced by '-'s so it is not mistakable for a link
12
- // ex: bsky-app-abc23-567xy
13
- // regex: bsky-app-[a-z2-7]{5}-[a-z2-7]{5}
14
- export const genInvCode = (cfg: ServerConfig): string => {
15
- return cfg.service.hostname.replaceAll('.', '-') + '-' + getRandomToken()
16
- }
17
-
18
- export const genInvCodes = (cfg: ServerConfig, count: number): string[] => {
19
- const codes: string[] = []
20
- for (let i = 0; i < count; i++) {
21
- codes.push(genInvCode(cfg))
22
- }
23
- return codes
24
- }
25
-
26
- // Formatted xxxxx-xxxxx where digits are in base32
27
- export const getRandomToken = () => {
28
- const token = crypto.randomStr(8, 'base32').slice(0, 10)
29
- return token.slice(0, 5) + '-' + token.slice(5, 10)
30
- }
31
-
32
- export const safeResolveDidDoc = async (
33
- ctx: { idResolver: IdResolver },
34
- did: string,
35
- forceRefresh?: boolean,
36
- ): Promise<DidDocument | undefined> => {
37
- try {
38
- const didDoc = await ctx.idResolver.did.resolve(did, forceRefresh)
39
- return didDoc ?? undefined
40
- } catch (err) {
41
- httpLogger.warn({ err, did }, 'failed to resolve did doc')
42
- }
43
- }
44
-
45
- export const didDocForSession = async (
46
- ctx: { idResolver: IdResolver; cfg: ServerConfig },
47
- did: string,
48
- forceRefresh?: boolean,
49
- ): Promise<DidDocument | undefined> => {
50
- if (!ctx.cfg.identity.enableDidDocWithSession) return
51
- return safeResolveDidDoc(ctx, did, forceRefresh)
52
- }
53
-
54
- export const isValidDidDocForService = async (
55
- ctx: {
56
- plcClient: plc.Client
57
- idResolver: IdResolver
58
- cfg: ServerConfig
59
- plcRotationKey: crypto.Keypair
60
- actorStore: ActorStore
61
- },
62
- did: string,
63
- ): Promise<boolean> => {
64
- try {
65
- await assertValidDidDocumentForService(ctx, did)
66
- return true
67
- } catch {
68
- return false
69
- }
70
- }
71
-
72
- export const assertValidDidDocumentForService = async (
73
- ctx: {
74
- plcClient: plc.Client
75
- idResolver: IdResolver
76
- cfg: ServerConfig
77
- plcRotationKey: crypto.Keypair
78
- actorStore: ActorStore
79
- },
80
- did: string,
81
- ) => {
82
- if (did.startsWith('did:plc')) {
83
- const resolved = await ctx.plcClient.getDocumentData(did)
84
- await assertValidDocContents(ctx, did, {
85
- pdsEndpoint: resolved.services['atproto_pds']?.endpoint,
86
- signingKey: resolved.verificationMethods['atproto'],
87
- rotationKeys: resolved.rotationKeys,
88
- })
89
- } else {
90
- const resolved = await ctx.idResolver.did.resolve(did, true)
91
- if (!resolved) {
92
- throw new InvalidRequestError('Could not resolve DID')
93
- }
94
- await assertValidDocContents(ctx, did, {
95
- pdsEndpoint: getPdsEndpoint(resolved),
96
- signingKey: getSigningDidKey(resolved),
97
- })
98
- }
99
- }
100
-
101
- const assertValidDocContents = async (
102
- ctx: {
103
- cfg: ServerConfig
104
- plcRotationKey: crypto.Keypair
105
- actorStore: ActorStore
106
- },
107
- did: string,
108
- contents: {
109
- signingKey?: string
110
- pdsEndpoint?: string
111
- rotationKeys?: string[]
112
- },
113
- ) => {
114
- const { signingKey, pdsEndpoint, rotationKeys } = contents
115
-
116
- const plcRotationKey =
117
- ctx.cfg.entryway?.plcRotationKey ?? ctx.plcRotationKey.did()
118
- if (rotationKeys !== undefined && !rotationKeys.includes(plcRotationKey)) {
119
- throw new InvalidRequestError(
120
- 'Server rotation key not included in PLC DID data',
121
- )
122
- }
123
-
124
- if (!pdsEndpoint || pdsEndpoint !== ctx.cfg.service.publicUrl) {
125
- throw new InvalidRequestError(
126
- 'DID document atproto_pds service endpoint does not match PDS public url',
127
- )
128
- }
129
-
130
- const keypair = await ctx.actorStore.keypair(did)
131
- if (!signingKey || signingKey !== keypair.did()) {
132
- throw new InvalidRequestError(
133
- 'DID document verification method does not match expected signing key',
134
- )
135
- }
136
- }
@@ -1,27 +0,0 @@
1
- import { Server } from '@atproto/xrpc-server'
2
- import { isUserOrAdmin } from '../../../../../auth-verifier.js'
3
- import { AppContext } from '../../../../../context.js'
4
- import { com } from '../../../../../lexicons/index.js'
5
- import { getCarStream } from '../getRepo.js'
6
- import { assertRepoAvailability } from '../util.js'
7
-
8
- export default function (server: Server, ctx: AppContext) {
9
- server.add(com.atproto.sync.getCheckout, {
10
- auth: ctx.authVerifier.authorizationOrAdminTokenOptional({
11
- authorize: () => {
12
- // always allow
13
- },
14
- }),
15
- handler: async ({ params, auth }) => {
16
- const { did } = params
17
- await assertRepoAvailability(ctx, did, isUserOrAdmin(auth, did))
18
-
19
- const carStream = await getCarStream(ctx, did)
20
-
21
- return {
22
- encoding: 'application/vnd.ipld.car' as const,
23
- body: carStream,
24
- }
25
- },
26
- })
27
- }
@@ -1,33 +0,0 @@
1
- import { InvalidRequestError, Server } from '@atproto/xrpc-server'
2
- import { isUserOrAdmin } from '../../../../../auth-verifier.js'
3
- import { AppContext } from '../../../../../context.js'
4
- import { com } from '../../../../../lexicons/index.js'
5
- import { assertRepoAvailability } from '../util.js'
6
-
7
- export default function (server: Server, ctx: AppContext) {
8
- server.add(com.atproto.sync.getHead, {
9
- auth: ctx.authVerifier.authorizationOrAdminTokenOptional({
10
- authorize: () => {
11
- // always allow
12
- },
13
- }),
14
- handler: async ({ params, auth }) => {
15
- const { did } = params
16
- await assertRepoAvailability(ctx, did, isUserOrAdmin(auth, did))
17
-
18
- const root = await ctx.actorStore.read(did, (store) =>
19
- store.repo.storage.getRoot(),
20
- )
21
- if (root === null) {
22
- throw new InvalidRequestError(
23
- `Could not find root for DID: ${did}`,
24
- 'HeadNotFound',
25
- )
26
- }
27
- return {
28
- encoding: 'application/json' as const,
29
- body: { root: root.toString() },
30
- }
31
- },
32
- })
33
- }
@@ -1,61 +0,0 @@
1
- import { parseCid } from '@atproto/lex-data'
2
- import { BlobNotFoundError } from '@atproto/repo'
3
- import { InvalidRequestError, Server } from '@atproto/xrpc-server'
4
- import { AuthScope } from '../../../../auth-scope.js'
5
- import { isUserOrAdmin } from '../../../../auth-verifier.js'
6
- import { AppContext } from '../../../../context.js'
7
- import { com } from '../../../../lexicons/index.js'
8
- import { assertRepoAvailability } from './util.js'
9
-
10
- export default function (server: Server, ctx: AppContext) {
11
- server.add(com.atproto.sync.getBlob, {
12
- auth: ctx.authVerifier.authorizationOrAdminTokenOptional({
13
- additional: [AuthScope.Takendown],
14
- authorize: () => {
15
- // always allow
16
- },
17
- }),
18
- handler: async ({ params, res, auth }) => {
19
- const { did } = params
20
- await assertRepoAvailability(ctx, did, isUserOrAdmin(auth, did))
21
-
22
- const cid = parseCid(params.cid)
23
- const found = await ctx.actorStore.read(params.did, async (store) => {
24
- try {
25
- return await store.repo.blob.getBlob(cid)
26
- } catch (err) {
27
- if (err instanceof BlobNotFoundError) {
28
- throw new InvalidRequestError('Blob not found')
29
- } else {
30
- throw err
31
- }
32
- }
33
- })
34
- if (!found) {
35
- throw new InvalidRequestError('Blob not found')
36
- }
37
- res.setHeader('content-length', found.size)
38
-
39
- // Important Security headers
40
-
41
- // This prevents the browser from trying to guess the content type
42
- // and potentially loading the blob as executable code, or rendering it
43
- // in some other unsafe way.
44
- res.setHeader('x-content-type-options', 'nosniff')
45
-
46
- // This forces the browser to download the blob instead of trying to
47
- // render it when visiting the URL. This is important to prevent XSS
48
- // attacks if the blob happens to be HTML. Even if JS is disabled via the
49
- // CSP header below, a blob could still contain malicious HTML links.
50
- res.setHeader('content-disposition', `attachment; filename="${cid}"`)
51
-
52
- // This should prevent the browser from executing the blob in any way
53
- res.setHeader('content-security-policy', `default-src 'none'; sandbox`)
54
-
55
- return {
56
- encoding: found.mimeType || ('application/octet-stream' as const),
57
- body: found.stream,
58
- }
59
- },
60
- })
61
- }
@@ -1,37 +0,0 @@
1
- import { byteIterableToStream } from '@atproto/common'
2
- import { parseCid } from '@atproto/lex-data'
3
- import { blocksToCarStream } from '@atproto/repo'
4
- import { InvalidRequestError, Server } from '@atproto/xrpc-server'
5
- import { isUserOrAdmin } from '../../../../auth-verifier.js'
6
- import { AppContext } from '../../../../context.js'
7
- import { com } from '../../../../lexicons/index.js'
8
- import { assertRepoAvailability } from './util.js'
9
-
10
- export default function (server: Server, ctx: AppContext) {
11
- server.add(com.atproto.sync.getBlocks, {
12
- auth: ctx.authVerifier.authorizationOrAdminTokenOptional({
13
- authorize: () => {
14
- // always allow
15
- },
16
- }),
17
- handler: async ({ params, auth }) => {
18
- const { did } = params
19
- await assertRepoAvailability(ctx, did, isUserOrAdmin(auth, did))
20
-
21
- const cids = params.cids.map(parseCid)
22
- const got = await ctx.actorStore.read(did, (store) =>
23
- store.repo.storage.getBlocks(cids),
24
- )
25
- if (got.missing.length > 0) {
26
- const missingStr = got.missing.map((c) => c.toString())
27
- throw new InvalidRequestError(`Could not find cids: ${missingStr}`)
28
- }
29
- const car = blocksToCarStream(null, got.blocks)
30
-
31
- return {
32
- encoding: 'application/vnd.ipld.car' as const,
33
- body: byteIterableToStream(car),
34
- }
35
- },
36
- })
37
- }