fedipod-server 0.28.1 → 0.30.0

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 (438) hide show
  1. package/README.md +38 -34
  2. package/config/server.json +22 -0
  3. package/dist/claims.js +3 -2
  4. package/dist/directory.d.ts +2 -0
  5. package/dist/door.d.ts +4 -0
  6. package/dist/door.js +31 -0
  7. package/dist/fedipod.d.ts +16 -0
  8. package/dist/fedipod.js +13 -0
  9. package/dist/front.d.ts +3 -0
  10. package/dist/front.js +94 -0
  11. package/dist/handler.d.ts +39 -101
  12. package/dist/handler.js +86 -617
  13. package/dist/handler.jsonld +6 -30
  14. package/dist/identities.d.ts +62 -0
  15. package/dist/identities.js +236 -0
  16. package/dist/mounts.d.ts +43 -0
  17. package/dist/mounts.js +123 -0
  18. package/dist/opt-in.d.ts +46 -0
  19. package/dist/opt-in.js +176 -0
  20. package/dist/store-pod.js +37 -0
  21. package/package.json +10 -18
  22. package/lib/client/c2s.mjs +0 -582
  23. package/lib/client/localapi.mjs +0 -87
  24. package/lib/client/masto/accounts.mjs +0 -309
  25. package/lib/client/masto/body.mjs +0 -156
  26. package/lib/client/masto/index.mjs +0 -206
  27. package/lib/client/masto/instance.mjs +0 -112
  28. package/lib/client/masto/media.mjs +0 -79
  29. package/lib/client/masto/oauth.mjs +0 -656
  30. package/lib/client/masto/render.mjs +0 -518
  31. package/lib/client/masto/statuses.mjs +0 -372
  32. package/lib/client/masto/timelines.mjs +0 -438
  33. package/lib/client/oidc-auth.mjs +0 -62
  34. package/lib/client/streaming.mjs +0 -154
  35. package/lib/client/webpush.mjs +0 -98
  36. package/lib/connections/acctfeed.mjs +0 -257
  37. package/lib/connections/atproto.mjs +0 -309
  38. package/lib/connections/bskyfeed.mjs +0 -243
  39. package/lib/connections/bskygroup.mjs +0 -162
  40. package/lib/connections/fediacct.mjs +0 -253
  41. package/lib/connections/import.mjs +0 -357
  42. package/lib/connections/tagfeed.mjs +0 -212
  43. package/lib/connections/vault.mjs +0 -114
  44. package/lib/core/as2.mjs +0 -206
  45. package/lib/core/contexts/activitystreams.json +0 -379
  46. package/lib/core/contexts/anno.json +0 -126
  47. package/lib/core/contexts/did-v1.json +0 -57
  48. package/lib/core/contexts/fep-5711.json +0 -36
  49. package/lib/core/contexts/gotosocial.json +0 -86
  50. package/lib/core/contexts/identity-v1.json +0 -152
  51. package/lib/core/contexts/index.mjs +0 -63
  52. package/lib/core/contexts/join-lemmy.json +0 -33
  53. package/lib/core/contexts/joinmastodon.json +0 -28
  54. package/lib/core/contexts/litepub-0.1.json +0 -60
  55. package/lib/core/contexts/map.json +0 -19
  56. package/lib/core/contexts/miscellany.json +0 -19
  57. package/lib/core/contexts/quotes.json +0 -18
  58. package/lib/core/contexts/schemaorg.json +0 -8845
  59. package/lib/core/contexts/security-data-integrity-v1.json +0 -78
  60. package/lib/core/contexts/security-data-integrity-v2.json +0 -81
  61. package/lib/core/contexts/security-multikey-v1.json +0 -35
  62. package/lib/core/contexts/security-v1.json +0 -74
  63. package/lib/core/contexts/webfinger.json +0 -10
  64. package/lib/core/deliver.mjs +0 -371
  65. package/lib/core/graphview.mjs +0 -327
  66. package/lib/core/intake/activities.mjs +0 -633
  67. package/lib/core/intake/activity.mjs +0 -318
  68. package/lib/core/intake/channel.mjs +0 -144
  69. package/lib/core/intake/group.mjs +0 -256
  70. package/lib/core/intake/index.mjs +0 -701
  71. package/lib/core/intake/notes.mjs +0 -360
  72. package/lib/core/intake/verify.mjs +0 -142
  73. package/lib/core/keys.mjs +0 -153
  74. package/lib/core/lease.mjs +0 -206
  75. package/lib/core/polls.mjs +0 -105
  76. package/lib/core/profile-page.mjs +0 -104
  77. package/lib/core/proof.mjs +0 -79
  78. package/lib/core/publisher/collections.mjs +0 -237
  79. package/lib/core/publisher/index.mjs +0 -500
  80. package/lib/core/publisher/notes.mjs +0 -453
  81. package/lib/core/publisher/questions.mjs +0 -239
  82. package/lib/core/publisher/restore.mjs +0 -224
  83. package/lib/core/shapes/activitystreams.ttl +0 -157
  84. package/lib/core/shapes/index.mjs +0 -132
  85. package/lib/core/shapes/shapes-text.mjs +0 -13
  86. package/lib/core/social.mjs +0 -531
  87. package/lib/core/storage.mjs +0 -176
  88. package/lib/core/store.mjs +0 -568
  89. package/lib/core/wire-quotes.mjs +0 -71
  90. package/lib/core/wire.mjs +0 -889
  91. package/lib/device/account.mjs +0 -87
  92. package/lib/device/admin/index.mjs +0 -13
  93. package/lib/device/admin/origins.mjs +0 -35
  94. package/lib/device/admin/routes/connections.mjs +0 -144
  95. package/lib/device/admin/routes/gateway.mjs +0 -199
  96. package/lib/device/admin/routes/lifecycle.mjs +0 -200
  97. package/lib/device/admin/routes/owner.mjs +0 -322
  98. package/lib/device/admin/routes/setup.mjs +0 -412
  99. package/lib/device/admin/routes/social.mjs +0 -188
  100. package/lib/device/admin/server.mjs +0 -95
  101. package/lib/device/admin/static.mjs +0 -247
  102. package/lib/device/admin/surface.mjs +0 -315
  103. package/lib/device/certs.mjs +0 -281
  104. package/lib/device/cli/commands/account.mjs +0 -586
  105. package/lib/device/cli/commands/run.mjs +0 -278
  106. package/lib/device/cli/commands/service.mjs +0 -221
  107. package/lib/device/cli/commands/setup.mjs +0 -447
  108. package/lib/device/cli/commands/state.mjs +0 -561
  109. package/lib/device/cli/context.mjs +0 -288
  110. package/lib/device/export-collections.mjs +0 -161
  111. package/lib/device/gateway-move.mjs +0 -58
  112. package/lib/device/home.mjs +0 -161
  113. package/lib/device/migrate.mjs +0 -115
  114. package/lib/device/ports.mjs +0 -27
  115. package/lib/device/remote.mjs +0 -54
  116. package/lib/device/setup.mjs +0 -459
  117. package/lib/device/update.mjs +0 -96
  118. package/lib/gateway/caches.mjs +0 -36
  119. package/lib/gateway/directory.mjs +0 -90
  120. package/lib/gateway/front-core.mjs +0 -970
  121. package/lib/gateway/gateway-core.mjs +0 -165
  122. package/lib/gateway/headers.mjs +0 -49
  123. package/lib/gateway/httpsig.mjs +0 -159
  124. package/lib/gateway/notices.mjs +0 -84
  125. package/lib/gateway/quiet.mjs +0 -189
  126. package/lib/pod/README.md +0 -61
  127. package/lib/pod/actor.mjs +0 -96
  128. package/lib/pod/collection.mjs +0 -77
  129. package/lib/pod/containers.mjs +0 -140
  130. package/lib/pod/discovery.mjs +0 -46
  131. package/lib/pod/featured.mjs +0 -18
  132. package/lib/pod/followers.mjs +0 -24
  133. package/lib/pod/following.mjs +0 -10
  134. package/lib/pod/http.mjs +0 -74
  135. package/lib/pod/inbox.mjs +0 -166
  136. package/lib/pod/links.mjs +0 -35
  137. package/lib/pod/media.mjs +0 -27
  138. package/lib/pod/notes.mjs +0 -80
  139. package/lib/pod/notifications.mjs +0 -89
  140. package/lib/pod/outbox.mjs +0 -18
  141. package/lib/pod/package.json +0 -19
  142. package/lib/pod/policy.mjs +0 -58
  143. package/lib/pod/private.mjs +0 -19
  144. package/lib/pod/root.mjs +0 -104
  145. package/lib/pod/state.mjs +0 -40
  146. package/lib/pod/transport.mjs +0 -525
  147. package/lib/pod/urls.mjs +0 -85
  148. package/lib/server/embed.mjs +0 -423
  149. package/lib/session/README.md +0 -137
  150. package/lib/session/demo.html +0 -94
  151. package/lib/session/fedi-account.mjs +0 -408
  152. package/lib/session/fedi-login.mjs +0 -123
  153. package/lib/session/oidc-session.mjs +0 -233
  154. package/lib/session/package.json +0 -49
  155. package/lib/shared/guard.mjs +0 -213
  156. package/lib/shared/links.mjs +0 -9
  157. package/lib/shared/safefetch.mjs +0 -235
  158. package/lib/shared/ua.mjs +0 -29
  159. package/phanpy/dist/404.html +0 -40
  160. package/phanpy/dist/_headers +0 -2
  161. package/phanpy/dist/apple-touch-icon.png +0 -0
  162. package/phanpy/dist/assets/ICONS-DIPJeU0C.js +0 -2
  163. package/phanpy/dist/assets/ICONS-DIPJeU0C.js.map +0 -1
  164. package/phanpy/dist/assets/ScheduledAtField-D-Abfo4J.js +0 -183
  165. package/phanpy/dist/assets/ScheduledAtField-D-Abfo4J.js.map +0 -1
  166. package/phanpy/dist/assets/Temml-CCjoacWt.woff2 +0 -0
  167. package/phanpy/dist/assets/__vite-browser-external-C7iut881.js +0 -2
  168. package/phanpy/dist/assets/__vite-browser-external-C7iut881.js.map +0 -1
  169. package/phanpy/dist/assets/boosts-carousel-BiOaNdMT.jpg +0 -0
  170. package/phanpy/dist/assets/catch-up-O5q5C75Z.png +0 -0
  171. package/phanpy/dist/assets/chunk-aKtaBQYM.js +0 -1
  172. package/phanpy/dist/assets/compose-CFEx7wb4.js +0 -2
  173. package/phanpy/dist/assets/compose-CFEx7wb4.js.map +0 -1
  174. package/phanpy/dist/assets/compose-ZJN5xSb4.js +0 -35
  175. package/phanpy/dist/assets/compose-ZJN5xSb4.js.map +0 -1
  176. package/phanpy/dist/assets/debug.module-YFQgwnIr.js +0 -52
  177. package/phanpy/dist/assets/debug.module-YFQgwnIr.js.map +0 -1
  178. package/phanpy/dist/assets/dom-p1YcJ5Rw.js +0 -2
  179. package/phanpy/dist/assets/dom-p1YcJ5Rw.js.map +0 -1
  180. package/phanpy/dist/assets/home-mobile-dark@2x-Dc-J8-SM.png +0 -0
  181. package/phanpy/dist/assets/home-mobile-light@2x-Bd3fod8m.png +0 -0
  182. package/phanpy/dist/assets/home-tablet-dark@2x-BgcNI8le.png +0 -0
  183. package/phanpy/dist/assets/home-tablet-light@2x-BW2RV9T6.png +0 -0
  184. package/phanpy/dist/assets/icons/add-circle-line-WD0mwORD.js +0 -1
  185. package/phanpy/dist/assets/icons/alert-line-CpFUMf9s.js +0 -1
  186. package/phanpy/dist/assets/icons/android-2-line-Bzxnrd3S.js +0 -1
  187. package/phanpy/dist/assets/icons/announcement-line-5nwaJFJm.js +0 -1
  188. package/phanpy/dist/assets/icons/arrow-down-circle-line-a7Id9-Iv.js +0 -1
  189. package/phanpy/dist/assets/icons/arrow-down-line-B8uzXzq6.js +0 -1
  190. package/phanpy/dist/assets/icons/arrow-left-line-CGrGT9C-.js +0 -1
  191. package/phanpy/dist/assets/icons/arrow-right-line-CE-HERfX.js +0 -1
  192. package/phanpy/dist/assets/icons/arrow-to-up-line-CvdQjmcy.js +0 -1
  193. package/phanpy/dist/assets/icons/arrow-up-circle-line-DEparSNF.js +0 -1
  194. package/phanpy/dist/assets/icons/arrow-up-line-C7yBeugc.js +0 -1
  195. package/phanpy/dist/assets/icons/arrows-right-line-BtbXmJGP.js +0 -1
  196. package/phanpy/dist/assets/icons/at-line-CF66Bznk.js +0 -1
  197. package/phanpy/dist/assets/icons/attachment-line-BY8It-l9.js +0 -1
  198. package/phanpy/dist/assets/icons/blockquote-line-BS6pU_hm.js +0 -1
  199. package/phanpy/dist/assets/icons/board-line-C0UWXyA6.js +0 -1
  200. package/phanpy/dist/assets/icons/bookmark-line-1CtX5JLF.js +0 -1
  201. package/phanpy/dist/assets/icons/building-5-line-Dd59MzbO.js +0 -1
  202. package/phanpy/dist/assets/icons/bus-2-line-6_dvA0GG.js +0 -1
  203. package/phanpy/dist/assets/icons/calendar-day-line-Crpl_fmu.js +0 -1
  204. package/phanpy/dist/assets/icons/calendar-month-line-vommts2C.js +0 -1
  205. package/phanpy/dist/assets/icons/calendar-time-add-line-BU_DTlQk.js +0 -1
  206. package/phanpy/dist/assets/icons/camera-line-Cv69MEei.js +0 -1
  207. package/phanpy/dist/assets/icons/celebrate-line-B8DvIoi0.js +0 -1
  208. package/phanpy/dist/assets/icons/chart-bar-line-FK-QOmtF.js +0 -1
  209. package/phanpy/dist/assets/icons/chart-line-line-BGcJAFWw.js +0 -1
  210. package/phanpy/dist/assets/icons/chat-3-line-YFK2-hwz.js +0 -1
  211. package/phanpy/dist/assets/icons/check-circle-line-DsAxFr5-.js +0 -1
  212. package/phanpy/dist/assets/icons/clipboard-line-BBp364gJ.js +0 -1
  213. package/phanpy/dist/assets/icons/close-circle-line-CICdiuGz.js +0 -1
  214. package/phanpy/dist/assets/icons/close-line-DYrFWcjv.js +0 -1
  215. package/phanpy/dist/assets/icons/cloud-line-tiQAbah8.js +0 -1
  216. package/phanpy/dist/assets/icons/code-line-fAl8iiV3.js +0 -1
  217. package/phanpy/dist/assets/icons/comment-2-line-CR3g7WeB.js +0 -1
  218. package/phanpy/dist/assets/icons/copy-2-line-CLW69yF5.js +0 -1
  219. package/phanpy/dist/assets/icons/delete-2-line-B8xmbr4n.js +0 -1
  220. package/phanpy/dist/assets/icons/document-3-line-DBGNhAg2.js +0 -1
  221. package/phanpy/dist/assets/icons/document-line-C7mb9sb7.js +0 -1
  222. package/phanpy/dist/assets/icons/down-line-BGqSSThd.js +0 -1
  223. package/phanpy/dist/assets/icons/edit-4-line-DcgGaEhx.js +0 -1
  224. package/phanpy/dist/assets/icons/emoji-2-line-D8YgnM-y.js +0 -1
  225. package/phanpy/dist/assets/icons/exit-line-Dc07BS-x.js +0 -1
  226. package/phanpy/dist/assets/icons/external-link-line-BvpSkmjO.js +0 -1
  227. package/phanpy/dist/assets/icons/eye-2-line-CiWXx-f_.js +0 -1
  228. package/phanpy/dist/assets/icons/eye-close-line-BgTaSJ4P.js +0 -1
  229. package/phanpy/dist/assets/icons/filter-2-line-B_mR2usy.js +0 -1
  230. package/phanpy/dist/assets/icons/filter-line-C_nm-3cU.js +0 -1
  231. package/phanpy/dist/assets/icons/flag-1-line-C2HB05I0.js +0 -1
  232. package/phanpy/dist/assets/icons/forbid-circle-line-D3LTT9yd.js +0 -1
  233. package/phanpy/dist/assets/icons/formula-line-DLrt2d6j.js +0 -1
  234. package/phanpy/dist/assets/icons/grid-line-CgUmEikf.js +0 -1
  235. package/phanpy/dist/assets/icons/group-line-C5fnX0wU.js +0 -1
  236. package/phanpy/dist/assets/icons/hand-finger-2-line-BGgxbuL9.js +0 -1
  237. package/phanpy/dist/assets/icons/hashtag-line-CyTEEXBb.js +0 -1
  238. package/phanpy/dist/assets/icons/heart-crack-line-BZddbO2C.js +0 -1
  239. package/phanpy/dist/assets/icons/heart-line-CJ7K47J4.js +0 -1
  240. package/phanpy/dist/assets/icons/history-2-line-kWWvFzqv.js +0 -1
  241. package/phanpy/dist/assets/icons/history-line-bGQiwbTH.js +0 -1
  242. package/phanpy/dist/assets/icons/home-3-line-fRU1zeLG.js +0 -1
  243. package/phanpy/dist/assets/icons/information-line-iNk6-sOY.js +0 -1
  244. package/phanpy/dist/assets/icons/keyboard-line-DsCyuQNz.js +0 -1
  245. package/phanpy/dist/assets/icons/layout-4-line-CZkOX52Z.js +0 -1
  246. package/phanpy/dist/assets/icons/layout-5-line-B_znt5wO.js +0 -1
  247. package/phanpy/dist/assets/icons/left-line-eUw0tya4.js +0 -1
  248. package/phanpy/dist/assets/icons/lightning-line-DaKoDdix.js +0 -1
  249. package/phanpy/dist/assets/icons/link-2-line-DCqLmMA7.js +0 -1
  250. package/phanpy/dist/assets/icons/list-check-line-BAxosBh9.js +0 -1
  251. package/phanpy/dist/assets/icons/lock-line-CPoaXeUW.js +0 -1
  252. package/phanpy/dist/assets/icons/mail-line-B0P8aa1L.js +0 -1
  253. package/phanpy/dist/assets/icons/moon-line-CEqNAToP.js +0 -1
  254. package/phanpy/dist/assets/icons/more-1-fill-Dw2e5xab.js +0 -1
  255. package/phanpy/dist/assets/icons/more-3-line-BIiVjYTz.js +0 -1
  256. package/phanpy/dist/assets/icons/notification-line-BZZq2Gtu.js +0 -1
  257. package/phanpy/dist/assets/icons/pencil-line-CKh8-A1v.js +0 -1
  258. package/phanpy/dist/assets/icons/photo-album-line-Bnfg2u40.js +0 -1
  259. package/phanpy/dist/assets/icons/pin-line-DpTolyhs.js +0 -1
  260. package/phanpy/dist/assets/icons/play-fill-B0-G_8lX.js +0 -1
  261. package/phanpy/dist/assets/icons/qrcode-2-line-B6SPCaHn.js +0 -1
  262. package/phanpy/dist/assets/icons/quill-pen-line-B6LUrnCP.js +0 -1
  263. package/phanpy/dist/assets/icons/quote-left-fill-hQZ1cj_6.js +0 -1
  264. package/phanpy/dist/assets/icons/radar-line-CKyroTth.js +0 -1
  265. package/phanpy/dist/assets/icons/react-line-CoIKhhtK.js +0 -1
  266. package/phanpy/dist/assets/icons/refresh-2-line-D0mTF97S.js +0 -1
  267. package/phanpy/dist/assets/icons/right-line-B3KWJaqc.js +0 -1
  268. package/phanpy/dist/assets/icons/rocket-line-4KZl537D.js +0 -1
  269. package/phanpy/dist/assets/icons/round-fill-C69NTrZ0.js +0 -1
  270. package/phanpy/dist/assets/icons/round-line-B9k_1uo-.js +0 -1
  271. package/phanpy/dist/assets/icons/route-line-B28ReHcE.js +0 -1
  272. package/phanpy/dist/assets/icons/rows-4-line-CrBniagM.js +0 -1
  273. package/phanpy/dist/assets/icons/scan-line-DSf74YdP.js +0 -1
  274. package/phanpy/dist/assets/icons/search-2-line-B6geIU1z.js +0 -1
  275. package/phanpy/dist/assets/icons/settings-3-line-azJwK47w.js +0 -1
  276. package/phanpy/dist/assets/icons/settings-6-line-C_5zc5YR.js +0 -1
  277. package/phanpy/dist/assets/icons/share-2-line-D5MxWjrm.js +0 -1
  278. package/phanpy/dist/assets/icons/share-forward-line-Cp61fZzZ.js +0 -1
  279. package/phanpy/dist/assets/icons/sparkles-2-line-DYYyXTaW.js +0 -1
  280. package/phanpy/dist/assets/icons/sparkles-line-C2hY1s6I.js +0 -1
  281. package/phanpy/dist/assets/icons/time-line-BF3eet1v.js +0 -1
  282. package/phanpy/dist/assets/icons/transfer-4-line-oisfvTBw.js +0 -1
  283. package/phanpy/dist/assets/icons/translate-line-BFWol2Ce.js +0 -1
  284. package/phanpy/dist/assets/icons/unlock-line-X_x5vwv3.js +0 -1
  285. package/phanpy/dist/assets/icons/upload-3-line-DgzwUJeW.js +0 -1
  286. package/phanpy/dist/assets/icons/user-4-line-BVSynZCp.js +0 -1
  287. package/phanpy/dist/assets/icons/user-add-2-line-BlGS5Q8q.js +0 -1
  288. package/phanpy/dist/assets/icons/user-add-line-BbXdHG4z.js +0 -1
  289. package/phanpy/dist/assets/icons/user-edit-line-BFAHOV0X.js +0 -1
  290. package/phanpy/dist/assets/icons/user-follow-line-BXux0wSd.js +0 -1
  291. package/phanpy/dist/assets/icons/user-star-line-DdYlpHLU.js +0 -1
  292. package/phanpy/dist/assets/icons/user-warning-line-Cj43j0_E.js +0 -1
  293. package/phanpy/dist/assets/icons/user-x-line-DIDgNlPH.js +0 -1
  294. package/phanpy/dist/assets/icons/volume-line-Bs390KQt.js +0 -1
  295. package/phanpy/dist/assets/icons/volume-mute-line-DzlzIqFZ.js +0 -1
  296. package/phanpy/dist/assets/icons/walk-line-yNXfB-md.js +0 -1
  297. package/phanpy/dist/assets/icons/world-2-line-CenkGIwj.js +0 -1
  298. package/phanpy/dist/assets/icons/zoom-in-line-CaENUphf.js +0 -1
  299. package/phanpy/dist/assets/icons/zoom-out-line-BDNk0EWo.js +0 -1
  300. package/phanpy/dist/assets/instances-BNPptnn-.json +0 -333
  301. package/phanpy/dist/assets/locales/ar-SA-CfheRbCu.js +0 -1
  302. package/phanpy/dist/assets/locales/ca-ES-DHRW86Tz.js +0 -1
  303. package/phanpy/dist/assets/locales/cs-CZ-CKoqEuA1.js +0 -1
  304. package/phanpy/dist/assets/locales/de-DE-ByRPMRFy.js +0 -1
  305. package/phanpy/dist/assets/locales/eo-UY-CPC7wLCS.js +0 -1
  306. package/phanpy/dist/assets/locales/es-ES-dJa0Fd9t.js +0 -1
  307. package/phanpy/dist/assets/locales/eu-ES-C3djlPR2.js +0 -1
  308. package/phanpy/dist/assets/locales/fa-IR-DTT490Ck.js +0 -1
  309. package/phanpy/dist/assets/locales/fi-FI-B23MCPuz.js +0 -1
  310. package/phanpy/dist/assets/locales/fr-FR-BcaQsO5C.js +0 -1
  311. package/phanpy/dist/assets/locales/gl-ES-BR-CVKBN.js +0 -1
  312. package/phanpy/dist/assets/locales/he-IL-CfheRbCu.js +0 -1
  313. package/phanpy/dist/assets/locales/hu-HU-CfheRbCu.js +0 -1
  314. package/phanpy/dist/assets/locales/it-IT-C1136UFV.js +0 -1
  315. package/phanpy/dist/assets/locales/ja-JP-CRZmRAhD.js +0 -1
  316. package/phanpy/dist/assets/locales/kab-Cz8xH_TT.js +0 -1
  317. package/phanpy/dist/assets/locales/ko-KR-CG9UiY4o.js +0 -1
  318. package/phanpy/dist/assets/locales/lt-LT-CJcI6sHZ.js +0 -1
  319. package/phanpy/dist/assets/locales/nb-NO-CfheRbCu.js +0 -1
  320. package/phanpy/dist/assets/locales/nl-NL-DxN4Yc1t.js +0 -1
  321. package/phanpy/dist/assets/locales/oc-FR-CfheRbCu.js +0 -1
  322. package/phanpy/dist/assets/locales/pl-PL-DkwGXf6P.js +0 -1
  323. package/phanpy/dist/assets/locales/pseudo-LOCALE-CQ4XxkQ0.js +0 -1
  324. package/phanpy/dist/assets/locales/pt-BR-nGL0HdFS.js +0 -1
  325. package/phanpy/dist/assets/locales/pt-PT-Cp17aj2z.js +0 -1
  326. package/phanpy/dist/assets/locales/ru-RU-0Y8cIoaK.js +0 -1
  327. package/phanpy/dist/assets/locales/th-TH-CfheRbCu.js +0 -1
  328. package/phanpy/dist/assets/locales/tok-CfheRbCu.js +0 -1
  329. package/phanpy/dist/assets/locales/tr-TR-CfheRbCu.js +0 -1
  330. package/phanpy/dist/assets/locales/uk-UA-C5E3dFBf.js +0 -1
  331. package/phanpy/dist/assets/locales/zh-CN-BHJi7_et.js +0 -1
  332. package/phanpy/dist/assets/locales/zh-TW-CfheRbCu.js +0 -1
  333. package/phanpy/dist/assets/main-BdqNbG-a.js +0 -26
  334. package/phanpy/dist/assets/main-BdqNbG-a.js.map +0 -1
  335. package/phanpy/dist/assets/mock-home-DGhR__He.js +0 -2
  336. package/phanpy/dist/assets/mock-home-DGhR__He.js.map +0 -1
  337. package/phanpy/dist/assets/multi-column-ROck0NVt.jpg +0 -0
  338. package/phanpy/dist/assets/multi-hashtag-timeline-DH5INVHi.jpg +0 -0
  339. package/phanpy/dist/assets/nested-comments-thread-hv59kZLc.jpg +0 -0
  340. package/phanpy/dist/assets/polyfill-force-H8sUkLGp.js +0 -2
  341. package/phanpy/dist/assets/polyfill-force-H8sUkLGp.js.map +0 -1
  342. package/phanpy/dist/assets/pwa-viewport-ogKbF51K.js +0 -20
  343. package/phanpy/dist/assets/pwa-viewport-ogKbF51K.js.map +0 -1
  344. package/phanpy/dist/assets/style-B1iLPTPR.css +0 -2
  345. package/phanpy/dist/assets/temml-DuyIQMei.js +0 -97
  346. package/phanpy/dist/assets/temml-DuyIQMei.js.map +0 -1
  347. package/phanpy/dist/assets/tinyld.light.node-DtbBhLYC.js +0 -2
  348. package/phanpy/dist/assets/tinyld.light.node-DtbBhLYC.js.map +0 -1
  349. package/phanpy/dist/assets/year-in-posts-B2lywqdx.png +0 -0
  350. package/phanpy/dist/assets/year-in-posts-DJv_star.js +0 -3
  351. package/phanpy/dist/assets/year-in-posts-DJv_star.js.map +0 -1
  352. package/phanpy/dist/compose/index.html +0 -20
  353. package/phanpy/dist/favicon.ico +0 -0
  354. package/phanpy/dist/index.html +0 -73
  355. package/phanpy/dist/logo-192.png +0 -0
  356. package/phanpy/dist/logo-512.png +0 -0
  357. package/phanpy/dist/logo-badge-72.png +0 -0
  358. package/phanpy/dist/logo-maskable-512.png +0 -0
  359. package/phanpy/dist/logo-monochrome-512.png +0 -0
  360. package/phanpy/dist/logo-monochrome-maskable-512.png +0 -0
  361. package/phanpy/dist/manifest.webmanifest +0 -1
  362. package/phanpy/dist/og-image-2.jpg +0 -0
  363. package/phanpy/dist/og-image.png +0 -0
  364. package/phanpy/dist/robots.txt +0 -2
  365. package/phanpy/dist/sw.js +0 -2
  366. package/phanpy/dist/sw.js.map +0 -1
  367. package/phanpy/dist/version.json +0 -1
  368. package/run-agent.mjs +0 -897
  369. package/vendor/gate.cjs +0 -138
  370. package/vendor/idp-grant.cjs +0 -394
  371. package/vendor/jfetch.cjs +0 -16
  372. package/web/admin/actors.js +0 -145
  373. package/web/admin/bar.css +0 -126
  374. package/web/admin/bar.js +0 -99
  375. package/web/admin/client/client.js +0 -66
  376. package/web/admin/client/index.html +0 -69
  377. package/web/admin/client-pick.js +0 -79
  378. package/web/admin/common.js +0 -23
  379. package/web/admin/connections.js +0 -112
  380. package/web/admin/gateway.js +0 -133
  381. package/web/admin/group.js +0 -258
  382. package/web/admin/index.html +0 -603
  383. package/web/admin/notices-bar.js +0 -90
  384. package/web/admin/oauth-signin.mjs +0 -37
  385. package/web/admin/record.js +0 -390
  386. package/web/admin/setup/index.html +0 -241
  387. package/web/admin/setup/setup.js +0 -326
  388. package/web/admin/tokens.css +0 -68
  389. package/web/admin/upkeep.js +0 -177
  390. package/web/admin/window.css +0 -55
  391. package/web/admin/window.js +0 -136
  392. package/web/app/README.md +0 -81
  393. package/web/app/admin-facade.mjs +0 -588
  394. package/web/app/agent.mjs +0 -663
  395. package/web/app/atproto-browser.mjs +0 -86
  396. package/web/app/authorize_interaction.html +0 -56
  397. package/web/app/authorize_interaction.js +0 -69
  398. package/web/app/boot.mjs +0 -576
  399. package/web/app/deliver-relay.mjs +0 -129
  400. package/web/app/dist/boot.js +0 -34218
  401. package/web/app/dist/boot.js.map +0 -7
  402. package/web/app/dist/sw.js +0 -72810
  403. package/web/app/dist/sw.js.map +0 -7
  404. package/web/app/fediacct-browser.mjs +0 -146
  405. package/web/app/gateway-move.mjs +0 -60
  406. package/web/app/idb-kv.mjs +0 -35
  407. package/web/app/index.html +0 -242
  408. package/web/app/keys-browser.mjs +0 -71
  409. package/web/app/keystore.mjs +0 -82
  410. package/web/app/oidc-session.mjs +0 -6
  411. package/web/app/pod-auth.mjs +0 -248
  412. package/web/app/pod-remote.mjs +0 -84
  413. package/web/app/shims/_globals.mjs +0 -2
  414. package/web/app/shims/fedify-sig.mjs +0 -77
  415. package/web/app/shims/node-crypto.mjs +0 -113
  416. package/web/app/shims/node-fs.mjs +0 -17
  417. package/web/app/shims/node-path.mjs +0 -19
  418. package/web/app/shims/node-url.mjs +0 -7
  419. package/web/app/shims/prelude.js +0 -58
  420. package/web/app/shims/safefetch.mjs +0 -58
  421. package/web/app/shims/shapes-text.mjs +0 -8
  422. package/web/app/shims/web-push.mjs +0 -14
  423. package/web/app/signup.mjs +0 -318
  424. package/web/app/sw-src.mjs +0 -220
  425. package/web/app/update.js +0 -70
  426. package/web/front/admin.html +0 -55
  427. package/web/front/admin.js +0 -89
  428. package/web/front/install.sh +0 -69
  429. package/web/front/new-account.html +0 -35
  430. package/web/front/new-account.js +0 -13
  431. package/web/front/notices.html +0 -69
  432. package/web/front/notices.js +0 -107
  433. package/web/front/run.html +0 -58
  434. package/web/front/run.js +0 -195
  435. package/web/front/solid-oidc-client.js +0 -6
  436. package/web/icons/forum.svg +0 -11
  437. package/web/icons/gateway.svg +0 -14
  438. package/web/icons/local.svg +0 -11
