fedipod-server 0.9.0 → 0.11.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/dist/claims.js +1 -1
- package/dist/handler.d.ts +1 -1
- package/dist/handler.js +35 -2
- package/dist/handler.jsonld +1 -1
- package/lib/admin.mjs +3 -3
- package/lib/c2s.mjs +27 -2
- package/lib/deliver.mjs +6 -0
- package/lib/embed.mjs +1 -0
- package/lib/export-collections.mjs +1 -1
- package/lib/front-core.mjs +272 -49
- package/lib/gateway-core.mjs +3 -7
- package/lib/httpsig.mjs +33 -2
- package/lib/import.mjs +1 -1
- package/lib/intake.mjs +357 -118
- package/lib/links.mjs +6 -32
- package/lib/mastoapi.mjs +449 -38
- package/lib/migrate.mjs +4 -18
- package/lib/pod/README.md +61 -0
- package/lib/pod/actor.mjs +96 -0
- package/lib/pod/collection.mjs +77 -0
- package/lib/pod/containers.mjs +136 -0
- package/lib/pod/discovery.mjs +46 -0
- package/lib/pod/featured.mjs +18 -0
- package/lib/pod/followers.mjs +24 -0
- package/lib/pod/following.mjs +10 -0
- package/lib/pod/http.mjs +74 -0
- package/lib/pod/inbox.mjs +144 -0
- package/lib/pod/links.mjs +35 -0
- package/lib/pod/media.mjs +27 -0
- package/lib/pod/notes.mjs +80 -0
- package/lib/pod/notifications.mjs +89 -0
- package/lib/pod/outbox.mjs +18 -0
- package/lib/pod/package.json +19 -0
- package/lib/pod/policy.mjs +58 -0
- package/lib/pod/private.mjs +19 -0
- package/lib/pod/root.mjs +63 -0
- package/lib/pod/state.mjs +39 -0
- package/lib/pod/transport.mjs +477 -0
- package/lib/pod/urls.mjs +71 -0
- package/lib/polls.mjs +105 -0
- package/lib/publisher.mjs +357 -188
- package/lib/remote.mjs +30 -395
- package/lib/social.mjs +20 -9
- package/lib/storage.mjs +2 -2
- package/lib/store.mjs +8 -1
- package/lib/tagfeed.mjs +19 -2
- package/lib/wire.mjs +87 -67
- package/package.json +1 -1
- package/run-agent.mjs +20 -39
- package/web/admin/admin.js +141 -74
- package/web/admin/bar.css +9 -13
- package/web/admin/bar.js +2 -2
- package/web/admin/client/client.js +1 -1
- package/web/admin/client/index.html +5 -6
- package/web/admin/index.html +53 -65
- package/web/admin/setup/index.html +2 -1
- package/web/admin/setup/setup.js +1 -1
- package/web/admin/tokens.css +56 -0
- package/web/app/README.md +77 -0
- package/web/app/admin-facade.mjs +549 -0
- package/web/app/agent.mjs +490 -0
- package/web/app/atproto-browser.mjs +86 -0
- package/web/app/boot.mjs +340 -0
- package/web/app/deliver-relay.mjs +72 -0
- package/web/app/dist/boot.js +34067 -0
- package/web/app/dist/boot.js.map +7 -0
- package/web/app/dist/sw.js +53745 -0
- package/web/app/dist/sw.js.map +7 -0
- package/web/app/fediacct-browser.mjs +146 -0
- package/web/app/idb-kv.mjs +35 -0
- package/web/app/index.html +203 -0
- package/web/app/index.html~ +152 -0
- package/web/app/keys-browser.mjs +46 -0
- package/web/app/keystore.mjs +99 -0
- package/web/app/oidc-session.mjs +189 -0
- package/web/app/pod-auth.mjs +248 -0
- package/web/app/pod-remote.mjs +84 -0
- package/web/app/shims/_globals.mjs +2 -0
- package/web/app/shims/fedify-sig.mjs +77 -0
- package/web/app/shims/node-crypto.mjs +113 -0
- package/web/app/shims/node-fs.mjs +17 -0
- package/web/app/shims/node-path.mjs +19 -0
- package/web/app/shims/node-url.mjs +7 -0
- package/web/app/shims/prelude.js +58 -0
- package/web/app/shims/safefetch.mjs +58 -0
- package/web/app/shims/web-push.mjs +14 -0
- package/web/app/signup.mjs +248 -0
- package/web/app/site/_headers +9 -0
- package/web/app/site/_redirects +21 -0
- package/web/app/site/admin/admin.js +1181 -0
- package/web/app/site/admin/bar.css +60 -0
- package/web/app/site/admin/bar.js +61 -0
- package/web/app/site/admin/client/client.js +66 -0
- package/web/app/site/admin/client/index.html +43 -0
- package/web/app/site/admin/index.html +556 -0
- package/web/app/site/admin/setup/index.html +191 -0
- package/web/app/site/admin/setup/setup.js +308 -0
- package/web/app/site/admin/tokens.css +56 -0
- package/web/app/site/admin/window.css +55 -0
- package/web/app/site/admin/window.js +136 -0
- package/web/app/site/app/404.html +40 -0
- package/web/app/site/app/_headers +2 -0
- package/web/app/site/app/apple-touch-icon.png +0 -0
- package/web/app/site/app/assets/ICONS-DIPJeU0C.js +2 -0
- package/web/app/site/app/assets/ICONS-DIPJeU0C.js.map +1 -0
- package/web/app/site/app/assets/ScheduledAtField-D-Abfo4J.js +183 -0
- package/web/app/site/app/assets/ScheduledAtField-D-Abfo4J.js.map +1 -0
- package/web/app/site/app/assets/Temml-CCjoacWt.woff2 +0 -0
- package/web/app/site/app/assets/__vite-browser-external-C7iut881.js +2 -0
- package/web/app/site/app/assets/__vite-browser-external-C7iut881.js.map +1 -0
- package/web/app/site/app/assets/boosts-carousel-BiOaNdMT.jpg +0 -0
- package/web/app/site/app/assets/catch-up-O5q5C75Z.png +0 -0
- package/web/app/site/app/assets/chunk-aKtaBQYM.js +1 -0
- package/web/app/site/app/assets/compose-CFEx7wb4.js +2 -0
- package/web/app/site/app/assets/compose-CFEx7wb4.js.map +1 -0
- package/web/app/site/app/assets/compose-ZJN5xSb4.js +35 -0
- package/web/app/site/app/assets/compose-ZJN5xSb4.js.map +1 -0
- package/web/app/site/app/assets/debug.module-YFQgwnIr.js +52 -0
- package/web/app/site/app/assets/debug.module-YFQgwnIr.js.map +1 -0
- package/web/app/site/app/assets/dom-p1YcJ5Rw.js +2 -0
- package/web/app/site/app/assets/dom-p1YcJ5Rw.js.map +1 -0
- package/web/app/site/app/assets/home-mobile-dark@2x-Dc-J8-SM.png +0 -0
- package/web/app/site/app/assets/home-mobile-light@2x-Bd3fod8m.png +0 -0
- package/web/app/site/app/assets/home-tablet-dark@2x-BgcNI8le.png +0 -0
- package/web/app/site/app/assets/home-tablet-light@2x-BW2RV9T6.png +0 -0
- package/web/app/site/app/assets/icons/add-circle-line-WD0mwORD.js +1 -0
- package/web/app/site/app/assets/icons/alert-line-CpFUMf9s.js +1 -0
- package/web/app/site/app/assets/icons/android-2-line-Bzxnrd3S.js +1 -0
- package/web/app/site/app/assets/icons/announcement-line-5nwaJFJm.js +1 -0
- package/web/app/site/app/assets/icons/arrow-down-circle-line-a7Id9-Iv.js +1 -0
- package/web/app/site/app/assets/icons/arrow-down-line-B8uzXzq6.js +1 -0
- package/web/app/site/app/assets/icons/arrow-left-line-CGrGT9C-.js +1 -0
- package/web/app/site/app/assets/icons/arrow-right-line-CE-HERfX.js +1 -0
- package/web/app/site/app/assets/icons/arrow-to-up-line-CvdQjmcy.js +1 -0
- package/web/app/site/app/assets/icons/arrow-up-circle-line-DEparSNF.js +1 -0
- package/web/app/site/app/assets/icons/arrow-up-line-C7yBeugc.js +1 -0
- package/web/app/site/app/assets/icons/arrows-right-line-BtbXmJGP.js +1 -0
- package/web/app/site/app/assets/icons/at-line-CF66Bznk.js +1 -0
- package/web/app/site/app/assets/icons/attachment-line-BY8It-l9.js +1 -0
- package/web/app/site/app/assets/icons/blockquote-line-BS6pU_hm.js +1 -0
- package/web/app/site/app/assets/icons/board-line-C0UWXyA6.js +1 -0
- package/web/app/site/app/assets/icons/bookmark-line-1CtX5JLF.js +1 -0
- package/web/app/site/app/assets/icons/building-5-line-Dd59MzbO.js +1 -0
- package/web/app/site/app/assets/icons/bus-2-line-6_dvA0GG.js +1 -0
- package/web/app/site/app/assets/icons/calendar-day-line-Crpl_fmu.js +1 -0
- package/web/app/site/app/assets/icons/calendar-month-line-vommts2C.js +1 -0
- package/web/app/site/app/assets/icons/calendar-time-add-line-BU_DTlQk.js +1 -0
- package/web/app/site/app/assets/icons/camera-line-Cv69MEei.js +1 -0
- package/web/app/site/app/assets/icons/celebrate-line-B8DvIoi0.js +1 -0
- package/web/app/site/app/assets/icons/chart-bar-line-FK-QOmtF.js +1 -0
- package/web/app/site/app/assets/icons/chart-line-line-BGcJAFWw.js +1 -0
- package/web/app/site/app/assets/icons/chat-3-line-YFK2-hwz.js +1 -0
- package/web/app/site/app/assets/icons/check-circle-line-DsAxFr5-.js +1 -0
- package/web/app/site/app/assets/icons/clipboard-line-BBp364gJ.js +1 -0
- package/web/app/site/app/assets/icons/close-circle-line-CICdiuGz.js +1 -0
- package/web/app/site/app/assets/icons/close-line-DYrFWcjv.js +1 -0
- package/web/app/site/app/assets/icons/cloud-line-tiQAbah8.js +1 -0
- package/web/app/site/app/assets/icons/code-line-fAl8iiV3.js +1 -0
- package/web/app/site/app/assets/icons/comment-2-line-CR3g7WeB.js +1 -0
- package/web/app/site/app/assets/icons/copy-2-line-CLW69yF5.js +1 -0
- package/web/app/site/app/assets/icons/delete-2-line-B8xmbr4n.js +1 -0
- package/web/app/site/app/assets/icons/document-3-line-DBGNhAg2.js +1 -0
- package/web/app/site/app/assets/icons/document-line-C7mb9sb7.js +1 -0
- package/web/app/site/app/assets/icons/down-line-BGqSSThd.js +1 -0
- package/web/app/site/app/assets/icons/edit-4-line-DcgGaEhx.js +1 -0
- package/web/app/site/app/assets/icons/emoji-2-line-D8YgnM-y.js +1 -0
- package/web/app/site/app/assets/icons/exit-line-Dc07BS-x.js +1 -0
- package/web/app/site/app/assets/icons/external-link-line-BvpSkmjO.js +1 -0
- package/web/app/site/app/assets/icons/eye-2-line-CiWXx-f_.js +1 -0
- package/web/app/site/app/assets/icons/eye-close-line-BgTaSJ4P.js +1 -0
- package/web/app/site/app/assets/icons/filter-2-line-B_mR2usy.js +1 -0
- package/web/app/site/app/assets/icons/filter-line-C_nm-3cU.js +1 -0
- package/web/app/site/app/assets/icons/flag-1-line-C2HB05I0.js +1 -0
- package/web/app/site/app/assets/icons/forbid-circle-line-D3LTT9yd.js +1 -0
- package/web/app/site/app/assets/icons/formula-line-DLrt2d6j.js +1 -0
- package/web/app/site/app/assets/icons/grid-line-CgUmEikf.js +1 -0
- package/web/app/site/app/assets/icons/group-line-C5fnX0wU.js +1 -0
- package/web/app/site/app/assets/icons/hand-finger-2-line-BGgxbuL9.js +1 -0
- package/web/app/site/app/assets/icons/hashtag-line-CyTEEXBb.js +1 -0
- package/web/app/site/app/assets/icons/heart-crack-line-BZddbO2C.js +1 -0
- package/web/app/site/app/assets/icons/heart-line-CJ7K47J4.js +1 -0
- package/web/app/site/app/assets/icons/history-2-line-kWWvFzqv.js +1 -0
- package/web/app/site/app/assets/icons/history-line-bGQiwbTH.js +1 -0
- package/web/app/site/app/assets/icons/home-3-line-fRU1zeLG.js +1 -0
- package/web/app/site/app/assets/icons/information-line-iNk6-sOY.js +1 -0
- package/web/app/site/app/assets/icons/keyboard-line-DsCyuQNz.js +1 -0
- package/web/app/site/app/assets/icons/layout-4-line-CZkOX52Z.js +1 -0
- package/web/app/site/app/assets/icons/layout-5-line-B_znt5wO.js +1 -0
- package/web/app/site/app/assets/icons/left-line-eUw0tya4.js +1 -0
- package/web/app/site/app/assets/icons/lightning-line-DaKoDdix.js +1 -0
- package/web/app/site/app/assets/icons/link-2-line-DCqLmMA7.js +1 -0
- package/web/app/site/app/assets/icons/list-check-line-BAxosBh9.js +1 -0
- package/web/app/site/app/assets/icons/lock-line-CPoaXeUW.js +1 -0
- package/web/app/site/app/assets/icons/mail-line-B0P8aa1L.js +1 -0
- package/web/app/site/app/assets/icons/moon-line-CEqNAToP.js +1 -0
- package/web/app/site/app/assets/icons/more-1-fill-Dw2e5xab.js +1 -0
- package/web/app/site/app/assets/icons/more-3-line-BIiVjYTz.js +1 -0
- package/web/app/site/app/assets/icons/notification-line-BZZq2Gtu.js +1 -0
- package/web/app/site/app/assets/icons/pencil-line-CKh8-A1v.js +1 -0
- package/web/app/site/app/assets/icons/photo-album-line-Bnfg2u40.js +1 -0
- package/web/app/site/app/assets/icons/pin-line-DpTolyhs.js +1 -0
- package/web/app/site/app/assets/icons/play-fill-B0-G_8lX.js +1 -0
- package/web/app/site/app/assets/icons/qrcode-2-line-B6SPCaHn.js +1 -0
- package/web/app/site/app/assets/icons/quill-pen-line-B6LUrnCP.js +1 -0
- package/web/app/site/app/assets/icons/quote-left-fill-hQZ1cj_6.js +1 -0
- package/web/app/site/app/assets/icons/radar-line-CKyroTth.js +1 -0
- package/web/app/site/app/assets/icons/react-line-CoIKhhtK.js +1 -0
- package/web/app/site/app/assets/icons/refresh-2-line-D0mTF97S.js +1 -0
- package/web/app/site/app/assets/icons/right-line-B3KWJaqc.js +1 -0
- package/web/app/site/app/assets/icons/rocket-line-4KZl537D.js +1 -0
- package/web/app/site/app/assets/icons/round-fill-C69NTrZ0.js +1 -0
- package/web/app/site/app/assets/icons/round-line-B9k_1uo-.js +1 -0
- package/web/app/site/app/assets/icons/route-line-B28ReHcE.js +1 -0
- package/web/app/site/app/assets/icons/rows-4-line-CrBniagM.js +1 -0
- package/web/app/site/app/assets/icons/scan-line-DSf74YdP.js +1 -0
- package/web/app/site/app/assets/icons/search-2-line-B6geIU1z.js +1 -0
- package/web/app/site/app/assets/icons/settings-3-line-azJwK47w.js +1 -0
- package/web/app/site/app/assets/icons/settings-6-line-C_5zc5YR.js +1 -0
- package/web/app/site/app/assets/icons/share-2-line-D5MxWjrm.js +1 -0
- package/web/app/site/app/assets/icons/share-forward-line-Cp61fZzZ.js +1 -0
- package/web/app/site/app/assets/icons/sparkles-2-line-DYYyXTaW.js +1 -0
- package/web/app/site/app/assets/icons/sparkles-line-C2hY1s6I.js +1 -0
- package/web/app/site/app/assets/icons/time-line-BF3eet1v.js +1 -0
- package/web/app/site/app/assets/icons/transfer-4-line-oisfvTBw.js +1 -0
- package/web/app/site/app/assets/icons/translate-line-BFWol2Ce.js +1 -0
- package/web/app/site/app/assets/icons/unlock-line-X_x5vwv3.js +1 -0
- package/web/app/site/app/assets/icons/upload-3-line-DgzwUJeW.js +1 -0
- package/web/app/site/app/assets/icons/user-4-line-BVSynZCp.js +1 -0
- package/web/app/site/app/assets/icons/user-add-2-line-BlGS5Q8q.js +1 -0
- package/web/app/site/app/assets/icons/user-add-line-BbXdHG4z.js +1 -0
- package/web/app/site/app/assets/icons/user-edit-line-BFAHOV0X.js +1 -0
- package/web/app/site/app/assets/icons/user-follow-line-BXux0wSd.js +1 -0
- package/web/app/site/app/assets/icons/user-star-line-DdYlpHLU.js +1 -0
- package/web/app/site/app/assets/icons/user-warning-line-Cj43j0_E.js +1 -0
- package/web/app/site/app/assets/icons/user-x-line-DIDgNlPH.js +1 -0
- package/web/app/site/app/assets/icons/volume-line-Bs390KQt.js +1 -0
- package/web/app/site/app/assets/icons/volume-mute-line-DzlzIqFZ.js +1 -0
- package/web/app/site/app/assets/icons/walk-line-yNXfB-md.js +1 -0
- package/web/app/site/app/assets/icons/world-2-line-CenkGIwj.js +1 -0
- package/web/app/site/app/assets/icons/zoom-in-line-CaENUphf.js +1 -0
- package/web/app/site/app/assets/icons/zoom-out-line-BDNk0EWo.js +1 -0
- package/web/app/site/app/assets/instances-BNPptnn-.json +333 -0
- package/web/app/site/app/assets/locales/ar-SA-CfheRbCu.js +1 -0
- package/web/app/site/app/assets/locales/ca-ES-DHRW86Tz.js +1 -0
- package/web/app/site/app/assets/locales/cs-CZ-CKoqEuA1.js +1 -0
- package/web/app/site/app/assets/locales/de-DE-ByRPMRFy.js +1 -0
- package/web/app/site/app/assets/locales/eo-UY-CPC7wLCS.js +1 -0
- package/web/app/site/app/assets/locales/es-ES-dJa0Fd9t.js +1 -0
- package/web/app/site/app/assets/locales/eu-ES-C3djlPR2.js +1 -0
- package/web/app/site/app/assets/locales/fa-IR-DTT490Ck.js +1 -0
- package/web/app/site/app/assets/locales/fi-FI-B23MCPuz.js +1 -0
- package/web/app/site/app/assets/locales/fr-FR-BcaQsO5C.js +1 -0
- package/web/app/site/app/assets/locales/gl-ES-BR-CVKBN.js +1 -0
- package/web/app/site/app/assets/locales/he-IL-CfheRbCu.js +1 -0
- package/web/app/site/app/assets/locales/hu-HU-CfheRbCu.js +1 -0
- package/web/app/site/app/assets/locales/it-IT-C1136UFV.js +1 -0
- package/web/app/site/app/assets/locales/ja-JP-CRZmRAhD.js +1 -0
- package/web/app/site/app/assets/locales/kab-Cz8xH_TT.js +1 -0
- package/web/app/site/app/assets/locales/ko-KR-CG9UiY4o.js +1 -0
- package/web/app/site/app/assets/locales/lt-LT-CJcI6sHZ.js +1 -0
- package/web/app/site/app/assets/locales/nb-NO-CfheRbCu.js +1 -0
- package/web/app/site/app/assets/locales/nl-NL-DxN4Yc1t.js +1 -0
- package/web/app/site/app/assets/locales/oc-FR-CfheRbCu.js +1 -0
- package/web/app/site/app/assets/locales/pl-PL-DkwGXf6P.js +1 -0
- package/web/app/site/app/assets/locales/pseudo-LOCALE-CQ4XxkQ0.js +1 -0
- package/web/app/site/app/assets/locales/pt-BR-nGL0HdFS.js +1 -0
- package/web/app/site/app/assets/locales/pt-PT-Cp17aj2z.js +1 -0
- package/web/app/site/app/assets/locales/ru-RU-0Y8cIoaK.js +1 -0
- package/web/app/site/app/assets/locales/th-TH-CfheRbCu.js +1 -0
- package/web/app/site/app/assets/locales/tok-CfheRbCu.js +1 -0
- package/web/app/site/app/assets/locales/tr-TR-CfheRbCu.js +1 -0
- package/web/app/site/app/assets/locales/uk-UA-C5E3dFBf.js +1 -0
- package/web/app/site/app/assets/locales/zh-CN-BHJi7_et.js +1 -0
- package/web/app/site/app/assets/locales/zh-TW-CfheRbCu.js +1 -0
- package/web/app/site/app/assets/main-BdqNbG-a.js +26 -0
- package/web/app/site/app/assets/main-BdqNbG-a.js.map +1 -0
- package/web/app/site/app/assets/mock-home-DGhR__He.js +2 -0
- package/web/app/site/app/assets/mock-home-DGhR__He.js.map +1 -0
- package/web/app/site/app/assets/multi-column-ROck0NVt.jpg +0 -0
- package/web/app/site/app/assets/multi-hashtag-timeline-DH5INVHi.jpg +0 -0
- package/web/app/site/app/assets/nested-comments-thread-hv59kZLc.jpg +0 -0
- package/web/app/site/app/assets/polyfill-force-H8sUkLGp.js +2 -0
- package/web/app/site/app/assets/polyfill-force-H8sUkLGp.js.map +1 -0
- package/web/app/site/app/assets/pwa-viewport-ogKbF51K.js +20 -0
- package/web/app/site/app/assets/pwa-viewport-ogKbF51K.js.map +1 -0
- package/web/app/site/app/assets/style-B1iLPTPR.css +2 -0
- package/web/app/site/app/assets/temml-DuyIQMei.js +97 -0
- package/web/app/site/app/assets/temml-DuyIQMei.js.map +1 -0
- package/web/app/site/app/assets/tinyld.light.node-DtbBhLYC.js +2 -0
- package/web/app/site/app/assets/tinyld.light.node-DtbBhLYC.js.map +1 -0
- package/web/app/site/app/assets/year-in-posts-B2lywqdx.png +0 -0
- package/web/app/site/app/assets/year-in-posts-DJv_star.js +3 -0
- package/web/app/site/app/assets/year-in-posts-DJv_star.js.map +1 -0
- package/web/app/site/app/compose/index.html +20 -0
- package/web/app/site/app/favicon.ico +0 -0
- package/web/app/site/app/index.html +73 -0
- package/web/app/site/app/logo-192.png +0 -0
- package/web/app/site/app/logo-512.png +0 -0
- package/web/app/site/app/logo-badge-72.png +0 -0
- package/web/app/site/app/logo-maskable-512.png +0 -0
- package/web/app/site/app/logo-monochrome-512.png +0 -0
- package/web/app/site/app/logo-monochrome-maskable-512.png +0 -0
- package/web/app/site/app/manifest.webmanifest +1 -0
- package/web/app/site/app/og-image-2.jpg +0 -0
- package/web/app/site/app/og-image.png +0 -0
- package/web/app/site/app/robots.txt +2 -0
- package/web/app/site/app/version.json +1 -0
- package/web/app/site/boot.js +34067 -0
- package/web/app/site/index.html +203 -0
- package/web/app/site/sw.js +53745 -0
- package/web/app/sw-src.mjs +205 -0
- package/web/front/#new-account.html# +43 -0
- package/web/front/admin.html +1 -81
- package/web/front/admin.js +85 -0
- package/web/front/new-account.html +1 -9
- package/web/front/new-account.js +13 -0
- package/web/front/run.html +1 -92
- package/web/front/run.js +107 -0
- package/lib/podrdf.mjs +0 -132
package/web/front/run.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// run.js — the opt-in / opt-out page's script, in a file of its own.
|
|
2
|
+
//
|
|
3
|
+
// It lived inline in run.html until 2026-09-09. Out here the page can be served
|
|
4
|
+
// under `script-src 'self'`, which is what stops a stray bit of markup from
|
|
5
|
+
// becoming running code; inline script cannot be told apart from injected
|
|
6
|
+
// script by any policy. Served by the front at /run.js.
|
|
7
|
+
//
|
|
8
|
+
// A module, because it awaits an import of /solid-oidc-client.js at the top
|
|
9
|
+
// level — which is itself the proof this mechanism works: that file has been
|
|
10
|
+
// loaded from a route by this page all along.
|
|
11
|
+
const $ = (id) => document.getElementById(id);
|
|
12
|
+
|
|
13
|
+
// The Solid-OIDC client for the sign-in round trip. Constructed once; the
|
|
14
|
+
// redirect state (PKCE, csrf) lives in this tab's sessionStorage, so the same
|
|
15
|
+
// session finishes the login on the way back.
|
|
16
|
+
let session = null;
|
|
17
|
+
try {
|
|
18
|
+
const { SessionCore } = await import('/solid-oidc-client.js');
|
|
19
|
+
session = new SessionCore({ redirect_uris: [location.origin + '/run'], client_name: 'FediPod gateway' });
|
|
20
|
+
} catch { /* leave null — the "did not load" notes below fire */ }
|
|
21
|
+
|
|
22
|
+
// Offered only where this server actually runs identities. An
|
|
23
|
+
// unauthenticated probe tells the two apart: 501 = not offered here,
|
|
24
|
+
// anything else = offered (a real opt-in still needs the signed-in proof).
|
|
25
|
+
let offered = true;
|
|
26
|
+
(async () => {
|
|
27
|
+
const res = await fetch('/api/agent', { method: 'POST',
|
|
28
|
+
headers: { 'content-type': 'application/json' }, body: '{}' }).catch(() => null);
|
|
29
|
+
if (!res || res.status === 501) {
|
|
30
|
+
offered = false;
|
|
31
|
+
const n = $('run-note');
|
|
32
|
+
n.hidden = false;
|
|
33
|
+
n.textContent = 'This server does not run identities. Your agent stays where it is.';
|
|
34
|
+
runFormCheck();
|
|
35
|
+
}
|
|
36
|
+
})();
|
|
37
|
+
|
|
38
|
+
function runFormCheck() {
|
|
39
|
+
let ok = false;
|
|
40
|
+
try { ok = /^https?:$/.test(new URL($('run-pod-url').value.trim()).protocol); } catch { /* not yet */ }
|
|
41
|
+
const issuerOk = /^https?:\/\/\S+/.test($('run-issuer').value.trim());
|
|
42
|
+
$('run-continue').disabled = !(offered && ok && issuerOk);
|
|
43
|
+
$('run-leave').disabled = !(offered && ok && issuerOk);
|
|
44
|
+
}
|
|
45
|
+
$('run-pod-url').addEventListener('input', () => {
|
|
46
|
+
runFormCheck();
|
|
47
|
+
// The identity provider is usually the server itself — still editable.
|
|
48
|
+
try {
|
|
49
|
+
const u = new URL($('run-pod-url').value.trim());
|
|
50
|
+
const apex = u.hostname.split('.').slice(1).join('.');
|
|
51
|
+
if (!$('run-issuer').value && apex) $('run-issuer').value = `${u.protocol}//${apex}${u.port ? ':' + u.port : ''}`;
|
|
52
|
+
} catch { /* not a URL yet */ }
|
|
53
|
+
runFormCheck();
|
|
54
|
+
});
|
|
55
|
+
$('run-issuer').addEventListener('input', runFormCheck);
|
|
56
|
+
|
|
57
|
+
const runStart = (action) => {
|
|
58
|
+
const n = $('run-note');
|
|
59
|
+
if (!session) { n.hidden = false; n.textContent = 'the sign-in library did not load — reload and try again'; return; }
|
|
60
|
+
const u = new URL($('run-pod-url').value.trim());
|
|
61
|
+
if (u.pathname === '') u.pathname = '/';
|
|
62
|
+
if (!u.pathname.endsWith('/')) u.pathname += '/';
|
|
63
|
+
u.search = ''; u.hash = '';
|
|
64
|
+
sessionStorage.setItem('fp-run', JSON.stringify({ podBase: u.href, action }));
|
|
65
|
+
session.login($('run-issuer').value.trim(), location.origin + '/run')
|
|
66
|
+
.catch((e) => { n.hidden = false; n.textContent = 'sign-in failed to start: ' + e.message; });
|
|
67
|
+
};
|
|
68
|
+
$('run-continue').onclick = () => runStart('opt-in');
|
|
69
|
+
$('run-leave').onclick = () => runStart('opt-out');
|
|
70
|
+
|
|
71
|
+
// Back from the identity provider: finish the opt-in with the proven login.
|
|
72
|
+
(async () => {
|
|
73
|
+
if (!session) return;
|
|
74
|
+
await session.handleRedirectFromLogin().catch(() => {});
|
|
75
|
+
const pending = sessionStorage.getItem('fp-run');
|
|
76
|
+
if (!session.isActive || !pending) return;
|
|
77
|
+
sessionStorage.removeItem('fp-run');
|
|
78
|
+
const p = JSON.parse(pending);
|
|
79
|
+
const n = $('run-note');
|
|
80
|
+
n.hidden = false;
|
|
81
|
+
n.textContent = 'signed in as ' + session.webId + ' — asking the server…';
|
|
82
|
+
// The signed fetch builds a DPoP proof from the URL, so it must be absolute.
|
|
83
|
+
const res = await session.authFetch(location.origin + '/api/agent', {
|
|
84
|
+
method: 'POST', headers: { 'content-type': 'application/json' },
|
|
85
|
+
body: JSON.stringify({ action: p.action, podBase: p.podBase }),
|
|
86
|
+
}).catch(() => null);
|
|
87
|
+
const d = res ? await res.json().catch(() => ({})) : {};
|
|
88
|
+
if (res && res.status === 201 && d.doorSecret) {
|
|
89
|
+
// Built as nodes, not as a string of HTML. Three of the pieces below come
|
|
90
|
+
// back from the server and one comes from sessionStorage, and pasting any
|
|
91
|
+
// of them into innerHTML means whatever markup they contain is rendered.
|
|
92
|
+
// Only the fixed wording is markup here; everything variable is text.
|
|
93
|
+
const say = (tag, text) => { const e = document.createElement(tag); e.textContent = text; return e; };
|
|
94
|
+
n.textContent = 'Your identity runs here now. This is your door secret — ';
|
|
95
|
+
n.append(say('b', 'save it now'));
|
|
96
|
+
n.append(', it is shown only this once. It opens your admin pages at ');
|
|
97
|
+
n.append(say('code', p.podBase.replace(/\/$/, '') + d.doorPath));
|
|
98
|
+
n.append(':', say('pre', d.doorSecret));
|
|
99
|
+
n.append('To check it works:', say('pre', d.command));
|
|
100
|
+
n.append('Lost it? Opt in again — that mints a fresh one and retires this one.');
|
|
101
|
+
} else if (res && res.status === 200) {
|
|
102
|
+
n.textContent = 'Done — this server no longer runs that identity. Your pod and its data are untouched.';
|
|
103
|
+
} else {
|
|
104
|
+
n.textContent = (p.action === 'opt-in' ? 'opt-in' : 'opt-out') + ' failed: '
|
|
105
|
+
+ (d.error || (res ? 'HTTP ' + res.status : 'no response'));
|
|
106
|
+
}
|
|
107
|
+
})();
|
package/lib/podrdf.mjs
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
// podrdf.mjs — the RDF source of truth under /activitypods-js/fediverse/:
|
|
2
|
-
// settings, contacts, and one document per note. Same documents and AS2
|
|
3
|
-
// vocabulary as dk's local.mjs (plan: ap-pod-mapping.md).
|
|
4
|
-
//
|
|
5
|
-
// Parsed and serialised by rdflib, never by hand. Escaping, encoding and shape
|
|
6
|
-
// are exactly what a regex gets wrong quietly — a tab inside a literal, a '%'
|
|
7
|
-
// in a slug, a triple laid out in a form the pattern did not anticipate — and
|
|
8
|
-
// a hand-built serialiser writes the documents the hand-built parser reads
|
|
9
|
-
// back, so the two bugs cover for each other. See claude/plans/no-regex-rdf.md.
|
|
10
|
-
//
|
|
11
|
-
// The container it lives in is a Storage (lib/storage.mjs): a pod over HTTP or
|
|
12
|
-
// a directory. Callers still speak in absolute URLs, which is what the rest of
|
|
13
|
-
// the agent has.
|
|
14
|
-
|
|
15
|
-
import * as $rdf from 'rdflib';
|
|
16
|
-
|
|
17
|
-
const AS = $rdf.Namespace('https://www.w3.org/ns/activitystreams#');
|
|
18
|
-
const RDF = $rdf.Namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#');
|
|
19
|
-
const XSD = $rdf.Namespace('http://www.w3.org/2001/XMLSchema#');
|
|
20
|
-
const TURTLE = 'text/turtle';
|
|
21
|
-
|
|
22
|
-
export class PodRdf {
|
|
23
|
-
constructor({ storage }) {
|
|
24
|
-
this.storage = storage;
|
|
25
|
-
this.base = storage.base;
|
|
26
|
-
this.fedi = this.base;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Callers hold absolute URLs; the storage works in paths under its base.
|
|
30
|
-
_rel(url) {
|
|
31
|
-
if (!url.startsWith(this.fedi)) throw new Error(`${url} is not under ${this.fedi}`);
|
|
32
|
-
return url.slice(this.fedi.length);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
async get(url) {
|
|
36
|
-
const r = await this.storage.read(this._rel(url));
|
|
37
|
-
if (!r.ok) throw new Error(`pod GET ${url} → ${r.status}`);
|
|
38
|
-
return r.body;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async put(url, body, contentType = TURTLE) {
|
|
42
|
-
const r = await this.storage.write(this._rel(url), body, contentType);
|
|
43
|
-
if (!r.ok) throw new Error(`pod PUT ${url} → ${r.why}`);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
async delete(url) {
|
|
47
|
-
if (!await this.storage.remove(this._rel(url))) throw new Error(`pod DELETE ${url} failed`);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Child resource URLs of {fedi}{kind}/ (empty when the container is absent).
|
|
51
|
-
async listNotes(kind) {
|
|
52
|
-
const { names } = await this.storage.list(`${kind}/`);
|
|
53
|
-
return names
|
|
54
|
-
// `.<pid>.tmp` is what FileStorage.write leaves if it is interrupted
|
|
55
|
-
// between the write and the rename. It is not a note, and handing one to
|
|
56
|
-
// the parser produces a failure that reads like a corrupt document.
|
|
57
|
-
.filter(n => !n.endsWith('/') && !/\.(acl|meta)$/.test(n) && !/\.\d+\.tmp$/.test(n))
|
|
58
|
-
.map(n => `${this.fedi}${kind}/${n}`);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
_graph(url, ttl) {
|
|
62
|
-
const g = $rdf.graph();
|
|
63
|
-
$rdf.parse(ttl, g, url, TURTLE);
|
|
64
|
-
return g;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Inverse of writeNote for one resource.
|
|
68
|
-
async readNote(url) {
|
|
69
|
-
const g = this._graph(url, await this.get(url));
|
|
70
|
-
const doc = $rdf.sym(url);
|
|
71
|
-
const iri = (p) => g.any(doc, AS(p), null, doc)?.value;
|
|
72
|
-
const str = (p) => g.any(doc, AS(p), null, doc)?.value;
|
|
73
|
-
const attachments = g.each(doc, AS('attachment'), null, doc).map((a) => {
|
|
74
|
-
const mediaType = g.any(a, AS('mediaType'), null, doc)?.value;
|
|
75
|
-
const description = g.any(a, AS('name'), null, doc)?.value;
|
|
76
|
-
return { url: a.value, mediaType: mediaType || '', ...(description ? { description } : {}) };
|
|
77
|
-
});
|
|
78
|
-
return {
|
|
79
|
-
noteId: iri('url'), actor: iri('attributedTo'),
|
|
80
|
-
published: str('published'), inReplyTo: iri('inReplyTo'), content: str('content'),
|
|
81
|
-
...(attachments.length ? { attachments } : {}),
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Incoming or own post → one RDF resource. kind: 'timeline' | 'posts'
|
|
86
|
-
async writeNote(kind, slug, { noteId, actor, published, content, inReplyTo, attachments }) {
|
|
87
|
-
const url = `${this.fedi}${kind}/${slug}`;
|
|
88
|
-
const doc = $rdf.sym(url);
|
|
89
|
-
const g = $rdf.graph();
|
|
90
|
-
g.add(doc, RDF('type'), AS('Note'), doc);
|
|
91
|
-
g.add(doc, AS('url'), $rdf.sym(noteId), doc);
|
|
92
|
-
g.add(doc, AS('attributedTo'), $rdf.sym(actor), doc);
|
|
93
|
-
// Two-arg with a NamedNode is how rdflib takes a datatype; passing it
|
|
94
|
-
// third silently yields an xsd:string, which would drop ^^xsd:dateTime
|
|
95
|
-
// from every note published from here on.
|
|
96
|
-
if (published) g.add(doc, AS('published'), $rdf.literal(published, XSD('dateTime')), doc);
|
|
97
|
-
if (inReplyTo) g.add(doc, AS('inReplyTo'), $rdf.sym(inReplyTo), doc);
|
|
98
|
-
g.add(doc, AS('content'), $rdf.literal(content || ''), doc);
|
|
99
|
-
for (const a of attachments || []) {
|
|
100
|
-
const at = $rdf.sym(a.url);
|
|
101
|
-
g.add(doc, AS('attachment'), at, doc);
|
|
102
|
-
g.add(at, RDF('type'), AS('Document'), doc);
|
|
103
|
-
if (a.mediaType) g.add(at, AS('mediaType'), $rdf.literal(a.mediaType), doc);
|
|
104
|
-
if (a.description) g.add(at, AS('name'), $rdf.literal(a.description), doc);
|
|
105
|
-
}
|
|
106
|
-
await this.put(url, $rdf.serialize(doc, g, url, TURTLE));
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Contacts doc — the followers/following truth, rebuilt whole each change.
|
|
110
|
-
async writeContacts({ followers, following }) {
|
|
111
|
-
const url = this.fedi + 'contacts';
|
|
112
|
-
const doc = $rdf.sym(url);
|
|
113
|
-
const me = $rdf.sym(url + '#me');
|
|
114
|
-
const g = $rdf.graph();
|
|
115
|
-
g.add(me, RDF('type'), AS('Person'), doc);
|
|
116
|
-
for (const f of followers) g.add(me, AS('followers'), $rdf.sym(f.actor), doc);
|
|
117
|
-
for (const f of following) g.add(me, AS('following'), $rdf.sym(f.actor), doc);
|
|
118
|
-
await this.put(url, $rdf.serialize(doc, g, url, TURTLE));
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Settings doc — handle + pointer to the public face.
|
|
122
|
-
async writeSettings({ handle, actorUrl }) {
|
|
123
|
-
const url = this.fedi + 'settings';
|
|
124
|
-
const doc = $rdf.sym(url);
|
|
125
|
-
const me = $rdf.sym(url + '#me');
|
|
126
|
-
const g = $rdf.graph();
|
|
127
|
-
g.add(me, RDF('type'), AS('Person'), doc);
|
|
128
|
-
g.add(me, AS('preferredUsername'), $rdf.literal(handle), doc);
|
|
129
|
-
g.add(me, AS('url'), $rdf.sym(actorUrl), doc);
|
|
130
|
-
await this.put(url, $rdf.serialize(doc, g, url, TURTLE));
|
|
131
|
-
}
|
|
132
|
-
}
|