@atproto/pds 0.5.12 → 0.5.15

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 (326) hide show
  1. package/CHANGELOG.md +53 -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/dist/lexicons/app/bsky/actor/defs.defs.d.ts +6 -0
  10. package/dist/lexicons/app/bsky/actor/defs.defs.d.ts.map +1 -1
  11. package/dist/lexicons/app/bsky/actor/defs.defs.js +1 -0
  12. package/dist/lexicons/app/bsky/actor/defs.defs.js.map +1 -1
  13. package/package.json +42 -38
  14. package/build.templates.cjs +0 -22
  15. package/example.env +0 -42
  16. package/jest.config.cjs +0 -27
  17. package/src/account-manager/account-manager.ts +0 -916
  18. package/src/account-manager/db/index.ts +0 -21
  19. package/src/account-manager/db/migrations/001-init.ts +0 -115
  20. package/src/account-manager/db/migrations/002-account-deactivation.ts +0 -17
  21. package/src/account-manager/db/migrations/003-privileged-app-passwords.ts +0 -12
  22. package/src/account-manager/db/migrations/004-oauth.ts +0 -122
  23. package/src/account-manager/db/migrations/005-oauth-account-management.ts +0 -136
  24. package/src/account-manager/db/migrations/006-oauth-permission-sets.ts +0 -20
  25. package/src/account-manager/db/migrations/007-lexicon-failures-index.ts +0 -14
  26. package/src/account-manager/db/migrations/index.ts +0 -17
  27. package/src/account-manager/db/schema/account-device.ts +0 -14
  28. package/src/account-manager/db/schema/account.ts +0 -16
  29. package/src/account-manager/db/schema/actor.ts +0 -17
  30. package/src/account-manager/db/schema/app-password.ts +0 -13
  31. package/src/account-manager/db/schema/authorization-request.ts +0 -30
  32. package/src/account-manager/db/schema/authorized-client.ts +0 -23
  33. package/src/account-manager/db/schema/device.ts +0 -18
  34. package/src/account-manager/db/schema/email-token.ts +0 -19
  35. package/src/account-manager/db/schema/index.ts +0 -43
  36. package/src/account-manager/db/schema/invite-code.ts +0 -24
  37. package/src/account-manager/db/schema/lexicon.ts +0 -15
  38. package/src/account-manager/db/schema/refresh-token.ts +0 -11
  39. package/src/account-manager/db/schema/repo-root.ts +0 -12
  40. package/src/account-manager/db/schema/token.ts +0 -38
  41. package/src/account-manager/db/schema/used-refresh-token.ts +0 -13
  42. package/src/account-manager/helpers/account-device.ts +0 -63
  43. package/src/account-manager/helpers/account.ts +0 -355
  44. package/src/account-manager/helpers/auth.ts +0 -222
  45. package/src/account-manager/helpers/authorization-request.ts +0 -90
  46. package/src/account-manager/helpers/authorized-client.ts +0 -75
  47. package/src/account-manager/helpers/device.ts +0 -47
  48. package/src/account-manager/helpers/email-token.ts +0 -87
  49. package/src/account-manager/helpers/invite.ts +0 -263
  50. package/src/account-manager/helpers/lexicon.ts +0 -67
  51. package/src/account-manager/helpers/password.ts +0 -136
  52. package/src/account-manager/helpers/repo.ts +0 -24
  53. package/src/account-manager/helpers/scrypt.ts +0 -53
  54. package/src/account-manager/helpers/token.ts +0 -158
  55. package/src/account-manager/helpers/used-refresh-token.ts +0 -30
  56. package/src/account-manager/oauth-store.ts +0 -880
  57. package/src/account-manager/scope-reference-getter.ts +0 -106
  58. package/src/actor-store/actor-store-reader.ts +0 -45
  59. package/src/actor-store/actor-store-resources.ts +0 -8
  60. package/src/actor-store/actor-store-transactor.ts +0 -31
  61. package/src/actor-store/actor-store-writer.ts +0 -17
  62. package/src/actor-store/actor-store.ts +0 -210
  63. package/src/actor-store/blob/reader.ts +0 -160
  64. package/src/actor-store/blob/transactor.ts +0 -383
  65. package/src/actor-store/db/index.ts +0 -20
  66. package/src/actor-store/db/migrations/001-init.ts +0 -105
  67. package/src/actor-store/db/migrations/index.ts +0 -5
  68. package/src/actor-store/db/schema/account-pref.ts +0 -11
  69. package/src/actor-store/db/schema/backlink.ts +0 -9
  70. package/src/actor-store/db/schema/blob.ts +0 -14
  71. package/src/actor-store/db/schema/index.ts +0 -23
  72. package/src/actor-store/db/schema/record-blob.ts +0 -8
  73. package/src/actor-store/db/schema/record.ts +0 -14
  74. package/src/actor-store/db/schema/repo-block.ts +0 -10
  75. package/src/actor-store/db/schema/repo-root.ts +0 -10
  76. package/src/actor-store/migrate.ts +0 -39
  77. package/src/actor-store/preference/reader.ts +0 -48
  78. package/src/actor-store/preference/transactor.ts +0 -55
  79. package/src/actor-store/preference/util.ts +0 -39
  80. package/src/actor-store/record/reader.ts +0 -374
  81. package/src/actor-store/record/transactor.ts +0 -111
  82. package/src/actor-store/repo/reader.ts +0 -31
  83. package/src/actor-store/repo/sql-repo-reader.ts +0 -150
  84. package/src/actor-store/repo/sql-repo-transactor.ts +0 -105
  85. package/src/actor-store/repo/transactor.ts +0 -227
  86. package/src/api/app/bsky/actor/getPreferences.ts +0 -57
  87. package/src/api/app/bsky/actor/getProfile.ts +0 -41
  88. package/src/api/app/bsky/actor/getProfiles.ts +0 -51
  89. package/src/api/app/bsky/actor/index.ts +0 -13
  90. package/src/api/app/bsky/actor/putPreferences.ts +0 -62
  91. package/src/api/app/bsky/feed/getActorLikes.ts +0 -63
  92. package/src/api/app/bsky/feed/getAuthorFeed.ts +0 -84
  93. package/src/api/app/bsky/feed/getFeed.ts +0 -47
  94. package/src/api/app/bsky/feed/getPostThread.ts +0 -251
  95. package/src/api/app/bsky/feed/getTimeline.ts +0 -50
  96. package/src/api/app/bsky/feed/index.ts +0 -15
  97. package/src/api/app/bsky/index.ts +0 -11
  98. package/src/api/app/bsky/notification/index.ts +0 -7
  99. package/src/api/app/bsky/notification/registerPush.ts +0 -71
  100. package/src/api/app/bsky/util/resolver.ts +0 -20
  101. package/src/api/com/atproto/admin/deleteAccount.ts +0 -22
  102. package/src/api/com/atproto/admin/disableAccountInvites.ts +0 -18
  103. package/src/api/com/atproto/admin/disableInviteCodes.ts +0 -21
  104. package/src/api/com/atproto/admin/enableAccountInvites.ts +0 -18
  105. package/src/api/com/atproto/admin/getAccountInfo.ts +0 -32
  106. package/src/api/com/atproto/admin/getAccountInfos.ts +0 -34
  107. package/src/api/com/atproto/admin/getInviteCodes.ts +0 -126
  108. package/src/api/com/atproto/admin/getSubjectStatus.ts +0 -76
  109. package/src/api/com/atproto/admin/index.ts +0 -31
  110. package/src/api/com/atproto/admin/sendEmail.ts +0 -47
  111. package/src/api/com/atproto/admin/updateAccountEmail.ts +0 -32
  112. package/src/api/com/atproto/admin/updateAccountHandle.ts +0 -47
  113. package/src/api/com/atproto/admin/updateAccountPassword.ts +0 -34
  114. package/src/api/com/atproto/admin/updateSubjectStatus.ts +0 -68
  115. package/src/api/com/atproto/admin/util.ts +0 -66
  116. package/src/api/com/atproto/identity/getRecommendedDidCredentials.ts +0 -50
  117. package/src/api/com/atproto/identity/index.ts +0 -17
  118. package/src/api/com/atproto/identity/requestPlcOperationSignature.ts +0 -59
  119. package/src/api/com/atproto/identity/resolveHandle.ts +0 -50
  120. package/src/api/com/atproto/identity/signPlcOperation.ts +0 -85
  121. package/src/api/com/atproto/identity/submitPlcOperation.ts +0 -65
  122. package/src/api/com/atproto/identity/updateHandle.ts +0 -66
  123. package/src/api/com/atproto/index.ts +0 -19
  124. package/src/api/com/atproto/moderation/createReport.ts +0 -41
  125. package/src/api/com/atproto/moderation/index.ts +0 -7
  126. package/src/api/com/atproto/repo/applyWrites.ts +0 -226
  127. package/src/api/com/atproto/repo/createRecord.ts +0 -143
  128. package/src/api/com/atproto/repo/deleteRecord.ts +0 -122
  129. package/src/api/com/atproto/repo/describeRepo.ts +0 -43
  130. package/src/api/com/atproto/repo/getRecord.ts +0 -40
  131. package/src/api/com/atproto/repo/importRepo.ts +0 -101
  132. package/src/api/com/atproto/repo/index.ts +0 -25
  133. package/src/api/com/atproto/repo/listMissingBlobs.ts +0 -29
  134. package/src/api/com/atproto/repo/listRecords.ts +0 -36
  135. package/src/api/com/atproto/repo/putRecord.ts +0 -211
  136. package/src/api/com/atproto/repo/uploadBlob.ts +0 -60
  137. package/src/api/com/atproto/server/activateAccount.ts +0 -37
  138. package/src/api/com/atproto/server/checkAccountStatus.ts +0 -51
  139. package/src/api/com/atproto/server/confirmEmail.ts +0 -39
  140. package/src/api/com/atproto/server/createAccount.ts +0 -327
  141. package/src/api/com/atproto/server/createAppPassword.ts +0 -53
  142. package/src/api/com/atproto/server/createInviteCode.ts +0 -38
  143. package/src/api/com/atproto/server/createInviteCodes.ts +0 -42
  144. package/src/api/com/atproto/server/createSession.ts +0 -97
  145. package/src/api/com/atproto/server/deactivateAccount.ts +0 -41
  146. package/src/api/com/atproto/server/deleteAccount.ts +0 -85
  147. package/src/api/com/atproto/server/deleteSession.ts +0 -23
  148. package/src/api/com/atproto/server/describeServer.ts +0 -29
  149. package/src/api/com/atproto/server/getAccountInviteCodes.ts +0 -142
  150. package/src/api/com/atproto/server/getServiceAuth.ts +0 -111
  151. package/src/api/com/atproto/server/getSession.ts +0 -80
  152. package/src/api/com/atproto/server/index.ts +0 -55
  153. package/src/api/com/atproto/server/listAppPasswords.ts +0 -45
  154. package/src/api/com/atproto/server/refreshSession.ts +0 -72
  155. package/src/api/com/atproto/server/requestAccountDelete.ts +0 -66
  156. package/src/api/com/atproto/server/requestEmailConfirmation.ts +0 -68
  157. package/src/api/com/atproto/server/requestEmailUpdate.ts +0 -86
  158. package/src/api/com/atproto/server/requestPasswordReset.ts +0 -52
  159. package/src/api/com/atproto/server/reserveSigningKey.ts +0 -15
  160. package/src/api/com/atproto/server/resetPassword.ts +0 -50
  161. package/src/api/com/atproto/server/revokeAppPassword.ts +0 -42
  162. package/src/api/com/atproto/server/updateEmail.ts +0 -52
  163. package/src/api/com/atproto/server/util.ts +0 -136
  164. package/src/api/com/atproto/sync/deprecated/getCheckout.ts +0 -27
  165. package/src/api/com/atproto/sync/deprecated/getHead.ts +0 -33
  166. package/src/api/com/atproto/sync/getBlob.ts +0 -61
  167. package/src/api/com/atproto/sync/getBlocks.ts +0 -37
  168. package/src/api/com/atproto/sync/getLatestCommit.ts +0 -33
  169. package/src/api/com/atproto/sync/getRecord.ts +0 -49
  170. package/src/api/com/atproto/sync/getRepo.ts +0 -75
  171. package/src/api/com/atproto/sync/getRepoStatus.ts +0 -34
  172. package/src/api/com/atproto/sync/index.ts +0 -27
  173. package/src/api/com/atproto/sync/listBlobs.ts +0 -33
  174. package/src/api/com/atproto/sync/listRepos.ts +0 -74
  175. package/src/api/com/atproto/sync/subscribeRepos.ts +0 -73
  176. package/src/api/com/atproto/sync/util.ts +0 -37
  177. package/src/api/com/atproto/temp/checkSignupQueue.ts +0 -34
  178. package/src/api/com/atproto/temp/index.ts +0 -7
  179. package/src/api/index.ts +0 -10
  180. package/src/api/proxy.ts +0 -44
  181. package/src/app-view.ts +0 -24
  182. package/src/auth-output.ts +0 -52
  183. package/src/auth-routes.ts +0 -64
  184. package/src/auth-scope.ts +0 -40
  185. package/src/auth-verifier.ts +0 -668
  186. package/src/background.ts +0 -65
  187. package/src/basic-routes.ts +0 -52
  188. package/src/bsky-app-view.ts +0 -33
  189. package/src/config/config.ts +0 -553
  190. package/src/config/env.ts +0 -167
  191. package/src/config/index.ts +0 -3
  192. package/src/config/secrets.ts +0 -54
  193. package/src/context.ts +0 -523
  194. package/src/crawlers.ts +0 -46
  195. package/src/db/cast.ts +0 -52
  196. package/src/db/db.ts +0 -140
  197. package/src/db/index.ts +0 -4
  198. package/src/db/migrator.ts +0 -40
  199. package/src/db/pagination.ts +0 -132
  200. package/src/db/tables/moderation.ts +0 -80
  201. package/src/db/util.ts +0 -108
  202. package/src/did-cache/db/index.ts +0 -21
  203. package/src/did-cache/db/migrations.ts +0 -17
  204. package/src/did-cache/db/schema.ts +0 -9
  205. package/src/did-cache/index.ts +0 -131
  206. package/src/disk-blobstore.ts +0 -172
  207. package/src/error.ts +0 -19
  208. package/src/handle/explicit-slurs.ts +0 -22
  209. package/src/handle/index.ts +0 -49
  210. package/src/handle/reserved.ts +0 -1059
  211. package/src/image/image-url-builder.ts +0 -16
  212. package/src/index.ts +0 -189
  213. package/src/lexicons.ts +0 -4
  214. package/src/logger.ts +0 -35
  215. package/src/mailer/index.ts +0 -111
  216. package/src/mailer/moderation.ts +0 -33
  217. package/src/mailer/templates/confirm-email.d.ts +0 -4
  218. package/src/mailer/templates/confirm-email.hbs +0 -158
  219. package/src/mailer/templates/delete-account.d.ts +0 -4
  220. package/src/mailer/templates/delete-account.hbs +0 -156
  221. package/src/mailer/templates/plc-operation.d.ts +0 -4
  222. package/src/mailer/templates/plc-operation.hbs +0 -153
  223. package/src/mailer/templates/reset-password.d.ts +0 -4
  224. package/src/mailer/templates/reset-password.hbs +0 -154
  225. package/src/mailer/templates/update-email.d.ts +0 -4
  226. package/src/mailer/templates/update-email.hbs +0 -153
  227. package/src/mailer/templates.ts +0 -17
  228. package/src/pipethrough.ts +0 -716
  229. package/src/rate-limits.ts +0 -59
  230. package/src/read-after-write/index.ts +0 -3
  231. package/src/read-after-write/types.ts +0 -35
  232. package/src/read-after-write/util.ts +0 -101
  233. package/src/read-after-write/viewer.ts +0 -290
  234. package/src/redis.ts +0 -25
  235. package/src/repo/index.ts +0 -2
  236. package/src/repo/prepare.ts +0 -266
  237. package/src/repo/types.ts +0 -65
  238. package/src/scripts/README.md +0 -40
  239. package/src/scripts/index.ts +0 -20
  240. package/src/scripts/publish-identity.ts +0 -60
  241. package/src/scripts/rebuild-repo.ts +0 -119
  242. package/src/scripts/rotate-keys.ts +0 -146
  243. package/src/scripts/sequencer-recovery/index.ts +0 -23
  244. package/src/scripts/sequencer-recovery/recoverer.ts +0 -297
  245. package/src/scripts/sequencer-recovery/recovery-db.ts +0 -65
  246. package/src/scripts/sequencer-recovery/repair-repos.ts +0 -49
  247. package/src/scripts/sequencer-recovery/user-queues.ts +0 -44
  248. package/src/scripts/util.ts +0 -7
  249. package/src/sequencer/db/index.ts +0 -21
  250. package/src/sequencer/db/migrations/001-init.ts +0 -35
  251. package/src/sequencer/db/migrations/index.ts +0 -5
  252. package/src/sequencer/db/schema.ts +0 -19
  253. package/src/sequencer/events.ts +0 -199
  254. package/src/sequencer/index.ts +0 -3
  255. package/src/sequencer/outbox.ts +0 -123
  256. package/src/sequencer/sequencer.ts +0 -290
  257. package/src/util/compression.ts +0 -16
  258. package/src/util/debug.ts +0 -10
  259. package/src/util/http.ts +0 -31
  260. package/src/util/types.ts +0 -7
  261. package/src/well-known.ts +0 -30
  262. package/test.env +0 -2
  263. package/tests/__snapshots__/takedown-appeal.test.ts.snap +0 -43
  264. package/tests/_oauth_client_assets_middleware.ts +0 -23
  265. package/tests/_puppeteer.ts +0 -147
  266. package/tests/_types.d.ts +0 -16
  267. package/tests/_util.ts +0 -191
  268. package/tests/account-deactivation.test.ts +0 -204
  269. package/tests/account-deletion.test.ts +0 -300
  270. package/tests/account-manager.test.ts +0 -462
  271. package/tests/account-migration.test.ts +0 -221
  272. package/tests/account-status.test.ts +0 -206
  273. package/tests/account.test.ts +0 -595
  274. package/tests/app-passwords.test.ts +0 -262
  275. package/tests/auth.test.ts +0 -405
  276. package/tests/blob-deletes.test.ts +0 -204
  277. package/tests/create-post.test.ts +0 -79
  278. package/tests/crud.test.ts +0 -1595
  279. package/tests/db.test.ts +0 -170
  280. package/tests/email-confirmation.test.ts +0 -227
  281. package/tests/entryway-mock.ts +0 -323
  282. package/tests/entryway.test.ts +0 -145
  283. package/tests/file-uploads.test.ts +0 -301
  284. package/tests/get-service-auth.test.ts +0 -81
  285. package/tests/handle-validation.test.ts +0 -56
  286. package/tests/handles.test.ts +0 -274
  287. package/tests/invite-codes.test.ts +0 -367
  288. package/tests/invites-admin.test.ts +0 -252
  289. package/tests/moderation.test.ts +0 -280
  290. package/tests/moderator-auth.test.ts +0 -177
  291. package/tests/oauth.test.ts +0 -334
  292. package/tests/plc-operations.test.ts +0 -239
  293. package/tests/preferences.test.ts +0 -352
  294. package/tests/proxied/__snapshots__/admin.test.ts.snap +0 -516
  295. package/tests/proxied/__snapshots__/feedgen.test.ts.snap +0 -215
  296. package/tests/proxied/__snapshots__/views.test.ts.snap +0 -4456
  297. package/tests/proxied/admin.test.ts +0 -340
  298. package/tests/proxied/feedgen.test.ts +0 -66
  299. package/tests/proxied/notif.test.ts +0 -85
  300. package/tests/proxied/procedures.test.ts +0 -175
  301. package/tests/proxied/proxy-catchall.test.ts +0 -256
  302. package/tests/proxied/proxy-header.test.ts +0 -239
  303. package/tests/proxied/proxy-oauth-aud.test.ts +0 -182
  304. package/tests/proxied/read-after-write.test.ts +0 -382
  305. package/tests/proxied/views.test.ts +0 -608
  306. package/tests/races.test.ts +0 -89
  307. package/tests/rate-limits.test.ts +0 -70
  308. package/tests/recovery.test.ts +0 -180
  309. package/tests/seeds/basic.ts +0 -165
  310. package/tests/seeds/follows.ts +0 -57
  311. package/tests/seeds/likes.ts +0 -14
  312. package/tests/seeds/reposts.ts +0 -18
  313. package/tests/seeds/thread.ts +0 -40
  314. package/tests/seeds/users-bulk.ts +0 -246
  315. package/tests/seeds/users.ts +0 -67
  316. package/tests/sequencer.test.ts +0 -251
  317. package/tests/server.test.ts +0 -151
  318. package/tests/sync/invertible-ops.test.ts +0 -99
  319. package/tests/sync/list.test.ts +0 -43
  320. package/tests/sync/subscribe-repos.test.ts +0 -672
  321. package/tests/sync/sync.test.ts +0 -316
  322. package/tests/takedown-appeal.test.ts +0 -166
  323. package/tsconfig.build.json +0 -9
  324. package/tsconfig.build.tsbuildinfo +0 -1
  325. package/tsconfig.json +0 -7
  326. 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
- }