package/README.md CHANGED
@@ -30,13 +30,12 @@ before installing: a server that does not meet them cannot offer accounts, and
30
30
  sign-up refuses rather than half-working.
31
31
 
32
32
  - **Community Solid Server 7.**
33
- - **Pods on subdomains or on paths.** A subdomain pod answers on its own
34
- address (`@mei@mei.example.org`); a suffix pod on a path of the server's own
35
- host answers under that path, and the server fronts it so its address is the
36
- server's host (`@aisha@server.example`, for a pod at
37
- `https://server.example/aisha/`). Either works — a suffix pod cannot resolve
38
- its own handle, so it is followable only through the server's apex, which the
39
- server also runs.
33
+ - **Subdomained or suffixed pods.** A subdomained pod answers on its own
34
+ address (`@mei@mei.example.org`); a suffixed pod answers under its path, and
35
+ the server fronts it so its address is the server's host
36
+ (`@aisha@server.example`, for a pod at `https://server.example/aisha/`).
37
+ Either works — a suffixed pod cannot resolve its own handle, so it is
38
+ followable only through the server's apex, which the server also runs.
40
39
  - **A single worker.** Run the server as one copy of itself — `--workers 1`,
41
40
  which is the default. With more, it still serves pods normally, but no pod
42
41
  can be an account: sign-up is refused, and an account set up earlier goes on
