@atproto/pds 0.5.11 → 0.5.14

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