@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,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
- }