@@ -53,6 +52,10 @@ sign-up refuses rather than half-working.
53
52
  npm install fedipod-server
54
53
  ```
55
54
 
55
+ It installs `fedipod` with it: the agent, the Gateway's front and the pages
56
+ are that package's, and a fix there reaches this component at your next
57
+ `npm install`.
58
+
56
59
  Add the package context to your CSS config and import the shipped snippet:
57
60
 
58
61
  ```json
@@ -70,8 +73,8 @@ Add the package context to your CSS config and import the shipped snippet:
70
73
 
71
74
  Then set what you need on the `urn:fedipod:server:Handler` node and restart
72
75
  the server.
73
- A subdomain-pods CSS config gives each identity an origin of its own; a
74
- suffix (path) config hosts each on a path of the shared host. Both opt in.
76
+ A CSS config with subdomained pods gives each identity an origin of its own;
77
+ one with suffixed pods hosts each under its own path. Both opt in.
75
78
  The snippet places the component in the routing waterfall ahead of
76
79
  the LDP catch-all, on the initializer and finalizer lists so identities start
77
80
  and stop with the server, and on the websocket handler list for the live feed.
@@ -88,9 +91,9 @@ and stop with the server, and on the websocket handler list for the live feed.
88
91
  ```
89
92
 
90
93
  An identity is provisioned when its owner opts in: its name is the pod's
91
- subdomain label, or its last path segment on a suffix pod, and it publishes an
94
+ subdomain label, or its last path segment on a suffixed pod, and it publishes an
92
95
  actor and a signing key on the pod itself. Its handle resolves on the pod for a
93
- subdomain, and through the server's apex for a suffix pod. Everything it is made of lives on its pod — its state, its private
96
+ subdomained pod, and through the server's apex for a suffixed pod. Everything it is made of lives on its pod — its state, its private
94
97
  signing key, the secret guarding its own pages, and the credentials for any
95
98
  accounts its owner connects on other servers. Each identity has its own
96
99
  secret; one owner's opens nobody else's door. The opt-in reply is where the
@@ -108,9 +111,9 @@ naming the pod the identity runs on. Nothing private is in it.
108
111
  |---|---|
109
112
  | `agentRuntimeOptIn` | Whether pod owners can sign up. With it off, nothing runs. |
110
113
  | `agentDataDir` | Where each identity keeps the file naming its pod; its log lines go to the server's own log. Required whenever sign-up is on. |
111
- | `agentUiPath` | Where the owner's pages live on the pod's origin. `/fp/` by default; empty serves no pages. On a suffix pod it is under the pod's path, e.g. `/aisha/fp/`. |
114
+ | `agentUiPath` | Where the owner's pages live on the pod's origin. `/fp/` by default; empty serves no pages. On a suffixed pod it is under the pod's path, e.g. `/aisha/fp/`. |
112
115
  | `agentRegistryContainer` | The internal container holding the sign-up rows. |
113
- | `runPage` | The HTML of the page where a pod owner opts in or out. The package's own `web/front/run.html` is served unless you set this. |
116
+ | `runPage` | The HTML of the page where a pod owner opts in or out. The page `fedipod` ships is served unless you set this. |
114
117
  | `runPath` | Where that page answers. `/.fediverse-account` unless you set it. The path it takes is one the pod no longer serves, so it is yours to name; the dot keeps it out of the way of anybody's data. |
115
118
  | `agentWebIdSuffix` | Path from a pod's base to its owner's WebID. Defaults to `profile/card#me`. |
