@atproto/bsky 0.0.250 → 0.0.253

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 (473) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/dist/api/age-assurance/const.js +19 -19
  3. package/dist/api/age-assurance/const.js.map +1 -1
  4. package/dist/api/app/bsky/feed/getFeed.d.ts.map +1 -1
  5. package/dist/api/app/bsky/feed/getFeed.js +4 -0
  6. package/dist/api/app/bsky/feed/getFeed.js.map +1 -1
  7. package/dist/api/app/bsky/feed/searchPosts.js +5 -0
  8. package/dist/api/app/bsky/feed/searchPosts.js.map +1 -1
  9. package/dist/api/app/bsky/feed/searchPostsV2.js +5 -0
  10. package/dist/api/app/bsky/feed/searchPostsV2.js.map +1 -1
  11. package/dist/config.d.ts +2 -0
  12. package/dist/config.d.ts.map +1 -1
  13. package/dist/config.js +5 -0
  14. package/dist/config.js.map +1 -1
  15. package/dist/hydration/feed.d.ts +1 -2
  16. package/dist/hydration/feed.d.ts.map +1 -1
  17. package/dist/hydration/feed.js.map +1 -1
  18. package/dist/kws.d.ts +8 -0
  19. package/dist/kws.d.ts.map +1 -1
  20. package/dist/kws.js +53 -4
  21. package/dist/kws.js.map +1 -1
  22. package/package.json +28 -23
  23. package/bin/migration-create.ts +0 -46
  24. package/buf.gen.yaml +0 -12
  25. package/proto/bsky.proto +0 -1907
  26. package/proto/courier.proto +0 -84
  27. package/proto/rolodex.proto +0 -116
  28. package/src/api/age-assurance/const.ts +0 -203
  29. package/src/api/age-assurance/index.ts +0 -34
  30. package/src/api/age-assurance/kws/age-verified.test.ts +0 -98
  31. package/src/api/age-assurance/kws/age-verified.ts +0 -81
  32. package/src/api/age-assurance/kws/const.ts +0 -33
  33. package/src/api/age-assurance/kws/external-payload.test.ts +0 -72
  34. package/src/api/age-assurance/kws/external-payload.ts +0 -149
  35. package/src/api/age-assurance/redirects/kws-age-verified.ts +0 -107
  36. package/src/api/age-assurance/stash.ts +0 -23
  37. package/src/api/age-assurance/types.ts +0 -10
  38. package/src/api/age-assurance/util.ts +0 -68
  39. package/src/api/age-assurance/webhooks/kws-age-verified.ts +0 -75
  40. package/src/api/app/bsky/actor/getProfile.ts +0 -106
  41. package/src/api/app/bsky/actor/getProfiles.ts +0 -99
  42. package/src/api/app/bsky/actor/getSuggestions.ts +0 -163
  43. package/src/api/app/bsky/actor/searchActors.ts +0 -171
  44. package/src/api/app/bsky/actor/searchActorsTypeahead.ts +0 -164
  45. package/src/api/app/bsky/ageassurance/begin.ts +0 -175
  46. package/src/api/app/bsky/ageassurance/getConfig.ts +0 -16
  47. package/src/api/app/bsky/ageassurance/getState.ts +0 -58
  48. package/src/api/app/bsky/bookmark/createBookmark.ts +0 -39
  49. package/src/api/app/bsky/bookmark/deleteBookmark.ts +0 -32
  50. package/src/api/app/bsky/bookmark/getBookmarks.ts +0 -97
  51. package/src/api/app/bsky/bookmark/util.ts +0 -13
  52. package/src/api/app/bsky/contact/dismissMatch.ts +0 -26
  53. package/src/api/app/bsky/contact/getMatches.ts +0 -111
  54. package/src/api/app/bsky/contact/getSyncStatus.ts +0 -38
  55. package/src/api/app/bsky/contact/importContacts.ts +0 -119
  56. package/src/api/app/bsky/contact/removeData.ts +0 -25
  57. package/src/api/app/bsky/contact/sendNotification.ts +0 -33
  58. package/src/api/app/bsky/contact/startPhoneVerification.ts +0 -26
  59. package/src/api/app/bsky/contact/util.ts +0 -92
  60. package/src/api/app/bsky/contact/verifyPhone.ts +0 -29
  61. package/src/api/app/bsky/draft/createDraft.ts +0 -45
  62. package/src/api/app/bsky/draft/deleteDraft.ts +0 -20
  63. package/src/api/app/bsky/draft/getDrafts.ts +0 -44
  64. package/src/api/app/bsky/draft/updateDraft.ts +0 -26
  65. package/src/api/app/bsky/embed/getEmbedExternalView.ts +0 -154
  66. package/src/api/app/bsky/feed/getActorFeeds.ts +0 -101
  67. package/src/api/app/bsky/feed/getActorLikes.ts +0 -128
  68. package/src/api/app/bsky/feed/getAuthorFeed.ts +0 -279
  69. package/src/api/app/bsky/feed/getFeed.ts +0 -277
  70. package/src/api/app/bsky/feed/getFeedGenerator.ts +0 -68
  71. package/src/api/app/bsky/feed/getFeedGenerators.ts +0 -86
  72. package/src/api/app/bsky/feed/getLikes.ts +0 -151
  73. package/src/api/app/bsky/feed/getListFeed.ts +0 -147
  74. package/src/api/app/bsky/feed/getPostThread.ts +0 -156
  75. package/src/api/app/bsky/feed/getPosts.ts +0 -100
  76. package/src/api/app/bsky/feed/getQuotes.ts +0 -122
  77. package/src/api/app/bsky/feed/getRepostedBy.ts +0 -121
  78. package/src/api/app/bsky/feed/getSuggestedFeeds.ts +0 -39
  79. package/src/api/app/bsky/feed/getTimeline.ts +0 -127
  80. package/src/api/app/bsky/feed/searchPosts.ts +0 -267
  81. package/src/api/app/bsky/feed/searchPostsV2.ts +0 -236
  82. package/src/api/app/bsky/graph/getActorStarterPacks.ts +0 -103
  83. package/src/api/app/bsky/graph/getBlocks.ts +0 -94
  84. package/src/api/app/bsky/graph/getFollowers.ts +0 -153
  85. package/src/api/app/bsky/graph/getFollows.ts +0 -151
  86. package/src/api/app/bsky/graph/getKnownFollowers.ts +0 -123
  87. package/src/api/app/bsky/graph/getList.ts +0 -152
  88. package/src/api/app/bsky/graph/getListBlocks.ts +0 -87
  89. package/src/api/app/bsky/graph/getListMutes.ts +0 -87
  90. package/src/api/app/bsky/graph/getLists.ts +0 -125
  91. package/src/api/app/bsky/graph/getListsWithMembership.ts +0 -146
  92. package/src/api/app/bsky/graph/getMutes.ts +0 -87
  93. package/src/api/app/bsky/graph/getRelationships.ts +0 -58
  94. package/src/api/app/bsky/graph/getStarterPack.ts +0 -82
  95. package/src/api/app/bsky/graph/getStarterPacks.ts +0 -86
  96. package/src/api/app/bsky/graph/getStarterPacksWithMembership.ts +0 -136
  97. package/src/api/app/bsky/graph/getSuggestedFollowsByActor.ts +0 -171
  98. package/src/api/app/bsky/graph/muteActor.ts +0 -24
  99. package/src/api/app/bsky/graph/muteActorList.ts +0 -19
  100. package/src/api/app/bsky/graph/muteThread.ts +0 -19
  101. package/src/api/app/bsky/graph/searchStarterPacks.ts +0 -169
  102. package/src/api/app/bsky/graph/unmuteActor.ts +0 -21
  103. package/src/api/app/bsky/graph/unmuteActorList.ts +0 -19
  104. package/src/api/app/bsky/graph/unmuteThread.ts +0 -19
  105. package/src/api/app/bsky/labeler/getServices.ts +0 -41
  106. package/src/api/app/bsky/notification/getPreferences.ts +0 -49
  107. package/src/api/app/bsky/notification/getUnreadCount.ts +0 -83
  108. package/src/api/app/bsky/notification/listActivitySubscriptions.ts +0 -116
  109. package/src/api/app/bsky/notification/listNotifications.ts +0 -272
  110. package/src/api/app/bsky/notification/putActivitySubscription.ts +0 -69
  111. package/src/api/app/bsky/notification/putPreferences.ts +0 -17
  112. package/src/api/app/bsky/notification/putPreferencesV2.ts +0 -64
  113. package/src/api/app/bsky/notification/registerPush.ts +0 -40
  114. package/src/api/app/bsky/notification/unregisterPush.ts +0 -39
  115. package/src/api/app/bsky/notification/updateSeen.ts +0 -52
  116. package/src/api/app/bsky/notification/util.ts +0 -134
  117. package/src/api/app/bsky/unspecced/getAgeAssuranceState.ts +0 -48
  118. package/src/api/app/bsky/unspecced/getConfig.ts +0 -20
  119. package/src/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.ts +0 -162
  120. package/src/api/app/bsky/unspecced/getPopularFeedGenerators.ts +0 -91
  121. package/src/api/app/bsky/unspecced/getPostThreadOtherV2.ts +0 -126
  122. package/src/api/app/bsky/unspecced/getPostThreadV2.ts +0 -148
  123. package/src/api/app/bsky/unspecced/getSuggestedFeeds.ts +0 -100
  124. package/src/api/app/bsky/unspecced/getSuggestedOnboardingUsers.ts +0 -143
  125. package/src/api/app/bsky/unspecced/getSuggestedStarterPacks.ts +0 -165
  126. package/src/api/app/bsky/unspecced/getSuggestedUsers.ts +0 -183
  127. package/src/api/app/bsky/unspecced/getSuggestedUsersForDiscover.ts +0 -175
  128. package/src/api/app/bsky/unspecced/getSuggestedUsersForExplore.ts +0 -178
  129. package/src/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.ts +0 -178
  130. package/src/api/app/bsky/unspecced/getTaggedSuggestions.ts +0 -27
  131. package/src/api/app/bsky/unspecced/getTrendingTopics.ts +0 -96
  132. package/src/api/app/bsky/unspecced/getTrends.ts +0 -162
  133. package/src/api/app/bsky/unspecced/initAgeAssurance.ts +0 -150
  134. package/src/api/blob-dispatcher.ts +0 -41
  135. package/src/api/blob-resolver.ts +0 -401
  136. package/src/api/com/atproto/admin/getAccountInfos.ts +0 -49
  137. package/src/api/com/atproto/admin/getSubjectStatus.ts +0 -79
  138. package/src/api/com/atproto/admin/updateSubjectStatus.ts +0 -80
  139. package/src/api/com/atproto/identity/resolveHandle.ts +0 -19
  140. package/src/api/com/atproto/label/queryLabels.ts +0 -42
  141. package/src/api/com/atproto/repo/getRecord.ts +0 -44
  142. package/src/api/com/atproto/temp/fetchLabels.ts +0 -9
  143. package/src/api/external.ts +0 -15
  144. package/src/api/health.ts +0 -47
  145. package/src/api/index.ts +0 -216
  146. package/src/api/internal/bsky/actor/getProfiles.ts +0 -87
  147. package/src/api/kws/api.ts +0 -113
  148. package/src/api/kws/index.ts +0 -29
  149. package/src/api/kws/types.ts +0 -78
  150. package/src/api/kws/util.test.ts +0 -50
  151. package/src/api/kws/util.ts +0 -109
  152. package/src/api/kws/webhook.ts +0 -134
  153. package/src/api/sitemap.ts +0 -76
  154. package/src/api/util.ts +0 -45
  155. package/src/api/well-known.ts +0 -44
  156. package/src/auth-verifier.ts +0 -522
  157. package/src/bsync.ts +0 -41
  158. package/src/cache/read-through.ts +0 -157
  159. package/src/config.ts +0 -710
  160. package/src/context.ts +0 -143
  161. package/src/courier.ts +0 -41
  162. package/src/data-plane/client/hosts.ts +0 -103
  163. package/src/data-plane/client/index.ts +0 -125
  164. package/src/data-plane/client/util.test.ts +0 -29
  165. package/src/data-plane/client/util.ts +0 -74
  166. package/src/data-plane/index.ts +0 -2
  167. package/src/data-plane/server/background.ts +0 -66
  168. package/src/data-plane/server/bsync-subscription.ts +0 -590
  169. package/src/data-plane/server/db/database-schema.ts +0 -90
  170. package/src/data-plane/server/db/db.ts +0 -204
  171. package/src/data-plane/server/db/index.ts +0 -2
  172. package/src/data-plane/server/db/migrations/20230309T045948368Z-init.ts +0 -305
  173. package/src/data-plane/server/db/migrations/20230408T152211201Z-notification-init.ts +0 -25
  174. package/src/data-plane/server/db/migrations/20230417T210628672Z-moderation-init.ts +0 -127
  175. package/src/data-plane/server/db/migrations/20230420T211446071Z-did-cache.ts +0 -14
  176. package/src/data-plane/server/db/migrations/20230427T194702079Z-notif-record-index.ts +0 -14
  177. package/src/data-plane/server/db/migrations/20230605T144730094Z-post-profile-aggs.ts +0 -23
  178. package/src/data-plane/server/db/migrations/20230607T211442112Z-feed-generator-init.ts +0 -34
  179. package/src/data-plane/server/db/migrations/20230608T155101190Z-algo-whats-hot-view.ts +0 -85
  180. package/src/data-plane/server/db/migrations/20230608T201813132Z-mute-lists.ts +0 -78
  181. package/src/data-plane/server/db/migrations/20230608T205147239Z-mutes.ts +0 -15
  182. package/src/data-plane/server/db/migrations/20230609T153623961Z-blocks.ts +0 -33
  183. package/src/data-plane/server/db/migrations/20230609T232122649Z-actor-deletion-indexes.ts +0 -27
  184. package/src/data-plane/server/db/migrations/20230610T203555962Z-suggested-follows.ts +0 -13
  185. package/src/data-plane/server/db/migrations/20230611T215300060Z-actor-state.ts +0 -13
  186. package/src/data-plane/server/db/migrations/20230620T161134972Z-post-langs.ts +0 -9
  187. package/src/data-plane/server/db/migrations/20230627T212437895Z-optional-handle.ts +0 -15
  188. package/src/data-plane/server/db/migrations/20230629T220835893Z-remove-post-hierarchy.ts +0 -32
  189. package/src/data-plane/server/db/migrations/20230703T045536691Z-feed-and-label-indices.ts +0 -31
  190. package/src/data-plane/server/db/migrations/20230720T164800037Z-posts-cursor-idx.ts +0 -19
  191. package/src/data-plane/server/db/migrations/20230807T035309811Z-feed-item-delete-invite-for-user-idx.ts +0 -14
  192. package/src/data-plane/server/db/migrations/20230808T172902639Z-repo-rev.ts +0 -12
  193. package/src/data-plane/server/db/migrations/20230810T203349843Z-action-duration.ts +0 -23
  194. package/src/data-plane/server/db/migrations/20230817T195936007Z-native-notifications.ts +0 -16
  195. package/src/data-plane/server/db/migrations/20230830T205507322Z-suggested-feeds.ts +0 -13
  196. package/src/data-plane/server/db/migrations/20230904T211011773Z-block-lists.ts +0 -24
  197. package/src/data-plane/server/db/migrations/20230906T222220386Z-thread-gating.ts +0 -27
  198. package/src/data-plane/server/db/migrations/20230920T213858047Z-add-tags-to-post.ts +0 -9
  199. package/src/data-plane/server/db/migrations/20230929T192920807Z-record-cursor-indexes.ts +0 -40
  200. package/src/data-plane/server/db/migrations/20231003T202833377Z-create-moderation-subject-status.ts +0 -123
  201. package/src/data-plane/server/db/migrations/20231220T225126090Z-blob-takedowns.ts +0 -66
  202. package/src/data-plane/server/db/migrations/20240124T023719200Z-tagged-suggestions.ts +0 -15
  203. package/src/data-plane/server/db/migrations/20240226T225725627Z-labelers.ts +0 -27
  204. package/src/data-plane/server/db/migrations/20240530T170337073Z-account-deactivation.ts +0 -12
  205. package/src/data-plane/server/db/migrations/20240606T171229898Z-thread-mutes.ts +0 -15
  206. package/src/data-plane/server/db/migrations/20240606T222548219Z-starter-packs.ts +0 -45
  207. package/src/data-plane/server/db/migrations/20240719T203853939Z-priority-notifs.ts +0 -25
  208. package/src/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.ts +0 -12
  209. package/src/data-plane/server/db/migrations/20240723T220703655Z-quotes.ts +0 -28
  210. package/src/data-plane/server/db/migrations/20240801T193939827Z-post-gate.ts +0 -17
  211. package/src/data-plane/server/db/migrations/20240808T224251220Z-post-gate-flags.ts +0 -25
  212. package/src/data-plane/server/db/migrations/20240829T211238293Z-simplify-actor-sync.ts +0 -23
  213. package/src/data-plane/server/db/migrations/20240831T134810923Z-pinned-posts.ts +0 -17
  214. package/src/data-plane/server/db/migrations/20241114T153108102Z-add-starter-packs-name.ts +0 -19
  215. package/src/data-plane/server/db/migrations/20250116T222618297Z-post-embed-video.ts +0 -17
  216. package/src/data-plane/server/db/migrations/20250207T174822012Z-add-label-exp.ts +0 -9
  217. package/src/data-plane/server/db/migrations/20250404T163421487Z-verifications.ts +0 -39
  218. package/src/data-plane/server/db/migrations/20250526T023712742Z-like-repost-via.ts +0 -17
  219. package/src/data-plane/server/db/migrations/20250528T221913281Z-add-record-tags.ts +0 -9
  220. package/src/data-plane/server/db/migrations/20250602T190357447Z-add-private-data.ts +0 -22
  221. package/src/data-plane/server/db/migrations/20250611T140649895Z-add-activity-subscription.ts +0 -22
  222. package/src/data-plane/server/db/migrations/20250627T025331240Z-add-actor-age-assurance-columns.ts +0 -22
  223. package/src/data-plane/server/db/migrations/20250812T183735692Z-add-bookmarks.ts +0 -23
  224. package/src/data-plane/server/db/migrations/20250813T174955711Z-add-post-agg-bookmarks.ts +0 -12
  225. package/src/data-plane/server/db/migrations/20251120T004738098Z-update-actor-age-assurance-v2.ts +0 -28
  226. package/src/data-plane/server/db/migrations/20260112T133951271Z-add-drafts.ts +0 -24
  227. package/src/data-plane/server/db/migrations/20260604T224952774Z-post-embed-gallery-image.ts +0 -19
  228. package/src/data-plane/server/db/migrations/index.ts +0 -60
  229. package/src/data-plane/server/db/migrations/provider.ts +0 -26
  230. package/src/data-plane/server/db/pagination.ts +0 -341
  231. package/src/data-plane/server/db/tables/activity-subscription.ts +0 -12
  232. package/src/data-plane/server/db/tables/actor-block.ts +0 -14
  233. package/src/data-plane/server/db/tables/actor-state.ts +0 -10
  234. package/src/data-plane/server/db/tables/actor-sync.ts +0 -9
  235. package/src/data-plane/server/db/tables/actor.ts +0 -19
  236. package/src/data-plane/server/db/tables/algo.ts +0 -11
  237. package/src/data-plane/server/db/tables/blob-takedown.ts +0 -9
  238. package/src/data-plane/server/db/tables/bookmark.ts +0 -11
  239. package/src/data-plane/server/db/tables/did-cache.ts +0 -13
  240. package/src/data-plane/server/db/tables/draft.ts +0 -11
  241. package/src/data-plane/server/db/tables/duplicate-record.ts +0 -12
  242. package/src/data-plane/server/db/tables/feed-generator.ts +0 -21
  243. package/src/data-plane/server/db/tables/feed-item.ts +0 -12
  244. package/src/data-plane/server/db/tables/follow.ts +0 -15
  245. package/src/data-plane/server/db/tables/label.ts +0 -13
  246. package/src/data-plane/server/db/tables/labeler.ts +0 -16
  247. package/src/data-plane/server/db/tables/like.ts +0 -18
  248. package/src/data-plane/server/db/tables/list-block.ts +0 -15
  249. package/src/data-plane/server/db/tables/list-item.ts +0 -16
  250. package/src/data-plane/server/db/tables/list-mute.ts +0 -9
  251. package/src/data-plane/server/db/tables/list.ts +0 -19
  252. package/src/data-plane/server/db/tables/mute.ts +0 -9
  253. package/src/data-plane/server/db/tables/notification-push-token.ts +0 -10
  254. package/src/data-plane/server/db/tables/notification.ts +0 -16
  255. package/src/data-plane/server/db/tables/post-agg.ts +0 -16
  256. package/src/data-plane/server/db/tables/post-embed.ts +0 -47
  257. package/src/data-plane/server/db/tables/post-gate.ts +0 -12
  258. package/src/data-plane/server/db/tables/post.ts +0 -28
  259. package/src/data-plane/server/db/tables/private-data.ts +0 -13
  260. package/src/data-plane/server/db/tables/profile-agg.ts +0 -14
  261. package/src/data-plane/server/db/tables/profile.ts +0 -17
  262. package/src/data-plane/server/db/tables/quote.ts +0 -15
  263. package/src/data-plane/server/db/tables/record.ts +0 -15
  264. package/src/data-plane/server/db/tables/repost.ts +0 -18
  265. package/src/data-plane/server/db/tables/starter-pack.ts +0 -17
  266. package/src/data-plane/server/db/tables/subscription.ts +0 -9
  267. package/src/data-plane/server/db/tables/suggested-feed.ts +0 -10
  268. package/src/data-plane/server/db/tables/suggested-follow.ts +0 -10
  269. package/src/data-plane/server/db/tables/tagged-suggestion.ts +0 -11
  270. package/src/data-plane/server/db/tables/thread-gate.ts +0 -12
  271. package/src/data-plane/server/db/tables/thread-mute.ts +0 -9
  272. package/src/data-plane/server/db/tables/verification.ts +0 -20
  273. package/src/data-plane/server/db/tables/view-param.ts +0 -12
  274. package/src/data-plane/server/db/types.ts +0 -12
  275. package/src/data-plane/server/db/util.ts +0 -67
  276. package/src/data-plane/server/index.ts +0 -44
  277. package/src/data-plane/server/indexing/index.ts +0 -458
  278. package/src/data-plane/server/indexing/plugins/block.ts +0 -84
  279. package/src/data-plane/server/indexing/plugins/chat-declaration.ts +0 -60
  280. package/src/data-plane/server/indexing/plugins/feed-generator.ts +0 -80
  281. package/src/data-plane/server/indexing/plugins/follow.ts +0 -132
  282. package/src/data-plane/server/indexing/plugins/germ-declaration.ts +0 -57
  283. package/src/data-plane/server/indexing/plugins/labeler.ts +0 -74
  284. package/src/data-plane/server/indexing/plugins/like.ts +0 -151
  285. package/src/data-plane/server/indexing/plugins/list-block.ts +0 -84
  286. package/src/data-plane/server/indexing/plugins/list-item.ts +0 -92
  287. package/src/data-plane/server/indexing/plugins/list.ts +0 -80
  288. package/src/data-plane/server/indexing/plugins/notif-declaration.ts +0 -57
  289. package/src/data-plane/server/indexing/plugins/post-gate.ts +0 -101
  290. package/src/data-plane/server/indexing/plugins/post.ts +0 -675
  291. package/src/data-plane/server/indexing/plugins/profile.ts +0 -90
  292. package/src/data-plane/server/indexing/plugins/repost.ts +0 -176
  293. package/src/data-plane/server/indexing/plugins/starter-pack.ts +0 -74
  294. package/src/data-plane/server/indexing/plugins/status.ts +0 -57
  295. package/src/data-plane/server/indexing/plugins/thread-gate.ts +0 -101
  296. package/src/data-plane/server/indexing/plugins/verification.ts +0 -113
  297. package/src/data-plane/server/indexing/processor.ts +0 -292
  298. package/src/data-plane/server/routes/activity-subscription.ts +0 -84
  299. package/src/data-plane/server/routes/blocks.ts +0 -127
  300. package/src/data-plane/server/routes/bookmarks.ts +0 -83
  301. package/src/data-plane/server/routes/drafts.ts +0 -37
  302. package/src/data-plane/server/routes/feed-gens.ts +0 -89
  303. package/src/data-plane/server/routes/feeds.ts +0 -176
  304. package/src/data-plane/server/routes/follows.ts +0 -141
  305. package/src/data-plane/server/routes/identity.ts +0 -59
  306. package/src/data-plane/server/routes/index.ts +0 -67
  307. package/src/data-plane/server/routes/interactions.ts +0 -120
  308. package/src/data-plane/server/routes/labels.ts +0 -55
  309. package/src/data-plane/server/routes/likes.ts +0 -92
  310. package/src/data-plane/server/routes/lists.ts +0 -88
  311. package/src/data-plane/server/routes/moderation.ts +0 -102
  312. package/src/data-plane/server/routes/mutes.ts +0 -195
  313. package/src/data-plane/server/routes/notifs.ts +0 -239
  314. package/src/data-plane/server/routes/profile.ts +0 -220
  315. package/src/data-plane/server/routes/quotes.ts +0 -32
  316. package/src/data-plane/server/routes/records.ts +0 -119
  317. package/src/data-plane/server/routes/relationships.ts +0 -174
  318. package/src/data-plane/server/routes/reposts.ts +0 -76
  319. package/src/data-plane/server/routes/search.ts +0 -181
  320. package/src/data-plane/server/routes/site-standard.ts +0 -12
  321. package/src/data-plane/server/routes/sitemap.ts +0 -43
  322. package/src/data-plane/server/routes/starter-packs.ts +0 -32
  323. package/src/data-plane/server/routes/suggestions.ts +0 -175
  324. package/src/data-plane/server/routes/sync.ts +0 -16
  325. package/src/data-plane/server/routes/threads.ts +0 -33
  326. package/src/data-plane/server/subscription.ts +0 -152
  327. package/src/data-plane/server/util.ts +0 -202
  328. package/src/error.ts +0 -12
  329. package/src/etcd.ts +0 -90
  330. package/src/feature-gates/README.md +0 -83
  331. package/src/feature-gates/gates.ts +0 -25
  332. package/src/feature-gates/index.ts +0 -235
  333. package/src/feature-gates/metrics.test.ts +0 -196
  334. package/src/feature-gates/metrics.ts +0 -107
  335. package/src/feature-gates/types.ts +0 -62
  336. package/src/feature-gates/utils.test.ts +0 -66
  337. package/src/feature-gates/utils.ts +0 -135
  338. package/src/hydration/actor.ts +0 -578
  339. package/src/hydration/external.test.ts +0 -281
  340. package/src/hydration/external.ts +0 -268
  341. package/src/hydration/feed.ts +0 -456
  342. package/src/hydration/graph.ts +0 -354
  343. package/src/hydration/hydrator.ts +0 -1835
  344. package/src/hydration/label.ts +0 -207
  345. package/src/hydration/util.ts +0 -199
  346. package/src/image/index.ts +0 -2
  347. package/src/image/invalidator.ts +0 -33
  348. package/src/image/logger.ts +0 -6
  349. package/src/image/server.ts +0 -228
  350. package/src/image/sharp.ts +0 -89
  351. package/src/image/uri.ts +0 -114
  352. package/src/image/util.ts +0 -41
  353. package/src/index.ts +0 -312
  354. package/src/kws.ts +0 -197
  355. package/src/logger.ts +0 -40
  356. package/src/pipeline.ts +0 -60
  357. package/src/redis.ts +0 -205
  358. package/src/rolodex.ts +0 -42
  359. package/src/stash.ts +0 -76
  360. package/src/util/debug.ts +0 -10
  361. package/src/util/http.ts +0 -42
  362. package/src/util/retry.ts +0 -10
  363. package/src/util/standard-site.test.ts +0 -423
  364. package/src/util/standard-site.ts +0 -196
  365. package/src/util/uris.ts +0 -38
  366. package/src/util.ts +0 -48
  367. package/src/views/index.ts +0 -2783
  368. package/src/views/threads-v2.ts +0 -510
  369. package/src/views/types.ts +0 -193
  370. package/src/views/util.ts +0 -114
  371. package/test.env +0 -2
  372. package/tests/__snapshots__/feed-generation.test.ts.snap +0 -2463
  373. package/tests/_util.ts +0 -292
  374. package/tests/admin/admin-auth.test.ts +0 -190
  375. package/tests/admin/moderation.test.ts +0 -222
  376. package/tests/auth.test.ts +0 -90
  377. package/tests/blob-resolver.test.ts +0 -125
  378. package/tests/data-plane/__snapshots__/indexing.test.ts.snap +0 -887
  379. package/tests/data-plane/db.test.ts +0 -189
  380. package/tests/data-plane/duplicate-records.test.ts +0 -156
  381. package/tests/data-plane/handle-invalidation.test.ts +0 -153
  382. package/tests/data-plane/indexing.test.ts +0 -827
  383. package/tests/data-plane/subscription.test.ts +0 -128
  384. package/tests/data-plane/thread-mutes.test.ts +0 -175
  385. package/tests/entryway-auth.test.ts +0 -177
  386. package/tests/etcd.test.ts +0 -302
  387. package/tests/feed-generation.test.ts +0 -919
  388. package/tests/hydration/util.test.ts +0 -119
  389. package/tests/image/server.test.ts +0 -97
  390. package/tests/image/sharp.test.ts +0 -199
  391. package/tests/image/uri.test.ts +0 -106
  392. package/tests/label-hydration.test.ts +0 -245
  393. package/tests/postgates.test.ts +0 -182
  394. package/tests/query-labels.test.ts +0 -85
  395. package/tests/redis-cache.test.ts +0 -230
  396. package/tests/seed/feed-hidden-replies.ts +0 -63
  397. package/tests/seed/get-suggested-starter-packs.ts +0 -64
  398. package/tests/seed/get-trends.ts +0 -71
  399. package/tests/seed/known-followers.ts +0 -111
  400. package/tests/seed/postgates.ts +0 -57
  401. package/tests/server.test.ts +0 -115
  402. package/tests/sitemap.test.ts +0 -75
  403. package/tests/stash.test.ts +0 -180
  404. package/tests/utils.test.ts +0 -36
  405. package/tests/views/__snapshots__/actor-search.test.ts.snap +0 -155
  406. package/tests/views/__snapshots__/author-feed.test.ts.snap +0 -6301
  407. package/tests/views/__snapshots__/block-lists.test.ts.snap +0 -690
  408. package/tests/views/__snapshots__/blocks.test.ts.snap +0 -462
  409. package/tests/views/__snapshots__/bookmarks.test.ts.snap +0 -379
  410. package/tests/views/__snapshots__/follows.test.ts.snap +0 -798
  411. package/tests/views/__snapshots__/labeler-service.test.ts.snap +0 -233
  412. package/tests/views/__snapshots__/likes.test.ts.snap +0 -124
  413. package/tests/views/__snapshots__/list-feed.test.ts.snap +0 -883
  414. package/tests/views/__snapshots__/lists.test.ts.snap +0 -650
  415. package/tests/views/__snapshots__/mute-lists.test.ts.snap +0 -705
  416. package/tests/views/__snapshots__/mutes.test.ts.snap +0 -353
  417. package/tests/views/__snapshots__/notifications.test.ts.snap +0 -3074
  418. package/tests/views/__snapshots__/posts.test.ts.snap +0 -1019
  419. package/tests/views/__snapshots__/profile.test.ts.snap +0 -811
  420. package/tests/views/__snapshots__/quotes.test.ts.snap +0 -445
  421. package/tests/views/__snapshots__/reposts.test.ts.snap +0 -112
  422. package/tests/views/__snapshots__/starter-packs.test.ts.snap +0 -836
  423. package/tests/views/__snapshots__/thread-v2.test.ts.snap +0 -1298
  424. package/tests/views/__snapshots__/thread.test.ts.snap +0 -2051
  425. package/tests/views/__snapshots__/threadgating.test.ts.snap +0 -189
  426. package/tests/views/__snapshots__/timeline.test.ts.snap +0 -7252
  427. package/tests/views/account-deactivation.test.ts +0 -81
  428. package/tests/views/actor-likes.test.ts +0 -138
  429. package/tests/views/actor-search.test.ts +0 -261
  430. package/tests/views/age-assurance-v2.test.ts +0 -823
  431. package/tests/views/age-assurance.test.ts +0 -479
  432. package/tests/views/author-feed.test.ts +0 -694
  433. package/tests/views/block-lists.test.ts +0 -661
  434. package/tests/views/blocks.test.ts +0 -889
  435. package/tests/views/bookmarks.test.ts +0 -345
  436. package/tests/views/drafts.test.ts +0 -430
  437. package/tests/views/feed-hidden-replies.test.ts +0 -243
  438. package/tests/views/feed-view-post.test.ts +0 -501
  439. package/tests/views/follows.test.ts +0 -372
  440. package/tests/views/get-config.test.ts +0 -64
  441. package/tests/views/get-suggested-onboarding-users.test.ts +0 -193
  442. package/tests/views/get-suggested-starter-packs.test.ts +0 -137
  443. package/tests/views/get-trends.test.ts +0 -141
  444. package/tests/views/internal-actor.test.ts +0 -127
  445. package/tests/views/known-followers.test.ts +0 -193
  446. package/tests/views/labeler-service.test.ts +0 -242
  447. package/tests/views/labels-needs-review.test.ts +0 -316
  448. package/tests/views/labels-takedown.test.ts +0 -247
  449. package/tests/views/likes.test.ts +0 -192
  450. package/tests/views/list-feed.test.ts +0 -195
  451. package/tests/views/lists.test.ts +0 -412
  452. package/tests/views/mute-lists.test.ts +0 -509
  453. package/tests/views/mutes.test.ts +0 -308
  454. package/tests/views/notifications.test.ts +0 -1581
  455. package/tests/views/post-search.test.ts +0 -200
  456. package/tests/views/posts-debug.test.ts +0 -79
  457. package/tests/views/posts.test.ts +0 -427
  458. package/tests/views/profile-debug.test.ts +0 -75
  459. package/tests/views/profile.test.ts +0 -795
  460. package/tests/views/quotes.test.ts +0 -133
  461. package/tests/views/reposts.test.ts +0 -112
  462. package/tests/views/starter-packs.test.ts +0 -395
  463. package/tests/views/suggestions.test.ts +0 -145
  464. package/tests/views/thread-v2.test.ts +0 -2005
  465. package/tests/views/thread.test.ts +0 -637
  466. package/tests/views/threadgating.test.ts +0 -843
  467. package/tests/views/timeline.test.ts +0 -328
  468. package/tests/views/verification.test.ts +0 -296
  469. package/tsconfig.build.json +0 -10
  470. package/tsconfig.build.tsbuildinfo +0 -1
  471. package/tsconfig.json +0 -7
  472. package/tsconfig.tests.json +0 -8
  473. package/vitest.config.ts +0 -10
