fedipod-server 0.29.0 → 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 (440) hide show
  1. package/README.md +11 -6
  2. package/dist/door.d.ts +4 -0
  3. package/dist/door.js +31 -0
  4. package/dist/fedipod.d.ts +16 -0
  5. package/dist/fedipod.js +13 -0
  6. package/dist/front.d.ts +3 -0
  7. package/dist/front.js +94 -0
  8. package/dist/handler.d.ts +36 -101
  9. package/dist/handler.js +85 -645
  10. package/dist/handler.jsonld +2 -30
  11. package/dist/identities.d.ts +62 -0
  12. package/dist/identities.js +236 -0
  13. package/dist/mounts.d.ts +43 -0
  14. package/dist/mounts.js +123 -0
  15. package/dist/opt-in.d.ts +46 -0
  16. package/dist/opt-in.js +176 -0
  17. package/package.json +10 -18
  18. package/lib/client/c2s.mjs +0 -636
  19. package/lib/client/localapi.mjs +0 -87
  20. package/lib/client/masto/accounts.mjs +0 -310
  21. package/lib/client/masto/body.mjs +0 -156
  22. package/lib/client/masto/index.mjs +0 -206
  23. package/lib/client/masto/instance.mjs +0 -112
  24. package/lib/client/masto/media.mjs +0 -79
  25. package/lib/client/masto/oauth.mjs +0 -656
  26. package/lib/client/masto/render.mjs +0 -518
  27. package/lib/client/masto/statuses.mjs +0 -372
  28. package/lib/client/masto/timelines.mjs +0 -438
  29. package/lib/client/oidc-auth.mjs +0 -62
  30. package/lib/client/streaming.mjs +0 -154
  31. package/lib/client/webpush.mjs +0 -98
  32. package/lib/connections/acctfeed.mjs +0 -257
  33. package/lib/connections/atproto.mjs +0 -309
  34. package/lib/connections/bskyfeed.mjs +0 -243
  35. package/lib/connections/bskygroup.mjs +0 -162
  36. package/lib/connections/fediacct.mjs +0 -253
  37. package/lib/connections/import.mjs +0 -357
  38. package/lib/connections/tagfeed.mjs +0 -212
  39. package/lib/connections/vault.mjs +0 -114
  40. package/lib/core/as2.mjs +0 -206
  41. package/lib/core/contexts/activitystreams.json +0 -379
  42. package/lib/core/contexts/anno.json +0 -126
  43. package/lib/core/contexts/did-v1.json +0 -57
  44. package/lib/core/contexts/fep-5711.json +0 -36
  45. package/lib/core/contexts/gotosocial.json +0 -86
  46. package/lib/core/contexts/identity-v1.json +0 -152
  47. package/lib/core/contexts/index.mjs +0 -63
  48. package/lib/core/contexts/join-lemmy.json +0 -33
  49. package/lib/core/contexts/joinmastodon.json +0 -28
  50. package/lib/core/contexts/litepub-0.1.json +0 -60
  51. package/lib/core/contexts/map.json +0 -19
  52. package/lib/core/contexts/miscellany.json +0 -19
  53. package/lib/core/contexts/quotes.json +0 -18
  54. package/lib/core/contexts/schemaorg.json +0 -8845
  55. package/lib/core/contexts/security-data-integrity-v1.json +0 -78
  56. package/lib/core/contexts/security-data-integrity-v2.json +0 -81
  57. package/lib/core/contexts/security-multikey-v1.json +0 -35
  58. package/lib/core/contexts/security-v1.json +0 -74
  59. package/lib/core/contexts/webfinger.json +0 -10
  60. package/lib/core/deliver.mjs +0 -387
  61. package/lib/core/graphview.mjs +0 -327
  62. package/lib/core/intake/activities.mjs +0 -649
  63. package/lib/core/intake/activity.mjs +0 -318
  64. package/lib/core/intake/channel.mjs +0 -144
  65. package/lib/core/intake/group.mjs +0 -258
  66. package/lib/core/intake/index.mjs +0 -732
  67. package/lib/core/intake/notes.mjs +0 -367
  68. package/lib/core/intake/verify.mjs +0 -142
  69. package/lib/core/keys.mjs +0 -153
  70. package/lib/core/lease.mjs +0 -206
  71. package/lib/core/place.mjs +0 -82
  72. package/lib/core/polls.mjs +0 -105
  73. package/lib/core/profile-page.mjs +0 -104
  74. package/lib/core/proof.mjs +0 -79
  75. package/lib/core/publisher/collections.mjs +0 -272
  76. package/lib/core/publisher/index.mjs +0 -522
  77. package/lib/core/publisher/notes.mjs +0 -519
  78. package/lib/core/publisher/own.mjs +0 -143
  79. package/lib/core/publisher/questions.mjs +0 -241
  80. package/lib/core/publisher/restore.mjs +0 -224
  81. package/lib/core/shapes/activitystreams.ttl +0 -157
  82. package/lib/core/shapes/index.mjs +0 -132
  83. package/lib/core/shapes/shapes-text.mjs +0 -13
  84. package/lib/core/social.mjs +0 -561
  85. package/lib/core/storage.mjs +0 -176
  86. package/lib/core/store.mjs +0 -578
  87. package/lib/core/wire-quotes.mjs +0 -71
  88. package/lib/core/wire.mjs +0 -925
  89. package/lib/device/account.mjs +0 -87
  90. package/lib/device/admin/index.mjs +0 -13
  91. package/lib/device/admin/origins.mjs +0 -35
  92. package/lib/device/admin/routes/connections.mjs +0 -144
  93. package/lib/device/admin/routes/gateway.mjs +0 -199
  94. package/lib/device/admin/routes/lifecycle.mjs +0 -200
  95. package/lib/device/admin/routes/owner.mjs +0 -322
  96. package/lib/device/admin/routes/setup.mjs +0 -428
  97. package/lib/device/admin/routes/social.mjs +0 -188
  98. package/lib/device/admin/server.mjs +0 -95
  99. package/lib/device/admin/static.mjs +0 -247
  100. package/lib/device/admin/surface.mjs +0 -315
  101. package/lib/device/certs.mjs +0 -281
  102. package/lib/device/cli/commands/account.mjs +0 -586
  103. package/lib/device/cli/commands/run.mjs +0 -278
  104. package/lib/device/cli/commands/service.mjs +0 -221
  105. package/lib/device/cli/commands/setup.mjs +0 -489
  106. package/lib/device/cli/commands/state.mjs +0 -561
  107. package/lib/device/cli/context.mjs +0 -288
  108. package/lib/device/export-collections.mjs +0 -161
  109. package/lib/device/gateway-move.mjs +0 -58
  110. package/lib/device/home.mjs +0 -161
  111. package/lib/device/migrate.mjs +0 -115
  112. package/lib/device/ports.mjs +0 -27
  113. package/lib/device/remote.mjs +0 -54
  114. package/lib/device/setup.mjs +0 -496
  115. package/lib/device/update.mjs +0 -96
  116. package/lib/gateway/caches.mjs +0 -36
  117. package/lib/gateway/directory.mjs +0 -90
  118. package/lib/gateway/front-core.mjs +0 -966
  119. package/lib/gateway/gateway-core.mjs +0 -244
  120. package/lib/gateway/headers.mjs +0 -49
  121. package/lib/gateway/httpsig.mjs +0 -159
  122. package/lib/gateway/notices.mjs +0 -84
  123. package/lib/gateway/quiet.mjs +0 -189
  124. package/lib/gateway/relay-extras.mjs +0 -89
  125. package/lib/gateway/token-claims.mjs +0 -16
  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/location.mjs +0 -52
  138. package/lib/pod/media.mjs +0 -27
  139. package/lib/pod/notes.mjs +0 -78
  140. package/lib/pod/notifications.mjs +0 -89
  141. package/lib/pod/outbox.mjs +0 -18
  142. package/lib/pod/package.json +0 -19
  143. package/lib/pod/policy.mjs +0 -58
  144. package/lib/pod/private.mjs +0 -19
  145. package/lib/pod/root.mjs +0 -104
  146. package/lib/pod/state.mjs +0 -40
  147. package/lib/pod/transport.mjs +0 -674
  148. package/lib/pod/type-index.mjs +0 -101
  149. package/lib/pod/urls.mjs +0 -91
  150. package/lib/server/embed.mjs +0 -424
  151. package/lib/session/README.md +0 -137
  152. package/lib/session/demo.html +0 -94
  153. package/lib/session/fedi-account.mjs +0 -417
  154. package/lib/session/fedi-login.mjs +0 -123
  155. package/lib/session/oidc-session.mjs +0 -233
  156. package/lib/session/package.json +0 -49
  157. package/lib/shared/guard.mjs +0 -213
  158. package/lib/shared/links.mjs +0 -9
  159. package/lib/shared/safefetch.mjs +0 -235
  160. package/lib/shared/ua.mjs +0 -29
  161. package/phanpy/dist/404.html +0 -40
  162. package/phanpy/dist/_headers +0 -2
  163. package/phanpy/dist/apple-touch-icon.png +0 -0
  164. package/phanpy/dist/assets/ICONS-DIPJeU0C.js +0 -2
  165. package/phanpy/dist/assets/ICONS-DIPJeU0C.js.map +0 -1
  166. package/phanpy/dist/assets/ScheduledAtField-D-Abfo4J.js +0 -183
  167. package/phanpy/dist/assets/ScheduledAtField-D-Abfo4J.js.map +0 -1
  168. package/phanpy/dist/assets/Temml-CCjoacWt.woff2 +0 -0
  169. package/phanpy/dist/assets/__vite-browser-external-C7iut881.js +0 -2
  170. package/phanpy/dist/assets/__vite-browser-external-C7iut881.js.map +0 -1
  171. package/phanpy/dist/assets/boosts-carousel-BiOaNdMT.jpg +0 -0
  172. package/phanpy/dist/assets/catch-up-O5q5C75Z.png +0 -0
  173. package/phanpy/dist/assets/chunk-aKtaBQYM.js +0 -1
  174. package/phanpy/dist/assets/compose-CFEx7wb4.js +0 -2
  175. package/phanpy/dist/assets/compose-CFEx7wb4.js.map +0 -1
  176. package/phanpy/dist/assets/compose-ZJN5xSb4.js +0 -35
  177. package/phanpy/dist/assets/compose-ZJN5xSb4.js.map +0 -1
  178. package/phanpy/dist/assets/debug.module-YFQgwnIr.js +0 -52
  179. package/phanpy/dist/assets/debug.module-YFQgwnIr.js.map +0 -1
  180. package/phanpy/dist/assets/dom-p1YcJ5Rw.js +0 -2
  181. package/phanpy/dist/assets/dom-p1YcJ5Rw.js.map +0 -1
  182. package/phanpy/dist/assets/home-mobile-dark@2x-Dc-J8-SM.png +0 -0
  183. package/phanpy/dist/assets/home-mobile-light@2x-Bd3fod8m.png +0 -0
  184. package/phanpy/dist/assets/home-tablet-dark@2x-BgcNI8le.png +0 -0
  185. package/phanpy/dist/assets/home-tablet-light@2x-BW2RV9T6.png +0 -0
  186. package/phanpy/dist/assets/icons/add-circle-line-WD0mwORD.js +0 -1
  187. package/phanpy/dist/assets/icons/alert-line-CpFUMf9s.js +0 -1
  188. package/phanpy/dist/assets/icons/android-2-line-Bzxnrd3S.js +0 -1
  189. package/phanpy/dist/assets/icons/announcement-line-5nwaJFJm.js +0 -1
  190. package/phanpy/dist/assets/icons/arrow-down-circle-line-a7Id9-Iv.js +0 -1
  191. package/phanpy/dist/assets/icons/arrow-down-line-B8uzXzq6.js +0 -1
  192. package/phanpy/dist/assets/icons/arrow-left-line-CGrGT9C-.js +0 -1
  193. package/phanpy/dist/assets/icons/arrow-right-line-CE-HERfX.js +0 -1
  194. package/phanpy/dist/assets/icons/arrow-to-up-line-CvdQjmcy.js +0 -1
  195. package/phanpy/dist/assets/icons/arrow-up-circle-line-DEparSNF.js +0 -1
  196. package/phanpy/dist/assets/icons/arrow-up-line-C7yBeugc.js +0 -1
  197. package/phanpy/dist/assets/icons/arrows-right-line-BtbXmJGP.js +0 -1
  198. package/phanpy/dist/assets/icons/at-line-CF66Bznk.js +0 -1
  199. package/phanpy/dist/assets/icons/attachment-line-BY8It-l9.js +0 -1
  200. package/phanpy/dist/assets/icons/blockquote-line-BS6pU_hm.js +0 -1
  201. package/phanpy/dist/assets/icons/board-line-C0UWXyA6.js +0 -1
  202. package/phanpy/dist/assets/icons/bookmark-line-1CtX5JLF.js +0 -1
  203. package/phanpy/dist/assets/icons/building-5-line-Dd59MzbO.js +0 -1
  204. package/phanpy/dist/assets/icons/bus-2-line-6_dvA0GG.js +0 -1
  205. package/phanpy/dist/assets/icons/calendar-day-line-Crpl_fmu.js +0 -1
  206. package/phanpy/dist/assets/icons/calendar-month-line-vommts2C.js +0 -1
  207. package/phanpy/dist/assets/icons/calendar-time-add-line-BU_DTlQk.js +0 -1
  208. package/phanpy/dist/assets/icons/camera-line-Cv69MEei.js +0 -1
  209. package/phanpy/dist/assets/icons/celebrate-line-B8DvIoi0.js +0 -1
  210. package/phanpy/dist/assets/icons/chart-bar-line-FK-QOmtF.js +0 -1
  211. package/phanpy/dist/assets/icons/chart-line-line-BGcJAFWw.js +0 -1
  212. package/phanpy/dist/assets/icons/chat-3-line-YFK2-hwz.js +0 -1
  213. package/phanpy/dist/assets/icons/check-circle-line-DsAxFr5-.js +0 -1
  214. package/phanpy/dist/assets/icons/clipboard-line-BBp364gJ.js +0 -1
  215. package/phanpy/dist/assets/icons/close-circle-line-CICdiuGz.js +0 -1
  216. package/phanpy/dist/assets/icons/close-line-DYrFWcjv.js +0 -1
  217. package/phanpy/dist/assets/icons/cloud-line-tiQAbah8.js +0 -1
  218. package/phanpy/dist/assets/icons/code-line-fAl8iiV3.js +0 -1
  219. package/phanpy/dist/assets/icons/comment-2-line-CR3g7WeB.js +0 -1
  220. package/phanpy/dist/assets/icons/copy-2-line-CLW69yF5.js +0 -1
  221. package/phanpy/dist/assets/icons/delete-2-line-B8xmbr4n.js +0 -1
  222. package/phanpy/dist/assets/icons/document-3-line-DBGNhAg2.js +0 -1
  223. package/phanpy/dist/assets/icons/document-line-C7mb9sb7.js +0 -1
  224. package/phanpy/dist/assets/icons/down-line-BGqSSThd.js +0 -1
  225. package/phanpy/dist/assets/icons/edit-4-line-DcgGaEhx.js +0 -1
  226. package/phanpy/dist/assets/icons/emoji-2-line-D8YgnM-y.js +0 -1
  227. package/phanpy/dist/assets/icons/exit-line-Dc07BS-x.js +0 -1
  228. package/phanpy/dist/assets/icons/external-link-line-BvpSkmjO.js +0 -1
  229. package/phanpy/dist/assets/icons/eye-2-line-CiWXx-f_.js +0 -1
  230. package/phanpy/dist/assets/icons/eye-close-line-BgTaSJ4P.js +0 -1
  231. package/phanpy/dist/assets/icons/filter-2-line-B_mR2usy.js +0 -1
  232. package/phanpy/dist/assets/icons/filter-line-C_nm-3cU.js +0 -1
  233. package/phanpy/dist/assets/icons/flag-1-line-C2HB05I0.js +0 -1
  234. package/phanpy/dist/assets/icons/forbid-circle-line-D3LTT9yd.js +0 -1
  235. package/phanpy/dist/assets/icons/formula-line-DLrt2d6j.js +0 -1
  236. package/phanpy/dist/assets/icons/grid-line-CgUmEikf.js +0 -1
  237. package/phanpy/dist/assets/icons/group-line-C5fnX0wU.js +0 -1
  238. package/phanpy/dist/assets/icons/hand-finger-2-line-BGgxbuL9.js +0 -1
  239. package/phanpy/dist/assets/icons/hashtag-line-CyTEEXBb.js +0 -1
  240. package/phanpy/dist/assets/icons/heart-crack-line-BZddbO2C.js +0 -1
  241. package/phanpy/dist/assets/icons/heart-line-CJ7K47J4.js +0 -1
  242. package/phanpy/dist/assets/icons/history-2-line-kWWvFzqv.js +0 -1
  243. package/phanpy/dist/assets/icons/history-line-bGQiwbTH.js +0 -1
  244. package/phanpy/dist/assets/icons/home-3-line-fRU1zeLG.js +0 -1
  245. package/phanpy/dist/assets/icons/information-line-iNk6-sOY.js +0 -1
  246. package/phanpy/dist/assets/icons/keyboard-line-DsCyuQNz.js +0 -1
  247. package/phanpy/dist/assets/icons/layout-4-line-CZkOX52Z.js +0 -1
  248. package/phanpy/dist/assets/icons/layout-5-line-B_znt5wO.js +0 -1
  249. package/phanpy/dist/assets/icons/left-line-eUw0tya4.js +0 -1
  250. package/phanpy/dist/assets/icons/lightning-line-DaKoDdix.js +0 -1
  251. package/phanpy/dist/assets/icons/link-2-line-DCqLmMA7.js +0 -1
  252. package/phanpy/dist/assets/icons/list-check-line-BAxosBh9.js +0 -1
  253. package/phanpy/dist/assets/icons/lock-line-CPoaXeUW.js +0 -1
  254. package/phanpy/dist/assets/icons/mail-line-B0P8aa1L.js +0 -1
  255. package/phanpy/dist/assets/icons/moon-line-CEqNAToP.js +0 -1
  256. package/phanpy/dist/assets/icons/more-1-fill-Dw2e5xab.js +0 -1
  257. package/phanpy/dist/assets/icons/more-3-line-BIiVjYTz.js +0 -1
  258. package/phanpy/dist/assets/icons/notification-line-BZZq2Gtu.js +0 -1
  259. package/phanpy/dist/assets/icons/pencil-line-CKh8-A1v.js +0 -1
  260. package/phanpy/dist/assets/icons/photo-album-line-Bnfg2u40.js +0 -1
  261. package/phanpy/dist/assets/icons/pin-line-DpTolyhs.js +0 -1
  262. package/phanpy/dist/assets/icons/play-fill-B0-G_8lX.js +0 -1
  263. package/phanpy/dist/assets/icons/qrcode-2-line-B6SPCaHn.js +0 -1
  264. package/phanpy/dist/assets/icons/quill-pen-line-B6LUrnCP.js +0 -1
  265. package/phanpy/dist/assets/icons/quote-left-fill-hQZ1cj_6.js +0 -1
  266. package/phanpy/dist/assets/icons/radar-line-CKyroTth.js +0 -1
  267. package/phanpy/dist/assets/icons/react-line-CoIKhhtK.js +0 -1
  268. package/phanpy/dist/assets/icons/refresh-2-line-D0mTF97S.js +0 -1
  269. package/phanpy/dist/assets/icons/right-line-B3KWJaqc.js +0 -1
  270. package/phanpy/dist/assets/icons/rocket-line-4KZl537D.js +0 -1
  271. package/phanpy/dist/assets/icons/round-fill-C69NTrZ0.js +0 -1
  272. package/phanpy/dist/assets/icons/round-line-B9k_1uo-.js +0 -1
  273. package/phanpy/dist/assets/icons/route-line-B28ReHcE.js +0 -1
  274. package/phanpy/dist/assets/icons/rows-4-line-CrBniagM.js +0 -1
  275. package/phanpy/dist/assets/icons/scan-line-DSf74YdP.js +0 -1
  276. package/phanpy/dist/assets/icons/search-2-line-B6geIU1z.js +0 -1
  277. package/phanpy/dist/assets/icons/settings-3-line-azJwK47w.js +0 -1
  278. package/phanpy/dist/assets/icons/settings-6-line-C_5zc5YR.js +0 -1
  279. package/phanpy/dist/assets/icons/share-2-line-D5MxWjrm.js +0 -1
  280. package/phanpy/dist/assets/icons/share-forward-line-Cp61fZzZ.js +0 -1
  281. package/phanpy/dist/assets/icons/sparkles-2-line-DYYyXTaW.js +0 -1
  282. package/phanpy/dist/assets/icons/sparkles-line-C2hY1s6I.js +0 -1
  283. package/phanpy/dist/assets/icons/time-line-BF3eet1v.js +0 -1
  284. package/phanpy/dist/assets/icons/transfer-4-line-oisfvTBw.js +0 -1
  285. package/phanpy/dist/assets/icons/translate-line-BFWol2Ce.js +0 -1
  286. package/phanpy/dist/assets/icons/unlock-line-X_x5vwv3.js +0 -1
  287. package/phanpy/dist/assets/icons/upload-3-line-DgzwUJeW.js +0 -1
  288. package/phanpy/dist/assets/icons/user-4-line-BVSynZCp.js +0 -1
  289. package/phanpy/dist/assets/icons/user-add-2-line-BlGS5Q8q.js +0 -1
  290. package/phanpy/dist/assets/icons/user-add-line-BbXdHG4z.js +0 -1
  291. package/phanpy/dist/assets/icons/user-edit-line-BFAHOV0X.js +0 -1
  292. package/phanpy/dist/assets/icons/user-follow-line-BXux0wSd.js +0 -1
  293. package/phanpy/dist/assets/icons/user-star-line-DdYlpHLU.js +0 -1
  294. package/phanpy/dist/assets/icons/user-warning-line-Cj43j0_E.js +0 -1
  295. package/phanpy/dist/assets/icons/user-x-line-DIDgNlPH.js +0 -1
  296. package/phanpy/dist/assets/icons/volume-line-Bs390KQt.js +0 -1
  297. package/phanpy/dist/assets/icons/volume-mute-line-DzlzIqFZ.js +0 -1
  298. package/phanpy/dist/assets/icons/walk-line-yNXfB-md.js +0 -1
  299. package/phanpy/dist/assets/icons/world-2-line-CenkGIwj.js +0 -1
  300. package/phanpy/dist/assets/icons/zoom-in-line-CaENUphf.js +0 -1
  301. package/phanpy/dist/assets/icons/zoom-out-line-BDNk0EWo.js +0 -1
  302. package/phanpy/dist/assets/instances-BNPptnn-.json +0 -333
  303. package/phanpy/dist/assets/locales/ar-SA-CfheRbCu.js +0 -1
  304. package/phanpy/dist/assets/locales/ca-ES-DHRW86Tz.js +0 -1
  305. package/phanpy/dist/assets/locales/cs-CZ-CKoqEuA1.js +0 -1
  306. package/phanpy/dist/assets/locales/de-DE-ByRPMRFy.js +0 -1
  307. package/phanpy/dist/assets/locales/eo-UY-CPC7wLCS.js +0 -1
  308. package/phanpy/dist/assets/locales/es-ES-dJa0Fd9t.js +0 -1
  309. package/phanpy/dist/assets/locales/eu-ES-C3djlPR2.js +0 -1
  310. package/phanpy/dist/assets/locales/fa-IR-DTT490Ck.js +0 -1
  311. package/phanpy/dist/assets/locales/fi-FI-B23MCPuz.js +0 -1
  312. package/phanpy/dist/assets/locales/fr-FR-BcaQsO5C.js +0 -1
  313. package/phanpy/dist/assets/locales/gl-ES-BR-CVKBN.js +0 -1
  314. package/phanpy/dist/assets/locales/he-IL-CfheRbCu.js +0 -1
  315. package/phanpy/dist/assets/locales/hu-HU-CfheRbCu.js +0 -1
  316. package/phanpy/dist/assets/locales/it-IT-C1136UFV.js +0 -1
  317. package/phanpy/dist/assets/locales/ja-JP-CRZmRAhD.js +0 -1
  318. package/phanpy/dist/assets/locales/kab-Cz8xH_TT.js +0 -1
  319. package/phanpy/dist/assets/locales/ko-KR-CG9UiY4o.js +0 -1
  320. package/phanpy/dist/assets/locales/lt-LT-CJcI6sHZ.js +0 -1
  321. package/phanpy/dist/assets/locales/nb-NO-CfheRbCu.js +0 -1
  322. package/phanpy/dist/assets/locales/nl-NL-DxN4Yc1t.js +0 -1
  323. package/phanpy/dist/assets/locales/oc-FR-CfheRbCu.js +0 -1
  324. package/phanpy/dist/assets/locales/pl-PL-DkwGXf6P.js +0 -1
  325. package/phanpy/dist/assets/locales/pseudo-LOCALE-CQ4XxkQ0.js +0 -1
  326. package/phanpy/dist/assets/locales/pt-BR-nGL0HdFS.js +0 -1
  327. package/phanpy/dist/assets/locales/pt-PT-Cp17aj2z.js +0 -1
  328. package/phanpy/dist/assets/locales/ru-RU-0Y8cIoaK.js +0 -1
  329. package/phanpy/dist/assets/locales/th-TH-CfheRbCu.js +0 -1
  330. package/phanpy/dist/assets/locales/tok-CfheRbCu.js +0 -1
  331. package/phanpy/dist/assets/locales/tr-TR-CfheRbCu.js +0 -1
  332. package/phanpy/dist/assets/locales/uk-UA-C5E3dFBf.js +0 -1
  333. package/phanpy/dist/assets/locales/zh-CN-BHJi7_et.js +0 -1
  334. package/phanpy/dist/assets/locales/zh-TW-CfheRbCu.js +0 -1
  335. package/phanpy/dist/assets/main-BdqNbG-a.js +0 -26
  336. package/phanpy/dist/assets/main-BdqNbG-a.js.map +0 -1
  337. package/phanpy/dist/assets/mock-home-DGhR__He.js +0 -2
  338. package/phanpy/dist/assets/mock-home-DGhR__He.js.map +0 -1
  339. package/phanpy/dist/assets/multi-column-ROck0NVt.jpg +0 -0
  340. package/phanpy/dist/assets/multi-hashtag-timeline-DH5INVHi.jpg +0 -0
  341. package/phanpy/dist/assets/nested-comments-thread-hv59kZLc.jpg +0 -0
  342. package/phanpy/dist/assets/polyfill-force-H8sUkLGp.js +0 -2
  343. package/phanpy/dist/assets/polyfill-force-H8sUkLGp.js.map +0 -1
  344. package/phanpy/dist/assets/pwa-viewport-ogKbF51K.js +0 -20
  345. package/phanpy/dist/assets/pwa-viewport-ogKbF51K.js.map +0 -1
  346. package/phanpy/dist/assets/style-B1iLPTPR.css +0 -2
  347. package/phanpy/dist/assets/temml-DuyIQMei.js +0 -97
  348. package/phanpy/dist/assets/temml-DuyIQMei.js.map +0 -1
  349. package/phanpy/dist/assets/tinyld.light.node-DtbBhLYC.js +0 -2
  350. package/phanpy/dist/assets/tinyld.light.node-DtbBhLYC.js.map +0 -1
  351. package/phanpy/dist/assets/year-in-posts-B2lywqdx.png +0 -0
  352. package/phanpy/dist/assets/year-in-posts-DJv_star.js +0 -3
  353. package/phanpy/dist/assets/year-in-posts-DJv_star.js.map +0 -1
  354. package/phanpy/dist/compose/index.html +0 -20
  355. package/phanpy/dist/favicon.ico +0 -0
  356. package/phanpy/dist/index.html +0 -73
  357. package/phanpy/dist/logo-192.png +0 -0
  358. package/phanpy/dist/logo-512.png +0 -0
  359. package/phanpy/dist/logo-badge-72.png +0 -0
  360. package/phanpy/dist/logo-maskable-512.png +0 -0
  361. package/phanpy/dist/logo-monochrome-512.png +0 -0
  362. package/phanpy/dist/logo-monochrome-maskable-512.png +0 -0
  363. package/phanpy/dist/manifest.webmanifest +0 -1
  364. package/phanpy/dist/og-image-2.jpg +0 -0
  365. package/phanpy/dist/og-image.png +0 -0
  366. package/phanpy/dist/robots.txt +0 -2
  367. package/phanpy/dist/sw.js +0 -2
  368. package/phanpy/dist/sw.js.map +0 -1
  369. package/phanpy/dist/version.json +0 -1
  370. package/run-agent.mjs +0 -899
  371. package/vendor/gate.cjs +0 -138
  372. package/vendor/idp-grant.cjs +0 -394
  373. package/vendor/jfetch.cjs +0 -16
  374. package/web/admin/actors.js +0 -147
  375. package/web/admin/bar.css +0 -126
  376. package/web/admin/bar.js +0 -99
  377. package/web/admin/client/client.js +0 -66
  378. package/web/admin/client/index.html +0 -69
  379. package/web/admin/client-pick.js +0 -79
  380. package/web/admin/common.js +0 -23
  381. package/web/admin/connections.js +0 -112
  382. package/web/admin/gateway.js +0 -133
  383. package/web/admin/group.js +0 -258
  384. package/web/admin/index.html +0 -612
  385. package/web/admin/notices-bar.js +0 -90
  386. package/web/admin/oauth-signin.mjs +0 -37
  387. package/web/admin/record.js +0 -393
  388. package/web/admin/setup/index.html +0 -257
  389. package/web/admin/setup/setup.js +0 -339
  390. package/web/admin/tokens.css +0 -68
  391. package/web/admin/upkeep.js +0 -177
  392. package/web/admin/window.css +0 -55
  393. package/web/admin/window.js +0 -136
  394. package/web/app/README.md +0 -81
  395. package/web/app/admin-facade.mjs +0 -588
  396. package/web/app/agent.mjs +0 -672
  397. package/web/app/atproto-browser.mjs +0 -86
  398. package/web/app/authorize_interaction.html +0 -56
  399. package/web/app/authorize_interaction.js +0 -69
  400. package/web/app/boot.mjs +0 -616
  401. package/web/app/deliver-relay.mjs +0 -129
  402. package/web/app/dist/boot.js +0 -34562
  403. package/web/app/dist/boot.js.map +0 -7
  404. package/web/app/dist/sw.js +0 -73456
  405. package/web/app/dist/sw.js.map +0 -7
  406. package/web/app/fediacct-browser.mjs +0 -146
  407. package/web/app/gateway-move.mjs +0 -60
  408. package/web/app/idb-kv.mjs +0 -35
  409. package/web/app/index.html +0 -258
  410. package/web/app/keys-browser.mjs +0 -71
  411. package/web/app/keystore.mjs +0 -82
  412. package/web/app/oidc-session.mjs +0 -6
  413. package/web/app/pod-auth.mjs +0 -248
  414. package/web/app/pod-remote.mjs +0 -84
  415. package/web/app/shims/_globals.mjs +0 -2
  416. package/web/app/shims/fedify-sig.mjs +0 -77
  417. package/web/app/shims/node-crypto.mjs +0 -113
  418. package/web/app/shims/node-fs.mjs +0 -17
  419. package/web/app/shims/node-path.mjs +0 -19
  420. package/web/app/shims/node-url.mjs +0 -7
  421. package/web/app/shims/prelude.js +0 -58
  422. package/web/app/shims/safefetch.mjs +0 -58
  423. package/web/app/shims/shapes-text.mjs +0 -8
  424. package/web/app/shims/web-push.mjs +0 -14
  425. package/web/app/signup.mjs +0 -357
  426. package/web/app/sw-src.mjs +0 -220
  427. package/web/app/update.js +0 -70
  428. package/web/front/admin.html +0 -55
  429. package/web/front/admin.js +0 -89
  430. package/web/front/install.sh +0 -69
  431. package/web/front/new-account.html +0 -35
  432. package/web/front/new-account.js +0 -13
  433. package/web/front/notices.html +0 -69
  434. package/web/front/notices.js +0 -107
  435. package/web/front/run.html +0 -64
  436. package/web/front/run.js +0 -221
  437. package/web/front/solid-oidc-client.js +0 -6
  438. package/web/icons/forum.svg +0 -11
  439. package/web/icons/gateway.svg +0 -14
  440. package/web/icons/local.svg +0 -11