116
119
  | `agentPollSeconds` | How often the inbox is swept. Deliveries also wake the sweep as they land, so this is the fallback. |
@@ -134,10 +137,8 @@ Each identity answers on its pod's origin, so the pod is what a client
134
137
  connects to. Point a Mastodon app at `https://mei.example.org/` and it finds
135
138
  what it expects: nodeinfo, the client API under `/api/`, sign-in under
136
139
  `/oauth/`, the live feed at `/api/v1/streaming`, and the ActivityPub write API
137
- at `/ap/outbox`. The owner's own pages — the record and, in a repository
138
- checkout, the bundled web client — are behind `agentUiPath`, which the door
139
- secret guards. The published package does not carry the web client; point a
140
- Mastodon app at the pod instead.
140
+ at `/ap/outbox`. The owner's own pages — the record and the bundled web client — are behind
141
+ `agentUiPath`, which the door secret guards.
141
142
 
142
143
  The client API answers any origin, the way any Mastodon server does, so a
143
144
  browser client works too: it registers an app, and the authorize screen names
@@ -155,11 +156,11 @@ that document's address and registers nothing here. Once in, it posts to the
155
156
  outbox the actor names, and reads what the identity received at `/ap/inbox`,
156
157
  which nobody but the owner may read.
157
158
 
