most-box 0.1.0 → 0.1.2

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 (390) hide show
  1. package/README.md +24 -16
  2. package/electron/main.js +72 -8
  3. package/electron/preload.js +6 -0
  4. package/out/404/index.html +2 -2
  5. package/out/404.html +2 -2
  6. package/out/__next.__PAGE__.txt +6 -6
  7. package/out/__next._full.txt +23 -20
  8. package/out/__next._head.txt +3 -3
  9. package/out/__next._index.txt +8 -6
  10. package/out/__next._tree.txt +6 -4
  11. package/out/_next/static/chunks/0-n3pg7th.zza.js +1 -0
  12. package/out/_next/static/chunks/0.4j.0k5a64vg.js +1 -0
  13. package/out/_next/static/chunks/0.e2avjgna_b2.js +1 -0
  14. package/out/_next/static/chunks/0.ozi1_x2.m.~.js +1 -0
  15. package/out/_next/static/chunks/0.t5wlt51zou5.js +1 -0
  16. package/out/_next/static/chunks/0.w4hkvap~bva.js +1 -0
  17. package/out/_next/static/chunks/00d9h1tddnnnd.js +1 -0
  18. package/out/_next/static/chunks/00tkdqwxch-3s.js +1 -0
  19. package/out/_next/static/chunks/01l3o90g~1z42.js +1 -0
  20. package/out/_next/static/chunks/01mfky9camw6i.js +1 -0
  21. package/out/_next/static/chunks/01r.v-pqs1vrm.js +1 -0
  22. package/out/_next/static/chunks/03edqrb4zdj~g.js +31 -0
  23. package/out/_next/static/chunks/03h_6oo-gqkhz.js +1 -0
  24. package/out/_next/static/chunks/{0ho~log~~-jwp.css → 03h~nhgj0hv3p.css} +1 -1
  25. package/out/_next/static/chunks/04hcgsanv1hhu.js +1 -0
  26. package/out/_next/static/chunks/05g2q0w5b34.g.js +1 -0
  27. package/out/_next/static/chunks/05of77xycbt8~.js +1 -0
  28. package/out/_next/static/chunks/05zwemzfjx3sh.js +1 -0
  29. package/out/_next/static/chunks/06dpc5df94.v1.js +1 -0
  30. package/out/_next/static/chunks/06e1~1-z_ic9a.js +1 -0
  31. package/out/_next/static/chunks/075s7sn.ns~u5.js +1 -0
  32. package/out/_next/static/chunks/07dynrbvd3.f4.js +1 -0
  33. package/out/_next/static/chunks/07p~uva5pwgwe.js +1 -0
  34. package/out/_next/static/chunks/07r9nn-pzlgg1.js +1 -0
  35. package/out/_next/static/chunks/07td.jq7xff84.css +1 -0
  36. package/out/_next/static/chunks/08.72abkgwy9g.js +1 -0
  37. package/out/_next/static/chunks/08576xhv~~jck.js +1 -0
  38. package/out/_next/static/chunks/08u211~k~qu52.js +1 -0
  39. package/out/_next/static/chunks/098.p.2-zm4p7.js +1 -0
  40. package/out/_next/static/chunks/09ngvtajm7e5y.js +1 -0
  41. package/out/_next/static/chunks/09ps~-43n5qyo.js +1 -0
  42. package/out/_next/static/chunks/09v7_0gclxr46.js +1 -0
  43. package/out/_next/static/chunks/09yql86dir9c4.js +1 -0
  44. package/out/_next/static/chunks/09zmlfljowj1~.js +1 -0
  45. package/out/_next/static/chunks/0_s~ebb-7b2hr.js +1 -0
  46. package/out/_next/static/chunks/0_w-0-2z5oqd_.js +1 -0
  47. package/out/_next/static/chunks/0adx~d-j05c9d.css +24 -0
  48. package/out/_next/static/chunks/0ao1lbi4b.sfa.js +1 -0
  49. package/out/_next/static/chunks/0aq.rc9woa2nz.js +1 -0
  50. package/out/_next/static/chunks/0bld2u_ld~va2.js +1 -0
  51. package/out/_next/static/chunks/0bliugh5lxw55.js +1 -0
  52. package/out/_next/static/chunks/0cn9a7aimbdzq.js +1 -0
  53. package/out/_next/static/chunks/0d3f-nk3c.2re.js +1 -0
  54. package/out/_next/static/chunks/0dtohpf7~3d12.js +1 -0
  55. package/out/_next/static/chunks/0e-3e8h7g99yf.js +1 -0
  56. package/out/_next/static/chunks/0e531nije_ln2.js +1 -0
  57. package/out/_next/static/chunks/0e5zvj_rh0z3m.js +1 -0
  58. package/out/_next/static/chunks/0etes81d_cihn.js +1 -0
  59. package/out/_next/static/chunks/0f4y~rkk-n81e.js +1 -0
  60. package/out/_next/static/chunks/0fk~0~p7ivfn1.js +1 -0
  61. package/out/_next/static/chunks/0fw6juc~lsj3z.js +1 -0
  62. package/out/_next/static/chunks/0g0u7785a73vo.js +1 -0
  63. package/out/_next/static/chunks/0g_a~e050bgzg.css +1 -0
  64. package/out/_next/static/chunks/0g_fpgh7drfda.js +1 -0
  65. package/out/_next/static/chunks/{0n~dq4kpx9xxx.js → 0gcsdf57gcm6h.js} +1 -1
  66. package/out/_next/static/chunks/0gwian.hp3-92.js +1 -0
  67. package/out/_next/static/chunks/0gze5uso1mbe9.js +1 -0
  68. package/out/_next/static/chunks/0h4r.qtmpa6eh.js +1 -0
  69. package/out/_next/static/chunks/0hf.aosc-7172.js +1 -0
  70. package/out/_next/static/chunks/0hgz35c1ejbs9.js +1 -0
  71. package/out/_next/static/chunks/0hpev4am9jpmu.css +1 -0
  72. package/out/_next/static/chunks/0hrw-r.xmvmsq.js +1 -0
  73. package/out/_next/static/chunks/0hzg4al.v~8~m.js +1 -0
  74. package/out/_next/static/chunks/0ip9xrols_83o.js +1 -0
  75. package/out/_next/static/chunks/0j4-d0qf.v~kn.js +1 -0
  76. package/out/_next/static/chunks/0jhdeq.j9_02m.js +1 -0
  77. package/out/_next/static/chunks/0jy63h3i-y69i.js +1 -0
  78. package/out/_next/static/chunks/0kdnx_u-60k9s.js +1 -0
  79. package/out/_next/static/chunks/0kq~edq42o1-c.js +1 -0
  80. package/out/_next/static/chunks/0l5_.uqb-uqb8.js +1 -0
  81. package/out/_next/static/chunks/0l682p362d-5w.js +1 -0
  82. package/out/_next/static/chunks/0m68p9txef5rs.js +1 -0
  83. package/out/_next/static/chunks/0mex8svsiv-2l.js +1 -0
  84. package/out/_next/static/chunks/0mme-fm5d2oz2.js +1 -0
  85. package/out/_next/static/chunks/0myp4sjagr~h0.js +1 -0
  86. package/out/_next/static/chunks/0myq9gs8szydh.js +1 -0
  87. package/out/_next/static/chunks/0n.qlfk~z7o.6.js +1 -0
  88. package/out/_next/static/chunks/0n4t80gjc3q5h.js +1 -0
  89. package/out/_next/static/chunks/0o9ce4cyf76by.js +736 -0
  90. package/out/_next/static/chunks/0oz3yl6_-716p.js +1 -0
  91. package/out/_next/static/chunks/0p0sv~fuddvgr.js +1 -0
  92. package/out/_next/static/chunks/0pt.5cg1t09qs.js +1 -0
  93. package/out/_next/static/chunks/0q0ksgxg98xgd.js +1 -0
  94. package/out/_next/static/chunks/0qgx9t4jx16ua.css +1 -0
  95. package/out/_next/static/chunks/0qqupeexg83u7.js +1 -0
  96. package/out/_next/static/chunks/0rb-ri481.kc9.js +1 -0
  97. package/out/_next/static/chunks/0rsnmahfd.59p.js +1 -0
  98. package/out/_next/static/chunks/0rt6rgnvr-s_p.js +1 -0
  99. package/out/_next/static/chunks/0runh28p_gg6..js +1 -0
  100. package/out/_next/static/chunks/0shy.t1fwqcev.js +1 -0
  101. package/out/_next/static/chunks/{0d3shmwh5_nmn.js → 0t2xr05rlu96l.js} +1 -1
  102. package/out/_next/static/chunks/0t6h56rhg1y5i.js +1 -0
  103. package/out/_next/static/chunks/0tdqd1zunusgk.js +1 -0
  104. package/out/_next/static/chunks/0ujbnp38x63ek.js +1 -0
  105. package/out/_next/static/chunks/0ukyg~tkm~h2m.css +1 -0
  106. package/out/_next/static/chunks/0v68pdrp54lb-.js +1 -0
  107. package/out/_next/static/chunks/0vsm0m5sxrb.3.js +1 -0
  108. package/out/_next/static/chunks/0vzlz.iboqo3c.js +1 -0
  109. package/out/_next/static/chunks/0w87vbpkf-ogd.js +1 -0
  110. package/out/_next/static/chunks/0wtf0xsiicxx6.js +1 -0
  111. package/out/_next/static/chunks/0xdwau5k2augv.css +4 -0
  112. package/out/_next/static/chunks/0xgg0~kmf3gd-.js +1 -0
  113. package/out/_next/static/chunks/0xj24-70ptdzp.js +1 -0
  114. package/out/_next/static/chunks/0xxlx772fr3x4.js +1 -0
  115. package/out/_next/static/chunks/0y.li-~3oybew.js +1 -0
  116. package/out/_next/static/chunks/0yl2t7cs-n_ng.js +1 -0
  117. package/out/_next/static/chunks/0yq3kh.hchtm_.js +1 -0
  118. package/out/_next/static/chunks/0ys0l5au.9c2c.js +1 -0
  119. package/out/_next/static/chunks/0z48pmi6buytt.js +1 -0
  120. package/out/_next/static/chunks/0zapnvgy89mg..js +1 -0
  121. package/out/_next/static/chunks/0~.-vxi5oc.r0.js +1 -0
  122. package/out/_next/static/chunks/0~3ik-hfp9s-7.js +1 -0
  123. package/out/_next/static/chunks/0~4f5p6tvn1lq.js +1 -0
  124. package/out/_next/static/chunks/0~_0ys.2whxbw.js +1 -0
  125. package/out/_next/static/chunks/0~_ui9l7.2sxf.js +1 -0
  126. package/out/_next/static/chunks/1037jlyw5~7ht.js +1 -0
  127. package/out/_next/static/chunks/1045hfzu533z0.js +1 -0
  128. package/out/_next/static/chunks/104e5nmc.c-pl.js +1 -0
  129. package/out/_next/static/chunks/109taw1pbh-0b.js +1 -0
  130. package/out/_next/static/chunks/10x7~onqwp338.js +1 -0
  131. package/out/_next/static/chunks/10ynz1dy483wf.js +1 -0
  132. package/out/_next/static/chunks/11hds.mg~4_r-.js +1 -0
  133. package/out/_next/static/chunks/11ibzaklcauw~.js +1 -0
  134. package/out/_next/static/chunks/11z.0s6.42b.p.js +1 -0
  135. package/out/_next/static/chunks/12-9n56l0y3yr.js +1 -0
  136. package/out/_next/static/chunks/126enaq~f7scl.js +1 -0
  137. package/out/_next/static/chunks/12nr19.nnn6s3.js +5 -0
  138. package/out/_next/static/chunks/{0qub_r0x_r-e9.css → 12pep-2t-qg4n.css} +1 -1
  139. package/out/_next/static/chunks/1380op_pfk.qo.js +1 -0
  140. package/out/_next/static/chunks/146oiw1bggtn4.js +1 -0
  141. package/out/_next/static/chunks/14_inksek_rth.js +2 -0
  142. package/out/_next/static/chunks/14_po2rb_arn4.js +1 -0
  143. package/out/_next/static/chunks/14a4fwbiq.l3z.js +1 -0
  144. package/out/_next/static/chunks/14cowsqn95m1k.js +1 -0
  145. package/out/_next/static/chunks/14dtd3l03v.kx.js +1 -0
  146. package/out/_next/static/chunks/14tm3qa-v9o-4.js +1 -0
  147. package/out/_next/static/chunks/15-o4kb-evqd7.js +1 -0
  148. package/out/_next/static/chunks/153-sz7s.qml2.js +1 -0
  149. package/out/_next/static/chunks/157z7bowux3xj.js +1 -0
  150. package/out/_next/static/chunks/15m1_677az2cm.js +1 -0
  151. package/out/_next/static/chunks/15v.~.ne6ogkk.js +1 -0
  152. package/out/_next/static/chunks/16i.qbk8t8gf_.js +1 -0
  153. package/out/_next/static/chunks/16u9f35gylw8l.js +1 -0
  154. package/out/_next/static/chunks/16xls5tt_68lx.js +1 -0
  155. package/out/_next/static/chunks/17ajyb5ogk5yj.js +1 -0
  156. package/out/_next/static/chunks/17dyfxbq8yz8n.js +1 -0
  157. package/out/_next/static/chunks/180zln9pcq9ih.js +1 -0
  158. package/out/_next/static/chunks/1814izi5gh.kp.js +1 -0
  159. package/out/_next/static/chunks/turbopack-0xta0kqwzkf28.js +1 -0
  160. package/out/_next/static/media/KaTeX_AMS-Regular.0b~8ki5y928w2.woff +0 -0
  161. package/out/_next/static/media/KaTeX_AMS-Regular.0p1vbqd84i2~o.woff2 +0 -0
  162. package/out/_next/static/media/KaTeX_AMS-Regular.173t6ktr7uf-w.ttf +0 -0
  163. package/out/_next/static/media/KaTeX_Caligraphic-Bold.01-pzluls4zgb.woff2 +0 -0
  164. package/out/_next/static/media/KaTeX_Caligraphic-Bold.0x2v1lwn~880f.woff +0 -0
  165. package/out/_next/static/media/KaTeX_Caligraphic-Bold.16zv5fax0h0ka.ttf +0 -0
  166. package/out/_next/static/media/KaTeX_Caligraphic-Regular.02i3z7wig438t.ttf +0 -0
  167. package/out/_next/static/media/KaTeX_Caligraphic-Regular.0rysu1t-ncjq8.woff2 +0 -0
  168. package/out/_next/static/media/KaTeX_Caligraphic-Regular.10927swgekwun.woff +0 -0
  169. package/out/_next/static/media/KaTeX_Fraktur-Bold.0e-16u10iuyyf.woff +0 -0
  170. package/out/_next/static/media/KaTeX_Fraktur-Bold.0et27v~3~4uhe.ttf +0 -0
  171. package/out/_next/static/media/KaTeX_Fraktur-Bold.0w23i72~hprpq.woff2 +0 -0
  172. package/out/_next/static/media/KaTeX_Fraktur-Regular.0b.riegzdfue2.woff +0 -0
  173. package/out/_next/static/media/KaTeX_Fraktur-Regular.0rekyoa-52fj_.woff2 +0 -0
  174. package/out/_next/static/media/KaTeX_Fraktur-Regular.0vjwa15znhk~4.ttf +0 -0
  175. package/out/_next/static/media/KaTeX_Main-Bold.09i7~607shf-h.ttf +0 -0
  176. package/out/_next/static/media/KaTeX_Main-Bold.09lmynrorhcbw.woff +0 -0
  177. package/out/_next/static/media/KaTeX_Main-Bold.16pfc63_du6mx.woff2 +0 -0
  178. package/out/_next/static/media/KaTeX_Main-BoldItalic.0cp37g7x1q8h6.woff +0 -0
  179. package/out/_next/static/media/KaTeX_Main-BoldItalic.0d54rk08rx11s.woff2 +0 -0
  180. package/out/_next/static/media/KaTeX_Main-BoldItalic.15j6k~hix2t_0.ttf +0 -0
  181. package/out/_next/static/media/KaTeX_Main-Italic.0382gqciexmbu.woff +0 -0
  182. package/out/_next/static/media/KaTeX_Main-Italic.06o5nq0_91v60.woff2 +0 -0
  183. package/out/_next/static/media/KaTeX_Main-Italic.0su4i6mm18-wo.ttf +0 -0
  184. package/out/_next/static/media/KaTeX_Main-Regular.08zh8z.7shijf.ttf +0 -0
  185. package/out/_next/static/media/KaTeX_Main-Regular.0diheg01zyoph.woff +0 -0
  186. package/out/_next/static/media/KaTeX_Main-Regular.0kaf-ag2_wkm-.woff2 +0 -0
  187. package/out/_next/static/media/KaTeX_Math-BoldItalic.0ajzxypnbx1h1.ttf +0 -0
  188. package/out/_next/static/media/KaTeX_Math-BoldItalic.0ck1myuerwyqw.woff +0 -0
  189. package/out/_next/static/media/KaTeX_Math-BoldItalic.0ja97dn.cpc87.woff2 +0 -0
  190. package/out/_next/static/media/KaTeX_Math-Italic.09xkhecjcn5r9.woff +0 -0
  191. package/out/_next/static/media/KaTeX_Math-Italic.0x23a-bmp-5tg.ttf +0 -0
  192. package/out/_next/static/media/KaTeX_Math-Italic.0zrha2c4sl2je.woff2 +0 -0
  193. package/out/_next/static/media/KaTeX_SansSerif-Bold.05a9.pc1j_zx9.woff2 +0 -0
  194. package/out/_next/static/media/KaTeX_SansSerif-Bold.0jcl-ayi1uun0.woff +0 -0
  195. package/out/_next/static/media/KaTeX_SansSerif-Bold.0re8y.dm7.mt5.ttf +0 -0
  196. package/out/_next/static/media/KaTeX_SansSerif-Italic.0a0234dc3s62j.woff2 +0 -0
  197. package/out/_next/static/media/KaTeX_SansSerif-Italic.0judofdln9731.woff +0 -0
  198. package/out/_next/static/media/KaTeX_SansSerif-Italic.10z1iap9pfus8.ttf +0 -0
  199. package/out/_next/static/media/KaTeX_SansSerif-Regular.0h9yjlugq4q_e.woff +0 -0
  200. package/out/_next/static/media/KaTeX_SansSerif-Regular.0v6gcj32-czft.woff2 +0 -0
  201. package/out/_next/static/media/KaTeX_SansSerif-Regular.0zm18kga42ebc.ttf +0 -0
  202. package/out/_next/static/media/KaTeX_Script-Regular.0c4.h-mer83d_.woff2 +0 -0
  203. package/out/_next/static/media/KaTeX_Script-Regular.0q14y6zkzlpob.ttf +0 -0
  204. package/out/_next/static/media/KaTeX_Script-Regular.0ze6v4r_-99oy.woff +0 -0
  205. package/out/_next/static/media/KaTeX_Size1-Regular.013x6a4ierotp.woff2 +0 -0
  206. package/out/_next/static/media/KaTeX_Size1-Regular.0kidw0oi.m68o.woff +0 -0
  207. package/out/_next/static/media/KaTeX_Size1-Regular.0m6y-i6wfokni.ttf +0 -0
  208. package/out/_next/static/media/KaTeX_Size2-Regular.0blpmluwilgbg.woff +0 -0
  209. package/out/_next/static/media/KaTeX_Size2-Regular.0d5inmyp-tyv3.woff2 +0 -0
  210. package/out/_next/static/media/KaTeX_Size2-Regular.0wnhnvj-.k9d5.ttf +0 -0
  211. package/out/_next/static/media/KaTeX_Size3-Regular.01h0xm_sfctj3.woff +0 -0
  212. package/out/_next/static/media/KaTeX_Size3-Regular.0iukctyhw5j56.woff2 +0 -0
  213. package/out/_next/static/media/KaTeX_Size3-Regular.0jl8mqyf4gzpn.ttf +0 -0
  214. package/out/_next/static/media/KaTeX_Size4-Regular.0w3.rb_c4stzk.woff2 +0 -0
  215. package/out/_next/static/media/KaTeX_Size4-Regular.0wr_9l81-mu06.ttf +0 -0
  216. package/out/_next/static/media/KaTeX_Size4-Regular.12tvaesf3.zl3.woff +0 -0
  217. package/out/_next/static/media/KaTeX_Typewriter-Regular.0c4zdxz~8frhm.woff2 +0 -0
  218. package/out/_next/static/media/KaTeX_Typewriter-Regular.0cgrzn5l3kao5.woff +0 -0
  219. package/out/_next/static/media/KaTeX_Typewriter-Regular.128~qc3858otl.ttf +0 -0
  220. package/out/_not-found/__next._full.txt +21 -19
  221. package/out/_not-found/__next._head.txt +3 -3
  222. package/out/_not-found/__next._index.txt +8 -6
  223. package/out/_not-found/__next._not-found.__PAGE__.txt +4 -4
  224. package/out/_not-found/__next._not-found.txt +3 -3
  225. package/out/_not-found/__next._tree.txt +3 -2
  226. package/out/_not-found/index.html +2 -2
  227. package/out/_not-found/index.txt +21 -19
  228. package/out/admin/__next._full.txt +23 -0
  229. package/out/admin/__next._head.txt +5 -0
  230. package/out/admin/__next._index.txt +9 -0
  231. package/out/admin/__next._tree.txt +5 -0
  232. package/out/admin/__next.admin.__PAGE__.txt +9 -0
  233. package/out/admin/__next.admin.txt +5 -0
  234. package/out/admin/index.html +15 -0
  235. package/out/admin/index.txt +23 -0
  236. package/out/app/__next._full.txt +15 -13
  237. package/out/app/__next._head.txt +3 -3
  238. package/out/app/__next._index.txt +8 -6
  239. package/out/app/__next._tree.txt +4 -2
  240. package/out/app/__next.app.__PAGE__.txt +4 -4
  241. package/out/app/__next.app.txt +3 -4
  242. package/out/app/index.html +2 -2
  243. package/out/app/index.txt +15 -13
  244. package/out/chat/__next._full.txt +16 -14
  245. package/out/chat/__next._head.txt +3 -3
  246. package/out/chat/__next._index.txt +8 -6
  247. package/out/chat/__next._tree.txt +5 -3
  248. package/out/chat/__next.chat.__PAGE__.txt +4 -4
  249. package/out/chat/__next.chat.txt +4 -5
  250. package/out/chat/index.html +2 -2
  251. package/out/chat/index.txt +16 -14
  252. package/out/chat/join/__next._full.txt +25 -0
  253. package/out/chat/join/__next._head.txt +5 -0
  254. package/out/chat/join/__next._index.txt +9 -0
  255. package/out/chat/join/__next._tree.txt +5 -0
  256. package/out/chat/join/__next.chat.join.__PAGE__.txt +9 -0
  257. package/out/chat/join/__next.chat.join.txt +5 -0
  258. package/out/chat/join/__next.chat.txt +5 -0
  259. package/out/chat/join/index.html +15 -0
  260. package/out/chat/join/index.txt +25 -0
  261. package/out/download/__next._full.txt +34 -33
  262. package/out/download/__next._head.txt +3 -3
  263. package/out/download/__next._index.txt +8 -6
  264. package/out/download/__next._tree.txt +6 -4
  265. package/out/download/__next.download.__PAGE__.txt +13 -14
  266. package/out/download/__next.download.txt +3 -3
  267. package/out/download/index.html +2 -2
  268. package/out/download/index.txt +34 -33
  269. package/out/index.html +2 -2
  270. package/out/index.txt +23 -20
  271. package/out/note/__next._full.txt +24 -0
  272. package/out/{changelog → note}/__next._head.txt +3 -3
  273. package/out/note/__next._index.txt +9 -0
  274. package/out/note/__next._tree.txt +4 -0
  275. package/out/note/__next.note.__PAGE__.txt +9 -0
  276. package/out/note/__next.note.txt +5 -0
  277. package/out/note/index.html +15 -0
  278. package/out/note/index.txt +24 -0
  279. package/out/ping/__next._full.txt +23 -20
  280. package/out/ping/__next._head.txt +3 -3
  281. package/out/ping/__next._index.txt +8 -6
  282. package/out/ping/__next._tree.txt +6 -4
  283. package/out/ping/__next.ping.__PAGE__.txt +5 -5
  284. package/out/ping/__next.ping.txt +4 -4
  285. package/out/ping/index.html +2 -2
  286. package/out/ping/index.txt +23 -20
  287. package/out/web3/__next._full.txt +16 -14
  288. package/out/web3/__next._head.txt +3 -3
  289. package/out/web3/__next._index.txt +8 -6
  290. package/out/web3/__next._tree.txt +5 -3
  291. package/out/web3/__next.web3.__PAGE__.txt +4 -4
  292. package/out/web3/__next.web3.txt +4 -5
  293. package/out/web3/ed25519/__next._full.txt +14 -12
  294. package/out/web3/ed25519/__next._head.txt +3 -3
  295. package/out/web3/ed25519/__next._index.txt +8 -6
  296. package/out/web3/ed25519/__next._tree.txt +5 -3
  297. package/out/web3/ed25519/__next.web3.ed25519.__PAGE__.txt +2 -2
  298. package/out/web3/ed25519/__next.web3.ed25519.txt +3 -3
  299. package/out/web3/ed25519/__next.web3.txt +4 -5
  300. package/out/web3/ed25519/index.html +1 -1
  301. package/out/web3/ed25519/index.txt +14 -12
  302. package/out/web3/index.html +2 -2
  303. package/out/web3/index.txt +16 -14
  304. package/out/web3/tools/__next._full.txt +14 -12
  305. package/out/web3/tools/__next._head.txt +3 -3
  306. package/out/web3/tools/__next._index.txt +8 -6
  307. package/out/web3/tools/__next._tree.txt +5 -3
  308. package/out/web3/tools/__next.web3.tools.__PAGE__.txt +2 -2
  309. package/out/web3/tools/__next.web3.tools.txt +3 -3
  310. package/out/web3/tools/__next.web3.txt +4 -5
  311. package/out/web3/tools/index.html +1 -1
  312. package/out/web3/tools/index.txt +14 -12
  313. package/package.json +30 -13
  314. package/server/index.js +188 -901
  315. package/server/src/config.js +5 -1
  316. package/server/src/core/channelAttachment.js +68 -0
  317. package/server/src/core/cid.js +6 -71
  318. package/server/src/core/cidTopic.js +29 -0
  319. package/server/src/core/mostLink.js +88 -0
  320. package/server/src/http/access.js +123 -0
  321. package/server/src/http/app.js +1095 -0
  322. package/server/src/http/errors.js +35 -0
  323. package/server/src/http/nodeLogs.js +53 -0
  324. package/server/src/http/nodeStatus.js +146 -0
  325. package/server/src/http/staticFiles.js +84 -0
  326. package/server/src/http/uploads.js +114 -0
  327. package/server/src/index.js +1539 -301
  328. package/server/src/node/config.js +191 -0
  329. package/server/src/node/logs.js +94 -0
  330. package/server/src/utils/api.js +359 -8
  331. package/server/src/utils/auth.js +63 -0
  332. package/server/src/utils/dateTime.js +30 -0
  333. package/server/src/utils/downloadMessages.js +89 -0
  334. package/server/src/utils/errors.js +14 -0
  335. package/server/src/utils/mostWallet.js +185 -1
  336. package/server/src/utils/mp.js +2 -26
  337. package/server/src/utils/noteBackup.js +116 -0
  338. package/server/src/utils/noteUtils.js +128 -0
  339. package/server/src/utils/userIdentity.js +8 -61
  340. package/out/_next/static/chunks/003jnm.v5tzw5.js +0 -1
  341. package/out/_next/static/chunks/00re8v.gbcywn.js +0 -1
  342. package/out/_next/static/chunks/00s106sbq8t9v.js +0 -1
  343. package/out/_next/static/chunks/012hi627qrdnn.js +0 -1
  344. package/out/_next/static/chunks/0174xh3wfsjm1.js +0 -2
  345. package/out/_next/static/chunks/02~o2nmo5pmy1.js +0 -1
  346. package/out/_next/static/chunks/07t.dhhokszz5.css +0 -1
  347. package/out/_next/static/chunks/0_wia9ofmsi1c.css +0 -2
  348. package/out/_next/static/chunks/0ah8fihozo2_u.js +0 -5
  349. package/out/_next/static/chunks/0bzupvr5gt3k9.js +0 -31
  350. package/out/_next/static/chunks/0e_h0d3ekzks8.css +0 -1
  351. package/out/_next/static/chunks/0gdluj423gso1.js +0 -1
  352. package/out/_next/static/chunks/0gmoiq06srjay.css +0 -1
  353. package/out/_next/static/chunks/0imkasy7kb67u.js +0 -1
  354. package/out/_next/static/chunks/0jjc_b9q_ldi2.js +0 -1
  355. package/out/_next/static/chunks/0jl~j62iz2uvr.js +0 -1
  356. package/out/_next/static/chunks/0lqslm813wk_h.js +0 -1
  357. package/out/_next/static/chunks/0q782fxxd0lx~.js +0 -1
  358. package/out/_next/static/chunks/0slwj0c46k5cu.js +0 -1
  359. package/out/_next/static/chunks/0sorqk.oc6b7j.css +0 -1
  360. package/out/_next/static/chunks/0tapzqc6hgvx-.js +0 -1
  361. package/out/_next/static/chunks/0xsc7z5x8n7wg.js +0 -1
  362. package/out/_next/static/chunks/0zm~gys2jwl0g.js +0 -1
  363. package/out/_next/static/chunks/turbopack-0a_g3u0ud~jb8.js +0 -1
  364. package/out/changelog/__next._full.txt +0 -22
  365. package/out/changelog/__next._index.txt +0 -7
  366. package/out/changelog/__next._tree.txt +0 -3
  367. package/out/changelog/__next.changelog.__PAGE__.txt +0 -10
  368. package/out/changelog/__next.changelog.txt +0 -5
  369. package/out/changelog/index.html +0 -15
  370. package/out/changelog/index.txt +0 -22
  371. package/out/docs/__next._full.txt +0 -22
  372. package/out/docs/__next._head.txt +0 -5
  373. package/out/docs/__next._index.txt +0 -7
  374. package/out/docs/__next._tree.txt +0 -3
  375. package/out/docs/__next.docs.__PAGE__.txt +0 -10
  376. package/out/docs/__next.docs.txt +0 -5
  377. package/out/docs/getting-started/__next._full.txt +0 -22
  378. package/out/docs/getting-started/__next._head.txt +0 -5
  379. package/out/docs/getting-started/__next._index.txt +0 -7
  380. package/out/docs/getting-started/__next._tree.txt +0 -3
  381. package/out/docs/getting-started/__next.docs.getting-started.__PAGE__.txt +0 -10
  382. package/out/docs/getting-started/__next.docs.getting-started.txt +0 -5
  383. package/out/docs/getting-started/__next.docs.txt +0 -5
  384. package/out/docs/getting-started/index.html +0 -15
  385. package/out/docs/getting-started/index.txt +0 -22
  386. package/out/docs/index.html +0 -15
  387. package/out/docs/index.txt +0 -22
  388. /package/out/_next/static/{iOB2EBwOGZ0iYW7Lbg9u_ → t7ZIeQpVvjz4a7-5Tt-VK}/_buildManifest.js +0 -0
  389. /package/out/_next/static/{iOB2EBwOGZ0iYW7Lbg9u_ → t7ZIeQpVvjz4a7-5Tt-VK}/_clientMiddlewareManifest.js +0 -0
  390. /package/out/_next/static/{iOB2EBwOGZ0iYW7Lbg9u_ → t7ZIeQpVvjz4a7-5Tt-VK}/_ssgManifest.js +0 -0