package/web/front/run.js DELETED
@@ -1,221 +0,0 @@
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 beside the page it belongs to.
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
- // This page's own address. The identity provider is told it and sends the
17
- // reader back to it, so a hard-coded name would end the sign-in on a page that
18
- // does not exist wherever the operator put this one.
19
- const HERE = location.origin + location.pathname.replace(/\/$/u, '');
20
- let session = null;
21
- try {
22
- const { SessionCore } = await import('/solid-oidc-client.js');
23
- session = new SessionCore({ redirect_uris: [HERE], client_name: 'FediPod gateway' });
24
- } catch { /* leave null — the "did not load" notes below fire */ }
25
-
26
- // What this server knows before anything is typed. 501: it runs no
27
- // identities. A pod server that issued the reader's session names their pod
28
- // and its address, and the page shows one button per pod. Not signed in
29
- // there: one button, to its login. A Gateway knows nothing: the form below.
30
- let offered = true;
31
- const say = (tag, text) => { const e = document.createElement(tag); e.textContent = text; return e; };
32
- (async () => {
33
- const res = await fetch('/api/agent', { credentials: 'same-origin', headers: { accept: 'application/json' } }).catch(() => null);
34
- const d = res && res.ok ? await res.json().catch(() => ({})) : {};
35
- const n = $('run-note');
36
- if (!res || res.status === 501) {
37
- offered = false;
38
- n.hidden = false;
39
- n.textContent = 'This server does not run identities. Your agent stays where it is.';
40
- } else if (d.session === 'none') {
41
- $('run-form').hidden = true;
42
- showSignIn(d.loginUrl);
43
- } else if (d.session === 'ok' && Array.isArray(d.pods) && d.pods.length) {
44
- $('run-form').hidden = true;
45
- showPods(d.pods);
46
- }
47
- runFormCheck();
48
- })();
49
-
50
- async function refreshKnown() {
51
- const res = await fetch('/api/agent', { credentials: 'same-origin', headers: { accept: 'application/json' } }).catch(() => null);
52
- const d = res && res.ok ? await res.json().catch(() => ({})) : {};
53
- if (d.session === 'ok' && Array.isArray(d.pods) && d.pods.length) showPods(d.pods);
54
- }
55
-
56
- function showSignIn(loginUrl) {
57
- const k = $('run-known');
58
- k.hidden = false;
59
- k.replaceChildren();
60
- k.append(say('p', 'You are not signed in at this server.'));
61
- if (loginUrl) {
62
- const go = say('button', 'Sign in');
63
- go.type = 'button'; go.className = 'primary';
64
- go.onclick = () => { location.href = loginUrl; };
65
- const p = document.createElement('p'); p.className = 'actions'; p.append(go);
66
- k.append(p, say('p', 'Sign in, then come back to this page.'));
67
- k.lastChild.className = 'hint';
68
- }
69
- }
70
-
71
- function showPods(pods) {
72
- const k = $('run-known');
73
- k.hidden = false;
74
- k.replaceChildren();
75
- for (const pod of pods) {
76
- const box = document.createElement('div'); box.className = 'pod';
77
- // The names stand out from the sentences around them.
78
- const line = (before, id, after = '.') => { const p = say('p', before); p.append(say('code', id), after); return p; };
79
- box.append(line('Solid Identity (WebID): ', pod.webId, ''));
80
- const actions = document.createElement('p'); actions.className = 'actions';
81
- box.append(line('Fediverse Identity: ', pod.address, ''));
82
- if (pod.running) {
83
- const links = say('p', 'Manage your account: ');
84
- const m = say('a', pod.manage.split('?')[0]); m.href = pod.manage;
85
- links.append(m);
86
- box.append(links);
87
- const stop = say('button', 'Close this Fediverse account'); stop.type = 'button'; stop.className = 'primary';
88
- stop.onclick = () => runStart('opt-out', pod.podBase);
89
- actions.append(stop);
90
- } else {
91
- // Where on the pod the account goes: a container named fedipod, inside
92
- // the one named here (empty: the pod's own root).
93
- const field = document.createElement('p'); field.className = 'field';
94
- const id = `container-${k.children.length}`;
95
- const label = say('label', 'Store your data in a container named fedipod, inside this container');
96
- label.htmlFor = id;
97
- const input = document.createElement('input');
98
- input.type = 'text'; input.id = id; input.autocomplete = 'off'; input.spellcheck = false;
99
- try { input.placeholder = new URL(pod.podBase).pathname; } catch { input.placeholder = '/'; }
100
- field.append(label, input);
101
- box.append(field);
102
- const go = say('button', 'Create a Fediverse account'); go.type = 'button'; go.className = 'primary';
103
- go.onclick = () => runStart('opt-in', pod.podBase, input.value.trim());
104
- actions.append(go);
105
- }
106
- box.append(actions);
107
- k.append(box);
108
- }
109
- }
110
-
111
- function runFormCheck() {
112
- let ok = false;
113
- try { ok = /^https?:$/.test(new URL($('run-pod-url').value.trim()).protocol); } catch { /* not yet */ }
114
- const issuerOk = /^https?:\/\/\S+/.test($('run-issuer').value.trim());
115
- $('run-continue').disabled = !(offered && ok && issuerOk);
116
- $('run-leave').disabled = !(offered && ok && issuerOk);
117
- }
118
- $('run-pod-url').addEventListener('input', () => {
119
- runFormCheck();
120
- // The identity provider is usually the server itself — still editable.
121
- try {
122
- const u = new URL($('run-pod-url').value.trim());
123
- const apex = u.hostname.split('.').slice(1).join('.');
124
- if (!$('run-issuer').value && apex) $('run-issuer').value = `${u.protocol}//${apex}${u.port ? ':' + u.port : ''}`;
125
- } catch { /* not a URL yet */ }
126
- runFormCheck();
127
- });
128
- $('run-issuer').addEventListener('input', runFormCheck);
129
- // A browser that puts back what was in these boxes — a reload, the back
130
- // button, its own remembered values — fills them without anybody typing, and
131
- // no typing meant the button was never asked to wake up. It stayed grey over
132
- // a filled-in form, with nothing to say why.
133
- runFormCheck();
134
-
135
- const runStart = async (action, podBase = null, container = null, createIndex = false) => {
136
- const n = $('run-note');
137
- const u = new URL(podBase || $('run-pod-url').value.trim());
138
- if (u.pathname === '') u.pathname = '/';
139
- if (!u.pathname.endsWith('/')) u.pathname += '/';
140
- u.search = ''; u.hash = '';
141
- const p = { podBase: u.href, action,
142
- container: container ?? ($('run-container') ? $('run-container').value.trim() : ''),
143
- ...(createIndex ? { createIndex: true } : {}) };
144
-
145
- // A pod server issued the session this page is being read with, so ask it
146
- // first: where it knows who you are, there is nothing to sign in to again.
147
- // A Gateway fronting somebody else's pod answers 401 here and the login
148
- // below is the only way.
149
- n.hidden = false;
150
- n.textContent = 'asking the server…';
151
- const known = await fetch('/api/agent', {
152
- method: 'POST', credentials: 'same-origin',
153
- headers: { 'content-type': 'application/json' },
154
- body: JSON.stringify(p),
155
- }).catch(() => null);
156
- if (known && known.status !== 401) { await showReply(known, p); return; }
157
-
158
- if (!session) { n.textContent = 'the sign-in library did not load — reload and try again'; return; }
159
- sessionStorage.setItem('fp-run', JSON.stringify(p));
160
- session.login($('run-issuer').value.trim(), HERE)
161
- .catch((e) => { n.textContent = 'sign-in failed to start: ' + e.message; });
162
- };
163
- $('run-continue').onclick = () => runStart('opt-in');
164
- $('run-leave').onclick = () => runStart('opt-out');
165
-
166
- // What came of it, however the server was satisfied — the session it already
167
- // had, or a login proved afterwards.
168
- async function showReply(res, p) {
169
- const n = $('run-note');
170
- n.hidden = false;
171
- const d = res ? await res.json().catch(() => ({})) : {};
172
- // No public type index: nothing has been written. Ask.
173
- if (res && res.status === 409 && d.code === 'needs-index') {
174
- n.replaceChildren(say('p', `${d.error} Create it? It will be readable by anyone, like your profile.`));
175
- const yes = say('button', 'Create it and continue'); yes.type = 'button'; yes.className = 'primary';
176
- const no = say('button', 'No, stop'); no.type = 'button';
177
- yes.onclick = () => runStart(p.action, p.podBase, p.container || '', true);
178
- no.onclick = () => { n.textContent = 'Stopped. Nothing was written to your pod.'; };
179
- const row = document.createElement('p'); row.className = 'actions'; row.append(no, yes);
180
- n.append(row);
181
- yes.focus();
182
- return;
183
- }
184
- if (res && res.status === 201 && d.doorSecret) {
185
- // Built as nodes, not as a string of HTML. Three of the pieces below come
186
- // back from the server and one comes from sessionStorage, and pasting any
187
- // of them into innerHTML means whatever markup they contain is rendered.
188
- // Only the fixed wording is markup here; everything variable is text.
189
- const manage = `${p.podBase.replace(/\/$/, '')}${d.doorPath}?dk-token=${encodeURIComponent(d.doorSecret)}`;
190
- n.textContent = 'Your Fediverse account is ready. Manage it at ';
191
- const a = say('a', p.podBase.replace(/\/$/, '') + d.doorPath); a.href = manage;
192
- n.append(a, '.');
193
- refreshKnown();
194
- } else if (res && res.status === 200) {
195
- n.textContent = 'Your Fediverse account is closed. Your pod and its data are untouched.';
196
- refreshKnown();
197
- } else {
198
- n.textContent = (p.action === 'opt-in' ? 'opt-in' : 'opt-out') + ' failed: '
199
- + (d.error || (res ? 'HTTP ' + res.status : 'no response'));
200
- }
201
- }
202
-
203
- // Back from the identity provider: finish with the proven login.
204
- (async () => {
205
- if (!session) return;
206
- await session.handleRedirectFromLogin().catch(() => {});
207
- const pending = sessionStorage.getItem('fp-run');
208
- if (!session.isActive || !pending) return;
209
- sessionStorage.removeItem('fp-run');
210
- const p = JSON.parse(pending);
211
- const n = $('run-note');
212
- n.hidden = false;
213
- n.textContent = 'signed in as ' + session.webId + ' — asking the server…';
214
- // The signed fetch builds a DPoP proof from the URL, so it must be absolute.
215
- const res = await session.authFetch(location.origin + '/api/agent', {
216
- method: 'POST', headers: { 'content-type': 'application/json' },
217
- body: JSON.stringify({ action: p.action, podBase: p.podBase, container: p.container || '',
218
- ...(p.createIndex ? { createIndex: true } : {}) }),
219
- }).catch(() => null);
220
- await showReply(res, p);
221
- })();
@@ -1,6 +0,0 @@
1
- // @uvdsl/solid-oidc-client-browser@0.2.3 — vendored worker-free Solid-OIDC client (core build).
2
- // tarball sha512-WzVlxv46EUSoqm7ovsWJRZq8KEI/CdpA9O1fXoiP8bihs2cNxPnet3YcqvIYWYMsTrf0zsR031l5s/BzQ9MEgA==
3
- // license MIT — https://github.com/uvdsl/solid-oidc-client-browser
4
- // Regenerate with: node scripts/pin-solid-oidc.mjs
5
- var e=crypto;const t=e=>e instanceof CryptoKey;var r=async(t,r)=>{const a=`SHA-${t.slice(-3)}`;return new Uint8Array(await e.subtle.digest(a,r))};const a=new TextEncoder,n=new TextDecoder;function s(...e){const t=e.reduce(((e,{length:t})=>e+t),0),r=new Uint8Array(t);let a=0;for(const t of e)r.set(t,a),a+=t.length;return r}const i=e=>(e=>{let t=e;"string"==typeof t&&(t=a.encode(t));const r=[];for(let e=0;e<t.length;e+=32768)r.push(String.fromCharCode.apply(null,t.subarray(e,e+32768)));return btoa(r.join(""))})(e).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_"),o=e=>{let t=e;t instanceof Uint8Array&&(t=n.decode(t)),t=t.replace(/-/g,"+").replace(/_/g,"/").replace(/\s/g,"");try{return(e=>{const t=atob(e),r=new Uint8Array(t.length);for(let e=0;e<t.length;e++)r[e]=t.charCodeAt(e);return r})(t)}catch{throw new TypeError("The input to be decoded is not correctly encoded.")}};class c extends Error{constructor(e,t){super(e,t),this.code="ERR_JOSE_GENERIC",this.name=this.constructor.name,Error.captureStackTrace?.(this,this.constructor)}}c.code="ERR_JOSE_GENERIC";class d extends c{constructor(e,t,r="unspecified",a="unspecified"){super(e,{cause:{claim:r,reason:a,payload:t}}),this.code="ERR_JWT_CLAIM_VALIDATION_FAILED",this.claim=r,this.reason=a,this.payload=t}}d.code="ERR_JWT_CLAIM_VALIDATION_FAILED";class h extends c{constructor(e,t,r="unspecified",a="unspecified"){super(e,{cause:{claim:r,reason:a,payload:t}}),this.code="ERR_JWT_EXPIRED",this.claim=r,this.reason=a,this.payload=t}}h.code="ERR_JWT_EXPIRED";class l extends c{constructor(){super(...arguments),this.code="ERR_JOSE_ALG_NOT_ALLOWED"}}l.code="ERR_JOSE_ALG_NOT_ALLOWED";class p extends c{constructor(){super(...arguments),this.code="ERR_JOSE_NOT_SUPPORTED"}}p.code="ERR_JOSE_NOT_SUPPORTED";(class extends c{constructor(e="decryption operation failed",t){super(e,t),this.code="ERR_JWE_DECRYPTION_FAILED"}}).code="ERR_JWE_DECRYPTION_FAILED";(class extends c{constructor(){super(...arguments),this.code="ERR_JWE_INVALID"}}).code="ERR_JWE_INVALID";class u extends c{constructor(){super(...arguments),this.code="ERR_JWS_INVALID"}}u.code="ERR_JWS_INVALID";class f extends c{constructor(){super(...arguments),this.code="ERR_JWT_INVALID"}}f.code="ERR_JWT_INVALID";class w extends c{constructor(){super(...arguments),this.code="ERR_JWK_INVALID"}}w.code="ERR_JWK_INVALID";class y extends c{constructor(){super(...arguments),this.code="ERR_JWKS_INVALID"}}y.code="ERR_JWKS_INVALID";class m extends c{constructor(e="no applicable key found in the JSON Web Key Set",t){super(e,t),this.code="ERR_JWKS_NO_MATCHING_KEY"}}m.code="ERR_JWKS_NO_MATCHING_KEY";class g extends c{constructor(e="multiple matching keys found in the JSON Web Key Set",t){super(e,t),this.code="ERR_JWKS_MULTIPLE_MATCHING_KEYS"}}g.code="ERR_JWKS_MULTIPLE_MATCHING_KEYS";class _ extends c{constructor(e="request timed out",t){super(e,t),this.code="ERR_JWKS_TIMEOUT"}}_.code="ERR_JWKS_TIMEOUT";class S extends c{constructor(e="signature verification failed",t){super(e,t),this.code="ERR_JWS_SIGNATURE_VERIFICATION_FAILED"}}function E(e,t="algorithm.name"){return new TypeError(`CryptoKey does not support this operation, its ${t} must be ${e}`)}function b(e,t){return e.name===t}function k(e){return parseInt(e.name.slice(4),10)}function v(e,t,...r){switch(t){case"HS256":case"HS384":case"HS512":{if(!b(e.algorithm,"HMAC"))throw E("HMAC");const r=parseInt(t.slice(2),10);if(k(e.algorithm.hash)!==r)throw E(`SHA-${r}`,"algorithm.hash");break}case"RS256":case"RS384":case"RS512":{if(!b(e.algorithm,"RSASSA-PKCS1-v1_5"))throw E("RSASSA-PKCS1-v1_5");const r=parseInt(t.slice(2),10);if(k(e.algorithm.hash)!==r)throw E(`SHA-${r}`,"algorithm.hash");break}case"PS256":case"PS384":case"PS512":{if(!b(e.algorithm,"RSA-PSS"))throw E("RSA-PSS");const r=parseInt(t.slice(2),10);if(k(e.algorithm.hash)!==r)throw E(`SHA-${r}`,"algorithm.hash");break}case"EdDSA":if("Ed25519"!==e.algorithm.name&&"Ed448"!==e.algorithm.name)throw E("Ed25519 or Ed448");break;case"Ed25519":if(!b(e.algorithm,"Ed25519"))throw E("Ed25519");break;case"ES256":case"ES384":case"ES512":{if(!b(e.algorithm,"ECDSA"))throw E("ECDSA");const r=function(e){switch(e){case"ES256":return"P-256";case"ES384":return"P-384";case"ES512":return"P-521";default:throw new Error("unreachable")}}(t);if(e.algorithm.namedCurve!==r)throw E(r,"algorithm.namedCurve");break}default:throw new TypeError("CryptoKey does not support this operation")}!function(e,t){if(t.length&&!t.some((t=>e.usages.includes(t)))){let e="CryptoKey does not support this operation, its usages must include ";if(t.length>2){const r=t.pop();e+=`one of ${t.join(", ")}, or ${r}.`}else 2===t.length?e+=`one of ${t[0]} or ${t[1]}.`:e+=`${t[0]}.`;throw new TypeError(e)}}(e,r)}function A(e,t,...r){if((r=r.filter(Boolean)).length>2){const t=r.pop();e+=`one of type ${r.join(", ")}, or ${t}.`}else 2===r.length?e+=`one of type ${r[0]} or ${r[1]}.`:e+=`of type ${r[0]}.`;return null==t?e+=` Received ${t}`:"function"==typeof t&&t.name?e+=` Received function ${t.name}`:"object"==typeof t&&null!=t&&t.constructor?.name&&(e+=` Received an instance of ${t.constructor.name}`),e}S.code="ERR_JWS_SIGNATURE_VERIFICATION_FAILED";var T=(e,...t)=>A("Key must be ",e,...t);function P(e,t,...r){return A(`Key for the ${e} algorithm must be `,t,...r)}var R=e=>!!t(e)||"KeyObject"===e?.[Symbol.toStringTag];const I=["CryptoKey"];var C=(...e)=>{const t=e.filter(Boolean);if(0===t.length||1===t.length)return!0;let r;for(const e of t){const t=Object.keys(e);if(r&&0!==r.size)for(const e of t){if(r.has(e))return!1;r.add(e)}else r=new Set(t)}return!0};function D(e){if("object"!=typeof(t=e)||null===t||"[object Object]"!==Object.prototype.toString.call(e))return!1;var t;if(null===Object.getPrototypeOf(e))return!0;let r=e;for(;null!==Object.getPrototypeOf(r);)r=Object.getPrototypeOf(r);return Object.getPrototypeOf(e)===r}var W=(e,t)=>{if(e.startsWith("RS")||e.startsWith("PS")){const{modulusLength:r}=t.algorithm;if("number"!=typeof r||r<2048)throw new TypeError(`${e} requires key modulusLength to be 2048 bits or larger`)}};function H(e){return D(e)&&"string"==typeof e.kty}var J=async t=>{if(!t.alg)throw new TypeError('"alg" argument is required when "jwk.alg" is not present');const{algorithm:r,keyUsages:a}=function(e){let t,r;switch(e.kty){case"RSA":switch(e.alg){case"PS256":case"PS384":case"PS512":t={name:"RSA-PSS",hash:`SHA-${e.alg.slice(-3)}`},r=e.d?["sign"]:["verify"];break;case"RS256":case"RS384":case"RS512":t={name:"RSASSA-PKCS1-v1_5",hash:`SHA-${e.alg.slice(-3)}`},r=e.d?["sign"]:["verify"];break;case"RSA-OAEP":case"RSA-OAEP-256":case"RSA-OAEP-384":case"RSA-OAEP-512":t={name:"RSA-OAEP",hash:`SHA-${parseInt(e.alg.slice(-3),10)||1}`},r=e.d?["decrypt","unwrapKey"]:["encrypt","wrapKey"];break;default:throw new p('Invalid or unsupported JWK "alg" (Algorithm) Parameter value')}break;case"EC":switch(e.alg){case"ES256":t={name:"ECDSA",namedCurve:"P-256"},r=e.d?["sign"]:["verify"];break;case"ES384":t={name:"ECDSA",namedCurve:"P-384"},r=e.d?["sign"]:["verify"];break;case"ES512":t={name:"ECDSA",namedCurve:"P-521"},r=e.d?["sign"]:["verify"];break;case"ECDH-ES":case"ECDH-ES+A128KW":case"ECDH-ES+A192KW":case"ECDH-ES+A256KW":t={name:"ECDH",namedCurve:e.crv},r=e.d?["deriveBits"]:[];break;default:throw new p('Invalid or unsupported JWK "alg" (Algorithm) Parameter value')}break;case"OKP":switch(e.alg){case"Ed25519":t={name:"Ed25519"},r=e.d?["sign"]:["verify"];break;case"EdDSA":t={name:e.crv},r=e.d?["sign"]:["verify"];break;case"ECDH-ES":case"ECDH-ES+A128KW":case"ECDH-ES+A192KW":case"ECDH-ES+A256KW":t={name:e.crv},r=e.d?["deriveBits"]:[];break;default:throw new p('Invalid or unsupported JWK "alg" (Algorithm) Parameter value')}break;default:throw new p('Invalid or unsupported JWK "kty" (Key Type) Parameter value')}return{algorithm:t,keyUsages:r}}(t),n=[r,t.ext??!1,t.key_ops??a],s={...t};return delete s.alg,delete s.use,e.subtle.importKey("jwk",s,...n)};const x=e=>o(e);let K,O;const j=e=>"KeyObject"===e?.[Symbol.toStringTag],N=async(e,t,r,a,n=!1)=>{let s=e.get(t);if(s?.[a])return s[a];const i=await J({...r,alg:a});return n&&Object.freeze(t),s?s[a]=i:e.set(t,{[a]:i}),i};var U=(e,t)=>{if(j(e)){let r=e.export({format:"jwk"});return delete r.d,delete r.dp,delete r.dq,delete r.p,delete r.q,delete r.qi,r.k?x(r.k):(O||(O=new WeakMap),N(O,e,r,t))}if(H(e)){if(e.k)return o(e.k);O||(O=new WeakMap);return N(O,e,e,t,!0)}return e},$=(e,t)=>{if(j(e)){let r=e.export({format:"jwk"});return r.k?x(r.k):(K||(K=new WeakMap),N(K,e,r,t))}if(H(e)){if(e.k)return o(e.k);K||(K=new WeakMap);return N(K,e,e,t,!0)}return e};async function L(e,t){if(!D(e))throw new TypeError("JWK must be an object");switch(t||(t=e.alg),e.kty){case"oct":if("string"!=typeof e.k||!e.k)throw new TypeError('missing "k" (Key Value) Parameter value');return o(e.k);case"RSA":if("oth"in e&&void 0!==e.oth)throw new p('RSA JWK "oth" (Other Primes Info) Parameter value is not supported');case"EC":case"OKP":return J({...e,alg:t});default:throw new p('Unsupported "kty" (Key Type) Parameter value')}}const M=e=>e?.[Symbol.toStringTag],F=(e,t,r)=>{if(void 0!==t.use&&"sig"!==t.use)throw new TypeError("Invalid key for this operation, when present its use must be sig");if(void 0!==t.key_ops&&!0!==t.key_ops.includes?.(r))throw new TypeError(`Invalid key for this operation, when present its key_ops must include ${r}`);if(void 0!==t.alg&&t.alg!==e)throw new TypeError(`Invalid key for this operation, when present its alg must be ${e}`);return!0},G=(e,t,r,a)=>{if(!(t instanceof Uint8Array)){if(a&&H(t)){if(function(e){return H(e)&&"oct"===e.kty&&"string"==typeof e.k}(t)&&F(e,t,r))return;throw new TypeError('JSON Web Key for symmetric algorithms must have JWK "kty" (Key Type) equal to "oct" and the JWK "k" (Key Value) present')}if(!R(t))throw new TypeError(P(e,t,...I,"Uint8Array",a?"JSON Web Key":null));if("secret"!==t.type)throw new TypeError(`${M(t)} instances for symmetric algorithms must be of type "secret"`)}};function V(e,t,r,a){t.startsWith("HS")||"dir"===t||t.startsWith("PBES2")||/^A\d{3}(?:GCM)?KW$/.test(t)?G(t,r,a,e):((e,t,r,a)=>{if(a&&H(t))switch(r){case"sign":if(function(e){return"oct"!==e.kty&&"string"==typeof e.d}(t)&&F(e,t,r))return;throw new TypeError("JSON Web Key for this operation be a private JWK");case"verify":if(function(e){return"oct"!==e.kty&&void 0===e.d}(t)&&F(e,t,r))return;throw new TypeError("JSON Web Key for this operation be a public JWK")}if(!R(t))throw new TypeError(P(e,t,...I,a?"JSON Web Key":null));if("secret"===t.type)throw new TypeError(`${M(t)} instances for asymmetric algorithms must not be of type "secret"`);if("sign"===r&&"public"===t.type)throw new TypeError(`${M(t)} instances for asymmetric algorithm signing must be of type "private"`);if("decrypt"===r&&"public"===t.type)throw new TypeError(`${M(t)} instances for asymmetric algorithm decryption must be of type "private"`);if(t.algorithm&&"verify"===r&&"private"===t.type)throw new TypeError(`${M(t)} instances for asymmetric algorithm verifying must be of type "public"`);if(t.algorithm&&"encrypt"===r&&"private"===t.type)throw new TypeError(`${M(t)} instances for asymmetric algorithm encryption must be of type "public"`)})(t,r,a,e)}V.bind(void 0,!1);const q=V.bind(void 0,!0);function X(e,t,r,a,n){if(void 0!==n.crit&&void 0===a?.crit)throw new e('"crit" (Critical) Header Parameter MUST be integrity protected');if(!a||void 0===a.crit)return new Set;if(!Array.isArray(a.crit)||0===a.crit.length||a.crit.some((e=>"string"!=typeof e||0===e.length)))throw new e('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');let s;s=void 0!==r?new Map([...Object.entries(r),...t.entries()]):t;for(const t of a.crit){if(!s.has(t))throw new p(`Extension Header Parameter "${t}" is not recognized`);if(void 0===n[t])throw new e(`Extension Header Parameter "${t}" is missing`);if(s.get(t)&&void 0===a[t])throw new e(`Extension Header Parameter "${t}" MUST be integrity protected`)}return new Set(a.crit)}var z=(e,t)=>{if(void 0!==t&&(!Array.isArray(t)||t.some((e=>"string"!=typeof e))))throw new TypeError(`"${e}" option must be an array of strings`);if(t)return new Set(t)};var B=async r=>{if(r instanceof Uint8Array)return{kty:"oct",k:i(r)};if(!t(r))throw new TypeError(T(r,...I,"Uint8Array"));if(!r.extractable)throw new TypeError("non-extractable CryptoKey cannot be exported as a JWK");const{ext:a,key_ops:n,alg:s,use:o,...c}=await e.subtle.exportKey("jwk",r);return c};async function Y(e){return B(e)}function Q(e,t){const r=`SHA-${e.slice(-3)}`;switch(e){case"HS256":case"HS384":case"HS512":return{hash:r,name:"HMAC"};case"PS256":case"PS384":case"PS512":return{hash:r,name:"RSA-PSS",saltLength:e.slice(-3)>>3};case"RS256":case"RS384":case"RS512":return{hash:r,name:"RSASSA-PKCS1-v1_5"};case"ES256":case"ES384":case"ES512":return{hash:r,name:"ECDSA",namedCurve:t.namedCurve};case"Ed25519":return{name:"Ed25519"};case"EdDSA":return{name:t.name};default:throw new p(`alg ${e} is not supported either by JOSE or your javascript runtime`)}}async function Z(r,a,n){if("sign"===n&&(a=await $(a,r)),"verify"===n&&(a=await U(a,r)),t(a))return v(a,r,n),a;if(a instanceof Uint8Array){if(!r.startsWith("HS"))throw new TypeError(T(a,...I));return e.subtle.importKey("raw",a,{hash:`SHA-${r.slice(-3)}`,name:"HMAC"},!1,[n])}throw new TypeError(T(a,...I,"Uint8Array","JSON Web Key"))}var ee=async(t,r,a,n)=>{const s=await Z(t,r,"verify");W(t,s);const i=Q(t,s.algorithm);try{return await e.subtle.verify(i,s,a,n)}catch{return!1}};async function te(e,t,r){if(e instanceof Uint8Array&&(e=n.decode(e)),"string"!=typeof e)throw new u("Compact JWS must be a string or Uint8Array");const{0:i,1:c,2:d,length:h}=e.split(".");if(3!==h)throw new u("Invalid Compact JWS");const p=await async function(e,t,r){if(!D(e))throw new u("Flattened JWS must be an object");if(void 0===e.protected&&void 0===e.header)throw new u('Flattened JWS must have either of the "protected" or "header" members');if(void 0!==e.protected&&"string"!=typeof e.protected)throw new u("JWS Protected Header incorrect type");if(void 0===e.payload)throw new u("JWS Payload missing");if("string"!=typeof e.signature)throw new u("JWS Signature missing or incorrect type");if(void 0!==e.header&&!D(e.header))throw new u("JWS Unprotected Header incorrect type");let i={};if(e.protected)try{const t=o(e.protected);i=JSON.parse(n.decode(t))}catch{throw new u("JWS Protected Header is invalid")}if(!C(i,e.header))throw new u("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");const c={...i,...e.header};let d=!0;if(X(u,new Map([["b64",!0]]),r?.crit,i,c).has("b64")&&(d=i.b64,"boolean"!=typeof d))throw new u('The "b64" (base64url-encode payload) Header Parameter must be a boolean');const{alg:h}=c;if("string"!=typeof h||!h)throw new u('JWS "alg" (Algorithm) Header Parameter missing or invalid');const p=r&&z("algorithms",r.algorithms);if(p&&!p.has(h))throw new l('"alg" (Algorithm) Header Parameter value not allowed');if(d){if("string"!=typeof e.payload)throw new u("JWS Payload must be a string")}else if("string"!=typeof e.payload&&!(e.payload instanceof Uint8Array))throw new u("JWS Payload must be a string or an Uint8Array instance");let f=!1;"function"==typeof t?(t=await t(i,e),f=!0,q(h,t,"verify"),H(t)&&(t=await L(t,h))):q(h,t,"verify");const w=s(a.encode(e.protected??""),a.encode("."),"string"==typeof e.payload?a.encode(e.payload):e.payload);let y,m;try{y=o(e.signature)}catch{throw new u("Failed to base64url decode the signature")}if(!await ee(h,t,y,w))throw new S;if(d)try{m=o(e.payload)}catch{throw new u("Failed to base64url decode the payload")}else m="string"==typeof e.payload?a.encode(e.payload):e.payload;const g={payload:m};return void 0!==e.protected&&(g.protectedHeader=i),void 0!==e.header&&(g.unprotectedHeader=e.header),f?{...g,key:t}:g}({payload:c,protected:i,signature:d},t,r),f={payload:p.payload,protectedHeader:p.protectedHeader};return"function"==typeof t?{...f,key:p.key}:f}var re=e=>Math.floor(e.getTime()/1e3);const ae=86400,ne=/^(\+|\-)? ?(\d+|\d+\.\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)(?: (ago|from now))?$/i;var se=e=>{const t=ne.exec(e);if(!t||t[4]&&t[1])throw new TypeError("Invalid time period format");const r=parseFloat(t[2]);let a;switch(t[3].toLowerCase()){case"sec":case"secs":case"second":case"seconds":case"s":a=Math.round(r);break;case"minute":case"minutes":case"min":case"mins":case"m":a=Math.round(60*r);break;case"hour":case"hours":case"hr":case"hrs":case"h":a=Math.round(3600*r);break;case"day":case"days":case"d":a=Math.round(r*ae);break;case"week":case"weeks":case"w":a=Math.round(604800*r);break;default:a=Math.round(31557600*r)}return"-"===t[1]||"ago"===t[4]?-a:a};const ie=e=>e.toLowerCase().replace(/^application\//,"");var oe=(e,t,r={})=>{let a;try{a=JSON.parse(n.decode(t))}catch{}if(!D(a))throw new f("JWT Claims Set must be a top-level JSON object");const{typ:s}=r;if(s&&("string"!=typeof e.typ||ie(e.typ)!==ie(s)))throw new d('unexpected "typ" JWT header value',a,"typ","check_failed");const{requiredClaims:i=[],issuer:o,subject:c,audience:l,maxTokenAge:p}=r,u=[...i];void 0!==p&&u.push("iat"),void 0!==l&&u.push("aud"),void 0!==c&&u.push("sub"),void 0!==o&&u.push("iss");for(const e of new Set(u.reverse()))if(!(e in a))throw new d(`missing required "${e}" claim`,a,e,"missing");if(o&&!(Array.isArray(o)?o:[o]).includes(a.iss))throw new d('unexpected "iss" claim value',a,"iss","check_failed");if(c&&a.sub!==c)throw new d('unexpected "sub" claim value',a,"sub","check_failed");if(l&&(w=a.aud,y="string"==typeof l?[l]:l,!("string"==typeof w?y.includes(w):Array.isArray(w)&&y.some(Set.prototype.has.bind(new Set(w))))))throw new d('unexpected "aud" claim value',a,"aud","check_failed");var w,y;let m;switch(typeof r.clockTolerance){case"string":m=se(r.clockTolerance);break;case"number":m=r.clockTolerance;break;case"undefined":m=0;break;default:throw new TypeError("Invalid clockTolerance option type")}const{currentDate:g}=r,_=re(g||new Date);if((void 0!==a.iat||p)&&"number"!=typeof a.iat)throw new d('"iat" claim must be a number',a,"iat","invalid");if(void 0!==a.nbf){if("number"!=typeof a.nbf)throw new d('"nbf" claim must be a number',a,"nbf","invalid");if(a.nbf>_+m)throw new d('"nbf" claim timestamp check failed',a,"nbf","check_failed")}if(void 0!==a.exp){if("number"!=typeof a.exp)throw new d('"exp" claim must be a number',a,"exp","invalid");if(a.exp<=_-m)throw new h('"exp" claim timestamp check failed',a,"exp","check_failed")}if(p){const e=_-a.iat;if(e-m>("number"==typeof p?p:se(p)))throw new h('"iat" claim timestamp check failed (too far in the past)',a,"iat","check_failed");if(e<0-m)throw new d('"iat" claim timestamp check failed (it should be in the past)',a,"iat","check_failed")}return a};async function ce(e,t,r){const a=await te(e,t,r);if(a.protectedHeader.crit?.includes("b64")&&!1===a.protectedHeader.b64)throw new f("JWTs MUST NOT use unencoded payload");const n={payload:oe(a.protectedHeader,a.payload,r),protectedHeader:a.protectedHeader};return"function"==typeof t?{...n,key:a.key}:n}var de=async(t,r,a)=>{const n=await Z(t,r,"sign");W(t,n);const s=await e.subtle.sign(Q(t,n.algorithm),n,a);return new Uint8Array(s)};class he{constructor(e){if(!(e instanceof Uint8Array))throw new TypeError("payload must be an instance of Uint8Array");this._payload=e}setProtectedHeader(e){if(this._protectedHeader)throw new TypeError("setProtectedHeader can only be called once");return this._protectedHeader=e,this}setUnprotectedHeader(e){if(this._unprotectedHeader)throw new TypeError("setUnprotectedHeader can only be called once");return this._unprotectedHeader=e,this}async sign(e,t){if(!this._protectedHeader&&!this._unprotectedHeader)throw new u("either setProtectedHeader or setUnprotectedHeader must be called before #sign()");if(!C(this._protectedHeader,this._unprotectedHeader))throw new u("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");const r={...this._protectedHeader,...this._unprotectedHeader};let o=!0;if(X(u,new Map([["b64",!0]]),t?.crit,this._protectedHeader,r).has("b64")&&(o=this._protectedHeader.b64,"boolean"!=typeof o))throw new u('The "b64" (base64url-encode payload) Header Parameter must be a boolean');const{alg:c}=r;if("string"!=typeof c||!c)throw new u('JWS "alg" (Algorithm) Header Parameter missing or invalid');q(c,e,"sign");let d,h=this._payload;o&&(h=a.encode(i(h))),d=this._protectedHeader?a.encode(i(JSON.stringify(this._protectedHeader))):a.encode("");const l=s(d,a.encode("."),h),p=await de(c,e,l),f={signature:i(p),payload:""};return o&&(f.payload=n.decode(h)),this._unprotectedHeader&&(f.header=this._unprotectedHeader),this._protectedHeader&&(f.protected=n.decode(d)),f}}class le{constructor(e){this._flattened=new he(e)}setProtectedHeader(e){return this._flattened.setProtectedHeader(e),this}async sign(e,t){const r=await this._flattened.sign(e,t);if(void 0===r.payload)throw new TypeError("use the flattened module for creating JWS with b64: false");return`${r.protected}.${r.payload}.${r.signature}`}}function pe(e,t){if(!Number.isFinite(t))throw new TypeError(`Invalid ${e} input`);return t}class ue{constructor(e={}){if(!D(e))throw new TypeError("JWT Claims Set MUST be an object");this._payload=e}setIssuer(e){return this._payload={...this._payload,iss:e},this}setSubject(e){return this._payload={...this._payload,sub:e},this}setAudience(e){return this._payload={...this._payload,aud:e},this}setJti(e){return this._payload={...this._payload,jti:e},this}setNotBefore(e){return"number"==typeof e?this._payload={...this._payload,nbf:pe("setNotBefore",e)}:e instanceof Date?this._payload={...this._payload,nbf:pe("setNotBefore",re(e))}:this._payload={...this._payload,nbf:re(new Date)+se(e)},this}setExpirationTime(e){return"number"==typeof e?this._payload={...this._payload,exp:pe("setExpirationTime",e)}:e instanceof Date?this._payload={...this._payload,exp:pe("setExpirationTime",re(e))}:this._payload={...this._payload,exp:re(new Date)+se(e)},this}setIssuedAt(e){return void 0===e?this._payload={...this._payload,iat:re(new Date)}:e instanceof Date?this._payload={...this._payload,iat:pe("setIssuedAt",re(e))}:this._payload="string"==typeof e?{...this._payload,iat:pe("setIssuedAt",re(new Date)+se(e))}:{...this._payload,iat:pe("setIssuedAt",e)},this}}class fe extends ue{setProtectedHeader(e){return this._protectedHeader=e,this}async sign(e,t){const r=new le(a.encode(JSON.stringify(this._payload)));if(r.setProtectedHeader(this._protectedHeader),Array.isArray(this._protectedHeader?.crit)&&this._protectedHeader.crit.includes("b64")&&!1===this._protectedHeader.b64)throw new f("JWTs MUST NOT use unencoded payload");return r.sign(e,t)}}const we=(e,t)=>{if("string"!=typeof e||!e)throw new w(`${t} missing or invalid`)};async function ye(e,t){if(!D(e))throw new TypeError("JWK must be an object");if(t??(t="sha256"),"sha256"!==t&&"sha384"!==t&&"sha512"!==t)throw new TypeError('digestAlgorithm must one of "sha256", "sha384", or "sha512"');let n;switch(e.kty){case"EC":we(e.crv,'"crv" (Curve) Parameter'),we(e.x,'"x" (X Coordinate) Parameter'),we(e.y,'"y" (Y Coordinate) Parameter'),n={crv:e.crv,kty:e.kty,x:e.x,y:e.y};break;case"OKP":we(e.crv,'"crv" (Subtype of Key Pair) Parameter'),we(e.x,'"x" (Public Key) Parameter'),n={crv:e.crv,kty:e.kty,x:e.x};break;case"RSA":we(e.e,'"e" (Exponent) Parameter'),we(e.n,'"n" (Modulus) Parameter'),n={e:e.e,kty:e.kty,n:e.n};break;case"oct":we(e.k,'"k" (Key Value) Parameter'),n={k:e.k,kty:e.kty};break;default:throw new p('"kty" (Key Type) Parameter missing or unsupported')}const s=a.encode(JSON.stringify(n));return i(await r(t,s))}function me(e){return D(e)}function ge(e){return"function"==typeof structuredClone?structuredClone(e):JSON.parse(JSON.stringify(e))}class _e{constructor(e){if(this._cached=new WeakMap,!function(e){return e&&"object"==typeof e&&Array.isArray(e.keys)&&e.keys.every(me)}(e))throw new y("JSON Web Key Set malformed");this._jwks=ge(e)}async getKey(e,t){const{alg:r,kid:a}={...e,...t?.header},n=function(e){switch("string"==typeof e&&e.slice(0,2)){case"RS":case"PS":return"RSA";case"ES":return"EC";case"Ed":return"OKP";default:throw new p('Unsupported "alg" value for a JSON Web Key Set')}}(r),s=this._jwks.keys.filter((e=>{let t=n===e.kty;if(t&&"string"==typeof a&&(t=a===e.kid),t&&"string"==typeof e.alg&&(t=r===e.alg),t&&"string"==typeof e.use&&(t="sig"===e.use),t&&Array.isArray(e.key_ops)&&(t=e.key_ops.includes("verify")),t)switch(r){case"ES256":t="P-256"===e.crv;break;case"ES256K":t="secp256k1"===e.crv;break;case"ES384":t="P-384"===e.crv;break;case"ES512":t="P-521"===e.crv;break;case"Ed25519":t="Ed25519"===e.crv;break;case"EdDSA":t="Ed25519"===e.crv||"Ed448"===e.crv}return t})),{0:i,length:o}=s;if(0===o)throw new m;if(1!==o){const e=new g,{_cached:t}=this;throw e[Symbol.asyncIterator]=async function*(){for(const e of s)try{yield await Se(t,e,r)}catch{}},e}return Se(this._cached,i,r)}}async function Se(e,t,r){const a=e.get(t)||e.set(t,{}).get(t);if(void 0===a[r]){const e=await L({...t,ext:!0},r);if(e instanceof Uint8Array||"public"!==e.type)throw new y("JSON Web Key Set members must be public keys");a[r]=e}return a[r]}function Ee(e){const t=new _e(e),r=async(e,r)=>t.getKey(e,r);return Object.defineProperties(r,{jwks:{value:()=>ge(t._jwks),enumerable:!0,configurable:!1,writable:!1}}),r}var be=async(e,t,r)=>{let a,n,s=!1;"function"==typeof AbortController&&(a=new AbortController,n=setTimeout((()=>{s=!0,a.abort()}),t));const i=await fetch(e.href,{signal:a?a.signal:void 0,redirect:"manual",headers:r.headers}).catch((e=>{if(s)throw new _;throw e}));if(void 0!==n&&clearTimeout(n),200!==i.status)throw new c("Expected 200 OK from the JSON Web Key Set HTTP response");try{return await i.json()}catch{throw new c("Failed to parse the JSON Web Key Set HTTP response as JSON")}};let ke;if("undefined"==typeof navigator||!navigator.userAgent?.startsWith?.("Mozilla/5.0 ")){ke=`${"jose"}/${"v5.10.0"}`}const ve=Symbol();class Ae{constructor(e,t){if(!(e instanceof URL))throw new TypeError("url must be an instance of URL");var r,a;this._url=new URL(e.href),this._options={agent:t?.agent,headers:t?.headers},this._timeoutDuration="number"==typeof t?.timeoutDuration?t?.timeoutDuration:5e3,this._cooldownDuration="number"==typeof t?.cooldownDuration?t?.cooldownDuration:3e4,this._cacheMaxAge="number"==typeof t?.cacheMaxAge?t?.cacheMaxAge:6e5,void 0!==t?.[ve]&&(this._cache=t?.[ve],r=t?.[ve],a=this._cacheMaxAge,"object"==typeof r&&null!==r&&"uat"in r&&"number"==typeof r.uat&&!(Date.now()-r.uat>=a)&&"jwks"in r&&D(r.jwks)&&Array.isArray(r.jwks.keys)&&Array.prototype.every.call(r.jwks.keys,D)&&(this._jwksTimestamp=this._cache.uat,this._local=Ee(this._cache.jwks)))}coolingDown(){return"number"==typeof this._jwksTimestamp&&Date.now()<this._jwksTimestamp+this._cooldownDuration}fresh(){return"number"==typeof this._jwksTimestamp&&Date.now()<this._jwksTimestamp+this._cacheMaxAge}async getKey(e,t){this._local&&this.fresh()||await this.reload();try{return await this._local(e,t)}catch(r){if(r instanceof m&&!1===this.coolingDown())return await this.reload(),this._local(e,t);throw r}}async reload(){this._pendingFetch&&("undefined"!=typeof WebSocketPair||"undefined"!=typeof navigator&&"Cloudflare-Workers"===navigator.userAgent||"undefined"!=typeof EdgeRuntime&&"vercel"===EdgeRuntime)&&(this._pendingFetch=void 0);const e=new Headers(this._options.headers);ke&&!e.has("User-Agent")&&(e.set("User-Agent",ke),this._options.headers=Object.fromEntries(e.entries())),this._pendingFetch||(this._pendingFetch=be(this._url,this._timeoutDuration,this._options).then((e=>{this._local=Ee(e),this._cache&&(this._cache.uat=Date.now(),this._cache.jwks=e),this._jwksTimestamp=Date.now(),this._pendingFetch=void 0})).catch((e=>{throw this._pendingFetch=void 0,e}))),await this._pendingFetch}}function Te(e,t){const r=new Ae(e,t),a=async(e,t)=>r.getKey(e,t);return Object.defineProperties(a,{coolingDown:{get:()=>r.coolingDown(),enumerable:!0,configurable:!1},fresh:{get:()=>r.fresh(),enumerable:!0,configurable:!1},reload:{value:()=>r.reload(),enumerable:!0,configurable:!1,writable:!1},reloading:{get:()=>!!r._pendingFetch,enumerable:!0,configurable:!1},jwks:{value:()=>r._local?.jwks(),enumerable:!0,configurable:!1,writable:!1}}),a}const Pe=o;function Re(e){const t=e?.modulusLength??2048;if("number"!=typeof t||t<2048)throw new p("Invalid or unsupported modulusLength option provided, 2048 bits or larger keys must be used");return t}async function Ie(t,r){return async function(t,r){let a,n;switch(t){case"PS256":case"PS384":case"PS512":a={name:"RSA-PSS",hash:`SHA-${t.slice(-3)}`,publicExponent:new Uint8Array([1,0,1]),modulusLength:Re(r)},n=["sign","verify"];break;case"RS256":case"RS384":case"RS512":a={name:"RSASSA-PKCS1-v1_5",hash:`SHA-${t.slice(-3)}`,publicExponent:new Uint8Array([1,0,1]),modulusLength:Re(r)},n=["sign","verify"];break;case"RSA-OAEP":case"RSA-OAEP-256":case"RSA-OAEP-384":case"RSA-OAEP-512":a={name:"RSA-OAEP",hash:`SHA-${parseInt(t.slice(-3),10)||1}`,publicExponent:new Uint8Array([1,0,1]),modulusLength:Re(r)},n=["decrypt","unwrapKey","encrypt","wrapKey"];break;case"ES256":a={name:"ECDSA",namedCurve:"P-256"},n=["sign","verify"];break;case"ES384":a={name:"ECDSA",namedCurve:"P-384"},n=["sign","verify"];break;case"ES512":a={name:"ECDSA",namedCurve:"P-521"},n=["sign","verify"];break;case"Ed25519":a={name:"Ed25519"},n=["sign","verify"];break;case"EdDSA":{n=["sign","verify"];const e=r?.crv??"Ed25519";switch(e){case"Ed25519":case"Ed448":a={name:e};break;default:throw new p("Invalid or unsupported crv option provided")}break}case"ECDH-ES":case"ECDH-ES+A128KW":case"ECDH-ES+A192KW":case"ECDH-ES+A256KW":{n=["deriveKey","deriveBits"];const e=r?.crv??"P-256";switch(e){case"P-256":case"P-384":case"P-521":a={name:"ECDH",namedCurve:e};break;case"X25519":case"X448":a={name:e};break;default:throw new p("Invalid or unsupported crv option provided, supported values are P-256, P-384, P-521, X25519, and X448")}break}default:throw new p('Invalid or unsupported JWK "alg" (Algorithm) Parameter value')}return e.subtle.generateKey(a,r?.extractable??!1,n)}(t,r)}const Ce=async(e,t,r)=>{const a=new URL(t),n=a.origin+a.pathname+a.search,s=new URL(e).origin,i=await fetch(`${s}/.well-known/openid-configuration`).then((e=>{if(!e.ok)throw new Error(`HTTP error! Status: ${e.status}`);return e.json()})),o=i.issuer,c=e=>e.endsWith("/")?e.slice(0,-1):e;if(c(e)!==c(o))throw new Error("RFC 9207 - iss !== idp - "+o+" !== "+e);sessionStorage.setItem("idp",o),sessionStorage.setItem("token_endpoint",i.token_endpoint),sessionStorage.setItem("jwks_uri",i.jwks_uri);let d=r?.client_id;if(!d){const e=i.registration_endpoint,t=await(async(e,t)=>{const r={...t,grant_types:["authorization_code","refresh_token"],token_endpoint_auth_method:"none",application_type:"web",subject_type:"public"};return fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)})})(e,r??{redirect_uris:[n]}).then((e=>{if(!e.ok)throw new Error(`HTTP error! Status: ${e.status}`);return e.json()}));d=t.client_id}try{new URL(d)}catch{sessionStorage.setItem("client_id",d)}const{pkce_code_verifier:h,pkce_code_challenge:l}=await De();sessionStorage.setItem("pkce_code_verifier",h);const p=window.crypto.randomUUID();sessionStorage.setItem("csrf_token",p);const u=i.authorization_endpoint+"?response_type=code"+`&redirect_uri=${encodeURIComponent(n)}&scope=openid offline_access webid`+`&client_id=${encodeURIComponent(d)}&code_challenge_method=S256`+`&code_challenge=${l}`+`&state=${p}&prompt=consent`;window.location.href=u},De=async()=>{const e=window.crypto.randomUUID()+"-"+window.crypto.randomUUID(),t=new Uint8Array(await window.crypto.subtle.digest("SHA-256",(new TextEncoder).encode(e)));return{pkce_code_verifier:e,pkce_code_challenge:btoa(String.fromCharCode(...t)).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}},We=async(e,t,r,a,n,s)=>{const i=await Y(s.publicKey);i.alg="ES256";const o=await new fe({htu:n,htm:"POST"}).setIssuedAt().setJti(window.crypto.randomUUID()).setProtectedHeader({alg:"ES256",typ:"dpop+jwt",jwk:i}).sign(s.privateKey);return fetch(n,{method:"POST",headers:{dpop:o,"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"authorization_code",code:e,code_verifier:t,redirect_uri:r,client_id:a})})},He=async(e,t,r,a)=>{const n=await Y(a.publicKey);n.alg="ES256";const s=await new fe({htu:r,htm:"POST"}).setIssuedAt().setJti(self.crypto.randomUUID()).setProtectedHeader({alg:"ES256",typ:"dpop+jwt",jwk:n}).sign(a.privateKey);return fetch(r,{method:"POST",headers:{dpop:s,"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"refresh_token",refresh_token:e,client_id:t})})};var Je;!function(e){e.STATE_CHANGE="sessionStateChange",e.EXPIRATION_WARNING="sessionExpirationWarning",e.EXPIRATION="sessionExpiration"}(Je||(Je={}));class xe extends EventTarget{isActive_=!1;exp_;webId_=void 0;currentAth_=void 0;information;database;refreshPromise;resolveRefresh;rejectRefresh;constructor(e,t){super(),this.authFetch=this.authFetch.bind(this),this.information={clientDetails:e},this.database=t?.database,t?.onSessionStateChange&&this.addEventListener(Je.STATE_CHANGE,(e=>t.onSessionStateChange?.(e))),t?.onSessionExpirationWarning&&this.addEventListener(Je.EXPIRATION_WARNING,(e=>t?.onSessionExpirationWarning?.(e))),t?.onSessionExpiration&&this.addEventListener(Je.EXPIRATION,(e=>t?.onSessionExpiration?.(e)))}async login(e,t){await Ce(e,t,this.information.clientDetails)}async handleRedirectFromLogin(){const e=await(async(e,t)=>{const r=new URL(window.location.href),a=r.searchParams.get("code");if(null===a)return{clientDetails:e};const n=sessionStorage.getItem("idp");if(null===n||r.searchParams.get("iss")!==n)throw new Error("RFC 9207 - iss !== idp - "+r.searchParams.get("iss")+" !== "+n);if(r.searchParams.get("state")!==sessionStorage.getItem("csrf_token"))throw new Error("RFC 6749 - state !== csrf_token - "+r.searchParams.get("state")+" !== "+sessionStorage.getItem("csrf_token"));r.searchParams.delete("iss"),r.searchParams.delete("state"),r.searchParams.delete("code"),window.history.pushState({},document.title,r.toString());const s=sessionStorage.getItem("pkce_code_verifier");if(null===s)throw new Error("Access Token Request preparation - Could not find in sessionStorage: pkce_code_verifier");const i=e?.client_id||sessionStorage.getItem("client_id");if(!i)throw new Error("Access Token Request preparation - Could not find in sessionStorage: client_id (dynamic registration)");const o=sessionStorage.getItem("token_endpoint");if(null===o)throw new Error("Access Token Request preparation - Could not find in sessionStorage: token_endpoint");const c=await Ie("ES256"),d=await We(a,s,r.toString(),i,o,c).then((e=>{if(!e.ok)throw new Error(`HTTP error! Status: ${e.status}`);return e.json()})),h=d.access_token,l=sessionStorage.getItem("jwks_uri");if(null===l)throw new Error("Access Token validation preparation - Could not find in sessionStorage: jwks_uri");const p=Te(new URL(l)),{payload:u}=await ce(h,p,{issuer:n,audience:"solid"}),f=await ye(await Y(c.publicKey));if(u.cnf.jkt!==f)throw new Error("Access Token validation failed on `jkt`: jkt !== DPoP thumbprint - "+u.cnf.jkt+" !== "+f);if(u.client_id!==i)throw new Error("Access Token validation failed on `client_id`: JWT payload !== client_id - "+u.client_id+" !== "+i);const w={...d,dpop_key_pair:c},y={idp:n,jwks_uri:l,token_endpoint:o};return e||(e={redirect_uris:[r.toString()]}),e.client_id=i,t&&(await t.init(),await Promise.all([t.setItem("idp",n),t.setItem("jwks_uri",l),t.setItem("token_endpoint",o),t.setItem("client_id",i),t.setItem("dpop_keypair",c),t.setItem("refresh_token",d.refresh_token)]),t.close()),sessionStorage.removeItem("csrf_token"),sessionStorage.removeItem("pkce_code_verifier"),sessionStorage.removeItem("idp"),sessionStorage.removeItem("jwks_uri"),sessionStorage.removeItem("token_endpoint"),sessionStorage.removeItem("client_id"),{clientDetails:e,idpDetails:y,tokenDetails:w}})(this.information.clientDetails,this.database);e.tokenDetails&&(this.information.clientDetails=e.clientDetails,this.information.idpDetails=e.idpDetails,await this.setTokenDetails(e.tokenDetails),this.dispatchStateChangeEvent())}async restore(){if(!this.database)throw new Error("Could not refresh tokens: missing database. Provide database in sessionOption.");if(this.refreshPromise)return this.refreshPromise;this.refreshPromise=new Promise(((e,t)=>{this.resolveRefresh=e,this.rejectRefresh=t}));const e=this.isActive;return(async e=>{try{await e.init();const t=await e.getItem("client_id"),r=await e.getItem("token_endpoint"),a=await e.getItem("dpop_keypair"),n=await e.getItem("refresh_token");if(null===t||null===r||null===a||null===n)throw new Error("Could not refresh tokens: details missing from database.");const s=await He(n,t,r,a).then((e=>{if(!e.ok)throw new Error(`HTTP error! Status: ${e.status}`);return e.json()})),i=s.access_token,o=await e.getItem("idp");if(null===o)throw new Error("Access Token validation preparation - Could not find in sessionDatabase: idp");const c=await e.getItem("jwks_uri");if(null===c)throw new Error("Access Token validation preparation - Could not find in sessionDatabase: jwks_uri");const d=Te(new URL(c)),{payload:h}=await ce(i,d,{issuer:o,audience:"solid"}),l=await ye(await Y(a.publicKey));if(h.cnf.jkt!==l)throw new Error("Access Token validation failed on `jkt`: jkt !== DPoP thumbprint - "+h.cnf.jkt+" !== "+l);if(h.client_id!==t)throw new Error("Access Token validation failed on `client_id`: JWT payload !== client_id - "+h.client_id+" !== "+t);return await e.setItem("refresh_token",s.refresh_token),{...s,dpop_key_pair:a}}finally{e.close()}})(this.database).then((e=>this.setTokenDetails(e))).then((()=>this.resolveRefresh())).catch((e=>{this.isActive?(this.rejectRefresh(new Error(e||"Token refresh failed")),this.isExpired()?this.dispatchExpirationEvent():this.dispatchExpirationWarningEvent()):this.rejectRefresh(new Error("No session to restore."))})).finally((()=>{this.clearRefreshPromise(),e!==this.isActive&&this.dispatchStateChangeEvent()})),this.refreshPromise}async logout(){this.isActive_=!1,this.exp_=void 0,this.webId_=void 0,this.currentAth_=void 0,this.information.idpDetails=void 0,this.information.tokenDetails=void 0,this.refreshPromise&&this.rejectRefresh&&(this.rejectRefresh(new Error("Logout during token refresh.")),this.clearRefreshPromise()),this.database&&(await this.database.init(),await this.database.clear(),this.database.close()),this.dispatchStateChangeEvent()}async authFetch(e,t,r){if(!this.isActive)return fetch(e,t);let a,n,s;e instanceof Request?(a=new URL(e.url),n=t?.method||e?.method||"GET",s=new Headers(e.headers)):(t=t||{},a=new URL(e.toString()),n=t.method||"GET",s=t.headers?new Headers(t.headers):new Headers),await this._renewTokensIfExpired(),r=r??{htu:`${a.origin}${a.pathname}`,htm:n.toUpperCase()};const i=await this._createSignedDPoPToken(r);return s.set("dpop",i),s.set("authorization",`DPoP ${this.information.tokenDetails.access_token}`),e instanceof Request?fetch(new Request(e,{...t,headers:s})):fetch(a,{...t,headers:s})}async setTokenDetails(e){this.information.tokenDetails=e,await this._updateSessionDetailsFromToken(e.access_token)}clearRefreshPromise(){this.refreshPromise=void 0,this.resolveRefresh=void 0,this.rejectRefresh=void 0}get isActive(){return this.isActive_}get webId(){return this.webId_}isExpired(){return!this.exp_||this._isTokenExpired(this.exp_)}getExpiresIn(){return this.exp_?this._getTokenTTL(this.exp_):-1}getTokenDetails(){return this.information.tokenDetails}async _renewTokensIfExpired(){this.isExpired()&&(this.refreshPromise?await this.refreshPromise:await this.restore())}async _computeAth(e){const t=(new TextEncoder).encode(e),r=await crypto.subtle.digest("SHA-256",t),a=Array.from(new Uint8Array(r));return btoa(String.fromCharCode(...a)).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}async _createSignedDPoPToken(e){if(!this.information.tokenDetails||!this.currentAth_)throw new Error("Session not established.");e.ath=this.currentAth_;const t=await Y(this.information.tokenDetails.dpop_key_pair.publicKey);return new fe(e).setIssuedAt().setJti(window.crypto.randomUUID()).setProtectedHeader({alg:"ES256",typ:"dpop+jwt",jwk:t}).sign(this.information.tokenDetails.dpop_key_pair.privateKey)}async _updateSessionDetailsFromToken(e){if(e)try{const t=function(e){if("string"!=typeof e)throw new f("JWTs must use Compact JWS serialization, JWT must be a string");const{1:t,length:r}=e.split(".");if(5===r)throw new f("Only JWTs using Compact JWS serialization can be decoded");if(3!==r)throw new f("Invalid JWT");if(!t)throw new f("JWTs must contain a payload");let a,s;try{a=Pe(t)}catch{throw new f("Failed to base64url decode the payload")}try{s=JSON.parse(n.decode(a))}catch{throw new f("Failed to parse the decoded payload as JSON")}if(!D(s))throw new f("Invalid JWT Claims Set");return s}(e),r=t.webid;if(!r)throw new Error("Missing webid claim in access token");const a=t.exp;if(!a)throw new Error("Missing exp claim in access token");this.currentAth_=await this._computeAth(e),this.webId_=r,this.exp_=a,this.isActive_=!0}catch(e){await this.logout()}else await this.logout()}_isTokenExpired(e,t=0){return!("number"==typeof e&&!isNaN(e))||this._getTokenTTL(e,t)<0}_getTokenTTL(e,t=0){return e-(Math.floor(Date.now()/1e3)+t)}dispatchStateChangeEvent(){this.dispatchEvent(new CustomEvent(Je.STATE_CHANGE,{detail:{isActive:this.isActive,webId:this.webId}}))}dispatchExpirationWarningEvent(){this.dispatchEvent(new CustomEvent(Je.EXPIRATION_WARNING,{detail:{expires_in:this.getExpiresIn()}}))}dispatchExpirationEvent(){this.dispatchEvent(new CustomEvent(Je.EXPIRATION))}}export{xe as SessionCore,Je as SessionEvents};
6
-
@@ -1,11 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
2
- <!-- The forum: more than one person talking. Icon "messages-square" from
3
- Lucide (lucide.dev), ISC licence, © Lucide Contributors. -->
4
- <title>Federated Solid Forum</title>
5
- <rect width="32" height="32" rx="7" fill="#3b5bb5"/>
6
- <g transform="translate(4 4)" fill="none" stroke="#ffffff" stroke-width="2"
7
- stroke-linecap="round" stroke-linejoin="round">
8
- <path d="M16 10a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 14.286V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/>
9
- <path d="M20 9a2 2 0 0 1 2 2v10.286a.71.71 0 0 1-1.212.502l-2.202-2.202A2 2 0 0 0 17.172 19H10a2 2 0 0 1-2-2v-1"/>
10
- </g>
11
- </svg>
@@ -1,14 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
2
- <!-- The gateway: the door your mail comes through. Icon "door-open" from
3
- Lucide (lucide.dev), ISC licence, © Lucide Contributors. -->
4
- <title>FediPod gateway</title>
5
- <rect width="32" height="32" rx="7" fill="#b4531a"/>
6
- <g transform="translate(4 4)" fill="none" stroke="#ffffff" stroke-width="2"
7
- stroke-linecap="round" stroke-linejoin="round">
8
- <path d="M10 21H2"/>
9
- <path d="M10 3H7a2 2 0 00-2 2v16"/>
10
- <path d="M14 12h.01"/>
11
- <path d="M19 21V5a2 2 0 00-1.675-1.974l-6.163-1.013A1 1 0 0010 3v18a1 1 0 001.124.992z"/>
12
- <path d="M22 21h-3"/>
13
- </g>
14
- </svg>
@@ -1,11 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
2
- <!-- Your own pod and your own posts. Icon "house" from Lucide (lucide.dev),
3
- ISC licence, © Lucide Contributors. -->
4
- <title>FediPod</title>
5
- <rect width="32" height="32" rx="7" fill="#2f7d4f"/>
6
- <g transform="translate(4 4)" fill="none" stroke="#ffffff" stroke-width="2"
7
- stroke-linecap="round" stroke-linejoin="round">
8
- <path d="M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8"/>
9
- <path d="M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>
10
- </g>
11
- </svg>