158
- A subdomain pod gets an origin of its own and answers at its root; a suffix
159
- pod shares the host and answers under its own path (`/aisha/ap/actor`,
160
- `/aisha/api/…`, `/aisha/oauth/…`, its door at `/aisha/fp/`). So a host carries
161
- at most one root identity, but any number of path pods beside it; a second
162
- root identity on a host, or a path pod nesting under another, is refused at
159
+ A subdomained pod gets an origin of its own and answers at its root; a
160
+ suffixed pod answers under its own path (`/aisha/ap/actor`, `/aisha/api/…`,
161
+ `/aisha/oauth/…`, its door at `/aisha/fp/`). So a host carries at most one
162
+ root identity, but any number of suffixed pods beside it; a second root
163
+ identity on a host, or a suffixed pod nesting under another, is refused at
163
164
  opt-in rather than half-working.
164
165
 
165
166
  ### Before you turn it on
@@ -173,22 +174,22 @@ for anyone hosting other people, it is a promise being made to them.
173
174
  owner's door, with that identity's own door secret:
174
175
 
175
176
  ```
176
- # subdomain pod:
177
+ # subdomained pod:
177
178
  curl -X POST https://mei.example.org/fp/config \
178
179
  -H 'x-dk-token: THE_DOOR_SECRET_FROM_THE_OPT_IN_REPLY' -H 'content-type: application/json' \
179
180
  -d '{"password":"the one you will type into your phone"}'
180
- # suffix pod — the door is under the pod's path:
181
+ # suffixed pod — the door is under the pod's path:
181
182
  curl -X POST https://server.example/aisha/fp/config \
182
183
  -H 'x-dk-token: THE_DOOR_SECRET_FROM_THE_OPT_IN_REPLY' -H 'content-type: application/json' \
183
184
  -d '{"password":"the one you will type into your phone"}'
184
185
  ```