@@ -0,0 +1,191 @@
1
+ import fs from 'node:fs'
2
+ import os from 'node:os'
3
+ import path from 'node:path'
4
+ import { MAX_FILE_SIZE } from '../config.js'
5
+
6
+ const DEFAULT_CONFIG_DIR_NAME = '.most-box'
7
+ const DEFAULT_DATA_DIR_NAME = 'most-data'
8
+ const DEFAULT_CAPACITY_BYTES = 100 * 1024 * 1024 * 1024
9
+ export const DEFAULT_NODE_PORT = 1976
10
+ export const DEFAULT_NODE_HOST = '127.0.0.1'
11
+
12
+ export function getDefaultConfigDir() {
13
+ return path.join(os.homedir(), DEFAULT_CONFIG_DIR_NAME)
14
+ }
15
+
16
+ export function getDefaultDataPath() {
17
+ return path.join(os.homedir(), DEFAULT_DATA_DIR_NAME)
18
+ }
19
+
20
+ export function getDefaultNodeConfig() {
21
+ return {
22
+ dataPath: '',
23
+ host: DEFAULT_NODE_HOST,
24
+ port: DEFAULT_NODE_PORT,
25
+ capacityBytes: DEFAULT_CAPACITY_BYTES,
26
+ maxFileSizeBytes: MAX_FILE_SIZE,
27
+ remoteInvites: [],
28
+ }
29
+ }
30
+
31
+ export function normalizeRemoteInvites(value = []) {
32
+ const items = Array.isArray(value) ? value : String(value || '').split(',')
33
+ return Array.from(
34
+ new Set(items.map(item => String(item || '').trim()).filter(Boolean))
35
+ )
36
+ }
37
+
38
+ export function normalizeNodeConfig(raw = {}) {
39
+ const defaults = getDefaultNodeConfig()
40
+ const rawNode = raw.node && typeof raw.node === 'object' ? raw.node : {}
41
+
42
+ const capacityBytes = normalizePositiveInteger(
43
+ rawNode.capacityBytes ?? raw.capacityBytes,
44
+ defaults.capacityBytes
45
+ )
46
+ const maxFileSizeBytes = normalizePositiveInteger(
47
+ rawNode.maxFileSizeBytes ?? raw.maxFileSizeBytes,
48
+ defaults.maxFileSizeBytes
49
+ )
50
+ const remoteInvites = normalizeRemoteInvites(
51
+ rawNode.remoteInvites ?? raw.remoteInvites ?? defaults.remoteInvites
52
+ )
53
+ const host = normalizeHost(rawNode.host ?? raw.host, defaults.host)
54
+ const port = normalizePositiveInteger(
55
+ rawNode.port ?? raw.port,
56
+ defaults.port
57
+ )
58
+ return {
59
+ dataPath:
60
+ typeof raw.dataPath === 'string'
61
+ ? raw.dataPath.trim()
62
+ : defaults.dataPath,
63
+ host,
64
+ port,
65
+ capacityBytes,
66
+ maxFileSizeBytes,
67
+ remoteInvites,
68
+ }
69
+ }
70
+
71
+ export function createNodeConfigStore(configDir = getDefaultConfigDir()) {
72
+ const resolvedConfigDir = path.resolve(configDir)
73
+ const configFile = path.join(resolvedConfigDir, 'config.json')
74
+
75
+ function loadRawConfig() {
76
+ try {
77
+ if (fs.existsSync(configFile)) {
78
+ return JSON.parse(fs.readFileSync(configFile, 'utf-8'))
79
+ }
80
+ } catch (err) {
81
+ console.error('[Config] Load error:', err.message)
82
+ }
83
+ return {}
84
+ }
85
+
86
+ function saveRawConfig(config) {
87
+ try {
88
+ if (!fs.existsSync(resolvedConfigDir)) {
89
+ fs.mkdirSync(resolvedConfigDir, { recursive: true })
90
+ }
91
+ const tmpPath = configFile + '.tmp'
92
+ fs.writeFileSync(tmpPath, JSON.stringify(config, null, 2), 'utf-8')
93
+ fs.renameSync(tmpPath, configFile)
94
+ return true
95
+ } catch (err) {
96
+ console.error('[Config] Save error:', err.message)
97
+ return false
98
+ }
99
+ }
100
+
101
+ function getNodeConfig() {
102
+ return normalizeNodeConfig(loadRawConfig())
103
+ }
104
+
105
+ function getDataPath() {
106
+ return getNodeConfig().dataPath || getDefaultDataPath()
107
+ }
108
+
109
+ function saveNodeConfigPatch(patch = {}) {
110
+ const raw = loadRawConfig()
111
+ const current = normalizeNodeConfig(raw)
112
+ const next = normalizeNodeConfig({
113
+ ...raw,
114
+ dataPath:
115
+ patch.dataPath === undefined ? current.dataPath : patch.dataPath,
116
+ node: {
117
+ ...(raw.node && typeof raw.node === 'object' ? raw.node : {}),
118
+ host: patch.host === undefined ? current.host : patch.host,
119
+ port: patch.port === undefined ? current.port : patch.port,
120
+ capacityBytes:
121
+ patch.capacityBytes === undefined
122
+ ? current.capacityBytes
123
+ : patch.capacityBytes,
124
+ maxFileSizeBytes:
125
+ patch.maxFileSizeBytes === undefined
126
+ ? current.maxFileSizeBytes
127
+ : patch.maxFileSizeBytes,
128
+ remoteInvites:
129
+ patch.remoteInvites === undefined
130
+ ? current.remoteInvites
131
+ : patch.remoteInvites,
132
+ },
133
+ })
134
+
135
+ const saved = {
136
+ dataPath: next.dataPath,
137
+ node: {
138
+ host: next.host,
139
+ port: next.port,
140
+ capacityBytes: next.capacityBytes,
141
+ maxFileSizeBytes: next.maxFileSizeBytes,
142
+ remoteInvites: next.remoteInvites,
143
+ updatedAt: new Date().toISOString(),
144
+ },
145
+ }
146
+
147
+ return { success: saveRawConfig(saved), config: normalizeNodeConfig(saved) }
148
+ }
149
+
150
+ return {
151
+ configDir: resolvedConfigDir,
152
+ configFile,
153
+ loadRawConfig,
154
+ saveRawConfig,
155
+ getNodeConfig,
156
+ getDataPath,
157
+ saveNodeConfigPatch,
158
+ }
159
+ }
160
+
161
+ export function evaluateStorageLimits(config, input = {}) {
162
+ const size = Number(input.size ?? input.fileSize ?? 0)
163
+ const reasons = []
164
+
165
+ if (!Number.isFinite(size) || size < 0) {
166
+ reasons.push('invalid-size')
167
+ } else if (size > config.maxFileSizeBytes) {
168
+ reasons.push('file-too-large')
169
+ } else if (size > config.capacityBytes) {
170
+ reasons.push('capacity-too-small')
171
+ }
172
+
173
+ return {
174
+ accepted: reasons.length === 0,
175
+ reasons,
176
+ policy: config,
177
+ }
178
+ }
179
+
180
+ function normalizePositiveInteger(value, fallback) {
181
+ const parsed = Number(value)
182
+ if (!Number.isFinite(parsed) || parsed < 0) {
183
+ return fallback
184
+ }
185
+ return Math.floor(parsed)
186
+ }
187
+
188
+ function normalizeHost(value, fallback) {
189
+ const host = String(value || '').trim()
190
+ return host || fallback
191
+ }
@@ -0,0 +1,94 @@
1
+ import fs from 'node:fs'
2
+ import path from 'node:path'
3
+
4
+ const DEFAULT_MAX_LOG_LINES = 1000
5
+
6
+ export function createNodeLogger(configDir, options = {}) {
7
+ const maxLines = options.maxLines || DEFAULT_MAX_LOG_LINES
8
+ const logFile = options.logFile || path.join(configDir, 'node-events.log')
9
+
10
+ function append(input = {}) {
11
+ const entry = {
12
+ id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
13
+ ts: new Date().toISOString(),
14
+ level: input.level || 'info',
15
+ event: input.event || 'node:event',
16
+ message: input.message || input.event || 'Node event',
17
+ data: input.data || {},
18
+ }
19
+
20
+ try {
21
+ const logDir = path.dirname(logFile)
22
+ if (!fs.existsSync(logDir)) {
23
+ fs.mkdirSync(logDir, { recursive: true })
24
+ }
25
+ fs.appendFileSync(logFile, `${JSON.stringify(entry)}\n`, 'utf-8')
26
+ trimLogFile()
27
+ } catch (err) {
28
+ console.warn('[NodeLog] Failed to append:', err.message)
29
+ }
30
+
31
+ return entry
32
+ }
33
+
34
+ function list(limit = 100) {
35
+ try {
36
+ if (!fs.existsSync(logFile)) return []
37
+ const lines = fs
38
+ .readFileSync(logFile, 'utf-8')
39
+ .split('\n')
40
+ .filter(Boolean)
41
+ return lines
42
+ .slice(-Math.max(1, Math.min(Number(limit) || 100, maxLines)))
43
+ .map(line => {
44
+ try {
45
+ return JSON.parse(line)
46
+ } catch {
47
+ return null
48
+ }
49
+ })
50
+ .filter(Boolean)
51
+ .reverse()
52
+ } catch (err) {
53
+ console.warn('[NodeLog] Failed to read:', err.message)
54
+ return []
55
+ }
56
+ }
57
+
58
+ function clear() {
59
+ try {
60
+ const logDir = path.dirname(logFile)
61
+ if (!fs.existsSync(logDir)) {
62
+ fs.mkdirSync(logDir, { recursive: true })
63
+ }
64
+ fs.writeFileSync(logFile, '', 'utf-8')
65
+ return true
66
+ } catch (err) {
67
+ console.warn('[NodeLog] Failed to clear:', err.message)
68
+ return false
69
+ }
70
+ }
71
+
72
+ function trimLogFile() {
73
+ try {
74
+ if (!fs.existsSync(logFile)) return
75
+ const lines = fs
76
+ .readFileSync(logFile, 'utf-8')
77
+ .split('\n')
78
+ .filter(Boolean)
79
+ if (lines.length <= maxLines) return
80
+ fs.writeFileSync(
81
+ logFile,
82
+ `${lines.slice(-maxLines).join('\n')}\n`,
83
+ 'utf-8'
84
+ )
85
+ } catch {}
86
+ }
87
+
88
+ return {
89
+ logFile,
90
+ append,
91
+ list,
92
+ clear,
93
+ }
94
+ }
@@ -1,23 +1,189 @@
1
1
  import ky from 'ky'