@@ -1,150 +0,0 @@
1
- import crypto from 'node:crypto'
2
- import { isEmailValid } from '@hapi/address'
3
- import { isDisposableEmail } from 'disposable-email-domains-js'
4
- import {
5
- InvalidRequestError,
6
- MethodNotImplementedError,
7
- Server,
8
- } from '@atproto/xrpc-server'
9
- import { AppContext } from '../../../../context.js'
10
- import { KwsExternalPayloadError } from '../../../../kws.js'
11
- import { app } from '../../../../lexicons/index.js'
12
- import { httpLogger as log } from '../../../../logger.js'
13
- import { ActorInfo } from '../../../../proto/bsky_pb.js'
14
- import { KwsExternalPayload } from '../../../kws/types.js'
15
- import { createStashEvent, getClientUa } from '../../../kws/util.js'
16
-
17
- type InputSchema = app.bsky.unspecced.initAgeAssurance.$InputBody
18
-
19
- export default function (server: Server, ctx: AppContext) {
20
- server.add(app.bsky.unspecced.initAgeAssurance, {
21
- auth: ctx.authVerifier.standard,
22
- handler: async ({ auth, input, req }) => {
23
- if (!ctx.kwsClient) {
24
- throw new MethodNotImplementedError(
25
- 'This service is not configured to support age assurance.',
26
- )
27
- }
28
-
29
- const actorDid = auth.credentials.iss
30
-
31
- const actorInfo = await getAgeVerificationState(ctx, actorDid)
32
-
33
- if (actorInfo?.ageAssuranceStatus) {
34
- if (
35
- actorInfo.ageAssuranceStatus.status !== 'unknown' &&
36
- actorInfo.ageAssuranceStatus.status !== 'pending'
37
- ) {
38
- throw new InvalidRequestError(
39
- `Cannot initiate age assurance flow from current state: ${actorInfo.ageAssuranceStatus.status}`,
40
- 'InvalidInitiation',
41
- )
42
- }
43
- }
44
-
45
- const { countryCode, email, language } = validateInput(input.body)
46
-
47
- const attemptId = crypto.randomUUID()
48
- // Assumes `app.set('trust proxy', ...)` configured with `true` or specific values.
49
- const initIp = req.ip
50
- const initUa = getClientUa(req)
51
- const externalPayload: KwsExternalPayload = { actorDid, attemptId }
52
-
53
- try {
54
- await ctx.kwsClient.sendEmail({
55
- countryCode: countryCode.toUpperCase(),
56
- email,
57
- externalPayload,
58
- language,
59
- })
60
- } catch (err) {
61
- if (err instanceof KwsExternalPayloadError) {
62
- log.error(
63
- { externalPayload },
64
- 'Age Assurance flow failed because external payload got too long, which is caused by the DID being too long',
65
- )
66
- throw new InvalidRequestError(
67
- 'Age Assurance flow failed because DID is too long',
68
- 'DidTooLong',
69
- )
70
- }
71
- throw err
72
- }
73
-
74
- const event = await createStashEvent(ctx, {
75
- actorDid,
76
- attemptId,
77
- email,
78
- initIp,
79
- initUa,
80
- status: 'pending',
81
- })
82
-
83
- return {
84
- encoding: 'application/json',
85
- body: {
86
- status: event.status,
87
- lastInitiatedAt: event.createdAt,
88
- },
89
- }
90
- },
91
- })
92
- }
93
-
94
- // Supported languages for KWS Adult Verification.
95
- // This list comes from KWS's AV Developer Guide PDF doc.
96
- const kwsAvSupportedLanguages = [
97
- 'en',
98
- 'ar',
99
- 'zh-Hans',
100
- 'nl',
101
- 'tl',
102
- 'fr',
103
- 'de',
104
- 'id',
105
- 'it',
106
- 'ja',
107
- 'ko',
108
- 'pl',
109
- 'pt-BR',
110
- 'pt',
111
- 'ru',
112
- 'es',
113
- 'th',
114
- 'tr',
115
- 'vi',
116
- ]
117
-
118
- const validateInput = (input: InputSchema): InputSchema => {
119
- const { countryCode, email, language } = input
120
-
121
- if (!isEmailValid(email) || isDisposableEmail(email)) {
122
- throw new InvalidRequestError(
123
- 'This email address is not supported, please use a different email.',
124
- 'InvalidEmail',
125
- )
126
- }
127
-
128
- return {
129
- countryCode,
130
- email,
131
- language: kwsAvSupportedLanguages.includes(language) ? language : 'en',
132
- }
133
- }
134
-
135
- const getAgeVerificationState = async (
136
- ctx: AppContext,
137
- actorDid: string,
138
- ): Promise<ActorInfo | undefined> => {
139
- try {
140
- const res = await ctx.dataplane.getActors({
141
- dids: [actorDid],
142
- returnAgeAssuranceForDids: [actorDid],
143
- skipCacheForDids: [actorDid],
144
- })
145
-
146
- return res.actors[0]
147
- } catch (err) {
148
- return undefined
149
- }
150
- }
@@ -1,41 +0,0 @@
1
- import { Agent, Dispatcher, Pool, interceptors } from 'undici'
2
- import { isUnicastIp, unicastLookup } from '@atproto-labs/fetch-node'
3
- import { ServerConfig } from '../config.js'
4
- import { RETRYABLE_HTTP_STATUS_CODES } from '../util/retry.js'
5
-
6
- export function createBlobDispatcher(cfg: ServerConfig): Dispatcher {
7
- const baseDispatcher = new Agent({
8
- allowH2: cfg.proxyAllowHTTP2, // This is experimental
9
- headersTimeout: cfg.proxyHeadersTimeout,
10
- maxResponseSize: cfg.proxyMaxResponseSize,
11
- bodyTimeout: cfg.proxyBodyTimeout,
12
- factory: cfg.disableSsrfProtection
13
- ? undefined
14
- : (origin, opts) => {
15
- const { protocol, hostname } =
16
- origin instanceof URL ? origin : new URL(origin)
17
- if (protocol !== 'https:') {
18
- throw new Error(`Forbidden protocol "${protocol}"`)
19
- }
20
- if (isUnicastIp(hostname) === false) {
21
- throw new Error('Hostname resolved to non-unicast address')
22
- }
23
- return new Pool(origin, opts)
24
- },
25
- connect: {
26
- lookup: cfg.disableSsrfProtection ? undefined : unicastLookup,
27
- },
28
- })
29
-
30
- return baseDispatcher.compose(
31
- interceptors.redirect({
32
- maxRedirections: 10,
33
- throwOnMaxRedirect: true,
34
- }),
35
- interceptors.retry({
36
- statusCodes: [...RETRYABLE_HTTP_STATUS_CODES],
37
- methods: ['GET', 'HEAD'],
38
- maxRetries: cfg.proxyMaxRetries,
39
- }),
40
- )
41
- }
@@ -1,401 +0,0 @@
1
- import { Duplex, Transform, Writable } from 'node:stream'
2
- import { pipeline } from 'node:stream/promises'
3
- import createError, { isHttpError } from 'http-errors'
4
- import { Dispatcher } from 'undici'
5
- import {
6
- VerifyCidError,
7
- VerifyCidTransform,
8
- createDecoders,
9
- } from '@atproto/common'
10
- import { AtprotoDid, isAtprotoDid } from '@atproto/did'
11
- import { Cid } from '@atproto/lex'
12
- import {
13
- ACCEPT_ENCODING_COMPRESSED,
14
- ACCEPT_ENCODING_UNCOMPRESSED,
15
- buildProxiedContentEncoding,
16
- formatAcceptHeader,
17
- } from '@atproto-labs/xrpc-utils'
18
- import { ServerConfig } from '../config.js'
19
- import { AppContext } from '../context.js'
20
- import {
21
- Code,
22
- DataPlaneClient,
23
- getServiceEndpoint,
24
- isDataplaneError,
25
- unpackIdentityServices,
26
- } from '../data-plane/index.js'
27
- import { parseCid } from '../hydration/util.js'
28
- import { httpLogger as log } from '../logger.js'
29
- import {
30
- Middleware,
31
- proxyResponseHeaders,
32
- responseSignal,
33
- } from '../util/http.js'
34
- import { BSKY_USER_AGENT } from './util.js'
35
-
36
- export function createMiddleware(ctx: AppContext): Middleware {
37
- return async (req, res, next) => {
38
- if (req.method !== 'GET' && req.method !== 'HEAD') return next()
39
- if (!req.url?.startsWith('/blob/')) return next()
40
- const { length, 2: didParam, 3: cidParam } = req.url.split('/')
41
- if (length !== 4 || !didParam || !cidParam) return next()
42
-
43
- // @TODO Check sec-fetch-* headers (e.g. to prevent files from being
44
- // displayed as a web page) ?
45
-
46
- try {
47
- const streamOptions: StreamBlobOptions = {
48
- did: didParam,
49
- cid: cidParam,
50
- signal: responseSignal(res),
51
- // Because we will be verifying the CID, we need to ensure that the
52
- // upstream response can be de-compressed. We do this by negotiating the
53
- // "accept-encoding" header based on the downstream client's capabilities.
54
- acceptEncoding: buildProxiedContentEncoding(
55
- req.headers['accept-encoding'],
56
- ctx.cfg.proxyPreferCompressed,
57
- ),
58
- }
59
-
60
- await streamBlob(ctx, streamOptions, (upstream, { cid, did, url }) => {
61
- const encoding = upstream.headers['content-encoding']
62
- const verifier = createCidVerifier(cid, encoding)
63
-
64
- const logError = (err: unknown) => {
65
- log.warn(
66
- { err, did, cid: cid.toString(), pds: url.origin },
67
- 'blob resolution failed during transmission',
68
- )
69
- }
70
-
71
- const onError = (err: unknown) => {
72
- // No need to pipe the data (verifier) into the response, as it is
73
- // "errored". The response processing will continue in the "catch"
74
- // block below (because streamBlob() will reject the promise in case
75
- // of "error" event on the writable stream returned by the factory).
76
- clearTimeout(graceTimer)
77
- logError(err)
78
- }
79
-
80
- // Catch any error that occurs before the timer bellow is triggered.
81
- // The promise returned by streamBlob() will be rejected as soon as
82
- // the verifier errors.
83
- verifier.on('error', onError)
84
-
85
- // The way I/O work, it is likely that, in case of small payloads, the
86
- // full upstream response is already buffered at this point. In order to
87
- // return a 404 instead of a broken response stream, we allow the event
88
- // loop to to process any pending I/O events before we start piping the
89
- // bytes to the response. For larger payloads, the response will look
90
- // like a 200 with a broken chunked response stream. The only way around
91
- // that would be to buffer the entire response before piping it to the
92
- // response, which will hurt latency (need the full payload) and memory
93
- // usage (either RAM or DISK). Since this is more of an edge case, we
94
- // allow the broken response stream to be sent.
95
- const graceTimer = setTimeout(() => {
96
- verifier.off('error', onError)
97
-
98
- // Make sure that the content served from the bsky api domain cannot
99
- // be used to perform XSS attacks (by serving HTML pages)
100
- res.setHeader(
101
- 'Content-Security-Policy',
102
- `default-src 'none'; sandbox`,
103
- )
104
- res.setHeader('X-Content-Type-Options', 'nosniff')
105
- res.setHeader('X-Frame-Options', 'DENY')
106
- res.setHeader('X-XSS-Protection', '0')
107
-
108
- // @TODO Add a cache-control header ?
109
- // @TODO Add content-disposition header (to force download) ?
110
-
111
- proxyResponseHeaders(upstream, res)
112
-
113
- // Force chunked encoding. This is required because the verifier will
114
- // trigger an error *after* the last chunk has been passed through.
115
- // Because the number of bytes sent will match the content-length, the
116
- // HTTP response will be considered "complete" by the HTTP server. At
117
- // this point, only trailers headers could indicate that an error
118
- // occurred, but that is not the behavior we expect.
119
- res.removeHeader('content-length')
120
-
121
- // From this point on, triggering the next middleware (including any
122
- // error handler) can be problematic because content-type,
123
- // content-encoding, etc. headers have already been set. Because of
124
- // this, we make sure that res.headersSent is set to true, preventing
125
- // another error handler middleware from being called (from the catch
126
- // block bellow). Not flushing the headers here would require to
127
- // revert the headers set from this middleware (which we don't do for
128
- // now).
129
- res.flushHeaders()
130
-
131
- // Pipe the verifier output into the HTTP response
132
- void pipeline([verifier, res]).catch(logError)
133
- }, 10) // 0 works too. Allow for additional data to come in for 10ms.
134
-
135
- // Write the upstream response into the verifier.
136
- return verifier
137
- })
138
- } catch (err) {
139
- if (res.headersSent || res.destroyed) {
140
- res.destroy()
141
- } else if (err instanceof VerifyCidError) {
142
- // @NOTE This only works because of the graceTimer above. It will also
143
- // only be triggered for small payloads.
144
- next(createError(404, err.message))
145
- } else if (isHttpError(err)) {
146
- next(err)
147
- } else {
148
- next(createError(502, 'Upstream Error', { cause: err }))
149
- }
150
- }
151
- }
152
- }
153
-
154
- export type StreamBlobOptions = {
155
- cid: string
156
- did: string
157
- acceptEncoding?: string
158
- signal?: AbortSignal
159
- }
160
-
161
- export type StreamBlobFactory = (
162
- data: Dispatcher.StreamFactoryData,
163
- info: {
164
- url: URL
165
- did: AtprotoDid
166
- cid: Cid
167
- },
168
- ) => Writable
169
-
170
- export async function streamBlob(
171
- ctx: AppContext,
172
- options: StreamBlobOptions,
173
- factory: StreamBlobFactory,
174
- ) {
175
- const { did, cid } = parseBlobParams(options)
176
- const url = await getBlobUrl(ctx.dataplane, did, cid)
177
-
178
- const headers = getBlobHeaders(ctx.cfg, url)
179
-
180
- headers.set(
181
- 'accept-encoding',
182
- options.acceptEncoding ||
183
- formatAcceptHeader(
184
- ctx.cfg.proxyPreferCompressed
185
- ? ACCEPT_ENCODING_COMPRESSED
186
- : ACCEPT_ENCODING_UNCOMPRESSED,
187
- ),
188
- )
189
-
190
- let headersReceived = false
191
-
192
- return ctx.blobDispatcher
193
- .stream(
194
- {
195
- method: 'GET',
196
- origin: url.origin,
197
- path: url.pathname + url.search,
198
- headers,
199
- signal: options.signal,
200
- },
201
- (upstream) => {
202
- headersReceived = true
203
-
204
- if (upstream.statusCode !== 200) {
205
- log.warn(
206
- {
207
- did,
208
- cid: cid.toString(),
209
- pds: url.origin,
210
- status: upstream.statusCode,
211
- },
212
- `blob resolution failed upstream`,
213
- )
214
-
215
- throw upstream.statusCode >= 400 && upstream.statusCode < 500
216
- ? createError(404, 'Blob not found', { cause: upstream }) // 4xx => 404
217
- : createError(502, 'Upstream Error', { cause: upstream }) // !200 && !4xx => 502
218
- }
219
-
220
- return factory(upstream, { url, did, cid })
221
- },
222
- )
223
- .catch((err) => {
224
- // Is this a connection error, or a stream error ?
225
- if (!headersReceived) {
226
- // connection error, dns error, headers timeout, ...
227
- log.warn(
228
- { err, did, cid: cid.toString(), pds: url.origin },
229
- 'blob resolution failed during connection',
230
- )
231
-
232
- throw createError(502, 'Upstream Error', { cause: err })
233
- }
234
-
235
- throw err
236
- })
237
- }
238
-
239
- function parseBlobParams(params: { cid: string; did: string }) {
240
- const { cid, did } = params
241
- if (!isAtprotoDid(did)) throw createError(400, 'Invalid did')
242
- const cidObj = parseCid(cid)
243
- if (!cidObj) throw createError(400, 'Invalid cid')
244
- return { cid: cidObj, did }
245
- }
246
-
247
- async function getBlobUrl(
248
- dataplane: DataPlaneClient,
249
- did: string,
250
- cid: Cid,
251
- ): Promise<URL> {
252
- const pds = await getBlobPds(dataplane, did, cid)
253
-
254
- const url = new URL(`/xrpc/com.atproto.sync.getBlob`, pds)
255
- url.searchParams.set('did', did)
256
- url.searchParams.set('cid', cid.toString())
257
-
258
- return url
259
- }
260
-
261
- async function getBlobPds(
262
- dataplane: DataPlaneClient,
263
- did: string,
264
- cid: Cid,
265
- ): Promise<string> {
266
- const [identity, { takenDown }] = await Promise.all([
267
- dataplane.getIdentityByDid({ did }).catch((err) => {
268
- if (isDataplaneError(err, Code.NotFound)) {
269
- return undefined
270
- }
271
- throw err
272
- }),
273
- dataplane.getBlobTakedown({ did, cid: cid.toString() }),
274
- ])
275
-
276
- if (takenDown) {
277
- throw createError(404, 'Blob not found')
278
- }
279
-
280
- const services = identity && unpackIdentityServices(identity.services)
281
- const pds =
282
- services &&
283
- getServiceEndpoint(services, {
284
- id: 'atproto_pds',
285
- type: 'AtprotoPersonalDataServer',
286
- })
287
-
288
- if (!pds) {
289
- throw createError(404, 'Origin not found')
290
- }
291
-
292
- return pds
293
- }
294
-
295
- function getBlobHeaders(
296
- {
297
- blobRateLimitBypassKey: bypassKey,
298
- blobRateLimitBypassHostname: bypassHostname,
299
- }: ServerConfig,
300
- url: URL,
301
- ): Map<string, string> {
302
- const headers = new Map<string, string>()
303
-
304
- headers.set('user-agent', BSKY_USER_AGENT)
305
-
306
- if (bypassKey && bypassHostname) {
307
- const matchesUrl = bypassHostname.startsWith('.')
308
- ? url.hostname.endsWith(bypassHostname)
309
- : url.hostname === bypassHostname
310
-
311
- if (matchesUrl) {
312
- headers.set('x-ratelimit-bypass', bypassKey)
313
- }
314
- }
315
-
316
- return headers
317
- }
318
-
319
- /**
320
- * This function creates a passthrough stream that will decompress (if needed)
321
- * and verify the CID of the input stream. The output data will be identical to
322
- * the input data.
323
- *
324
- * If you need the un-compressed data, you should use a decompress + verify
325
- * pipeline instead.
326
- */
327
- function createCidVerifier(cid: Cid, encoding?: string | string[]): Duplex {
328
- // If the upstream content is compressed, we do not want to return a
329
- // de-compressed stream here. Indeed, the "compression" middleware will
330
- // compress the response before it is sent downstream, if it is not already
331
- // compressed. Because of this, it is preferable to return the content as-is
332
- // to avoid re-compressing it.
333
- //
334
- // We do still want to be able to verify the CID, which requires decompressing
335
- // the input bytes.
336
- //
337
- // To that end, we create a passthrough in order to "tee" the stream into two
338
- // streams: one that will be sent, unaltered, downstream, and a pipeline that
339
- // will be used to decompress & verify the CID (discarding de-compressed
340
- // data).
341
-
342
- const decoders = createDecoders(encoding)
343
- const verifier = new VerifyCidTransform(cid)
344
-
345
- // Optimization: If the content is not compressed, we don't need to "tee" the
346
- // stream, we can use the verifier as simple passthrough.
347
- if (!decoders.length) return verifier
348
-
349
- const pipelineController = new AbortController()
350
- const pipelineStreams: Duplex[] = [...decoders, verifier]
351
- const pipelineInput = pipelineStreams[0]!
352
-
353
- // Create a promise that will resolve if, and only if, the decoding and
354
- // verification succeed.
355
- const pipelinePromise: Promise<null | Error> = pipeline(pipelineStreams, {
356
- signal: pipelineController.signal,
357
- }).then(
358
- () => null,
359
- (err) => {
360
- const error = asError(err)
361
-
362
- // the data being processed by the pipeline is invalid (e.g. invalid
363
- // compressed content, non-matching the CID, ...). If that occurs, we can
364
- // destroy the passthrough (this allows not to wait for the "flush" event
365
- // to propagate the error).
366
- passthrough.destroy(error)
367
-
368
- return error
369
- },
370
- )
371
-
372
- // We don't care about the un-compressed data, we only use the verifier to
373
- // detect any error through the pipelinePromise. We still need to pass the
374
- // verifier into flowing mode to ensure that the pipelinePromise resolves.
375
- verifier.resume()
376
-
377
- const passthrough = new Transform({
378
- transform(chunk, encoding, callback) {
379
- pipelineInput.write(chunk, encoding)
380
- callback(null, chunk)
381
- },
382
- flush(callback) {
383
- // End the input stream, which will resolve the pipeline promise
384
- pipelineInput.end()
385
- // End the pass-through stream according to the result of the pipeline
386
- pipelinePromise.then(callback)
387
- },
388
- destroy(err, callback) {
389
- pipelineController.abort() // Causes pipeline() to destroy all streams
390
- callback(err)
391
- },
392
- })
393
-
394
- return passthrough
395
- }
396
-
397
- function asError(err: unknown): Error {
398
- return err instanceof Error
399
- ? err
400
- : new Error('Processing failed', { cause: err })
401
- }
@@ -1,49 +0,0 @@
1
- import { mapDefined } from '@atproto/common'
2
- import { DatetimeString, INVALID_HANDLE } from '@atproto/syntax'
3
- import { Server } from '@atproto/xrpc-server'
4
- import { AppContext } from '../../../../context.js'
5
- import { com } from '../../../../lexicons/index.js'
6
-
7
- export default function (server: Server, ctx: AppContext) {
8
- server.add(com.atproto.admin.getAccountInfos, {
9
- auth: ctx.authVerifier.optionalStandardOrRole,
10
- handler: async ({ params, auth }) => {
11
- const { dids } = params
12
- const { includeTakedowns } = ctx.authVerifier.parseCreds(auth)
13
-
14
- const actors = await ctx.hydrator.actor.getActors(dids, {
15
- includeTakedowns: true,
16
- skipCacheForDids: dids,
17
- })
18
-
19
- const infos = mapDefined(
20
- dids,
21
- (did): com.atproto.admin.defs.AccountView | undefined => {
22
- const info = actors.get(did)
23
- if (!info) return
24
- if (info.takedownRef && !includeTakedowns) return
25
- const profileRecord =
26
- !info.profileTakedownRef || includeTakedowns
27
- ? info.profile
28
- : undefined
29
-
30
- return {
31
- did,
32
- handle: info.handle ?? INVALID_HANDLE,
33
- relatedRecords: profileRecord ? [profileRecord] : undefined,
34
- indexedAt: (
35
- info.sortedAt ?? new Date(0)
36
- ).toISOString() as DatetimeString,
37
- }
38
- },
39
- )
40
-
41
- return {
42
- encoding: 'application/json',
43
- body: {
44
- infos,
45
- },
46
- }
47
- },
48
- })
49
- }