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.
- package/README.md +38 -34
- package/config/server.json +22 -0
- package/dist/claims.js +3 -2
- package/dist/directory.d.ts +2 -0
- package/dist/door.d.ts +4 -0
- package/dist/door.js +31 -0
- package/dist/fedipod.d.ts +16 -0
- package/dist/fedipod.js +13 -0
- package/dist/front.d.ts +3 -0
- package/dist/front.js +94 -0
- package/dist/handler.d.ts +39 -101
- package/dist/handler.js +86 -617
- package/dist/handler.jsonld +6 -30
- package/dist/identities.d.ts +62 -0
- package/dist/identities.js +236 -0
- package/dist/mounts.d.ts +43 -0
- package/dist/mounts.js +123 -0
- package/dist/opt-in.d.ts +46 -0
- package/dist/opt-in.js +176 -0
- package/dist/store-pod.js +37 -0
- package/package.json +10 -18
- package/lib/client/c2s.mjs +0 -582
- package/lib/client/localapi.mjs +0 -87
- package/lib/client/masto/accounts.mjs +0 -309
- package/lib/client/masto/body.mjs +0 -156
- package/lib/client/masto/index.mjs +0 -206
- package/lib/client/masto/instance.mjs +0 -112
- package/lib/client/masto/media.mjs +0 -79
- package/lib/client/masto/oauth.mjs +0 -656
- package/lib/client/masto/render.mjs +0 -518
- package/lib/client/masto/statuses.mjs +0 -372
- package/lib/client/masto/timelines.mjs +0 -438
- package/lib/client/oidc-auth.mjs +0 -62
- package/lib/client/streaming.mjs +0 -154
- package/lib/client/webpush.mjs +0 -98
- package/lib/connections/acctfeed.mjs +0 -257
- package/lib/connections/atproto.mjs +0 -309
- package/lib/connections/bskyfeed.mjs +0 -243
- package/lib/connections/bskygroup.mjs +0 -162
- package/lib/connections/fediacct.mjs +0 -253
- package/lib/connections/import.mjs +0 -357
- package/lib/connections/tagfeed.mjs +0 -212
- package/lib/connections/vault.mjs +0 -114
- package/lib/core/as2.mjs +0 -206
- package/lib/core/contexts/activitystreams.json +0 -379
- package/lib/core/contexts/anno.json +0 -126
- package/lib/core/contexts/did-v1.json +0 -57
- package/lib/core/contexts/fep-5711.json +0 -36
- package/lib/core/contexts/gotosocial.json +0 -86
- package/lib/core/contexts/identity-v1.json +0 -152
- package/lib/core/contexts/index.mjs +0 -63
- package/lib/core/contexts/join-lemmy.json +0 -33
- package/lib/core/contexts/joinmastodon.json +0 -28
- package/lib/core/contexts/litepub-0.1.json +0 -60
- package/lib/core/contexts/map.json +0 -19
- package/lib/core/contexts/miscellany.json +0 -19
- package/lib/core/contexts/quotes.json +0 -18
- package/lib/core/contexts/schemaorg.json +0 -8845
- package/lib/core/contexts/security-data-integrity-v1.json +0 -78
- package/lib/core/contexts/security-data-integrity-v2.json +0 -81
- package/lib/core/contexts/security-multikey-v1.json +0 -35
- package/lib/core/contexts/security-v1.json +0 -74
- package/lib/core/contexts/webfinger.json +0 -10
- package/lib/core/deliver.mjs +0 -371
- package/lib/core/graphview.mjs +0 -327
- package/lib/core/intake/activities.mjs +0 -633
- package/lib/core/intake/activity.mjs +0 -318
- package/lib/core/intake/channel.mjs +0 -144
- package/lib/core/intake/group.mjs +0 -256
- package/lib/core/intake/index.mjs +0 -701
- package/lib/core/intake/notes.mjs +0 -360
- package/lib/core/intake/verify.mjs +0 -142
- package/lib/core/keys.mjs +0 -153
- package/lib/core/lease.mjs +0 -206
- package/lib/core/polls.mjs +0 -105
- package/lib/core/profile-page.mjs +0 -104
- package/lib/core/proof.mjs +0 -79
- package/lib/core/publisher/collections.mjs +0 -237
- package/lib/core/publisher/index.mjs +0 -500
- package/lib/core/publisher/notes.mjs +0 -453
- package/lib/core/publisher/questions.mjs +0 -239
- package/lib/core/publisher/restore.mjs +0 -224
- package/lib/core/shapes/activitystreams.ttl +0 -157
- package/lib/core/shapes/index.mjs +0 -132
- package/lib/core/shapes/shapes-text.mjs +0 -13
- package/lib/core/social.mjs +0 -531
- package/lib/core/storage.mjs +0 -176
- package/lib/core/store.mjs +0 -568
- package/lib/core/wire-quotes.mjs +0 -71
- package/lib/core/wire.mjs +0 -889
- package/lib/device/account.mjs +0 -87
- package/lib/device/admin/index.mjs +0 -13
- package/lib/device/admin/origins.mjs +0 -35
- package/lib/device/admin/routes/connections.mjs +0 -144
- package/lib/device/admin/routes/gateway.mjs +0 -199
- package/lib/device/admin/routes/lifecycle.mjs +0 -200
- package/lib/device/admin/routes/owner.mjs +0 -322
- package/lib/device/admin/routes/setup.mjs +0 -412
- package/lib/device/admin/routes/social.mjs +0 -188
- package/lib/device/admin/server.mjs +0 -95
- package/lib/device/admin/static.mjs +0 -247
- package/lib/device/admin/surface.mjs +0 -315
- package/lib/device/certs.mjs +0 -281
- package/lib/device/cli/commands/account.mjs +0 -586
- package/lib/device/cli/commands/run.mjs +0 -278
- package/lib/device/cli/commands/service.mjs +0 -221
- package/lib/device/cli/commands/setup.mjs +0 -447
- package/lib/device/cli/commands/state.mjs +0 -561
- package/lib/device/cli/context.mjs +0 -288
- package/lib/device/export-collections.mjs +0 -161
- package/lib/device/gateway-move.mjs +0 -58
- package/lib/device/home.mjs +0 -161
- package/lib/device/migrate.mjs +0 -115
- package/lib/device/ports.mjs +0 -27
- package/lib/device/remote.mjs +0 -54
- package/lib/device/setup.mjs +0 -459
- package/lib/device/update.mjs +0 -96
- package/lib/gateway/caches.mjs +0 -36
- package/lib/gateway/directory.mjs +0 -90
- package/lib/gateway/front-core.mjs +0 -970
- package/lib/gateway/gateway-core.mjs +0 -165
- package/lib/gateway/headers.mjs +0 -49
- package/lib/gateway/httpsig.mjs +0 -159
- package/lib/gateway/notices.mjs +0 -84
- package/lib/gateway/quiet.mjs +0 -189
- package/lib/pod/README.md +0 -61
- package/lib/pod/actor.mjs +0 -96
- package/lib/pod/collection.mjs +0 -77
- package/lib/pod/containers.mjs +0 -140
- package/lib/pod/discovery.mjs +0 -46
- package/lib/pod/featured.mjs +0 -18
- package/lib/pod/followers.mjs +0 -24
- package/lib/pod/following.mjs +0 -10
- package/lib/pod/http.mjs +0 -74
- package/lib/pod/inbox.mjs +0 -166
- package/lib/pod/links.mjs +0 -35
- package/lib/pod/media.mjs +0 -27
- package/lib/pod/notes.mjs +0 -80
- package/lib/pod/notifications.mjs +0 -89
- package/lib/pod/outbox.mjs +0 -18
- package/lib/pod/package.json +0 -19
- package/lib/pod/policy.mjs +0 -58
- package/lib/pod/private.mjs +0 -19
- package/lib/pod/root.mjs +0 -104
- package/lib/pod/state.mjs +0 -40
- package/lib/pod/transport.mjs +0 -525
- package/lib/pod/urls.mjs +0 -85
- package/lib/server/embed.mjs +0 -423
- package/lib/session/README.md +0 -137
- package/lib/session/demo.html +0 -94
- package/lib/session/fedi-account.mjs +0 -408
- package/lib/session/fedi-login.mjs +0 -123
- package/lib/session/oidc-session.mjs +0 -233
- package/lib/session/package.json +0 -49
- package/lib/shared/guard.mjs +0 -213
- package/lib/shared/links.mjs +0 -9
- package/lib/shared/safefetch.mjs +0 -235
- package/lib/shared/ua.mjs +0 -29
- package/phanpy/dist/404.html +0 -40
- package/phanpy/dist/_headers +0 -2
- package/phanpy/dist/apple-touch-icon.png +0 -0
- package/phanpy/dist/assets/ICONS-DIPJeU0C.js +0 -2
- package/phanpy/dist/assets/ICONS-DIPJeU0C.js.map +0 -1
- package/phanpy/dist/assets/ScheduledAtField-D-Abfo4J.js +0 -183
- package/phanpy/dist/assets/ScheduledAtField-D-Abfo4J.js.map +0 -1
- package/phanpy/dist/assets/Temml-CCjoacWt.woff2 +0 -0
- package/phanpy/dist/assets/__vite-browser-external-C7iut881.js +0 -2
- package/phanpy/dist/assets/__vite-browser-external-C7iut881.js.map +0 -1
- package/phanpy/dist/assets/boosts-carousel-BiOaNdMT.jpg +0 -0
- package/phanpy/dist/assets/catch-up-O5q5C75Z.png +0 -0
- package/phanpy/dist/assets/chunk-aKtaBQYM.js +0 -1
- package/phanpy/dist/assets/compose-CFEx7wb4.js +0 -2
- package/phanpy/dist/assets/compose-CFEx7wb4.js.map +0 -1
- package/phanpy/dist/assets/compose-ZJN5xSb4.js +0 -35
- package/phanpy/dist/assets/compose-ZJN5xSb4.js.map +0 -1
- package/phanpy/dist/assets/debug.module-YFQgwnIr.js +0 -52
- package/phanpy/dist/assets/debug.module-YFQgwnIr.js.map +0 -1
- package/phanpy/dist/assets/dom-p1YcJ5Rw.js +0 -2
- package/phanpy/dist/assets/dom-p1YcJ5Rw.js.map +0 -1
- package/phanpy/dist/assets/home-mobile-dark@2x-Dc-J8-SM.png +0 -0
- package/phanpy/dist/assets/home-mobile-light@2x-Bd3fod8m.png +0 -0
- package/phanpy/dist/assets/home-tablet-dark@2x-BgcNI8le.png +0 -0
- package/phanpy/dist/assets/home-tablet-light@2x-BW2RV9T6.png +0 -0
- package/phanpy/dist/assets/icons/add-circle-line-WD0mwORD.js +0 -1
- package/phanpy/dist/assets/icons/alert-line-CpFUMf9s.js +0 -1
- package/phanpy/dist/assets/icons/android-2-line-Bzxnrd3S.js +0 -1
- package/phanpy/dist/assets/icons/announcement-line-5nwaJFJm.js +0 -1
- package/phanpy/dist/assets/icons/arrow-down-circle-line-a7Id9-Iv.js +0 -1
- package/phanpy/dist/assets/icons/arrow-down-line-B8uzXzq6.js +0 -1
- package/phanpy/dist/assets/icons/arrow-left-line-CGrGT9C-.js +0 -1
- package/phanpy/dist/assets/icons/arrow-right-line-CE-HERfX.js +0 -1
- package/phanpy/dist/assets/icons/arrow-to-up-line-CvdQjmcy.js +0 -1
- package/phanpy/dist/assets/icons/arrow-up-circle-line-DEparSNF.js +0 -1
- package/phanpy/dist/assets/icons/arrow-up-line-C7yBeugc.js +0 -1
- package/phanpy/dist/assets/icons/arrows-right-line-BtbXmJGP.js +0 -1
- package/phanpy/dist/assets/icons/at-line-CF66Bznk.js +0 -1
- package/phanpy/dist/assets/icons/attachment-line-BY8It-l9.js +0 -1
- package/phanpy/dist/assets/icons/blockquote-line-BS6pU_hm.js +0 -1
- package/phanpy/dist/assets/icons/board-line-C0UWXyA6.js +0 -1
- package/phanpy/dist/assets/icons/bookmark-line-1CtX5JLF.js +0 -1
- package/phanpy/dist/assets/icons/building-5-line-Dd59MzbO.js +0 -1
- package/phanpy/dist/assets/icons/bus-2-line-6_dvA0GG.js +0 -1
- package/phanpy/dist/assets/icons/calendar-day-line-Crpl_fmu.js +0 -1
- package/phanpy/dist/assets/icons/calendar-month-line-vommts2C.js +0 -1
- package/phanpy/dist/assets/icons/calendar-time-add-line-BU_DTlQk.js +0 -1
- package/phanpy/dist/assets/icons/camera-line-Cv69MEei.js +0 -1
- package/phanpy/dist/assets/icons/celebrate-line-B8DvIoi0.js +0 -1
- package/phanpy/dist/assets/icons/chart-bar-line-FK-QOmtF.js +0 -1
- package/phanpy/dist/assets/icons/chart-line-line-BGcJAFWw.js +0 -1
- package/phanpy/dist/assets/icons/chat-3-line-YFK2-hwz.js +0 -1
- package/phanpy/dist/assets/icons/check-circle-line-DsAxFr5-.js +0 -1
- package/phanpy/dist/assets/icons/clipboard-line-BBp364gJ.js +0 -1
- package/phanpy/dist/assets/icons/close-circle-line-CICdiuGz.js +0 -1
- package/phanpy/dist/assets/icons/close-line-DYrFWcjv.js +0 -1
- package/phanpy/dist/assets/icons/cloud-line-tiQAbah8.js +0 -1
- package/phanpy/dist/assets/icons/code-line-fAl8iiV3.js +0 -1
- package/phanpy/dist/assets/icons/comment-2-line-CR3g7WeB.js +0 -1
- package/phanpy/dist/assets/icons/copy-2-line-CLW69yF5.js +0 -1
- package/phanpy/dist/assets/icons/delete-2-line-B8xmbr4n.js +0 -1
- package/phanpy/dist/assets/icons/document-3-line-DBGNhAg2.js +0 -1
- package/phanpy/dist/assets/icons/document-line-C7mb9sb7.js +0 -1
- package/phanpy/dist/assets/icons/down-line-BGqSSThd.js +0 -1
- package/phanpy/dist/assets/icons/edit-4-line-DcgGaEhx.js +0 -1
- package/phanpy/dist/assets/icons/emoji-2-line-D8YgnM-y.js +0 -1
- package/phanpy/dist/assets/icons/exit-line-Dc07BS-x.js +0 -1
- package/phanpy/dist/assets/icons/external-link-line-BvpSkmjO.js +0 -1
- package/phanpy/dist/assets/icons/eye-2-line-CiWXx-f_.js +0 -1
- package/phanpy/dist/assets/icons/eye-close-line-BgTaSJ4P.js +0 -1
- package/phanpy/dist/assets/icons/filter-2-line-B_mR2usy.js +0 -1
- package/phanpy/dist/assets/icons/filter-line-C_nm-3cU.js +0 -1
- package/phanpy/dist/assets/icons/flag-1-line-C2HB05I0.js +0 -1
- package/phanpy/dist/assets/icons/forbid-circle-line-D3LTT9yd.js +0 -1
- package/phanpy/dist/assets/icons/formula-line-DLrt2d6j.js +0 -1
- package/phanpy/dist/assets/icons/grid-line-CgUmEikf.js +0 -1
- package/phanpy/dist/assets/icons/group-line-C5fnX0wU.js +0 -1
- package/phanpy/dist/assets/icons/hand-finger-2-line-BGgxbuL9.js +0 -1
- package/phanpy/dist/assets/icons/hashtag-line-CyTEEXBb.js +0 -1
- package/phanpy/dist/assets/icons/heart-crack-line-BZddbO2C.js +0 -1
- package/phanpy/dist/assets/icons/heart-line-CJ7K47J4.js +0 -1
- package/phanpy/dist/assets/icons/history-2-line-kWWvFzqv.js +0 -1
- package/phanpy/dist/assets/icons/history-line-bGQiwbTH.js +0 -1
- package/phanpy/dist/assets/icons/home-3-line-fRU1zeLG.js +0 -1
- package/phanpy/dist/assets/icons/information-line-iNk6-sOY.js +0 -1
- package/phanpy/dist/assets/icons/keyboard-line-DsCyuQNz.js +0 -1
- package/phanpy/dist/assets/icons/layout-4-line-CZkOX52Z.js +0 -1
- package/phanpy/dist/assets/icons/layout-5-line-B_znt5wO.js +0 -1
- package/phanpy/dist/assets/icons/left-line-eUw0tya4.js +0 -1
- package/phanpy/dist/assets/icons/lightning-line-DaKoDdix.js +0 -1
- package/phanpy/dist/assets/icons/link-2-line-DCqLmMA7.js +0 -1
- package/phanpy/dist/assets/icons/list-check-line-BAxosBh9.js +0 -1
- package/phanpy/dist/assets/icons/lock-line-CPoaXeUW.js +0 -1
- package/phanpy/dist/assets/icons/mail-line-B0P8aa1L.js +0 -1
- package/phanpy/dist/assets/icons/moon-line-CEqNAToP.js +0 -1
- package/phanpy/dist/assets/icons/more-1-fill-Dw2e5xab.js +0 -1
- package/phanpy/dist/assets/icons/more-3-line-BIiVjYTz.js +0 -1
- package/phanpy/dist/assets/icons/notification-line-BZZq2Gtu.js +0 -1
- package/phanpy/dist/assets/icons/pencil-line-CKh8-A1v.js +0 -1
- package/phanpy/dist/assets/icons/photo-album-line-Bnfg2u40.js +0 -1
- package/phanpy/dist/assets/icons/pin-line-DpTolyhs.js +0 -1
- package/phanpy/dist/assets/icons/play-fill-B0-G_8lX.js +0 -1
- package/phanpy/dist/assets/icons/qrcode-2-line-B6SPCaHn.js +0 -1
- package/phanpy/dist/assets/icons/quill-pen-line-B6LUrnCP.js +0 -1
- package/phanpy/dist/assets/icons/quote-left-fill-hQZ1cj_6.js +0 -1
- package/phanpy/dist/assets/icons/radar-line-CKyroTth.js +0 -1
- package/phanpy/dist/assets/icons/react-line-CoIKhhtK.js +0 -1
- package/phanpy/dist/assets/icons/refresh-2-line-D0mTF97S.js +0 -1
- package/phanpy/dist/assets/icons/right-line-B3KWJaqc.js +0 -1
- package/phanpy/dist/assets/icons/rocket-line-4KZl537D.js +0 -1
- package/phanpy/dist/assets/icons/round-fill-C69NTrZ0.js +0 -1
- package/phanpy/dist/assets/icons/round-line-B9k_1uo-.js +0 -1
- package/phanpy/dist/assets/icons/route-line-B28ReHcE.js +0 -1
- package/phanpy/dist/assets/icons/rows-4-line-CrBniagM.js +0 -1
- package/phanpy/dist/assets/icons/scan-line-DSf74YdP.js +0 -1
- package/phanpy/dist/assets/icons/search-2-line-B6geIU1z.js +0 -1
- package/phanpy/dist/assets/icons/settings-3-line-azJwK47w.js +0 -1
- package/phanpy/dist/assets/icons/settings-6-line-C_5zc5YR.js +0 -1
- package/phanpy/dist/assets/icons/share-2-line-D5MxWjrm.js +0 -1
- package/phanpy/dist/assets/icons/share-forward-line-Cp61fZzZ.js +0 -1
- package/phanpy/dist/assets/icons/sparkles-2-line-DYYyXTaW.js +0 -1
- package/phanpy/dist/assets/icons/sparkles-line-C2hY1s6I.js +0 -1
- package/phanpy/dist/assets/icons/time-line-BF3eet1v.js +0 -1
- package/phanpy/dist/assets/icons/transfer-4-line-oisfvTBw.js +0 -1
- package/phanpy/dist/assets/icons/translate-line-BFWol2Ce.js +0 -1
- package/phanpy/dist/assets/icons/unlock-line-X_x5vwv3.js +0 -1
- package/phanpy/dist/assets/icons/upload-3-line-DgzwUJeW.js +0 -1
- package/phanpy/dist/assets/icons/user-4-line-BVSynZCp.js +0 -1
- package/phanpy/dist/assets/icons/user-add-2-line-BlGS5Q8q.js +0 -1
- package/phanpy/dist/assets/icons/user-add-line-BbXdHG4z.js +0 -1
- package/phanpy/dist/assets/icons/user-edit-line-BFAHOV0X.js +0 -1
- package/phanpy/dist/assets/icons/user-follow-line-BXux0wSd.js +0 -1
- package/phanpy/dist/assets/icons/user-star-line-DdYlpHLU.js +0 -1
- package/phanpy/dist/assets/icons/user-warning-line-Cj43j0_E.js +0 -1
- package/phanpy/dist/assets/icons/user-x-line-DIDgNlPH.js +0 -1
- package/phanpy/dist/assets/icons/volume-line-Bs390KQt.js +0 -1
- package/phanpy/dist/assets/icons/volume-mute-line-DzlzIqFZ.js +0 -1
- package/phanpy/dist/assets/icons/walk-line-yNXfB-md.js +0 -1
- package/phanpy/dist/assets/icons/world-2-line-CenkGIwj.js +0 -1
- package/phanpy/dist/assets/icons/zoom-in-line-CaENUphf.js +0 -1
- package/phanpy/dist/assets/icons/zoom-out-line-BDNk0EWo.js +0 -1
- package/phanpy/dist/assets/instances-BNPptnn-.json +0 -333
- package/phanpy/dist/assets/locales/ar-SA-CfheRbCu.js +0 -1
- package/phanpy/dist/assets/locales/ca-ES-DHRW86Tz.js +0 -1
- package/phanpy/dist/assets/locales/cs-CZ-CKoqEuA1.js +0 -1
- package/phanpy/dist/assets/locales/de-DE-ByRPMRFy.js +0 -1
- package/phanpy/dist/assets/locales/eo-UY-CPC7wLCS.js +0 -1
- package/phanpy/dist/assets/locales/es-ES-dJa0Fd9t.js +0 -1
- package/phanpy/dist/assets/locales/eu-ES-C3djlPR2.js +0 -1
- package/phanpy/dist/assets/locales/fa-IR-DTT490Ck.js +0 -1
- package/phanpy/dist/assets/locales/fi-FI-B23MCPuz.js +0 -1
- package/phanpy/dist/assets/locales/fr-FR-BcaQsO5C.js +0 -1
- package/phanpy/dist/assets/locales/gl-ES-BR-CVKBN.js +0 -1
- package/phanpy/dist/assets/locales/he-IL-CfheRbCu.js +0 -1
- package/phanpy/dist/assets/locales/hu-HU-CfheRbCu.js +0 -1
- package/phanpy/dist/assets/locales/it-IT-C1136UFV.js +0 -1
- package/phanpy/dist/assets/locales/ja-JP-CRZmRAhD.js +0 -1
- package/phanpy/dist/assets/locales/kab-Cz8xH_TT.js +0 -1
- package/phanpy/dist/assets/locales/ko-KR-CG9UiY4o.js +0 -1
- package/phanpy/dist/assets/locales/lt-LT-CJcI6sHZ.js +0 -1
- package/phanpy/dist/assets/locales/nb-NO-CfheRbCu.js +0 -1
- package/phanpy/dist/assets/locales/nl-NL-DxN4Yc1t.js +0 -1
- package/phanpy/dist/assets/locales/oc-FR-CfheRbCu.js +0 -1
- package/phanpy/dist/assets/locales/pl-PL-DkwGXf6P.js +0 -1
- package/phanpy/dist/assets/locales/pseudo-LOCALE-CQ4XxkQ0.js +0 -1
- package/phanpy/dist/assets/locales/pt-BR-nGL0HdFS.js +0 -1
- package/phanpy/dist/assets/locales/pt-PT-Cp17aj2z.js +0 -1
- package/phanpy/dist/assets/locales/ru-RU-0Y8cIoaK.js +0 -1
- package/phanpy/dist/assets/locales/th-TH-CfheRbCu.js +0 -1
- package/phanpy/dist/assets/locales/tok-CfheRbCu.js +0 -1
- package/phanpy/dist/assets/locales/tr-TR-CfheRbCu.js +0 -1
- package/phanpy/dist/assets/locales/uk-UA-C5E3dFBf.js +0 -1
- package/phanpy/dist/assets/locales/zh-CN-BHJi7_et.js +0 -1
- package/phanpy/dist/assets/locales/zh-TW-CfheRbCu.js +0 -1
- package/phanpy/dist/assets/main-BdqNbG-a.js +0 -26
- package/phanpy/dist/assets/main-BdqNbG-a.js.map +0 -1
- package/phanpy/dist/assets/mock-home-DGhR__He.js +0 -2
- package/phanpy/dist/assets/mock-home-DGhR__He.js.map +0 -1
- package/phanpy/dist/assets/multi-column-ROck0NVt.jpg +0 -0
- package/phanpy/dist/assets/multi-hashtag-timeline-DH5INVHi.jpg +0 -0
- package/phanpy/dist/assets/nested-comments-thread-hv59kZLc.jpg +0 -0
- package/phanpy/dist/assets/polyfill-force-H8sUkLGp.js +0 -2
- package/phanpy/dist/assets/polyfill-force-H8sUkLGp.js.map +0 -1
- package/phanpy/dist/assets/pwa-viewport-ogKbF51K.js +0 -20
- package/phanpy/dist/assets/pwa-viewport-ogKbF51K.js.map +0 -1
- package/phanpy/dist/assets/style-B1iLPTPR.css +0 -2
- package/phanpy/dist/assets/temml-DuyIQMei.js +0 -97
- package/phanpy/dist/assets/temml-DuyIQMei.js.map +0 -1
- package/phanpy/dist/assets/tinyld.light.node-DtbBhLYC.js +0 -2
- package/phanpy/dist/assets/tinyld.light.node-DtbBhLYC.js.map +0 -1
- package/phanpy/dist/assets/year-in-posts-B2lywqdx.png +0 -0
- package/phanpy/dist/assets/year-in-posts-DJv_star.js +0 -3
- package/phanpy/dist/assets/year-in-posts-DJv_star.js.map +0 -1
- package/phanpy/dist/compose/index.html +0 -20
- package/phanpy/dist/favicon.ico +0 -0
- package/phanpy/dist/index.html +0 -73
- package/phanpy/dist/logo-192.png +0 -0
- package/phanpy/dist/logo-512.png +0 -0
- package/phanpy/dist/logo-badge-72.png +0 -0
- package/phanpy/dist/logo-maskable-512.png +0 -0
- package/phanpy/dist/logo-monochrome-512.png +0 -0
- package/phanpy/dist/logo-monochrome-maskable-512.png +0 -0
- package/phanpy/dist/manifest.webmanifest +0 -1
- package/phanpy/dist/og-image-2.jpg +0 -0
- package/phanpy/dist/og-image.png +0 -0
- package/phanpy/dist/robots.txt +0 -2
- package/phanpy/dist/sw.js +0 -2
- package/phanpy/dist/sw.js.map +0 -1
- package/phanpy/dist/version.json +0 -1
- package/run-agent.mjs +0 -897
- package/vendor/gate.cjs +0 -138
- package/vendor/idp-grant.cjs +0 -394
- package/vendor/jfetch.cjs +0 -16
- package/web/admin/actors.js +0 -145
- package/web/admin/bar.css +0 -126
- package/web/admin/bar.js +0 -99
- package/web/admin/client/client.js +0 -66
- package/web/admin/client/index.html +0 -69
- package/web/admin/client-pick.js +0 -79
- package/web/admin/common.js +0 -23
- package/web/admin/connections.js +0 -112
- package/web/admin/gateway.js +0 -133
- package/web/admin/group.js +0 -258
- package/web/admin/index.html +0 -603
- package/web/admin/notices-bar.js +0 -90
- package/web/admin/oauth-signin.mjs +0 -37
- package/web/admin/record.js +0 -390
- package/web/admin/setup/index.html +0 -241
- package/web/admin/setup/setup.js +0 -326
- package/web/admin/tokens.css +0 -68
- package/web/admin/upkeep.js +0 -177
- package/web/admin/window.css +0 -55
- package/web/admin/window.js +0 -136
- package/web/app/README.md +0 -81
- package/web/app/admin-facade.mjs +0 -588
- package/web/app/agent.mjs +0 -663
- package/web/app/atproto-browser.mjs +0 -86
- package/web/app/authorize_interaction.html +0 -56
- package/web/app/authorize_interaction.js +0 -69
- package/web/app/boot.mjs +0 -576
- package/web/app/deliver-relay.mjs +0 -129
- package/web/app/dist/boot.js +0 -34218
- package/web/app/dist/boot.js.map +0 -7
- package/web/app/dist/sw.js +0 -72810
- package/web/app/dist/sw.js.map +0 -7
- package/web/app/fediacct-browser.mjs +0 -146
- package/web/app/gateway-move.mjs +0 -60
- package/web/app/idb-kv.mjs +0 -35
- package/web/app/index.html +0 -242
- package/web/app/keys-browser.mjs +0 -71
- package/web/app/keystore.mjs +0 -82
- package/web/app/oidc-session.mjs +0 -6
- package/web/app/pod-auth.mjs +0 -248
- package/web/app/pod-remote.mjs +0 -84
- package/web/app/shims/_globals.mjs +0 -2
- package/web/app/shims/fedify-sig.mjs +0 -77
- package/web/app/shims/node-crypto.mjs +0 -113
- package/web/app/shims/node-fs.mjs +0 -17
- package/web/app/shims/node-path.mjs +0 -19
- package/web/app/shims/node-url.mjs +0 -7
- package/web/app/shims/prelude.js +0 -58
- package/web/app/shims/safefetch.mjs +0 -58
- package/web/app/shims/shapes-text.mjs +0 -8
- package/web/app/shims/web-push.mjs +0 -14
- package/web/app/signup.mjs +0 -318
- package/web/app/sw-src.mjs +0 -220
- package/web/app/update.js +0 -70
- package/web/front/admin.html +0 -55
- package/web/front/admin.js +0 -89
- package/web/front/install.sh +0 -69
- package/web/front/new-account.html +0 -35
- package/web/front/new-account.js +0 -13
- package/web/front/notices.html +0 -69
- package/web/front/notices.js +0 -107
- package/web/front/run.html +0 -58
- package/web/front/run.js +0 -195
- package/web/front/solid-oidc-client.js +0 -6
- package/web/icons/forum.svg +0 -11
- package/web/icons/gateway.svg +0 -14
- 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
|
-
- **
|
|
34
|
-
address (`@mei@mei.example.org`); a
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
|
74
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
138
|
-
|
|
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
|
|
159
|
-
pod
|
|
160
|
-
`/aisha/
|
|
161
|
-
|
|
162
|
-
|
|
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
|
-
#
|
|
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
|
-
#
|
|
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
|
|
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
|
|
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 (
|
|
249
|
-
npm run test:e2e:suffix # the same, for pods
|
|
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
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
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.
|
package/config/server.json
CHANGED
|
@@ -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
|
|
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.
|
package/dist/directory.d.ts
CHANGED
|
@@ -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
|
+
}
|
package/dist/fedipod.js
ADDED
|
@@ -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)');
|
package/dist/front.d.ts
ADDED
|
@@ -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
|
-
/**
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
86
|
-
|
|
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(
|
|
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
|
-
|
|
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 {};
|