2
+ import { buildAuthHeaders, normalizeAuthPath } from './auth.js'
2
3
 
3
4
  const STORAGE_KEY = 'mostbox_backend_url'
5
+ const INVITE_STORAGE_KEY = 'mostbox_backend_invite'
6
+ const LOCALHOST_BACKEND_URL = 'http://localhost:1976'
7
+
8
+ function isLocalFrontendOrigin() {
9
+ if (typeof window === 'undefined') return false
10
+
11
+ return ['localhost', '127.0.0.1'].includes(window.location.hostname)
12
+ }
13
+
14
+ function getDefaultBackendUrl() {
15
+ return isLocalFrontendOrigin() ? LOCALHOST_BACKEND_URL : ''
16
+ }
4
17
 
5
18
  function getBackendUrl() {
19
+ if (typeof window === 'undefined') return ''
20
+ return localStorage.getItem(STORAGE_KEY) || getDefaultBackendUrl()
21
+ }
22
+
23
+ function getConfiguredBackendUrl() {
6
24
  if (typeof window === 'undefined') return ''
7
25
  return localStorage.getItem(STORAGE_KEY) || ''
8
26
  }
9
27
 
28
+ function getRemoteBackendUrl() {
29
+ const configured = getConfiguredBackendUrl()
30
+ if (!configured) return ''
31
+ try {
32
+ const { hostname } = new URL(configured)
33
+ return ['localhost', '127.0.0.1', '::1'].includes(hostname)
34
+ ? ''
35
+ : configured
36
+ } catch {
37
+ return configured
38
+ }
39
+ }
40
+
41
+ function getBackendInvite() {
42
+ if (typeof window === 'undefined') return ''
43
+ return localStorage.getItem(INVITE_STORAGE_KEY) || ''
44
+ }
45
+
46
+ function normalizeBackendUrl(url) {
47
+ return (url || '').trim().replace(/\/+$/, '')
48
+ }
49
+
50
+ function isLocalBackendUrl(url) {
51
+ const value = normalizeBackendUrl(url)
52
+ if (!value) return false
53
+ try {
54
+ const { hostname } = new URL(value)
55
+ const normalized = hostname.toLowerCase()
56
+ return (
57
+ normalized === 'localhost' ||
58
+ normalized === '::1' ||
59
+ normalized === '[::1]' ||
60
+ normalized === '127.0.0.1' ||
61
+ normalized.startsWith('127.')
62
+ )
63
+ } catch {
64
+ return false
65
+ }
66
+ }
67
+
68
+ function shouldAttachBackendInvite(url = getBackendUrl()) {
69
+ return Boolean(getBackendInvite()) && !isLocalBackendUrl(url)
70
+ }
71
+
72
+ function getStoredIdentity() {
73
+ if (typeof window === 'undefined') return null
74
+ try {
75
+ const raw = localStorage.getItem('mostbox_identity')
76
+ return raw ? JSON.parse(raw) : null
77
+ } catch {
78
+ return null
79
+ }
80
+ }
81
+
82
+ function normalizePath(path) {
83
+ return path.startsWith('/') ? path : `/${path}`
84
+ }
85
+
86
+ function buildWebSocketUrl(base, wsPath = '/ws') {
87
+ const url = new URL(base)
88
+ const wsProtocol = url.protocol === 'https:' ? 'wss:' : 'ws:'
89
+ const basePath = url.pathname.replace(/\/+$/, '')
90
+ return `${wsProtocol}//${url.host}${basePath}${normalizePath(wsPath)}`
91
+ }
92
+
10
93
  function createApiInstance() {
11
- const url = getBackendUrl()
12
- return ky.create({
13
- prefix: url,
94
+ const client = ky.create({
95
+ hooks: {
96
+ beforeRequest: [
97
+ async ({ request }) => {
98
+ const headers = new Headers(request.headers || {})
99
+ const invite = getBackendInvite()
100
+ if (invite && shouldAttachBackendInvite(request.url)) {
101
+ headers.set('x-mostbox-invite', invite)
102
+ }
103
+
104
+ const identity = getStoredIdentity()
105
+ if (identity?.danger) {
106
+ try {
107
+ const authHeaders = await buildAuthHeaders(
108
+ identity,
109
+ request.method,
110
+ normalizeAuthPath(request.url)
111
+ )
112
+ for (const [key, value] of Object.entries(authHeaders)) {
113
+ headers.set(key, value)
114
+ }
115
+ } catch {
116
+ // Ignore invalid legacy identity data for public/backend probes.
117
+ }
118
+ }
119
+ return new Request(request, { headers })
120
+ },
121
+ ],
122
+ },
123
+ })
124
+
125
+ return new Proxy(client, {
126
+ get(target, prop, receiver) {
127
+ const value = Reflect.get(target, prop, receiver)
128
+ if (!['get', 'post', 'put', 'patch', 'delete', 'head'].includes(prop)) {
129
+ return value
130
+ }
131
+ return (input, options) => {
132
+ const nextInput = typeof input === 'string' ? getApiUrl(input) : input
133
+ return value.call(target, nextInput, options)
134
+ }
135
+ },
14
136
  })
15
137
  }
16
138
 
17
139
  export let api = createApiInstance()
18
140
 
141
+ export async function getApiErrorPayload(err) {
142
+ const response =
143
+ err && typeof err === 'object' && 'response' in err
144
+ ? err.response
145
+ : err instanceof Response
146
+ ? err
147
+ : null
148
+
149
+ if (!response) return {}
150
+
151
+ const data = response.bodyUsed
152
+ ? null
153
+ : await response
154
+ .clone()
155
+ .json()
156
+ .catch(() => null)
157
+
158
+ return {
159
+ status: response.status,
160
+ code: typeof data?.code === 'string' ? data.code : undefined,
161
+ error:
162
+ typeof data?.error === 'string'
163
+ ? data.error
164
+ : typeof data?.message === 'string'
165
+ ? data.message
166
+ : undefined,
167
+ }
168
+ }
169
+
170
+ export async function getApiErrorMessage(err, fallback = '请求失败') {
171
+ const data = await getApiErrorPayload(err)
172
+ if (data.error) return data.error
173
+
174
+ const errorName =
175
+ err && typeof err === 'object' && 'name' in err ? String(err.name) : ''
176
+ if (errorName === 'TimeoutError') return '请求超时,请稍后重试'
177
+
178
+ if (err instanceof Error && err.message) {
179
+ return err.message
180
+ }
181
+
182
+ return fallback
183
+ }
184
+
19
185
  export function setBackendUrl(url) {
20
- const cleaned = (url || '').trim().replace(/\/+$/, '')
186
+ const cleaned = normalizeBackendUrl(url)
21
187
  if (cleaned) {
22
188
  localStorage.setItem(STORAGE_KEY, cleaned)
23
189
  } else {
@@ -26,24 +192,209 @@ export function setBackendUrl(url) {
26
192
  api = createApiInstance()
27
193
  }
28
194
 
195
+ export function setBackendInvite(invite) {
196
+ const cleaned = (invite || '').trim()
197
+ if (cleaned) {
198
+ localStorage.setItem(INVITE_STORAGE_KEY, cleaned)
199
+ } else {
200
+ localStorage.removeItem(INVITE_STORAGE_KEY)
201
+ }
202
+ api = createApiInstance()
203
+ }
204
+
205
+ export function configureBackend({ url, invite }) {
206
+ setBackendUrl(url)
207
+ setBackendInvite(invite)
208
+ }
209
+
210
+ export function clearBackendConnection() {
211
+ setBackendUrl('')
212
+ setBackendInvite('')
213
+ }
214
+
29
215
  export function getBackendUrlExport() {
30
216
  return getBackendUrl()
31
217
  }
32
218
 
219
+ export function getRemoteBackendUrlExport() {
220
+ return getRemoteBackendUrl()
221
+ }
222
+
223
+ export function getBackendInviteExport() {
224
+ return getBackendInvite()
225
+ }
226
+
227
+ export function getApiUrl(path) {
228
+ const url = getBackendUrl()
229
+ return `${url}${normalizePath(path)}`
230
+ }
231
+
232
+ export async function getApiRequestHeaders(method = 'GET', path = '/') {
233
+ /** @type {Record<string, string>} */
234
+ const headers = {}
235
+ const invite = getBackendInvite()
236
+ if (invite && shouldAttachBackendInvite()) {
237
+ headers['x-mostbox-invite'] = invite
238
+ }
239
+ try {
240
+ Object.assign(
241
+ headers,
242
+ await buildAuthHeaders(
243
+ getStoredIdentity(),
244
+ method,
245
+ normalizeAuthPath(path)
246
+ )
247
+ )
248
+ } catch {
249
+ // Callers that require auth will receive the server's 401 response.
250
+ }
251
+ return headers
252
+ }
253
+
254
+ export function getWebSocketUrl(path = '/ws') {
255
+ if (typeof window === 'undefined') return normalizePath(path)
256
+
257
+ const base = getBackendUrl() || window.location.origin
258
+ return buildWebSocketUrl(base, path)
259
+ }
260
+
261
+ export async function getAuthenticatedWebSocketUrl(path = '/ws') {
262
+ if (typeof window === 'undefined') return normalizePath(path)
263
+
264
+ const base = getBackendUrl() || window.location.origin
265
+ const url = new URL(buildWebSocketUrl(base, path))
266
+
267
+ const invite = getBackendInvite()
268
+ if (invite && shouldAttachBackendInvite(url.toString())) {
269
+ url.searchParams.set('invite', invite)
270
+ }
271
+
272
+ const identity = getStoredIdentity()
273
+ if (identity?.danger) {
274
+ try {
275
+ const auth = await buildAuthHeaders(
276
+ identity,
277
+ 'GET',
278
+ normalizeAuthPath(path)
279
+ )
280
+ const [address, timestamp, signature] = String(
281
+ auth.Authorization || ''
282
+ ).split(',')
283
+ if (address && signature) {
284
+ url.searchParams.set('address', address)
285
+ url.searchParams.set('timestamp', timestamp)
286
+ url.searchParams.set('signature', signature)
287
+ }
288
+ } catch {
289
+ // Leave WebSocket unauthenticated when local identity data is invalid.
290
+ }
291
+ }
292
+
293
+ return url.toString()
294
+ }
295
+
33
296
  export async function checkBackendConnection() {
34
297
  const url = getBackendUrl()
298
+ const invite = shouldAttachBackendInvite(url) ? getBackendInvite() : ''
299
+ return checkBackendConnectionTarget({ url, invite })
300
+ }
301
+
302
+ async function probeHttp(cleanedUrl, invite, identity) {
35
303
  try {
36
- const res = await fetch(`${url}/api/node-id`, {
304
+ const headers = {}
305
+ if (invite) headers['x-mostbox-invite'] = invite
306
+ try {
307
+ Object.assign(
308
+ headers,
309
+ await buildAuthHeaders(identity, 'GET', '/api/remote/capabilities')
310
+ )
311
+ } catch {
312
+ // Backend detection should still work when old identity data is invalid.
313
+ }
314
+ const res = await fetch(`${cleanedUrl}/api/remote/capabilities`, {
37
315
  method: 'GET',
316
+ headers,
38
317
  signal: AbortSignal.timeout(3000),
39
318
  })
40
- return res.ok
319
+ if (!res.ok) return { ok: false, reason: 'http' }
320
+ return { ok: true }
41
321
  } catch {
42
- return false
322
+ return { ok: false, reason: 'http' }
323
+ }
324
+ }
325
+
326
+ async function probeWebSocket(cleanedUrl, invite, identity) {
327
+ if (typeof WebSocket === 'undefined') return { ok: true }
328
+
329
+ try {
330
+ const wsUrl = new URL(buildWebSocketUrl(cleanedUrl))
331
+
332
+ if (invite) {
333
+ wsUrl.searchParams.set('invite', invite)
334
+ }
335
+
336
+ if (identity?.danger) {
337
+ try {
338
+ const auth = await buildAuthHeaders(
339
+ identity,
340
+ 'GET',
341
+ normalizeAuthPath('/ws')
342
+ )
343
+ const [address, timestamp, signature] = String(
344
+ auth.Authorization || ''
345
+ ).split(',')
346
+ if (address && signature) {
347
+ wsUrl.searchParams.set('address', address)
348
+ wsUrl.searchParams.set('timestamp', timestamp)
349
+ wsUrl.searchParams.set('signature', signature)
350
+ }
351
+ } catch {
352
+ // Leave WebSocket unauthenticated when local identity data is invalid.
353
+ }
354
+ }
355
+
356
+ return await new Promise(resolve => {
357
+ const ws = new WebSocket(wsUrl.toString())
358
+ const timeout = setTimeout(() => {
359
+ ws.close()
360
+ resolve({ ok: false, reason: 'ws' })
361
+ }, 4000)
362
+
363
+ ws.onopen = () => {
364
+ clearTimeout(timeout)
365
+ ws.close()
366
+ resolve({ ok: true })
367
+ }
368
+
369
+ ws.onerror = () => {
370
+ clearTimeout(timeout)
371
+ resolve({ ok: false, reason: 'ws' })
372
+ }
373
+ })
374
+ } catch {
375
+ return { ok: false, reason: 'ws' }
43
376
  }
44
377
  }
45
378
 
379
+ export async function checkBackendConnectionTarget({ url, invite = '' }) {
380
+ const cleanedUrl = normalizeBackendUrl(url)
381
+ if (!cleanedUrl) return { ok: false, reason: 'http' }
382
+
383
+ const identity = getStoredIdentity()
384
+
385
+ const [httpResult, wsResult] = await Promise.all([
386
+ probeHttp(cleanedUrl, invite, identity),
387
+ probeWebSocket(cleanedUrl, invite, identity),
388
+ ])
389
+
390
+ if (!httpResult.ok) return httpResult
391
+ if (!wsResult.ok) return wsResult
392
+ return { ok: true }
393
+ }
394
+
46
395
  export async function detectSameOriginBackend() {
396
+ if (isLocalFrontendOrigin()) return false
397
+
47
398
  try {
48
399
  const res = await fetch('/api/node-id', {
49
400
  method: 'GET',
@@ -57,7 +408,7 @@ export async function detectSameOriginBackend() {
57
408
 
58
409
  export async function detectLocalhostBackend() {
59
410
  try {
60
- const res = await fetch('http://localhost:1976/api/node-id', {
411
+ const res = await fetch(`${LOCALHOST_BACKEND_URL}/api/node-id`, {
61
412
  method: 'GET',
62
413
  signal: AbortSignal.timeout(2000),
63
414
  })