@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
package/src/background.ts DELETED
@@ -1,65 +0,0 @@
1
- import PQueue from 'p-queue'
2
- import { dbLogger } from './logger.js'
3
- // A simple queue for in-process, out-of-band/backgrounded work
4
-
5
- type Task<TContext> = (ctx: TContext, signal: AbortSignal) => Promise<void>
6
-
7
- export type BackgroundQueueOptions = NonNullable<
8
- ConstructorParameters<typeof PQueue>[0]
9
- > & {
10
- concurrency: number
11
- }
12
-
13
- // @NOTE Keep this in sync with the BackgroundQueue in
14
- // - packages/bsky/src/data-plane/server/background.ts
15
- // - packages/ozone/src/background.ts
16
- // - packages/pds/src/background.ts
17
- export class BackgroundQueue<TContext = unknown> {
18
- private abortController = new AbortController()
19
- private queue: PQueue
20
-
21
- public get signal(): AbortSignal {
22
- return this.abortController.signal
23
- }
24
-
25
- public get destroyed() {
26
- return this.signal.aborted
27
- }
28
-
29
- constructor(
30
- private readonly context: TContext,
31
- options?: BackgroundQueueOptions,
32
- ) {
33
- this.queue = new PQueue(options)
34
- }
35
-
36
- add(task: Task<TContext>) {
37
- if (this.destroyed) return
38
-
39
- this.queue.add<void>(async () => {
40
- try {
41
- // The task will receive a signal allowing it to abort if the
42
- // backgroundQueue is destroyed.
43
- await task(this.context, this.signal)
44
- } catch (err) {
45
- dbLogger.error({ err }, 'background queue task failed')
46
- }
47
- })
48
- }
49
-
50
- async processAll() {
51
- const { queue } = this
52
- while (queue.size || queue.pending) await queue.onIdle()
53
- }
54
-
55
- // On destroy we stop accepting new tasks, but complete all pending/in-progress tasks.
56
- // The application calls this only once http connections have drained (tasks no longer being added).
57
- async destroy() {
58
- if (this.destroyed) {
59
- dbLogger.warn('BackgroundQueue.destroy() called multiple times')
60
- }
61
-
62
- this.abortController.abort()
63
- return this.processAll()
64
- }
65
- }
@@ -1,52 +0,0 @@
1
- import { Router } from 'express'
2
- import { sql } from 'kysely'
3
- import { AppContext } from './context.js'
4
-
5
- export const createRouter = (ctx: AppContext): Router => {
6
- const router = Router()
7
-
8
- router.get('/', function (req, res) {
9
- res.type('text/plain')
10
- res.send(`
11
- __ __
12
- /\\ \\__ /\\ \\__
13
- __ \\ \\ ,_\\ _____ _ __ ___\\ \\ ,_\\ ___
14
- /'__'\\ \\ \\ \\/ /\\ '__'\\/\\''__\\/ __'\\ \\ \\/ / __'\\
15
- /\\ \\L\\.\\_\\ \\ \\_\\ \\ \\L\\ \\ \\ \\//\\ \\L\\ \\ \\ \\_/\\ \\L\\ \\
16
- \\ \\__/.\\_\\\\ \\__\\\\ \\ ,__/\\ \\_\\\\ \\____/\\ \\__\\ \\____/
17
- \\/__/\\/_/ \\/__/ \\ \\ \\/ \\/_/ \\/___/ \\/__/\\/___/
18
- \\ \\_\\
19
- \\/_/
20
-
21
-
22
- This is an AT Protocol Personal Data Server (aka, an atproto PDS)
23
-
24
- Most API routes are under /xrpc/
25
-
26
- Code: https://github.com/bluesky-social/atproto
27
- Self-Host: https://github.com/bluesky-social/pds
28
- Protocol: https://atproto.com
29
- `)
30
- })
31
-
32
- router.get('/robots.txt', function (req, res) {
33
- res.type('text/plain')
34
- res.send(
35
- '# Hello!\n\n# Crawling the public API is allowed\nUser-agent: *\nAllow: /',
36
- )
37
- })
38
-
39
- router.get('/xrpc/_health', async function (req, res) {
40
- const { version } = ctx.cfg.service
41
- try {
42
- await sql`select 1`.execute(ctx.accountManager.db.db)
43
- } catch (err) {
44
- req.log.error({ err }, 'failed health check')
45
- res.status(503).send({ version, error: 'Service Unavailable' })
46
- return
47
- }
48
- res.send({ version })
49
- })
50
-
51
- return router
52
- }
@@ -1,33 +0,0 @@
1
- import { format } from 'node:util'
2
- import { Client } from '@atproto/lex'
3
-
4
- export type AppViewOptions = {
5
- url: string
6
- did: string
7
- cdnUrlPattern?: string
8
- validateResponse?: boolean
9
- }
10
-
11
- export class BskyAppView {
12
- public did: string
13
- public url: string
14
- public client: Client
15
- private cdnUrlPattern?: string
16
-
17
- constructor(options: AppViewOptions) {
18
- this.did = options.did
19
- this.url = options.url
20
- this.client = new Client(
21
- { service: options.url },
22
- {
23
- strictResponseProcessing: false,
24
- validateResponse: options.validateResponse ?? false,
25
- },
26
- )
27
- this.cdnUrlPattern = options.cdnUrlPattern
28
- }
29
-
30
- getImageUrl(pattern: string, did: string, cid: string): string | undefined {
31
- if (this.cdnUrlPattern) return format(this.cdnUrlPattern, pattern, did, cid)
32
- }
33
- }
@@ -1,553 +0,0 @@
1
- import assert from 'node:assert'
2
- import path from 'node:path'
3
- import { DAY, HOUR, SECOND } from '@atproto/common'
4
- import {
5
- BrandingInput as BrandingConfig,
6
- HcaptchaConfig,
7
- } from '@atproto/oauth-provider'
8
- import { DidString, ensureValidDid, isValidDid } from '@atproto/syntax'
9
- import { ServerEnvironment } from './env.js'
10
-
11
- export type { BrandingConfig }
12
-
13
- // off-config but still from env:
14
- // logging: LOG_LEVEL, LOG_SYSTEMS, LOG_ENABLED, LOG_DESTINATION
15
-
16
- export const envToCfg = (env: ServerEnvironment): ServerConfig => {
17
- const port = env.port ?? 2583
18
- const hostname = env.hostname ?? 'localhost'
19
- const publicUrl =
20
- hostname === 'localhost'
21
- ? `http://localhost:${port}`
22
- : `https://${hostname}`
23
- const did = env.serviceDid ?? `did:web:${hostname}`
24
-
25
- if (!isValidDid(did)) {
26
- throw new Error(`Invalid service DID: ${did}`)
27
- }
28
-
29
- const serviceCfg: ServerConfig['service'] = {
30
- port,
31
- hostname,
32
- publicUrl,
33
- did,
34
- version: env.version, // default?
35
- privacyPolicyUrl: env.privacyPolicyUrl,
36
- termsOfServiceUrl: env.termsOfServiceUrl,
37
- contactEmailAddress: env.contactEmailAddress,
38
- acceptingImports: env.acceptingImports ?? true,
39
- maxImportSize: env.maxImportSize,
40
- blobUploadLimit: env.blobUploadLimit ?? 5 * 1024 * 1024, // 5mb
41
- devMode: env.devMode ?? false,
42
- }
43
-
44
- const dbLoc = (name: string) => {
45
- return env.dataDirectory ? path.join(env.dataDirectory, name) : name
46
- }
47
-
48
- const disableWalAutoCheckpoint = env.disableWalAutoCheckpoint ?? false
49
-
50
- const dbCfg: ServerConfig['db'] = {
51
- accountDbLoc: env.accountDbLocation ?? dbLoc('account.sqlite'),
52
- sequencerDbLoc: env.sequencerDbLocation ?? dbLoc('sequencer.sqlite'),
53
- didCacheDbLoc: env.didCacheDbLocation ?? dbLoc('did_cache.sqlite'),
54
- disableWalAutoCheckpoint,
55
- }
56
-
57
- const actorStoreCfg: ServerConfig['actorStore'] = {
58
- directory: env.actorStoreDirectory ?? dbLoc('actors'),
59
- cacheSize: env.actorStoreCacheSize ?? 100,
60
- disableWalAutoCheckpoint,
61
- }
62
-
63
- let blobstoreCfg: ServerConfig['blobstore']
64
- if (env.blobstoreS3Bucket && env.blobstoreDiskLocation) {
65
- throw new Error('Cannot set both S3 and disk blobstore env vars')
66
- }
67
- if (env.blobstoreS3Bucket) {
68
- blobstoreCfg = {
69
- provider: 's3',
70
- bucket: env.blobstoreS3Bucket,
71
- uploadTimeoutMs: env.blobstoreS3UploadTimeoutMs || 20000,
72
- region: env.blobstoreS3Region,
73
- endpoint: env.blobstoreS3Endpoint,
74
- forcePathStyle: env.blobstoreS3ForcePathStyle,
75
- }
76
- if (env.blobstoreS3AccessKeyId || env.blobstoreS3SecretAccessKey) {
77
- if (!env.blobstoreS3AccessKeyId || !env.blobstoreS3SecretAccessKey) {
78
- throw new Error(
79
- 'Must specify both S3 access key id and secret access key blobstore env vars',
80
- )
81
- }
82
- blobstoreCfg.credentials = {
83
- accessKeyId: env.blobstoreS3AccessKeyId,
84
- secretAccessKey: env.blobstoreS3SecretAccessKey,
85
- }
86
- }
87
- } else if (env.blobstoreDiskLocation) {
88
- blobstoreCfg = {
89
- provider: 'disk',
90
- location: env.blobstoreDiskLocation,
91
- tempLocation: env.blobstoreDiskTmpLocation,
92
- }
93
- } else {
94
- throw new Error('Must configure either S3 or disk blobstore')
95
- }
96
-
97
- let serviceHandleDomains: string[]
98
- if (env.serviceHandleDomains && env.serviceHandleDomains.length > 0) {
99
- serviceHandleDomains = env.serviceHandleDomains
100
- } else {
101
- if (hostname === 'localhost') {
102
- serviceHandleDomains = ['.test']
103
- } else {
104
- serviceHandleDomains = [`.${hostname}`]
105
- }
106
- }
107
- const invalidDomain = serviceHandleDomains.find(
108
- (domain) => domain.length < 1 || !domain.startsWith('.'),
109
- )
110
- if (invalidDomain) {
111
- throw new Error(`Invalid handle domain: ${invalidDomain}`)
112
- }
113
-
114
- const identityCfg: ServerConfig['identity'] = {
115
- plcUrl: env.didPlcUrl ?? 'https://plc.directory',
116
- cacheMaxTTL: env.didCacheMaxTTL ?? DAY,
117
- cacheStaleTTL: env.didCacheStaleTTL ?? HOUR,
118
- resolverTimeout: env.resolverTimeout ?? 3 * SECOND,
119
- recoveryDidKey: env.recoveryDidKey ?? null,
120
- serviceHandleDomains,
121
- handleBackupNameservers: env.handleBackupNameservers,
122
- enableDidDocWithSession: !!env.enableDidDocWithSession,
123
- }
124
-
125
- let entrywayCfg: ServerConfig['entryway'] = null
126
- if (env.entrywayUrl) {
127
- assert(
128
- env.entrywayJwtVerifyKeyK256PublicKeyHex &&
129
- env.entrywayPlcRotationKey &&
130
- env.entrywayDid,
131
- 'if entryway url is configured, must include all required entryway configuration',
132
- )
133
- entrywayCfg = {
134
- url: env.entrywayUrl,
135
- did: env.entrywayDid,
136
- jwtPublicKeyHex: env.entrywayJwtVerifyKeyK256PublicKeyHex,
137
- plcRotationKey: env.entrywayPlcRotationKey,
138
- }
139
- }
140
-
141
- // default to being required if left undefined
142
- const invitesCfg: ServerConfig['invites'] =
143
- env.inviteRequired === false
144
- ? {
145
- required: false,
146
- }
147
- : {
148
- required: true,
149
- interval: env.inviteInterval ?? null,
150
- epoch: env.inviteEpoch ?? 0,
151
- }
152
-
153
- let emailCfg: ServerConfig['email']
154
- if (!env.emailFromAddress && !env.emailSmtpUrl) {
155
- emailCfg = null
156
- } else {
157
- if (!env.emailFromAddress || !env.emailSmtpUrl) {
158
- throw new Error(
159
- 'Partial email config, must set both emailFromAddress and emailSmtpUrl',
160
- )
161
- }
162
- emailCfg = {
163
- smtpUrl: env.emailSmtpUrl,
164
- fromAddress: env.emailFromAddress,
165
- disableConfirmationLink: env.emailDisableConfirmationLink ?? false,
166
- }
167
- }
168
-
169
- let moderationEmailCfg: ServerConfig['moderationEmail']
170
- if (!env.moderationEmailAddress && !env.moderationEmailSmtpUrl) {
171
- moderationEmailCfg = null
172
- } else {
173
- if (!env.moderationEmailAddress || !env.moderationEmailSmtpUrl) {
174
- throw new Error(
175
- 'Partial moderation email config, must set both emailFromAddress and emailSmtpUrl',
176
- )
177
- }
178
- moderationEmailCfg = {
179
- smtpUrl: env.moderationEmailSmtpUrl,
180
- fromAddress: env.moderationEmailAddress,
181
- disableConfirmationLink: false,
182
- }
183
- }
184
-
185
- const subscriptionCfg: ServerConfig['subscription'] = {
186
- maxBuffer: env.maxSubscriptionBuffer ?? 500,
187
- repoBackfillLimitMs: env.repoBackfillLimitMs ?? DAY,
188
- }
189
-
190
- let bskyAppViewCfg: ServerConfig['bskyAppView'] = null
191
- if (env.bskyAppViewUrl) {
192
- assert(
193
- env.bskyAppViewDid,
194
- 'if bsky appview service url is configured, must configure its did as well.',
195
- )
196
- bskyAppViewCfg = {
197
- url: env.bskyAppViewUrl,
198
- did: env.bskyAppViewDid,
199
- cdnUrlPattern: env.bskyAppViewCdnUrlPattern,
200
- }
201
- }
202
-
203
- let modServiceCfg: ServerConfig['modService'] = null
204
- if (env.modServiceUrl) {
205
- assert(
206
- env.modServiceDid,
207
- 'if mod service url is configured, must configure its did as well.',
208
- )
209
- modServiceCfg = {
210
- url: env.modServiceUrl,
211
- did: env.modServiceDid,
212
- }
213
- }
214
-
215
- let reportServiceCfg: ServerConfig['reportService'] = null
216
- if (env.reportServiceUrl) {
217
- assert(
218
- env.reportServiceDid,
219
- 'if report service url is configured, must configure its did as well.',
220
- )
221
- reportServiceCfg = {
222
- url: env.reportServiceUrl,
223
- did: env.reportServiceDid,
224
- }
225
- }
226
-
227
- // if there's a mod service, default report service into it
228
- if (modServiceCfg && !reportServiceCfg) {
229
- reportServiceCfg = modServiceCfg
230
- }
231
-
232
- const redisCfg: ServerConfig['redis'] = env.redisScratchAddress
233
- ? {
234
- address: env.redisScratchAddress,
235
- password: env.redisScratchPassword,
236
- }
237
- : null
238
-
239
- const rateLimitsCfg: ServerConfig['rateLimits'] = env.rateLimitsEnabled
240
- ? {
241
- enabled: true,
242
- bypassKey: env.rateLimitBypassKey,
243
- bypassIps: env.rateLimitBypassIps?.map((ipOrCidr) =>
244
- ipOrCidr.split('/')[0]?.trim(),
245
- ),
246
- }
247
- : { enabled: false }
248
-
249
- const crawlersCfg: ServerConfig['crawlers'] = env.crawlers ?? []
250
-
251
- const fetchCfg: ServerConfig['fetch'] = {
252
- disableSsrfProtection: env.disableSsrfProtection ?? env.devMode ?? false,
253
- maxResponseSize: env.fetchMaxResponseSize ?? 512 * 1024, // 512kb
254
- }
255
-
256
- const proxyCfg: ServerConfig['proxy'] = {
257
- disableSsrfProtection: env.disableSsrfProtection ?? env.devMode ?? false,
258
- allowHTTP2: env.proxyAllowHTTP2 ?? false,
259
- headersTimeout: env.proxyHeadersTimeout ?? 10e3,
260
- bodyTimeout: env.proxyBodyTimeout ?? 30e3,
261
- maxResponseSize: env.proxyMaxResponseSize ?? 10 * 1024 * 1024, // 10mb
262
- maxRetries:
263
- env.proxyMaxRetries != null && env.proxyMaxRetries > 0
264
- ? env.proxyMaxRetries
265
- : 0,
266
- preferCompressed: env.proxyPreferCompressed ?? false,
267
- }
268
-
269
- const brandingCfg = {
270
- name: env.serviceName ?? `${hostname} PDS`,
271
- logo: env.logoUrl,
272
- colors: {
273
- light: env.lightColor,
274
- dark: env.darkColor,
275
-
276
- contrastSaturation: env.contrastSaturation,
277
-
278
- primary: env.primaryColor,
279
- primaryContrast: env.primaryColorContrast,
280
- primaryHue: env.primaryColorHue,
281
-
282
- error: env.errorColor,
283
- errorContrast: env.errorColorContrast,
284
- errorHue: env.errorColorHue,
285
-
286
- warning: env.warningColor,
287
- warningContrast: env.warningColorContrast,
288
- warningHue: env.warningColorHue,
289
-
290
- info: env.infoColor,
291
- infoContrast: env.infoColorContrast,
292
- infoHue: env.infoColorHue,
293
-
294
- success: env.successColor,
295
- successContrast: env.successColorContrast,
296
- successHue: env.successColorHue,
297
- },
298
- links: [
299
- {
300
- title: { en: 'Home', fr: 'Accueil' },
301
- href: env.homeUrl,
302
- rel: 'canonical' as const, // Prevents login page from being indexed
303
- },
304
- {
305
- title: { en: 'Terms of Service' },
306
- href: env.termsOfServiceUrl,
307
- rel: 'terms-of-service' as const,
308
- },
309
- {
310
- title: { en: 'Privacy Policy' },
311
- href: env.privacyPolicyUrl,
312
- rel: 'privacy-policy' as const,
313
- },
314
- {
315
- title: { en: 'Support' },
316
- href: env.supportUrl,
317
- rel: 'help' as const,
318
- },
319
- ].filter(
320
- <T extends { href?: string }>(f: T): f is T & { href: string } =>
321
- f.href != null && f.href !== '',
322
- ),
323
- }
324
-
325
- const oauthCfg: ServerConfig['oauth'] = entrywayCfg
326
- ? {
327
- issuer: entrywayCfg.url,
328
- provider: undefined,
329
- }
330
- : {
331
- issuer: serviceCfg.publicUrl,
332
- provider: {
333
- hcaptcha:
334
- env.hcaptchaSiteKey &&
335
- env.hcaptchaSecretKey &&
336
- env.hcaptchaTokenSalt
337
- ? {
338
- siteKey: env.hcaptchaSiteKey,
339
- secretKey: env.hcaptchaSecretKey,
340
- tokenSalt: env.hcaptchaTokenSalt,
341
- }
342
- : undefined,
343
- branding: brandingCfg,
344
- trustedClients: env.trustedOAuthClients,
345
- },
346
- }
347
-
348
- const lexiconCfg: LexiconResolverConfig = {}
349
-
350
- if (env.lexiconDidAuthority != null) {
351
- ensureValidDid(env.lexiconDidAuthority)
352
- lexiconCfg.didAuthority = env.lexiconDidAuthority
353
- }
354
-
355
- return {
356
- service: serviceCfg,
357
- db: dbCfg,
358
- actorStore: actorStoreCfg,
359
- blobstore: blobstoreCfg,
360
- identity: identityCfg,
361
- entryway: entrywayCfg,
362
- invites: invitesCfg,
363
- email: emailCfg,
364
- moderationEmail: moderationEmailCfg,
365
- subscription: subscriptionCfg,
366
- bskyAppView: bskyAppViewCfg,
367
- modService: modServiceCfg,
368
- reportService: reportServiceCfg,
369
- redis: redisCfg,
370
- rateLimits: rateLimitsCfg,
371
- crawlers: crawlersCfg,
372
- fetch: fetchCfg,
373
- lexicon: lexiconCfg,
374
- proxy: proxyCfg,
375
- branding: brandingCfg,
376
- oauth: oauthCfg,
377
- }
378
- }
379
-
380
- export type ServerConfig = {
381
- service: ServiceConfig
382
- db: DatabaseConfig
383
- actorStore: ActorStoreConfig
384
- blobstore: S3BlobstoreConfig | DiskBlobstoreConfig
385
- identity: IdentityConfig
386
- entryway: EntrywayConfig | null
387
- invites: InvitesConfig
388
- email: EmailConfig | null
389
- moderationEmail: EmailConfig | null
390
- subscription: SubscriptionConfig
391
- bskyAppView: BksyAppViewConfig | null
392
- modService: ModServiceConfig | null
393
- reportService: ReportServiceConfig | null
394
- redis: RedisScratchConfig | null
395
- rateLimits: RateLimitsConfig
396
- crawlers: string[]
397
- fetch: FetchConfig
398
- proxy: ProxyConfig
399
- branding: BrandingConfig
400
- oauth: OAuthConfig
401
- lexicon: LexiconResolverConfig
402
- }
403
-
404
- export type ServiceConfig = {
405
- port: number
406
- hostname: string
407
- publicUrl: string
408
- did: DidString
409
- version?: string
410
- privacyPolicyUrl?: string
411
- termsOfServiceUrl?: string
412
- acceptingImports: boolean
413
- maxImportSize?: number
414
- blobUploadLimit: number
415
- contactEmailAddress?: string
416
- devMode: boolean
417
- }
418
-
419
- export type DatabaseConfig = {
420
- accountDbLoc: string
421
- sequencerDbLoc: string
422
- didCacheDbLoc: string
423
- disableWalAutoCheckpoint: boolean
424
- }
425
-
426
- export type ActorStoreConfig = {
427
- directory: string
428
- cacheSize: number
429
- disableWalAutoCheckpoint: boolean
430
- }
431
-
432
- export type S3BlobstoreConfig = {
433
- provider: 's3'
434
- bucket: string
435
- region?: string
436
- endpoint?: string
437
- forcePathStyle?: boolean
438
- uploadTimeoutMs?: number
439
- credentials?: {
440
- accessKeyId: string
441
- secretAccessKey: string
442
- }
443
- }
444
-
445
- export type DiskBlobstoreConfig = {
446
- provider: 'disk'
447
- location: string
448
- tempLocation?: string
449
- }
450
-
451
- export type IdentityConfig = {
452
- plcUrl: string
453
- resolverTimeout: number
454
- cacheStaleTTL: number
455
- cacheMaxTTL: number
456
- recoveryDidKey: string | null
457
- serviceHandleDomains: string[]
458
- handleBackupNameservers?: string[]
459
- enableDidDocWithSession: boolean
460
- }
461
-
462
- export type EntrywayConfig = {
463
- url: string
464
- did: string
465
- jwtPublicKeyHex: string
466
- plcRotationKey: string
467
- }
468
-
469
- export type FetchConfig = {
470
- disableSsrfProtection: boolean
471
- maxResponseSize: number
472
- }
473
-
474
- export type ProxyConfig = {
475
- disableSsrfProtection: boolean
476
- allowHTTP2: boolean
477
- headersTimeout: number
478
- bodyTimeout: number
479
- maxResponseSize: number
480
- maxRetries: number
481
-
482
- /**
483
- * When proxying requests that might get intercepted (for read-after-write) we
484
- * negotiate the encoding based on the client's preferences. We will however
485
- * use or own weights in order to be able to better control if the PDS will
486
- * need to perform content decoding. This settings allows to prefer compressed
487
- * content over uncompressed one.
488
- */
489
- preferCompressed: boolean
490
- }
491
-
492
- export type OAuthConfig = {
493
- issuer: string
494
- provider?: {
495
- hcaptcha?: HcaptchaConfig
496
- branding: BrandingConfig
497
- trustedClients?: string[]
498
- }
499
- }
500
-
501
- export type LexiconResolverConfig = {
502
- didAuthority?: `did:${string}:${string}`
503
- }
504
-
505
- export type InvitesConfig =
506
- | {
507
- required: true
508
- interval: number | null
509
- epoch: number
510
- }
511
- | {
512
- required: false
513
- }
514
-
515
- export type EmailConfig = {
516
- smtpUrl: string
517
- fromAddress: string
518
- disableConfirmationLink: boolean
519
- }
520
-
521
- export type SubscriptionConfig = {
522
- maxBuffer: number
523
- repoBackfillLimitMs: number
524
- }
525
-
526
- export type RedisScratchConfig = {
527
- address: string
528
- password?: string
529
- }
530
-
531
- export type RateLimitsConfig =
532
- | {
533
- enabled: true
534
- bypassKey?: string
535
- bypassIps?: string[]
536
- }
537
- | { enabled: false }
538
-
539
- export type BksyAppViewConfig = {
540
- url: string
541
- did: string
542
- cdnUrlPattern?: string
543
- }
544
-
545
- export type ModServiceConfig = {
546
- url: string
547
- did: string
548
- }
549
-
550
- export type ReportServiceConfig = {
551
- url: string
552
- did: string
553
- }