@atproto/pds 0.5.12 → 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 +36 -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,327 +0,0 @@
1
- import * as plc from '@did-plc/lib'
2
- import { isEmailValid } from '@hapi/address'
3
- import { isDisposableEmail } from 'disposable-email-domains-js'
4
- import { MINUTE, check } from '@atproto/common'
5
- import { ExportableKeypair, Keypair, Secp256k1Keypair } from '@atproto/crypto'
6
- import { AtprotoData, ensureAtpDocument } from '@atproto/identity'
7
- import { DidString } from '@atproto/syntax'
8
- import {
9
- AuthRequiredError,
10
- InvalidRequestError,
11
- Server,
12
- } from '@atproto/xrpc-server'
13
- import { NEW_PASSWORD_MAX_LENGTH } from '../../../../account-manager/helpers/scrypt.js'
14
- import { AppContext } from '../../../../context.js'
15
- import { baseNormalizeAndValidate } from '../../../../handle/index.js'
16
- import { com } from '../../../../lexicons/index.js'
17
- import { safeResolveDidDoc } from './util.js'
18
-
19
- export default function (server: Server, ctx: AppContext) {
20
- server.add(com.atproto.server.createAccount, {
21
- rateLimit: {
22
- durationMs: 5 * MINUTE,
23
- points: 100,
24
- },
25
- auth: ctx.authVerifier.userServiceAuthOptional,
26
- handler: async ({
27
- input,
28
- auth,
29
- req,
30
- }): Promise<com.atproto.server.createAccount.$Output> => {
31
- // @NOTE Until this code and the OAuthStore's `createAccount` are
32
- // refactored together, any change made here must be reflected over there.
33
-
34
- const requester = auth.credentials?.did ?? null
35
- const {
36
- did,
37
- handle,
38
- email,
39
- password,
40
- inviteCode,
41
- signingKey,
42
- plcOp,
43
- deactivated,
44
- } = ctx.entrywayClient
45
- ? await validateInputsForEntrywayPds(ctx, input.body)
46
- : await validateInputsForLocalPds(ctx, input.body, requester)
47
-
48
- await ctx.actorStore.create(did, signingKey)
49
-
50
- try {
51
- const commit = await ctx.actorStore.transact(did, (actorTxn) => {
52
- return actorTxn.repo.createRepo([])
53
- })
54
-
55
- const canTombstone =
56
- // @NOTE IMPORTANT Because the user may be bringing their own did, we
57
- // must make sure not to tombstone their did on failure if we didn't
58
- // create it here.
59
- !ctx.entrywayClient && !input.body.did && !!plcOp
60
-
61
- // Generate a real did with PLC
62
- if (plcOp) {
63
- await ctx.plcClient.sendOperation(did, plcOp)
64
- }
65
-
66
- try {
67
- const didDoc = await safeResolveDidDoc(ctx, did, true)
68
-
69
- const creds = await ctx.accountManager.createAccountAndSession({
70
- did,
71
- handle,
72
- email,
73
- password,
74
- repoCid: commit.cid,
75
- repoRev: commit.rev,
76
- inviteCode,
77
- deactivated,
78
- })
79
-
80
- try {
81
- const sequenceEvt = !deactivated
82
- if (sequenceEvt) {
83
- await ctx.sequencer.sequenceAccountCreation(did, handle, commit)
84
- }
85
-
86
- try {
87
- await ctx.actorStore
88
- .clearReservedKeypair(signingKey.did(), did)
89
- .catch((err) => {
90
- // @NOTE This is a cleanup operation so we won't fail the whole
91
- // flow if it fails, but we log it just in case
92
- req.log.error(
93
- { did, signingKeyDid: signingKey.did(), err },
94
- 'Failed to clear reserved keypair',
95
- )
96
- })
97
-
98
- return {
99
- encoding: 'application/json' as const,
100
- body: {
101
- handle,
102
- did: did,
103
- // @ts-expect-error https://github.com/bluesky-social/atproto/pull/4406
104
- didDoc,
105
- accessJwt: creds.accessJwt,
106
- refreshJwt: creds.refreshJwt,
107
- },
108
- }
109
- } catch (err) {
110
- if (sequenceEvt) await ctx.sequencer.sequenceAccountDeletion(did)
111
- throw err
112
- }
113
- } catch (err) {
114
- await ctx.accountManager.deleteAccount(did)
115
- throw err
116
- }
117
- } catch (err) {
118
- if (canTombstone) {
119
- await ctx.plcClient.tombstone(did, ctx.plcRotationKey)
120
- }
121
- throw err
122
- }
123
- } catch (err) {
124
- await ctx.actorStore.destroy(did)
125
- throw err
126
- }
127
- },
128
- })
129
- }
130
-
131
- const validateInputsForEntrywayPds = async (
132
- ctx: AppContext,
133
- input: com.atproto.server.createAccount.$InputBody,
134
- ) => {
135
- const handle = baseNormalizeAndValidate(input.handle)
136
-
137
- const { did, plcOp } = input
138
- if (!did || !plcOp) {
139
- throw new InvalidRequestError(
140
- 'non-entryway pds requires bringing a DID and plcOp',
141
- )
142
- }
143
- if (!check.is(plcOp, plc.def.operation)) {
144
- throw new InvalidRequestError('invalid plc operation', 'IncompatibleDidDoc')
145
- }
146
- const plcRotationKey = ctx.cfg.entryway?.plcRotationKey
147
- if (!plcRotationKey || !plcOp.rotationKeys.includes(plcRotationKey)) {
148
- throw new InvalidRequestError(
149
- 'PLC DID does not include service rotation key',
150
- 'IncompatibleDidDoc',
151
- )
152
- }
153
- try {
154
- await plc.assureValidOp(plcOp)
155
- await plc.assureValidSig([plcRotationKey], plcOp)
156
- } catch (err) {
157
- throw new InvalidRequestError('invalid plc operation', 'IncompatibleDidDoc')
158
- }
159
- const doc = plc.formatDidDoc({ did, ...plcOp })
160
- const data = ensureAtpDocument(doc)
161
-
162
- let signingKey: ExportableKeypair | undefined
163
- if (input.did) {
164
- signingKey = await ctx.actorStore.getReservedKeypair(input.did)
165
- }
166
- if (!signingKey) {
167
- signingKey = await ctx.actorStore.getReservedKeypair(data.signingKey)
168
- }
169
- if (!signingKey) {
170
- throw new InvalidRequestError('reserved signing key does not exist')
171
- }
172
-
173
- validateAtprotoData(data, {
174
- handle,
175
- pds: ctx.cfg.service.publicUrl,
176
- signingKey: signingKey.did(),
177
- })
178
-
179
- return {
180
- did,
181
- handle,
182
- email: undefined,
183
- password: undefined,
184
- inviteCode: undefined,
185
- signingKey,
186
- plcOp,
187
- deactivated: false,
188
- }
189
- }
190
-
191
- const validateInputsForLocalPds = async (
192
- ctx: AppContext,
193
- input: com.atproto.server.createAccount.$InputBody,
194
- requester: string | null,
195
- ) => {
196
- const { email, password, inviteCode } = input
197
- if (input.plcOp) {
198
- throw new InvalidRequestError('Unsupported input: "plcOp"')
199
- }
200
-
201
- if (password && password.length > NEW_PASSWORD_MAX_LENGTH) {
202
- throw new InvalidRequestError(
203
- `Password too long. Maximum length is ${NEW_PASSWORD_MAX_LENGTH} characters.`,
204
- )
205
- }
206
-
207
- if (ctx.cfg.invites.required && !inviteCode) {
208
- throw new InvalidRequestError(
209
- 'No invite code provided',
210
- 'InvalidInviteCode',
211
- )
212
- }
213
-
214
- if (!email) {
215
- throw new InvalidRequestError('Email is required')
216
- } else if (!isEmailValid(email) || isDisposableEmail(email)) {
217
- throw new InvalidRequestError(
218
- 'This email address is not supported, please use a different email.',
219
- )
220
- }
221
-
222
- // normalize & ensure valid handle
223
- const handle = await ctx.accountManager.normalizeAndValidateHandle(
224
- input.handle,
225
- { did: input.did },
226
- )
227
-
228
- // check that the invite code still has uses
229
- if (ctx.cfg.invites.required && inviteCode) {
230
- await ctx.accountManager.ensureInviteIsAvailable(inviteCode)
231
- }
232
-
233
- // check that the handle and email are available
234
- const [handleAccnt, emailAcct] = await Promise.all([
235
- ctx.accountManager.getAccount(handle),
236
- ctx.accountManager.getAccountByEmail(email),
237
- ])
238
- if (handleAccnt) {
239
- throw new InvalidRequestError(`Handle already taken: ${handle}`)
240
- } else if (emailAcct) {
241
- throw new InvalidRequestError(`Email already taken: ${email}`)
242
- }
243
-
244
- // determine the did & any plc ops we need to send
245
- // if the provided did document is poorly setup, we throw
246
- const signingKey = await Secp256k1Keypair.create({ exportable: true })
247
-
248
- let did: DidString
249
- let plcOp: plc.Operation | null
250
- let deactivated = false
251
- if (input.did) {
252
- if (input.did !== requester) {
253
- throw new AuthRequiredError(
254
- `Missing auth to create account with did: ${input.did}`,
255
- )
256
- }
257
- did = input.did
258
- plcOp = null
259
- deactivated = true
260
- } else {
261
- const formatted = await formatDidAndPlcOp(ctx, handle, input, signingKey)
262
- did = formatted.did as DidString
263
- plcOp = formatted.op
264
- }
265
-
266
- return {
267
- did,
268
- handle,
269
- email,
270
- password,
271
- inviteCode,
272
- signingKey,
273
- plcOp,
274
- deactivated,
275
- }
276
- }
277
-
278
- const formatDidAndPlcOp = async (
279
- ctx: AppContext,
280
- handle: string,
281
- input: com.atproto.server.createAccount.$InputBody,
282
- signingKey: Keypair,
283
- ) => {
284
- // if the user is not bringing a DID, then we format a create op for PLC
285
- const rotationKeys = [ctx.plcRotationKey.did()]
286
- if (ctx.cfg.identity.recoveryDidKey) {
287
- rotationKeys.unshift(ctx.cfg.identity.recoveryDidKey)
288
- }
289
- if (input.recoveryKey) {
290
- rotationKeys.unshift(input.recoveryKey)
291
- }
292
- return plc.createOp({
293
- signingKey: signingKey.did(),
294
- rotationKeys,
295
- handle,
296
- pds: ctx.cfg.service.publicUrl,
297
- signer: ctx.plcRotationKey,
298
- })
299
- }
300
- const validateAtprotoData = (
301
- data: AtprotoData,
302
- expected: {
303
- handle: string
304
- pds: string
305
- signingKey: string
306
- },
307
- ) => {
308
- // if the user is bringing their own did:
309
- // resolve the user's did doc data, including rotationKeys if did:plc
310
- // determine if we have the capability to make changes to their DID
311
- if (data.handle !== expected.handle) {
312
- throw new InvalidRequestError(
313
- 'provided handle does not match DID document handle',
314
- 'IncompatibleDidDoc',
315
- )
316
- } else if (data.pds !== expected.pds) {
317
- throw new InvalidRequestError(
318
- 'DID document pds endpoint does not match service endpoint',
319
- 'IncompatibleDidDoc',
320
- )
321
- } else if (data.signingKey !== expected.signingKey) {
322
- throw new InvalidRequestError(
323
- 'DID document signing key does not match service signing key',
324
- 'IncompatibleDidDoc',
325
- )
326
- }
327
- }
@@ -1,53 +0,0 @@
1
- import { ForbiddenError, Server } from '@atproto/xrpc-server'
2
- import { ACCESS_FULL } from '../../../../auth-scope.js'
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
- const auth = ctx.authVerifier.authorization({
10
- checkTakedown: true,
11
- scopes: ACCESS_FULL,
12
- authorize: () => {
13
- throw new ForbiddenError(
14
- 'OAuth credentials are not supported for this endpoint',
15
- )
16
- },
17
- })
18
-
19
- if (entrywayClient) {
20
- server.add(com.atproto.server.createAppPassword, {
21
- auth,
22
- handler: async ({ input: { body }, auth, req }) => {
23
- const { headers } = await ctx.entrywayAuthHeaders(
24
- req,
25
- auth.credentials.did,
26
- com.atproto.server.createAppPassword.$lxm,
27
- )
28
-
29
- return entrywayClient.xrpc(com.atproto.server.createAppPassword, {
30
- headers,
31
- body,
32
- })
33
- },
34
- })
35
- } else {
36
- server.add(com.atproto.server.createAppPassword, {
37
- auth,
38
- handler: async ({ input: { body }, auth }) => {
39
- const { name } = body
40
- const appPassword = await ctx.accountManager.createAppPassword(
41
- auth.credentials.did,
42
- name,
43
- body.privileged ?? false,
44
- )
45
-
46
- return {
47
- encoding: 'application/json' as const,
48
- body: appPassword,
49
- }
50
- },
51
- })
52
- }
53
- }
@@ -1,38 +0,0 @@
1
- import { InvalidRequestError, Server } from '@atproto/xrpc-server'
2
- import { AppContext } from '../../../../context.js'
3
- import { com } from '../../../../lexicons/index.js'
4
- import { genInvCode } from './util.js'
5
-
6
- export default function (server: Server, ctx: AppContext) {
7
- const { entryway } = ctx.cfg
8
-
9
- if (entryway) {
10
- server.add(com.atproto.server.createInviteCode, {
11
- auth: ctx.authVerifier.adminToken,
12
- handler: () => {
13
- throw new InvalidRequestError(
14
- 'Account invites are managed by the entryway service',
15
- )
16
- },
17
- })
18
- } else {
19
- server.add(com.atproto.server.createInviteCode, {
20
- auth: ctx.authVerifier.adminToken,
21
- handler: async ({ input }) => {
22
- const { useCount, forAccount = 'admin' } = input.body
23
-
24
- const code = genInvCode(ctx.cfg)
25
-
26
- await ctx.accountManager.createInviteCodes(
27
- [{ account: forAccount, codes: [code] }],
28
- useCount,
29
- )
30
-
31
- return {
32
- encoding: 'application/json' as const,
33
- body: { code },
34
- }
35
- },
36
- })
37
- }
38
- }
@@ -1,42 +0,0 @@
1
- import { InvalidRequestError, Server } from '@atproto/xrpc-server'
2
- import { AppContext } from '../../../../context.js'
3
- import { com } from '../../../../lexicons/index.js'
4
- import { genInvCodes } from './util.js'
5
-
6
- type AccountCodes = com.atproto.server.createInviteCodes.AccountCodes
7
-
8
- export default function (server: Server, ctx: AppContext) {
9
- const { entryway } = ctx.cfg
10
-
11
- if (entryway) {
12
- server.add(com.atproto.server.createInviteCodes, {
13
- auth: ctx.authVerifier.adminToken,
14
- handler: () => {
15
- throw new InvalidRequestError(
16
- 'Account invites are managed by the entryway service',
17
- )
18
- },
19
- })
20
- } else {
21
- server.add(com.atproto.server.createInviteCodes, {
22
- auth: ctx.authVerifier.adminToken,
23
- handler: async ({ input }) => {
24
- const { codeCount, useCount } = input.body
25
-
26
- const forAccounts = input.body.forAccounts ?? ['admin']
27
-
28
- const accountCodes: AccountCodes[] = []
29
- for (const account of forAccounts) {
30
- const codes = genInvCodes(ctx.cfg, codeCount)
31
- accountCodes.push({ account, codes })
32
- }
33
- await ctx.accountManager.createInviteCodes(accountCodes, useCount)
34
-
35
- return {
36
- encoding: 'application/json' as const,
37
- body: { codes: accountCodes },
38
- }
39
- },
40
- })
41
- }
42
- }
@@ -1,97 +0,0 @@
1
- import { DAY, MINUTE } from '@atproto/common'
2
- import { DidString, HandleString, INVALID_HANDLE } from '@atproto/syntax'
3
- import {
4
- AuthRequiredError,
5
- MethodRateLimit,
6
- Server,
7
- } from '@atproto/xrpc-server'
8
- import { formatAccountStatus } from '../../../../account-manager/account-manager.js'
9
- import { OLD_PASSWORD_MAX_LENGTH } from '../../../../account-manager/helpers/scrypt.js'
10
- import { AppContext } from '../../../../context.js'
11
- import { com } from '../../../../lexicons/index.js'
12
- import { didDocForSession } from './util.js'
13
-
14
- export default function (server: Server, ctx: AppContext) {
15
- const { entrywayClient } = ctx
16
-
17
- const rateLimit: MethodRateLimit<
18
- void,
19
- com.atproto.server.createSession.$Params,
20
- com.atproto.server.createSession.$Input
21
- > = [
22
- {
23
- durationMs: DAY,
24
- points: 300,
25
- calcKey: ({ input, req }) => `${input.body.identifier}-${req.ip}`,
26
- },
27
- {
28
- durationMs: 5 * MINUTE,
29
- points: 30,
30
- calcKey: ({ input, req }) => `${input.body.identifier}-${req.ip}`,
31
- },
32
- ]
33
-
34
- if (entrywayClient) {
35
- server.add(com.atproto.server.createSession, {
36
- rateLimit,
37
- handler: async ({ input: { body }, req }) => {
38
- const { headers } = ctx.entrywayPassthruHeaders(req)
39
- return entrywayClient.xrpc(com.atproto.server.createSession, {
40
- headers,
41
- body,
42
- })
43
- },
44
- })
45
- } else {
46
- server.add(com.atproto.server.createSession, {
47
- rateLimit,
48
- handler: async ({
49
- input: { body },
50
- }): Promise<com.atproto.server.createSession.$Output> => {
51
- if (body.password.length > OLD_PASSWORD_MAX_LENGTH) {
52
- throw new AuthRequiredError(
53
- 'Password too long. Consider resetting your password.',
54
- )
55
- }
56
-
57
- const { user, isSoftDeleted, appPassword } =
58
- await ctx.accountManager.login(body)
59
-
60
- if (!body.allowTakendown && isSoftDeleted) {
61
- throw new AuthRequiredError(
62
- 'Account has been taken down',
63
- 'AccountTakedown',
64
- )
65
- }
66
-
67
- const [{ accessJwt, refreshJwt }, didDoc] = await Promise.all([
68
- ctx.accountManager.createSession(
69
- user.did,
70
- appPassword,
71
- isSoftDeleted,
72
- ),
73
- didDocForSession(ctx, user.did),
74
- ])
75
-
76
- const { status, active } = formatAccountStatus(user)
77
-
78
- return {
79
- encoding: 'application/json',
80
- body: {
81
- accessJwt,
82
- refreshJwt,
83
-
84
- did: user.did as DidString,
85
- // @ts-expect-error https://github.com/bluesky-social/atproto/pull/4406
86
- didDoc,
87
- handle: (user.handle ?? INVALID_HANDLE) as HandleString,
88
- email: user.email ?? undefined,
89
- emailConfirmed: !!user.emailConfirmedAt,
90
- active,
91
- status,
92
- },
93
- }
94
- },
95
- })
96
- }
97
- }
@@ -1,41 +0,0 @@
1
- import { ForbiddenError, Server } from '@atproto/xrpc-server'
2
- import { ACCESS_FULL, AuthScope } from '../../../../auth-scope.js'
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
- const auth = ctx.authVerifier.authorization({
10
- additional: [AuthScope.Takendown],
11
- scopes: ACCESS_FULL,
12
- authorize: () => {
13
- throw new ForbiddenError(
14
- 'OAuth credentials are not supported for this endpoint',
15
- )
16
- },
17
- })
18
-
19
- if (entrywayClient) {
20
- server.add(com.atproto.server.deactivateAccount, {
21
- auth,
22
- // in the case of entryway, the full flow is deactivateAccount (PDS) -> deactivateAccount (Entryway) -> updateSubjectStatus(PDS)
23
- handler: async ({ input: { body }, req }) => {
24
- const { headers } = ctx.entrywayPassthruHeaders(req)
25
- await entrywayClient.xrpc(com.atproto.server.deactivateAccount, {
26
- headers,
27
- body,
28
- })
29
- },
30
- })
31
- } else {
32
- server.add(com.atproto.server.deactivateAccount, {
33
- auth,
34
- handler: async ({ input: { body }, auth }) => {
35
- await ctx.accountManager.deactivateAccount(auth.credentials.did, {
36
- deleteAfter: body.deleteAfter ?? null,
37
- })
38
- },
39
- })
40
- }
41
- }
@@ -1,85 +0,0 @@
1
- import { MINUTE } from '@atproto/common'
2
- import {
3
- AuthRequiredError,
4
- InvalidRequestError,
5
- MethodRateLimit,
6
- Server,
7
- } from '@atproto/xrpc-server'
8
- import { OLD_PASSWORD_MAX_LENGTH } from '../../../../account-manager/helpers/scrypt.js'
9
- import { AppContext } from '../../../../context.js'
10
- import { com } from '../../../../lexicons/index.js'
11
-
12
- export default function (server: Server, ctx: AppContext) {
13
- const { entrywayClient } = ctx
14
-
15
- const rateLimit: MethodRateLimit = {
16
- durationMs: 5 * MINUTE,
17
- points: 50,
18
- }
19
-
20
- if (entrywayClient) {
21
- server.add(com.atproto.server.deleteAccount, {
22
- rateLimit,
23
- handler: async ({ input: { body }, req }) => {
24
- const account = await ctx.accountManager.getAccount(body.did, {
25
- includeDeactivated: true,
26
- includeTakenDown: true,
27
- })
28
- if (!account) {
29
- throw new InvalidRequestError('account not found')
30
- }
31
-
32
- const { headers } = ctx.entrywayPassthruHeaders(req)
33
- await entrywayClient.xrpc(com.atproto.server.deleteAccount, {
34
- body,
35
- headers,
36
- })
37
- },
38
- })
39
- } else {
40
- server.add(com.atproto.server.deleteAccount, {
41
- rateLimit,
42
- handler: async ({ input: { body } }) => {
43
- const { did, password, token } = body
44
-
45
- if (password.length > OLD_PASSWORD_MAX_LENGTH) {
46
- throw new AuthRequiredError(
47
- 'Password too long. Consider resetting your password.',
48
- )
49
- }
50
-
51
- const account = await ctx.accountManager.getAccount(did, {
52
- includeDeactivated: true,
53
- includeTakenDown: true,
54
- })
55
- if (!account) {
56
- throw new InvalidRequestError('account not found')
57
- }
58
-
59
- const validPass = await ctx.accountManager.verifyAccountPassword(
60
- did,
61
- password,
62
- )
63
- if (!validPass) {
64
- throw new AuthRequiredError('Invalid did or password')
65
- }
66
-
67
- await ctx.accountManager.assertValidEmailToken(
68
- did,
69
- 'delete_account',
70
- token,
71
- )
72
-
73
- // @NOTE Order matters here: first "unlink" the account by removing it
74
- // from the account manager database ("source of truth"), then notify the
75
- // sequencer, and finally cleanup files from the file system.
76
- await ctx.accountManager.deleteAccount(did)
77
- try {
78
- await ctx.sequencer.sequenceAccountDeletion(did)
79
- } finally {
80
- await ctx.actorStore.destroy(did)
81
- }
82
- },
83
- })
84
- }
85
- }