185
186
 
186
- **Some pod paths stop being served.** On a subdomain pod the paths above
187
+ **Some pod paths stop being served.** On a subdomained pod the paths above
187
188
  belong to the identity, so pod resources at those names — a container called
188
189
  `api`, `oauth` or `fp`, or documents at `ap/actor`, `ap/outbox`,
189
190
  `ap/inbox`, `.well-known/oauth-authorization-server`,
190
191
  `.well-known/nodeinfo` and `nodeinfo/2.0` — are not served over HTTP there.
191
- On a suffix pod the same names are taken under the pod's own path
192
+ On a suffixed pod the same names are taken under the pod's own path
192
193
  (`/aisha/api/…`, `/aisha/ap/actor`, `/aisha/fp/`, and so on); the rest of the
193
194
  path, and every other pod on the host, is untouched.
194
195
  They stay in the pod and in its listings. Every other path is the pod, exactly
@@ -245,25 +246,28 @@ TypeScript, built the way CSS builds its own components.
245
246
  npm install
246
247
  npm run build # tsc → dist, then componentsjs-generator → dist/components
247
248
  npm test # unit tests, plus the transport against a real CSS store
248
- npm run test:e2e # boots a real server (subdomain pods) and uses it as a client would
249
- npm run test:e2e:suffix # the same, for pods on paths of one host (mode d)
249
+ npm run test:e2e # boots a real server (subdomained pods) and uses it as a client would
250
+ npm run test:e2e:suffix # the same, for suffixed pods (mode d)
250
251
  ```
251
252
 
252
253
  `npm test` drives a genuine CSS store stack — ETags, conditional writes,
253
254
  container listings — through the transport an identity uses, and checks the
254
255
  lease protocol and the deletion deny-list still hold across it.
255
256
 
256
- `npm test` is also what a publish runs, so a red suite blocks one.
257
+ `npm test` is also what a publish runs, so a red suite blocks one. In a
258
+ FediPod checkout the tests run against the checkout's own `fedipod`:
259
+ `scripts/link-fedipod.mjs` links it into `node_modules` before each test
260
+ script, and does nothing anywhere else.
257
261
 
258
262
  `npm run test:e2e` starts a real Community Solid Server with three pods (two
259
263
  become identities up front; the third opts in and out at runtime), then signs in as a phone app does, posts,
260
264
  receives a follow from another server, and watches the live feed. It takes
261
265
  about a minute. `FEDIPOD_E2E_LOG=info` shows the server's log while it runs.
262
- `npm run test:e2e:suffix` does the same on a server whose pods live on paths of
263
- one host (`@aisha@server`): it proves the apex WebFinger resolves straight to
264
- the pod actor, that the actor, inbox, client API, OAuth and door all answer
265
- under the pod's path, that two path pods on one origin stay separate, and that
266
- a signed delivery is verified at the pod's own door.
266
+ `npm run test:e2e:suffix` does the same on a server whose pods are suffixed
267
+ (`@aisha@server`): it proves the apex WebFinger resolves straight to the pod
268
+ actor, that the actor, inbox, client API, OAuth and door all answer under the
269
+ pod's path, that two suffixed pods on one origin stay separate, and that a
270
+ signed delivery is verified at the pod's own door.
267
271
 
268
272
  `dist/` and `node_modules/` are gitignored; `src/`, `config/` and this file are
269
273
  the sources.
@@ -60,6 +60,28 @@
60
60
  }
61
61
  ]
62
62
  },
63
+ {
64
+ "comment": "ActivityStreams documents are stored as application/activity+json. The spec asks a server to answer application/ld+json with the ActivityStreams profile for them too, and CSS alone refuses that form with 501. This relabels the one type as the other, both ways, without touching the bytes, so either Accept reads the same document.",
65
+ "@id": "urn:fedipod:server:ActivityStreamsReplacer",
66
+ "@type": "ContentTypeReplacer",
67
+ "replacements": [
68
+ { "ContentTypeReplacer:_replacements_key": "application/activity+json", "ContentTypeReplacer:_replacements_value": "application/ld+json" },
69
+ { "ContentTypeReplacer:_replacements_key": "application/ld+json", "ContentTypeReplacer:_replacements_value": "application/activity+json" }
70
+ ]
71
+ },
72
+ {
73
+ "comment": "The replacer goes first in the converter chain, before CSS's own ContentTypeReplacer.",
74
+ "@type": "Override",
75
+ "overrideInstance": { "@id": "urn:solid-server:default:ChainedConverter" },
76
+ "overrideSteps": [
77
+ {
78
+ "@type": "OverrideListInsertBefore",
79
+ "overrideParameter": { "@id": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/dist/storage/conversion/ChainedConverter.jsonld#ChainedConverter_converters" },
80
+ "overrideTarget": { "@id": "urn:solid-server:default:ContentTypeReplacer" },
81
+ "overrideValue": { "@id": "urn:fedipod:server:ActivityStreamsReplacer" }
82
+ }
83
+ ]
84
+ },
63
85
  {
64
86
  "comment": "Insert the handler into the routing waterfall just before the LDP catch-all, so it claims only the front routes and everything else stays normal CSS. OverrideListInsertBefore is available in componentsjs 5.x (which CSS 7 uses).",
65
87
  "@type": "Override",
package/dist/claims.js CHANGED
@@ -51,11 +51,12 @@ const AGENT_PATHS = new Set([
51
51
  ]);
52
52
  const AGENT_PREFIXES = ['/api/', '/oauth/', '/@']; // /@handle: the short profile address
53
53
  // An identity's inbox is the container `/<root>/ap/inbox/`, matched by shape
54
- // rather than a fixed root. A POST here is a delivery, verified at the door
54
+ // rather than a fixed root — and the root may be nested, wherever its owner put
55
+ // the `fedipod/` container. A POST here is a delivery, verified at the door
55
56
  // before it is written; the handler checks the exact path per identity. The
56
57
  // path is relative to the identity's mount (see agentClaims), so a suffix pod's
57
58
  // `/aisha/fedipod/ap/inbox/` arrives here already stripped to `/fedipod/ap/inbox/`.
58
- const isInboxPath = (pathname) => /^\/[^/]+\/ap\/inbox\/$/u.test(pathname);
59
+ const isInboxPath = (pathname) => /^\/(?:[^/]+\/)+ap\/inbox\/$/u.test(pathname);
59
60
  exports.isInboxPath = isInboxPath;
60
61
  /**
61
62
  * True when this path belongs to an identity's client surface.
@@ -38,6 +38,8 @@ export interface AgentRegistryRecord {
38
38
  host: string;
39
39
  webId: string;
40
40
  optedInAt: string;
41
+ /** Where on the pod the account lives, relative to it; absent on older rows, which are at fedipod/. */
42
+ root?: string;
41
43
  }
42
44
  /**
43
45
  * The registry key for an opted-in pod: its host plus its path. Several pods
package/dist/door.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { HttpHandlerInput } from '@solid/community-server';
2
+ import type { EmbeddedIdentity } from './identities';
3
+ import type { FediPodServerHandler } from './handler';
4
+ export declare function deliverAtDoor(h: FediPodServerHandler, identity: EmbeddedIdentity, request: HttpHandlerInput['request'], response: HttpHandlerInput['response']): Promise<void>;
package/dist/door.js ADDED
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ // door.ts — a delivery to an identity's own inbox, verified here: the server
3
+ // that stores the inbox is the one the request reached, so the signature is
4
+ // checked while its headers exist and the receipt is written beside the
5
+ // activity. The same door code the front runs; nothing is renamed.
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.deliverAtDoor = deliverAtDoor;
8
+ const adapt_1 = require("./adapt");
9
+ const fedipod_1 = require("./fedipod");
10
+ async function deliverAtDoor(h, identity, request, response) {
11
+ const s = h.internals();
12
+ const { deliverToInbox } = await (0, fedipod_1.esmImport)(fedipod_1.EMBED);
13
+ let whatwg;
14
+ try {
15
+ // The pod's own origin: the signature covers the path and the Host header, and both are the pod's.
16
+ whatwg = await (0, adapt_1.nodeToWhatwg)(request, new URL(identity.podHome).origin);
17
+ }
18
+ catch (e) {
19
+ const status = e.statusCode === 413 ? 413 : 400;
20
+ response.writeHead(status, { 'content-type': 'application/json' });
21
+ response.end(JSON.stringify({ error: e.message }));
22
+ return;
23
+ }
24
+ const out = await deliverToInbox(identity.agent, whatwg, {
25
+ podPut: (url, body, ct) => s.podPut(url, body, ct),
26
+ gatewayWebId: s.args.gatewayWebId ?? null,
27
+ });
28
+ s.logger.info(`FediPod: delivery for @${identity.handle} at the door — ${out.reason} (${out.status})`);
29
+ response.writeHead(out.status, { 'content-type': 'application/json' });
30
+ response.end(JSON.stringify({ reason: out.reason }));
31
+ }
@@ -0,0 +1,16 @@
1
+ export declare const FRONT_CORE = "fedipod/front";
2
+ export declare const FRONT_PAGES = "fedipod/front-pages";
3
+ export declare const EMBED = "fedipod/embed";
4
+ export declare const PLACE = "fedipod/place";
5
+ export declare const TRANSPORT = "fedipod/pod/transport.mjs";
6
+ export declare const esmImport: (s: string) => Promise<Record<string, Function>>;
7
+ /** The front's pages and the files they load, as fedipod/front-pages reads them. */
8
+ export interface FrontPages {
9
+ signupPage: string | null;
10
+ runPage: string | null;
11
+ adminPage: string | null;
12
+ noticesPage: string | null;
13
+ authBundle: string | null;
14
+ pageScripts: Record<string, string | null>;
15
+ installScript: string | null;
16
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ // fedipod.ts — the fedipod modules this component loads, by name, at runtime.
3
+ // They are an ESM tree; a real dynamic import() built via Function keeps tsc
4
+ // from downleveling it to require(), which cannot load an ESM module with
5
+ // top-level await under a CommonJS build.
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.esmImport = exports.TRANSPORT = exports.PLACE = exports.EMBED = exports.FRONT_PAGES = exports.FRONT_CORE = void 0;
8
+ exports.FRONT_CORE = 'fedipod/front';
9
+ exports.FRONT_PAGES = 'fedipod/front-pages';
10
+ exports.EMBED = 'fedipod/embed';
11
+ exports.PLACE = 'fedipod/place';
12
+ exports.TRANSPORT = 'fedipod/pod/transport.mjs';
13
+ exports.esmImport = new Function('s', 'return import(s)');
@@ -0,0 +1,3 @@
1
+ import type { HttpHandlerInput } from '@solid/community-server';
2
+ import type { FediPodServerHandler } from './handler';
3
+ export declare function serveFront(h: FediPodServerHandler, request: HttpHandlerInput['request'], response: HttpHandlerInput['response']): Promise<void>;
package/dist/front.js ADDED
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ // front.ts — a request the Gateway's front answers: the same routeFront the
3
+ // Netlify front runs, given this server's pages, its directory, its store
4
+ // and the opt-in controls.
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.serveFront = serveFront;
7
+ const adapt_1 = require("./adapt");
8
+ const fedipod_1 = require("./fedipod");
9
+ async function serveFront(h, request, response) {
10
+ const s = h.internals();
11
+ const { routeFront } = await (0, fedipod_1.esmImport)(fedipod_1.FRONT_CORE);
12
+ // Read on each request, so an edited page shows without a restart. A
13
+ // missing file is not fatal: the route it feeds answers 404.
14
+ const { frontPages } = await (0, fedipod_1.esmImport)(fedipod_1.FRONT_PAGES);
15
+ const pages = frontPages();
16
+ let whatwg;
17
+ try {
18
+ whatwg = await (0, adapt_1.nodeToWhatwg)(request, s.args.frontOrigin);
19
+ }
20
+ catch (e) {
21
+ const status = e.statusCode === 413 ? 413 : 400;
22
+ response.writeHead(status, { 'content-type': 'application/json' });
23
+ response.end(JSON.stringify({ error: e.message }));
24
+ return;
25
+ }
26
+ const out = await routeFront(whatwg, {
27
+ host: s.frontHost,
28
+ frontOrigin: s.args.frontOrigin,
29
+ // This server issued the session the reader is already using, so it can
30
+ // read it rather than sending them to an identity provider that has just
31
+ // told them who they are. Same-origin only; front-core decides that.
32
+ webIdsFromSession: (req) => h.webIdsFromSession(req),
33
+ gatewayWebId: s.args.gatewayWebId,
34
+ offersPods: !!s.args.offersPods,
35
+ signupPage: s.args.signupPage || pages.signupPage,
36
+ runPage: s.args.runPage || pages.runPage,
37
+ runPath: s.runPath,
38
+ adminPage: s.args.adminPage || pages.adminPage,
39
+ // The notices page renders here too, and says the server keeps none:
40
+ // a notices store is the Netlify front's, not this component's.
41
+ noticesPage: pages.noticesPage,
42
+ // The opt-in and roster pages load the sign-in library, and the installer
43
+ // command is handed out with it; without these the pages render but
44
+ // cannot be used.
45
+ authBundle: pages.authBundle,
46
+ // Each page's own script, so the pages can be served under
47
+ // `script-src 'self'` (see fedipod/front).
48
+ pageScripts: pages.pageScripts,
49
+ installScript: pages.installScript,
50
+ lookup: (handle) => h.dir.lookup(handle),
51
+ putDirectory: (handle, rec) => h.dir.putDirectory(handle, rec),
52
+ podPut: (_handle, url, body, ct) => s.podPut(url, body, ct),
53
+ // Reads for the public proxy. `s.io.read` goes STRAIGHT into the
54
+ // resource store, which applies no access control of its own — so this is
55
+ // the one place that has to say what may be read, and it says: only
56
+ // inside the pod of the handle being served, and never a server-internal
57
+ // tree. Without it a row could name any location and this would fetch it
58
+ // (the directory, with every user's receipt secret, included).
59
+ //
60
+ // The front now refuses to attach such a row at all (podHomeProblem in
61
+ // fedipod/front); this is the same refusal at the other end, because
62
+ // a row can also arrive from a seed or an older deploy.
63
+ podGet: async (url, opts) => {
64
+ const denied = { status: 403, text: async () => '', headers: { get: () => null } };
65
+ let target;
66
+ try {
67
+ target = new URL(url);
68
+ }
69
+ catch {
70
+ return denied;
71
+ }
72
+ if (/(^|\/)\.internal(\/|$)/u.test(target.pathname))
73
+ return denied;
74
+ // Which pod asked: routeFront reads `rec.podHome + rest` and passes
75
+ // that podHome here, so the confinement is a value on the call rather
76
+ // than state on the handler. No podHome, no read.
77
+ const home = opts?.podHome;
78
+ if (!home || !url.startsWith(home))
79
+ return denied;
80
+ const raw = await s.io.read(url);
81
+ return raw == null
82
+ ? { status: 404, text: async () => '', headers: { get: () => null } }
83
+ : { status: 200, text: async () => raw, headers: { get: () => null } };
84
+ },
85
+ agentControl: s.registry
86
+ ? {
87
+ optIn: (a) => h.optInPod(a),
88
+ optOut: (a) => h.optOutPod(a),
89
+ describe: (a) => h.describePod(a),
90
+ }
91
+ : undefined,
92
+ });
93
+ await (0, adapt_1.applyToNode)(response, out);
94
+ }
package/dist/handler.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import { HttpHandler } from '@solid/community-server';
2
- import type { HttpHandlerInput, ResourceStore, Initializable, Finalizable, ClusterManager } from '@solid/community-server';
3
- import type { Directory } from './directory';
2
+ import type { HttpHandlerInput, ResourceStore, Initializable, Finalizable, ClusterManager, Logger } from '@solid/community-server';
3
+ import type { IO, Directory, AgentRegistry } from './directory';
4
+ import type { AgentClaim } from './mounts';
5
+ import type { EmbeddedIdentity } from './identities';
4
6
  export interface FediPodServerArgs {
5
7
  /** The server's ResourceStore: the handler reads pods and writes inbox items and directory rows directly through it — no HTTP, no credential. */
6
8
  resourceStore: ResourceStore;
@@ -41,25 +43,31 @@ export interface FediPodServerArgs {
41
43
  /** An internal container URL where the runtime opt-in rows live. */
42
44
  agentRegistryContainer?: string;
43
45
  }
44
- /** One running identity, and the call that stops it. */
45
- interface EmbeddedIdentity {
46
- handle: string;
47
- host: string;
48
- /** Where the identity's own tree begins on its pod, and the actor inside it. */
49
- podHome: string;
50
- actorUrl: string;
51
- surface: {
52
- handler: (req: unknown, res: unknown) => Promise<void>;
53
- streaming?: unknown;
54
- };
55
- stop: () => Promise<void>;
56
- agent?: {
57
- store?: {
58
- getConfig?: () => {
59
- kind?: string;
60
- } | null | undefined;
61
- };
62
- };
46
+ /**
47
+ * What the parts beside this file share. Private on the class, because the
48
+ * component generator would otherwise offer every public field as a
49
+ * configurable member; read through internals().
50
+ */
51
+ export interface Internals {
52
+ args: FediPodServerArgs;
53
+ io: IO;
54
+ dir: Directory;
55
+ runPath: string;
56
+ uiPath: string;
57
+ frontHost: string;
58
+ podPut: (url: string, body: string, contentType: string) => Promise<boolean>;
59
+ logger: Logger;
60
+ registry: AgentRegistry | null;
61
+ claimed: Map<string, AgentClaim>;
62
+ agentHandles: Map<string, string>;
63
+ roots: Map<string, string>;
64
+ identities: Map<string, EmbeddedIdentity>;
65
+ surfaces: Map<string, EmbeddedIdentity>;
66
+ doorSecrets: Map<string, string>;
67
+ starting: Set<string>;
68
+ startCancelled: Set<string>;
69
+ stopping: boolean;
70
+ onSignal: ((signal: NodeJS.Signals) => void) | null;
63
71
  }
64
72
  export declare class FediPodServerHandler extends HttpHandler implements Initializable, Finalizable {
65
73
  private readonly args;
@@ -70,6 +78,7 @@ export declare class FediPodServerHandler extends HttpHandler implements Initial
70
78
  private readonly logger;
71
79
  private readonly claimed;
72
80
  private readonly agentHandles;
81
+ private readonly roots;
73
82
  private readonly frontHost;
74
83
  private readonly uiPath;
75
84
  private readonly identities;
@@ -81,61 +90,13 @@ export declare class FediPodServerHandler extends HttpHandler implements Initial
81
90
  private stopping;
82
91
  private onSignal;
83
92
  constructor(args: FediPodServerArgs);
84
- /**
85
- * Whether this pod may become an identity here, and the claim it earns: a
86
- * real URL, a place no other identity already sits, and a handle no other
87
- * identity uses — two pods must never share <agentDataDir>/<handle>/.
88
- *
89
- * A HOST-ROOT or subdomain pod needs an origin of its own, and it may not be
90
- * the front's host: the whole surface answers at the origin root, so two of
91
- * them, or one sharing the front, would collide. A SUFFIX pod lives on a path
92
- * (`server/aisha/`), so it may share its host — with the front and with other
93
- * suffix pods — provided no claim already contains or nests under its path.
94
- */
95
- private validateAgentPod;
96
- /**
97
- * The claim a request belongs to, or null. A request matches when its host is
98
- * the claim's host and its path is at or under the claim's mount; the deepest
99
- * mount wins, so a suffix pod's own routes are never swallowed by a shallower
100
- * claim on the same host.
101
- */
102
- private resolveClaim;
103
- /** A request path relative to a mount: `/aisha/ap/actor` under `/aisha` → `/ap/actor`. */
104
- private stripMount;
105
- /**
106
- * Start an agent for each opted-in pod. Runs before the server listens, so
107
- * the identities come up in the background and boot is never held on a pod.
108
- */
93
+ /** The shared state, for the parts beside this file. */
94
+ internals(): Internals;
95
+ /** Start an agent for each opted-in pod, before the server listens. */
109
96
  initialize(): Promise<void>;
110
97
  /** Stop every identity: timers cleared, state written, lease let go. */
111
98
  finalize(): Promise<void>;
112
- /**
113
- * One identity's door secret, in its own pod's state. `agentDataDir` is
114
- * handed in as the place an identity set up before this kept it, so its
115
- * owner's existing door link survives the move.
116
- */
117
- private doorSecretFor;
118
- private startIdentity;
119
- /**
120
- * When this server is also the door, give a running identity a
121
- * @handle@<frontHost> address: one inbox-only directory row so the
122
- * shared-domain handle resolves and the door can take verified delivery for
123
- * it. The row names the identity's own tree, which is where its inbox and
124
- * its actor are — the door writes deliveries there and the agent watches
125
- * that container. A row written by an attach belongs to its owner and is
126
- * left alone; one this server wrote itself is corrected. The identity keeps
127
- * its own ids on the pod; nothing is moved.
128
- */
129
- private frontIdentity;
130
99
  canHandle({ request }: HttpHandlerInput): Promise<void>;
131
- /**
132
- * Whether identities run in this process. They run in one: the lease admits
133
- * a single drainer, and the state each one holds is in memory. With workers,
134
- * that process is the primary — which serves no requests, so every process
135
- * still has to know which hosts belong to an identity even though only one
136
- * of them can answer for it.
137
- */
138
- private runsIdentities;
139
100
  /**
140
101
  * The identity a request belongs to (matched by host and mount) and the
141
102
  * request path relative to that identity's mount, or null. The identity is
@@ -146,35 +107,21 @@ export declare class FediPodServerHandler extends HttpHandler implements Initial
146
107
  identity: EmbeddedIdentity | undefined;
147
108
  rel: string;
148
109
  } | null;
149
- /**
150
- * A pod owner, already proven to control podBase, asks this server to run
151
- * their identity. Returns { httpStatus, ...body }; the secret appears in the
152
- * reply and nowhere else. Re-opting-in rotates the secret — that is how a
153
- * lost one is recovered.
154
- */
155
- /**
156
- * The WebIDs behind the account session in the request, or none. The server
157
- * keeps that session in a `css-account` cookie; its own account API is what
158
- * says which WebIDs the session owns, and it takes the same cookie. Nothing
159
- * here trusts the cookie's presence — the account API does the deciding, and
160
- * the caller picks the WebID that owns the pod being claimed.
161
- */
110
+ /** What a pod owner asks of this server; see opt-in.ts. */
162
111
  webIdsFromSession(request: {
163
112
  headers: {
164
113
  get(name: string): string | null;
165
114
  };
166
115
  }): Promise<string[]>;
167
- optInPod({ podBase, webId }: {
116
+ optInPod(a: {
168
117
  podBase: string;
169
118
  webId: string;
119
+ container?: string;
120
+ createIndex?: boolean;
170
121
  }): Promise<Record<string, unknown> & {
171
122
  httpStatus: number;
172
123
  }>;
173
- /**
174
- * What a pod would be as an identity here, without changing anything: its
175
- * handle, the host its address carries, and whether it runs here already.
176
- */
177
- describePod({ podBase }: {
124
+ describePod(a: {
178
125
  podBase: string;
179
126
  }): Promise<{
180
127
  handle: string;
@@ -183,19 +130,10 @@ export declare class FediPodServerHandler extends HttpHandler implements Initial
183
130
  running: boolean;
184
131
  manage: string;
185
132
  }>;
186
- /** The reverse: stop the identity and let the pod be plain LDP again. */
187
- optOutPod({ podBase }: {
133
+ optOutPod(a: {
188
134
  podBase: string;
189
135
  }): Promise<Record<string, unknown> & {
190
136
  httpStatus: number;
191
137
  }>;
192
- /**
193
- * A delivery to an identity's own inbox, verified here — the server that
194
- * stores the inbox is the one the request reached, so the signature is
195
- * checked while its headers exist and the receipt is written beside the
196
- * activity. The same door code the front runs; nothing is renamed.
197
- */
198
- private deliverAtDoor;
199
138
  handle({ request, response }: HttpHandlerInput): Promise<void>;
200
139
  }
201
- export {};