hfs 3.2.1 → 3.3.0-alpha1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/admin/assets/{af-U8Sl5sCM.js → af-CevhRske.js} +1 -1
- package/admin/assets/{am-n9TdXja0.js → am-4ouVTwuo.js} +1 -1
- package/admin/assets/{ar-CUpxfuw5.js → ar-71cK8dbb.js} +1 -1
- package/admin/assets/{ar-dz-DC58Z9cj.js → ar-dz-CO7oh1gG.js} +1 -1
- package/admin/assets/{ar-iq-BDkrto6W.js → ar-iq-CjG6db8J.js} +1 -1
- package/admin/assets/{ar-kw-Bz806GvG.js → ar-kw-DMsdR225.js} +1 -1
- package/admin/assets/{ar-ly-DW7JaKir.js → ar-ly-ZhxIwUOA.js} +1 -1
- package/admin/assets/{ar-ma-BuveKbkq.js → ar-ma-Bo3Z1RyK.js} +1 -1
- package/admin/assets/{ar-sa-DRvob1Jp.js → ar-sa-Db44biae.js} +1 -1
- package/admin/assets/{ar-tn-Cae7pfui.js → ar-tn-DNWRixE0.js} +1 -1
- package/admin/assets/{az-B7PpjwCU.js → az-B6LcmVzB.js} +1 -1
- package/admin/assets/{be-DSy_sPdD.js → be-Dp0KhO5x.js} +1 -1
- package/admin/assets/{bg-Djacfatx.js → bg-TsOJJvBm.js} +1 -1
- package/admin/assets/{bi-DOLGYGEN.js → bi-DstczOGo.js} +1 -1
- package/admin/assets/{bm-BmR133he.js → bm-Bf09NN15.js} +1 -1
- package/admin/assets/{bn-DsjLUmm3.js → bn-Da3tHLgx.js} +1 -1
- package/admin/assets/{bn-bd-C3SafRtu.js → bn-bd-CeSalisC.js} +1 -1
- package/admin/assets/{bo-DsMRUw9A.js → bo-Ctxe0IKQ.js} +1 -1
- package/admin/assets/{br-BxR8Zm95.js → br-Y3dPq3Tj.js} +1 -1
- package/admin/assets/{bs-gH68uvCb.js → bs-BbAlSeZx.js} +1 -1
- package/admin/assets/{ca-DfGL180b.js → ca-8-Nn97gi.js} +1 -1
- package/admin/assets/{cs-D4lFVAq6.js → cs-BD5ArFNW.js} +1 -1
- package/admin/assets/{cv-CFyqoRN7.js → cv-CdMFVXGr.js} +1 -1
- package/admin/assets/{cy-DuubtylZ.js → cy-B3QEYlIT.js} +1 -1
- package/admin/assets/{da-Cp7c-T-B.js → da-Bju2YQ9G.js} +1 -1
- package/admin/assets/{de-CeQXU72n.js → de-DdzCTquR.js} +1 -1
- package/admin/assets/{de-at-Cx01BLTk.js → de-at-DgyKCkPl.js} +1 -1
- package/admin/assets/{de-ch-K5Vn_bWQ.js → de-ch-Dk9qkzvn.js} +1 -1
- package/admin/assets/{dist-CfPsVFTp.js → dist-KY_8edrw.js} +1 -1
- package/admin/assets/{dv-DB4pdLQj.js → dv-C5KWK8o4.js} +1 -1
- package/admin/assets/{el-CNA5lg_z.js → el-BDL_lPlM.js} +1 -1
- package/admin/assets/{en-Bpua-Wb5.js → en-Ds3H1Wec.js} +1 -1
- package/admin/assets/{en-au-CKwJ7DKC.js → en-au-CgltfNUb.js} +1 -1
- package/admin/assets/{en-ca-D8vKBgWW.js → en-ca-DEsKzbWO.js} +1 -1
- package/admin/assets/{en-in-Bhx4y1uu.js → en-gb-21AYC3Ik.js} +1 -1
- package/admin/assets/{en-ie-0gd4plad.js → en-ie-aN3g-yqK.js} +1 -1
- package/admin/assets/{en-il-BYIz25Pw.js → en-il-CZl2d7NK.js} +1 -1
- package/admin/assets/{en-tt-Bk-if7Re.js → en-in-C7Kv4c3w.js} +1 -1
- package/admin/assets/{en-nz-CtIJOjgh.js → en-nz-DA_sIaGR.js} +1 -1
- package/admin/assets/{en-sg-iygWx8GW.js → en-sg-CP5PJpZf.js} +1 -1
- package/admin/assets/{en-gb-C3jRv20Y.js → en-tt-B5vDLhL7.js} +1 -1
- package/admin/assets/{eo-DAvER5ej.js → eo-VE1KDD1u.js} +1 -1
- package/admin/assets/{es-C98a0Ggy.js → es-SUzi5oTU.js} +1 -1
- package/admin/assets/{es-do-TCakoZXN.js → es-do-Iri0eWm8.js} +1 -1
- package/admin/assets/{es-mx-BCj7c6Zn.js → es-mx-DwneKeOc.js} +1 -1
- package/admin/assets/{es-pr-rsR3Q8oM.js → es-pr-C4zPUdA1.js} +1 -1
- package/admin/assets/{es-us-DC9NM1XV.js → es-us-BPS67etc.js} +1 -1
- package/admin/assets/{esm-BQaMpob3.js → esm-CyNQ7bBW.js} +1 -1
- package/admin/assets/{et-tJ-d1AZX.js → et-Ciqbfae0.js} +1 -1
- package/admin/assets/{eu-xzUajtaj.js → eu-CGhOwQpe.js} +1 -1
- package/admin/assets/{fa-kR15gQkC.js → fa-BWZiAv_E.js} +1 -1
- package/admin/assets/{fi-DQjRBOgG.js → fi-DJmgkVsJ.js} +1 -1
- package/admin/assets/{fo-BHMXHU45.js → fo-DVez5N-g.js} +1 -1
- package/admin/assets/{fr-DGS71Nvo.js → fr-D206itJo.js} +1 -1
- package/admin/assets/{fr-ca-Bkzyy0tT.js → fr-ca-C6JiEHfi.js} +1 -1
- package/admin/assets/{fr-ch-BRrWrRWV.js → fr-ch-DUTEuSU_.js} +1 -1
- package/admin/assets/{fy-Dkv180q7.js → fy-C_r06zH-.js} +1 -1
- package/admin/assets/{ga-xsoXuVDY.js → ga-CrdQqAN5.js} +1 -1
- package/admin/assets/{gd-cLPVqYdG.js → gd-iWHfhKAH.js} +1 -1
- package/admin/assets/{gl-BUG0DHTt.js → gl-zgfy-pQ0.js} +1 -1
- package/admin/assets/{gom-latn-BKRncAa1.js → gom-latn-CMZ7Vj7V.js} +1 -1
- package/admin/assets/{gu-BpmXErqK.js → gu-DNqIMjZc.js} +1 -1
- package/admin/assets/{he-DNxd9A8z.js → he-OJBbYFzL.js} +1 -1
- package/admin/assets/{hi-dNFE6t75.js → hi-ByrMhKpX.js} +1 -1
- package/admin/assets/{hr-DNZiZtn4.js → hr-CfRZXzCu.js} +1 -1
- package/admin/assets/{ht-B1LoCeln.js → ht-DDrMtLzJ.js} +1 -1
- package/admin/assets/{hu-q6SYps3j.js → hu-Ckeq3R6_.js} +1 -1
- package/admin/assets/{hy-am-BLa2HL3i.js → hy-am-OpZy7Nvg.js} +1 -1
- package/admin/assets/{id-4zvXdXSK.js → id-BE8-Ys79.js} +1 -1
- package/admin/assets/{index-D2UH6ajh.js → index-34fRsXFH.js} +128 -123
- package/admin/assets/{is-B7wmPDNy.js → is-BOxJcH5N.js} +1 -1
- package/admin/assets/{it-CGm31WTp.js → it-BFlrIXvP.js} +1 -1
- package/admin/assets/{it-ch-HfVNoF64.js → it-ch-ILAp-lZZ.js} +1 -1
- package/admin/assets/{ja-RGFi1Jc2.js → ja-CbbYAYyn.js} +1 -1
- package/admin/assets/{jv-BclbE5yu.js → jv-CuLkRQCH.js} +1 -1
- package/admin/assets/{ka-D3ZrxVjT.js → ka-BFeRDN-I.js} +1 -1
- package/admin/assets/{kk-B7aIapNy.js → kk-CMvQxaPk.js} +1 -1
- package/admin/assets/{km-DPwsGner.js → km-BdQbDUNF.js} +1 -1
- package/admin/assets/{kn-CuXmm_DG.js → kn-CE5AS6Nx.js} +1 -1
- package/admin/assets/{ko-BlPgy9aF.js → ko-Ctl1mHOt.js} +1 -1
- package/admin/assets/{ku-B6w51rl_.js → ku-Blbo7opr.js} +1 -1
- package/admin/assets/{ky-RLmSGZmf.js → ky-iCha_cZX.js} +1 -1
- package/admin/assets/{lb-AKcfj05J.js → lb-BaP0S6h1.js} +1 -1
- package/admin/assets/{lo-VBKOzJn1.js → lo-B_Q4zUMa.js} +1 -1
- package/admin/assets/{lt-53JaHFcf.js → lt-BOaP1KGX.js} +1 -1
- package/admin/assets/{lv-DGOgmu9w.js → lv-S1XMSUX1.js} +1 -1
- package/admin/assets/{me-zNrvFUXX.js → me-ChOLVJHC.js} +1 -1
- package/admin/assets/{mi-BBDE1uK4.js → mi-CnoIUOGl.js} +1 -1
- package/admin/assets/{mk-2LiSrAS9.js → mk-BoEaxVXE.js} +1 -1
- package/admin/assets/{ml-BEwbrVql.js → ml-BuvmVn6P.js} +1 -1
- package/admin/assets/{mn-LuMGd2Ic.js → mn-2bvGd1HI.js} +1 -1
- package/admin/assets/{mr-C_dFhleR.js → mr-BAoAWQmy.js} +1 -1
- package/admin/assets/{ms-BHnmZJI4.js → ms-C2eT9r-f.js} +1 -1
- package/admin/assets/{ms-my-FcVPbGSE.js → ms-my-D2ZXdcAf.js} +1 -1
- package/admin/assets/{mt-DzhvOV5Z.js → mt-BL5JZC4T.js} +1 -1
- package/admin/assets/{my-Mmp3v0PH.js → my-CuJ4L0Ji.js} +1 -1
- package/admin/assets/{nb-CYPvI8e3.js → nb-CjE6cT80.js} +1 -1
- package/admin/assets/{ne-BtVsV5BN.js → ne-BL9I0cb1.js} +1 -1
- package/admin/assets/{nl-C6aRDFNr.js → nl-Dt3mtMln.js} +1 -1
- package/admin/assets/{nl-be-X-pQSY5N.js → nl-be-Am1mjZK9.js} +1 -1
- package/admin/assets/{nn-C1m9zYBT.js → nn-ChSewyYy.js} +1 -1
- package/admin/assets/{oc-lnc-CFT7xZs-.js → oc-lnc-x6_ChCE9.js} +1 -1
- package/admin/assets/{pa-in-Bby4AmI2.js → pa-in-DVyN8o2P.js} +1 -1
- package/admin/assets/{pl-MmIf2tXf.js → pl-CqcuAUGV.js} +1 -1
- package/admin/assets/{pt-DHCh_z9j.js → pt-B2BPpD7K.js} +1 -1
- package/admin/assets/{pt-br-Cu8EXyIK.js → pt-br-oBVRyUzP.js} +1 -1
- package/admin/assets/{rn-DZUJ5hf0.js → rn-B3e3nkfp.js} +1 -1
- package/admin/assets/{ro-BRHg1GDk.js → ro-C2tWFx0Q.js} +1 -1
- package/admin/assets/{ru-Wv8fMN5W.js → ru-CCsEUnFL.js} +1 -1
- package/admin/assets/{rw-B_XP1EHM.js → rw-CaCkWlGA.js} +1 -1
- package/admin/assets/{sd-_X3CAPlB.js → sd-90Zixcez.js} +1 -1
- package/admin/assets/{se-FItkWaOK.js → se-DaZXpLsK.js} +1 -1
- package/admin/assets/{sha512-UQMP5wnF.js → sha512-DlGRFb_l.js} +1 -1
- package/admin/assets/{si-DhVYEiDt.js → si-CSoBAkgi.js} +1 -1
- package/admin/assets/{sk-cWZR9gF4.js → sk-pgQaqa2z.js} +1 -1
- package/admin/assets/{sl-CJckZkV8.js → sl-Cr5kSdA7.js} +1 -1
- package/admin/assets/{sq-B7eoM8fS.js → sq-Pxi2MZOP.js} +1 -1
- package/admin/assets/{sr-SfiQA7kg.js → sr-Fdc9-lC-.js} +1 -1
- package/admin/assets/{sr-cyrl-Db8Rrl0U.js → sr-cyrl-06jNWqpg.js} +1 -1
- package/admin/assets/{ss-Bian2WDB.js → ss-BjEzSMit.js} +1 -1
- package/admin/assets/{sv-D-Dsf8uN.js → sv-CqWqUpcA.js} +1 -1
- package/admin/assets/{sv-fi-BBv1GPVJ.js → sv-fi-CsO2xQHd.js} +1 -1
- package/admin/assets/{sw-BIzZvuq6.js → sw-xQUdgYhn.js} +1 -1
- package/admin/assets/{ta-C2JoHqar.js → ta-epbFrZ1M.js} +1 -1
- package/admin/assets/{te-ByKFS-hT.js → te-DusTwU6q.js} +1 -1
- package/admin/assets/{tet-Bq9OQkFH.js → tet-ylc9v4gl.js} +1 -1
- package/admin/assets/{tg-BPqYCigR.js → tg-2QfVTAJf.js} +1 -1
- package/admin/assets/{th-m4ghaYsj.js → th-QIm0Mh7I.js} +1 -1
- package/admin/assets/{tk-CFxWTO9D.js → tk-140KMZeW.js} +1 -1
- package/admin/assets/{tl-ph-BiBY15io.js → tl-ph-S7IZkbx3.js} +1 -1
- package/admin/assets/{tlh-CyBfXfLa.js → tlh-C2fYb34-.js} +1 -1
- package/admin/assets/{tr-69QiF4Yn.js → tr-Be-IM6i4.js} +1 -1
- package/admin/assets/{tzl-BG9jvswA.js → tzl-DMy30zde.js} +1 -1
- package/admin/assets/{tzm-IJGtGn0k.js → tzm-Cu882cHO.js} +1 -1
- package/admin/assets/{tzm-latn-CAelnev_.js → tzm-latn-BYxpYHet.js} +1 -1
- package/admin/assets/{ug-cn-CKlXJ1Cr.js → ug-cn-Cl8Jqk2E.js} +1 -1
- package/admin/assets/{uk-DazXNZ9b.js → uk-B-8XymtC.js} +1 -1
- package/admin/assets/{ur-BFAjqt9p.js → ur-ChGuAlvQ.js} +1 -1
- package/admin/assets/{uz-CjoAOeqe.js → uz-QbfaW7fT.js} +1 -1
- package/admin/assets/{uz-latn-CzIzARA0.js → uz-latn-DIQivLCy.js} +1 -1
- package/admin/assets/{vi-DZuOT62g.js → vi-C2CmYlDu.js} +1 -1
- package/admin/assets/{x-pseudo-DlpsSPis.js → x-pseudo-BWgm1XlP.js} +1 -1
- package/admin/assets/{yo-BvI53ejW.js → yo-8bNbPP6u.js} +1 -1
- package/admin/assets/{zh-ci4y7UyJ.js → zh-CeNSRZ4r.js} +1 -1
- package/admin/assets/{zh-cn-CwOh6Lhp.js → zh-cn-BlbF5C_X.js} +1 -1
- package/admin/assets/{zh-hk-CPgMd5VF.js → zh-hk-kg1c_VSK.js} +1 -1
- package/admin/assets/{zh-tw-DJiWMOSA.js → zh-tw-BCl4UsPA.js} +1 -1
- package/admin/index.html +1 -1
- package/frontend/assets/{dist-legacy-CFPnugjA.js → dist-legacy-DYE1EOcc.js} +1 -1
- package/frontend/assets/index-legacy-Br-Lpsst.js +1 -0
- package/frontend/assets/{lib-legacy-CCULxbTk.js → lib-legacy-C4Gw_0kX.js} +1 -1
- package/frontend/assets/{sha512-legacy-D8zcvvqa.js → sha512-legacy-D3RbPSpl.js} +1 -1
- package/frontend/index.html +1 -1
- package/npm-shrinkwrap.json +16 -12
- package/package.json +6 -5
- package/src/AsapStream.js +18 -14
- package/src/SendList.js +42 -16
- package/src/ThrottledStream.js +3 -3
- package/src/acme.js +23 -10
- package/src/adminApis.js +7 -6
- package/src/api.accounts.js +11 -7
- package/src/api.auth.js +8 -5
- package/src/api.cert.js +1 -1
- package/src/api.get_file_list.js +4 -3
- package/src/api.lang.js +3 -2
- package/src/api.monitor.js +1 -1
- package/src/api.net.js +3 -1
- package/src/api.plugins.js +2 -0
- package/src/api.vfs.js +5 -4
- package/src/apiMiddleware.js +5 -1
- package/src/auth.js +4 -1
- package/src/basicWeb.js +1 -1
- package/src/block.js +5 -4
- package/src/commands.js +6 -5
- package/src/comments.js +29 -13
- package/src/config.js +7 -4
- package/src/connections.js +3 -2
- package/src/consoleLog.js +5 -1
- package/src/cross-const.js +27 -1
- package/src/cross.js +32 -33
- package/src/ddns.js +1 -4
- package/src/events.js +1 -4
- package/src/fileAttr.js +6 -2
- package/src/frontEndApis.js +7 -3
- package/src/geo.js +8 -2
- package/src/github.js +10 -9
- package/src/index.js +1 -1
- package/src/ips.js +24 -3
- package/src/langs/embedded.js +2 -1
- package/src/langs/hfs-lang-ar.json +1 -0
- package/src/langs/hfs-lang-bg.json +1 -0
- package/src/langs/hfs-lang-de.json +1 -0
- package/src/langs/hfs-lang-el.json +1 -0
- package/src/langs/hfs-lang-es.json +1 -0
- package/src/langs/hfs-lang-fi.json +1 -0
- package/src/langs/hfs-lang-fr.json +1 -0
- package/src/langs/hfs-lang-hu.json +1 -0
- package/src/langs/hfs-lang-it.json +1 -0
- package/src/langs/hfs-lang-ja.json +1 -0
- package/src/langs/hfs-lang-ko.json +1 -0
- package/src/langs/hfs-lang-lt.json +1 -0
- package/src/langs/hfs-lang-ms.json +1 -0
- package/src/langs/hfs-lang-nl.json +1 -0
- package/src/langs/hfs-lang-pl.json +182 -0
- package/src/langs/hfs-lang-pt-br.json +1 -0
- package/src/langs/hfs-lang-ro.json +1 -0
- package/src/langs/hfs-lang-ru.json +1 -0
- package/src/langs/hfs-lang-sr-latn.json +1 -0
- package/src/langs/hfs-lang-sr.json +1 -0
- package/src/langs/hfs-lang-th.json +1 -0
- package/src/langs/hfs-lang-tr.json +1 -0
- package/src/langs/hfs-lang-uk.json +1 -0
- package/src/langs/hfs-lang-vi.json +1 -0
- package/src/langs/hfs-lang-zh-tw.json +1 -0
- package/src/langs/hfs-lang-zh.json +1 -0
- package/src/listen.js +18 -14
- package/src/log.js +11 -2
- package/src/middlewares.js +8 -6
- package/src/misc.js +3 -3
- package/src/multipartUpload.js +1 -2
- package/src/nat.js +5 -3
- package/src/outboundProxy.js +8 -0
- package/src/perm.js +5 -3
- package/src/plugins.js +58 -36
- package/src/selfCheck.js +8 -7
- package/src/serveFile.js +8 -6
- package/src/serveGuiAndSharedFiles.js +7 -6
- package/src/serveGuiFiles.js +13 -1
- package/src/serverCode.js +27 -0
- package/src/throttler.js +3 -2
- package/src/update.js +9 -3
- package/src/upload.js +30 -12
- package/src/uploadOwners.js +95 -0
- package/src/util-files.js +4 -2
- package/src/util-http.js +3 -1
- package/src/vfs.js +36 -28
- package/src/walkDir.js +24 -11
- package/src/watchLoad.js +13 -2
- package/src/webdav.js +16 -2
- package/src/zip.js +4 -3
- package/frontend/assets/index-legacy-CCOgiwQJ.js +0 -1
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
{
|
|
2
|
+
"author": "Flis666",
|
|
3
|
+
"version": 1.0,
|
|
4
|
+
"hfs_version": "0.57.5",
|
|
5
|
+
"translate": {
|
|
6
|
+
"Select": "Wybierz",
|
|
7
|
+
"n_files": "{n,plural,one{# plik} other{# plików}}",
|
|
8
|
+
"n_folders": "{n,plural,one{# folder} other{# foldery}}",
|
|
9
|
+
"filter_count": "{n,plural,one{# filtered} other{# filtered}}",
|
|
10
|
+
"select_count": "{n,plural, one{# selected} other{# selected}}",
|
|
11
|
+
"filter_placeholder": "Wpisz tutaj, aby filtrować listę poniżej",
|
|
12
|
+
"Select some files": "Wybierz kilka plików",
|
|
13
|
+
"zip_checkboxes": "Użyj pól wyboru, aby zaznaczyć pliki, a następnie możesz ponownie użyć opcji Zip",
|
|
14
|
+
"zip_tooltip_selected": "Pobierz wybrane elementy jako pojedynczy plik zip",
|
|
15
|
+
"zip_tooltip_whole": "Pobierz całą listę (nieprzefiltrowaną) jako pojedynczy plik zip. Jeśli zaznaczysz niektóre elementy, pobrane zostaną tylko te.",
|
|
16
|
+
"zip_confirm_search": "Pobrać WSZYSTKIE wyniki tego wyszukiwania jako archiwum ZIP?",
|
|
17
|
+
"zip_confirm_folder": "Pobrać CAŁY folder jako archiwum ZIP?",
|
|
18
|
+
"select_tooltip": "Wybór dotyczy opcji „Zip” i „Usuń” (jeśli są dostępne), ale możesz także filtrować listę",
|
|
19
|
+
"delete_hint": "Aby usunąć, najpierw kliknij Wybierz",
|
|
20
|
+
"delete_confirm": "Usunąć {n,plural,one{# pozycję} other{# pozycje}}?",
|
|
21
|
+
"delete_completed": "Usuwanie: {n} zakończone",
|
|
22
|
+
"delete_failed": ", {n,plural,one{# failed} other{# failed}}",
|
|
23
|
+
"delete_select": "Wybierz coś do usunięcia",
|
|
24
|
+
"Delete": "Usuń",
|
|
25
|
+
"Options": "Opcje",
|
|
26
|
+
"Search": "Szukaj",
|
|
27
|
+
"Zip": "Zip",
|
|
28
|
+
"search_msg": "Przeszukaj ten folder i podfoldery",
|
|
29
|
+
"Searching": "Wyszukiwanie",
|
|
30
|
+
"Searched": "Przeszukano",
|
|
31
|
+
"Clear search": "Wyczyść wyszukiwanie",
|
|
32
|
+
"Interrupted": "Przerwane",
|
|
33
|
+
"stopped_before": "Zatrzymane przed znalezieniem czegokolwiek",
|
|
34
|
+
"empty_list": "Nic tu nie ma",
|
|
35
|
+
"filter_none": "Brak dopasowań dla tego filtra",
|
|
36
|
+
"Admin-panel": "Panel administracyjny",
|
|
37
|
+
"Login": "Zaloguj",
|
|
38
|
+
"Username": "Nazwa użytkownika",
|
|
39
|
+
"Password": "Hasło",
|
|
40
|
+
"login_untrusted": "Logowanie przerwane: tożsamość serwera nie może być uznana za wiarygodną",
|
|
41
|
+
"login_bad_credentials": "Nieprawidłowe dane logowania",
|
|
42
|
+
"login_bad_cookies": "Ciasteczka nie działają - logowanie nie powiodło się",
|
|
43
|
+
"User panel": "Panel użytkownika",
|
|
44
|
+
"Change password": "Zmień hasło",
|
|
45
|
+
"enter_pass": "Wprowadź nowe hasło",
|
|
46
|
+
"enter_pass2": "POWTÓRZ to samo nowe hasło",
|
|
47
|
+
"pass2_mismatch": "Drugie hasło, które wprowadziłeś, nie pasuje do pierwszego. Procedura przerwana.",
|
|
48
|
+
"password_changed": "hasło_zmienione",
|
|
49
|
+
"Logout": "Wyloguj",
|
|
50
|
+
"connection error": "błąd połączenia",
|
|
51
|
+
"Full timestamp:": "Pełny znacznik czasu:",
|
|
52
|
+
"Search was interrupted": "Wyszukiwanie zostało przerwane",
|
|
53
|
+
"Stop list": "Lista zatrzymań",
|
|
54
|
+
"download_starting": "Twój pobieranie powinno teraz rozpocząć się",
|
|
55
|
+
"wrong_account": "Konto {u} nie ma dostępu, spróbuj inne",
|
|
56
|
+
"no_upload_here": "Brak uprawnień do przesyłania w bieżącym folderze",
|
|
57
|
+
"Create folder": "Utwórz folder",
|
|
58
|
+
"Pick files": "Wybierz pliki",
|
|
59
|
+
"Pick folder": "Wybierz folder",
|
|
60
|
+
"ready_to_upload": "{n,plural,one{# plik} other{# pliki}}, {size}, gotowe do przesłania",
|
|
61
|
+
"Send": "Wyślij",
|
|
62
|
+
"Clear": "Wyczyść",
|
|
63
|
+
"failed_upload": "Nie można przesłać {name}",
|
|
64
|
+
"file too large": "plik jest zbyt duży",
|
|
65
|
+
"Enter folder name": "Wprowadź nazwę folderu",
|
|
66
|
+
"Successfully created": "Pomyślnie utworzono",
|
|
67
|
+
"enter_folder": "Wejdź do folderu",
|
|
68
|
+
"folder_exists": "Folder o tej samej nazwie już istnieje",
|
|
69
|
+
"Sort by:": "Sortuj według: {by}",
|
|
70
|
+
"name": "nazwa",
|
|
71
|
+
"extension": "rozszerzenie",
|
|
72
|
+
"size": "rozmiar",
|
|
73
|
+
"time": "czas",
|
|
74
|
+
"Invert order": "Odwróć kolejność",
|
|
75
|
+
"Folders first": "Najpierw foldery",
|
|
76
|
+
"Numeric names": "Nazwy numeryczne",
|
|
77
|
+
"theme:": "motyw:",
|
|
78
|
+
"auto": "auto",
|
|
79
|
+
"light": "jasny",
|
|
80
|
+
"dark": "ciemny",
|
|
81
|
+
"parent folder": "folder nadrzędny",
|
|
82
|
+
"home": "dom",
|
|
83
|
+
"Continue": "Kontynuuj",
|
|
84
|
+
"Confirm": "Potwierdź",
|
|
85
|
+
"Don't": "Nie",
|
|
86
|
+
"Warning": "Ostrzeżenie",
|
|
87
|
+
"Error": "Błąd",
|
|
88
|
+
"Info": "Informacja",
|
|
89
|
+
"Unauthorized": "Nieautoryzowany",
|
|
90
|
+
"Forbidden": "Zabronione",
|
|
91
|
+
"Not found": "Nie znaleziono",
|
|
92
|
+
"Server error": "Błąd serwera",
|
|
93
|
+
"Upload": "Prześlij",
|
|
94
|
+
"upload_concluded": "Przesyłanie zakończone:",
|
|
95
|
+
"upload_finished": "{n} zakończonych ({size})",
|
|
96
|
+
"upload_errors": "{n} nieudanych",
|
|
97
|
+
"upload_file_rejected": "Niektóre pliki nie zostały zaakceptowane",
|
|
98
|
+
"delete_unfinished_upload": "Usunąć niedokończone przesyłanie?",
|
|
99
|
+
"File menu": "Menu pliku",
|
|
100
|
+
"Folder menu": "Menu folderu",
|
|
101
|
+
"Name": "Nazwa",
|
|
102
|
+
"file_open": "Otwórz",
|
|
103
|
+
"Download": "Pobierz",
|
|
104
|
+
"Missing permission": "Brak uprawnień",
|
|
105
|
+
"Reload": "Przeładuj",
|
|
106
|
+
"Get list": "Pobierz listę",
|
|
107
|
+
"Skip existing files": "Pomiń istniejące pliki",
|
|
108
|
+
"Size": "Rozmiar",
|
|
109
|
+
"Timestamp": "Znacznik czasu",
|
|
110
|
+
"Show": "Pokaż",
|
|
111
|
+
"Loading failed": "Nieudane ładowanie",
|
|
112
|
+
"Rename": "Zmień nazwę",
|
|
113
|
+
"Tiles mode:": "Tryb kafelków:",
|
|
114
|
+
"off": "wyłączony",
|
|
115
|
+
"Operation successful": "Operacja zakończona sukcesem",
|
|
116
|
+
"Uploader": "Przesyłający",
|
|
117
|
+
"Download counter": "Licznik pobierań",
|
|
118
|
+
"Switch zoom mode": "Przełącz tryb powiększenia",
|
|
119
|
+
"Full screen": "Pełny ekran",
|
|
120
|
+
"File Show help": "Pomoc dotycząca pliku",
|
|
121
|
+
"showHelpMain": "Możesz użyć klawiatury do niektórych działań:",
|
|
122
|
+
"showHelp_←/→": "←/→",
|
|
123
|
+
"showHelp_↑/↓": "↑/↓",
|
|
124
|
+
"showHelp_space": "spacja",
|
|
125
|
+
"showHelp_←/→_body": "Przejdź do poprzedniego/następnego pliku",
|
|
126
|
+
"showHelp_↑/↓_body": "Przewiń wysokie obrazy",
|
|
127
|
+
"Destination": "Cel",
|
|
128
|
+
"in_queue": "{n} w kolejce",
|
|
129
|
+
"enter_comment": "Komentarz dla {name}",
|
|
130
|
+
"Comment": "Komentarz",
|
|
131
|
+
"upload_dd_hint": "Możesz przesyłać pliki, przeciągając je na liście plików",
|
|
132
|
+
"Upload not available": "Przesyłanie niedostępne",
|
|
133
|
+
"Cut": "Wytnij",
|
|
134
|
+
"n_items": "{n,plural,one{# pozycję} other{# pozycje}}",
|
|
135
|
+
"move_results": "{good} przeniesiono, {bad} nieudanych",
|
|
136
|
+
"after_cut": "Twoje zaznaczenie jest teraz w schowku.\nPrzejdź do folderu docelowego, aby wkleić.",
|
|
137
|
+
"Cancel clipboard": "Anuluj schowek",
|
|
138
|
+
"to_clipboard_source": "Powrót do folderu źródłowego",
|
|
139
|
+
"Paste": "Wklej",
|
|
140
|
+
"clipboard_list": "Elementy w schowku:",
|
|
141
|
+
"Close": "Zamknij",
|
|
142
|
+
"Folder": "Folder",
|
|
143
|
+
"Web page": "Strona internetowa",
|
|
144
|
+
"Link": "Link",
|
|
145
|
+
"Auto-play": "Auto-odtwarzanie",
|
|
146
|
+
"autoplay_seconds": "Sekundy do oczekiwania na obrazy",
|
|
147
|
+
"Select all": "Wybierz wszystko",
|
|
148
|
+
"go_first": "Przejdź do pierwszego elementu",
|
|
149
|
+
"go_last": "Przejdź do ostatniego elementu",
|
|
150
|
+
"Shuffle": "Tasuj",
|
|
151
|
+
"Repeat": "Powtarzaj",
|
|
152
|
+
"showHelpListShortcut": "Z listy plików kliknij i przytrzymaj {key}, aby szybko pokazać",
|
|
153
|
+
"Invalid value": "Nieprawidłowa wartość",
|
|
154
|
+
"upload_interrupted": "{n} Przerwane",
|
|
155
|
+
"Overwrite policy": "Polityka nadpisania",
|
|
156
|
+
"Rename to avoid overwriting": "Zmień nazwę, aby uniknąć nadpisania",
|
|
157
|
+
"Overwrite existing files": "Nadpisz istniejące pliki",
|
|
158
|
+
"Menu": "Menu",
|
|
159
|
+
"clipboard": "Schowek ({content})",
|
|
160
|
+
"to_clipboard_source_tooltip": "Przejdź do folderu zawierającego elementy ze schowka",
|
|
161
|
+
"more_items": "{n} więcej elementów",
|
|
162
|
+
"Show details": "Pokaż szczegóły",
|
|
163
|
+
"upload_conflict": "już istnieje",
|
|
164
|
+
"Logged in": "Zalogowano",
|
|
165
|
+
"Logged out": "Wylogowano",
|
|
166
|
+
"Cancel": "Anuluj",
|
|
167
|
+
"allow_session_ip_change": "Zezwalaj na zmianę adresu IP podczas tej sesji",
|
|
168
|
+
"focus_hint": "Wpisując tekst na klawiaturze, możesz wyszukiwać i wybierać elementy na liście.",
|
|
169
|
+
"copy_links": "Kopiuj linki",
|
|
170
|
+
"Calculate": "Oblicz",
|
|
171
|
+
"Creation": "Utworzenie",
|
|
172
|
+
"creation": "utworzenie",
|
|
173
|
+
"required_change_password": "Musisz zmienić swoje hasło",
|
|
174
|
+
"Wildcards": "Symbole wieloznaczne",
|
|
175
|
+
"Considering resume": "Rozważanie wznowienia",
|
|
176
|
+
"Yes": "Tak",
|
|
177
|
+
"No": "Nie",
|
|
178
|
+
"esc_again": "Naciśnij ESC dwukrotnie do zamkniecia",
|
|
179
|
+
"insufficient storage": "za mało miejsca",
|
|
180
|
+
"Account disabled": "Konto wyłączone"
|
|
181
|
+
}
|
|
182
|
+
}
|
|
@@ -95,6 +95,7 @@
|
|
|
95
95
|
"upload_finished": "{n} finalizado ({size})",
|
|
96
96
|
"upload_errors": "{n} faliu",
|
|
97
97
|
"upload_file_rejected": "Alguns arquivos não foram aceitos",
|
|
98
|
+
"delete_unfinished_upload": "Remover o envio inacabado?",
|
|
98
99
|
"File menu": "Menu de arquivo",
|
|
99
100
|
"Folder menu": "Menu de Pasta",
|
|
100
101
|
"Name": "Nome",
|
|
@@ -96,6 +96,7 @@
|
|
|
96
96
|
"upload_finished": "{n} terminat ({size})",
|
|
97
97
|
"upload_errors": "{n} eșuat",
|
|
98
98
|
"upload_file_rejected": "Unele fișiere nu au fost acceptate",
|
|
99
|
+
"delete_unfinished_upload": "Eliminați încărcarea neterminată?",
|
|
99
100
|
"File menu": "Meniu fișier",
|
|
100
101
|
"Folder menu": "Meniu folder",
|
|
101
102
|
"Name": "Nume",
|
|
@@ -96,6 +96,7 @@
|
|
|
96
96
|
"upload_finished": "{n,plural, one{# файл загружен} few{# файла загружено} many{# файлов загружено}} ({size})",
|
|
97
97
|
"upload_errors": "{n,plural, one{# файл} few{# файла} many{# файлов}} неуспешно",
|
|
98
98
|
"upload_file_rejected": "Некоторые файлы не были приняты",
|
|
99
|
+
"delete_unfinished_upload": "Удалить незавершённую загрузку?",
|
|
99
100
|
"File menu": "Меню файла",
|
|
100
101
|
"Folder menu": "Меню папки",
|
|
101
102
|
"Name": "Имя",
|
|
@@ -95,6 +95,7 @@
|
|
|
95
95
|
"upload_finished": "{n} završeno ({size})",
|
|
96
96
|
"upload_errors": "{n,plural, one{# nije uspeo} other{# neuspešna}}",
|
|
97
97
|
"upload_file_rejected": "Neke datoteke nisu prihvaćene",
|
|
98
|
+
"delete_unfinished_upload": "Ukloniti nedovršeno otpremanje?",
|
|
98
99
|
"File menu": "Meni datoteke",
|
|
99
100
|
"Folder menu": "Meni fascikle",
|
|
100
101
|
"Name": "Ime",
|
|
@@ -98,6 +98,7 @@
|
|
|
98
98
|
"upload_finished": "{n} пребачен(о) ({size})",
|
|
99
99
|
"upload_errors": "{n} неуспешно пребачен(их)",
|
|
100
100
|
"upload_file_rejected": "Нека документа нису прихваћена",
|
|
101
|
+
"delete_unfinished_upload": "Уклонити недовршено отпремање?",
|
|
101
102
|
"download counter": "бројач преузимања",
|
|
102
103
|
"File menu": "Мени документа",
|
|
103
104
|
"Folder menu": "Мени фолдера",
|
|
@@ -96,6 +96,7 @@
|
|
|
96
96
|
"upload_finished": "{n} เสร็จสิ้น ({size})",
|
|
97
97
|
"upload_errors": "{n} ล้มเหลว",
|
|
98
98
|
"upload_file_rejected": "บางไฟล์ไม่ได้รับการยอมรับ",
|
|
99
|
+
"delete_unfinished_upload": "ลบการอัปโหลดที่ยังไม่เสร็จหรือไม่?",
|
|
99
100
|
"File menu": "เมนูไฟล์",
|
|
100
101
|
"Folder menu": "เมนูโฟลเดอร์",
|
|
101
102
|
"Name": "ชื่อ",
|
|
@@ -96,6 +96,7 @@
|
|
|
96
96
|
"upload_finished": "{n} tamamlandı ({size})",
|
|
97
97
|
"upload_errors": "{n} başarısız",
|
|
98
98
|
"upload_file_rejected": "Bazı dosyalar kabul edilmiyor",
|
|
99
|
+
"delete_unfinished_upload": "Tamamlanmamış yüklemeyi kaldır?",
|
|
99
100
|
"File menu": "Dosya Menüsü",
|
|
100
101
|
"Folder menu": "Klasör Menüsü",
|
|
101
102
|
"Name": "İsim",
|
|
@@ -96,6 +96,7 @@
|
|
|
96
96
|
"upload_finished": "{n,plural, one{# файл завантажено} few{# файли завантажено} many{# файлів завантажено}} ({size})",
|
|
97
97
|
"upload_errors": "{n,plural, one{# файл} few{# файли} many{# файлів}} неуспішно",
|
|
98
98
|
"upload_file_rejected": "Деякі файли не були прийняті",
|
|
99
|
+
"delete_unfinished_upload": "Видалити незавершене завантаження?",
|
|
99
100
|
"File menu": "Меню файлу",
|
|
100
101
|
"Folder menu": "Меню теки",
|
|
101
102
|
"Name": "Назва",
|
|
@@ -97,6 +97,7 @@
|
|
|
97
97
|
"upload_finished": "{n} thành công ({size})",
|
|
98
98
|
"upload_errors": "{n} thất bại",
|
|
99
99
|
"upload_file_rejected": "Một số file bị cấm...",
|
|
100
|
+
"delete_unfinished_upload": "Xóa bản upload chưa hoàn tất?",
|
|
100
101
|
"Download counter": "Bộ đếm download",
|
|
101
102
|
"File menu": "Menu",
|
|
102
103
|
"Folder menu": "Menu",
|
package/src/listen.js
CHANGED
|
@@ -69,11 +69,12 @@ const argv_1 = require("./argv");
|
|
|
69
69
|
const consoleLog_1 = require("./consoleLog");
|
|
70
70
|
const first_1 = require("./first");
|
|
71
71
|
const fileAttr_1 = require("./fileAttr");
|
|
72
|
+
const uploadOwners_1 = require("./uploadOwners");
|
|
72
73
|
let httpSrv;
|
|
73
74
|
let httpsSrv;
|
|
74
75
|
// the update relaunch can keep a bridge process alive, so we proactively close listeners here to release ports before the next binary binds; do it before (5) the storage file is closed, because sockets write there
|
|
75
76
|
(0, first_1.onProcessExit)(() => Promise.all([stopServer(httpSrv), stopServer(httpsSrv)]), 5);
|
|
76
|
-
const openBrowserAtStart = (0, config_1.defineConfig)(
|
|
77
|
+
const openBrowserAtStart = (0, config_1.defineConfig)(misc_1.CFG.open_browser_at_start, true);
|
|
77
78
|
exports.baseUrl = (0, config_1.defineConfig)(misc_1.CFG.base_url, '', x => /(?<=\/\/)[^\/]+/.exec(x)?.[0]); // compiled is host only
|
|
78
79
|
async function getBaseUrlOrDefault() {
|
|
79
80
|
return exports.baseUrl.get() || await nat_1.defaultBaseUrl.get();
|
|
@@ -87,7 +88,7 @@ const commonServerOptions = {
|
|
|
87
88
|
};
|
|
88
89
|
// these are properties that can be assigned to the server object
|
|
89
90
|
const commonServerAssign = { headersTimeout: 30_000, timeout: misc_1.MINUTE }; // 'headersTimeout' is not recognized by type lib, and 'timeout' is not effective when passed in parameters
|
|
90
|
-
const readyToListen = Promise.all([persistence_1.storedMap.isOpening(), fileAttr_1.fileAttrDb.isOpening(), events_1.default.once('app')]);
|
|
91
|
+
const readyToListen = Promise.all([persistence_1.storedMap.isOpening(), fileAttr_1.fileAttrDb.isOpening(), uploadOwners_1.uploadOwners.isOpening(), events_1.default.once('app')]);
|
|
91
92
|
const considerHttp = (0, misc_1.debounceAsync)(async () => {
|
|
92
93
|
await readyToListen;
|
|
93
94
|
void stopServer(httpSrv);
|
|
@@ -109,8 +110,8 @@ const considerHttp = (0, misc_1.debounceAsync)(async () => {
|
|
|
109
110
|
}
|
|
110
111
|
});
|
|
111
112
|
let openOnce = true;
|
|
112
|
-
exports.portCfg = (0, config_1.defineConfig)(
|
|
113
|
-
const listenInterface = (0, config_1.defineConfig)(
|
|
113
|
+
exports.portCfg = (0, config_1.defineConfig)(misc_1.CFG.port, 80);
|
|
114
|
+
const listenInterface = (0, config_1.defineConfig)(misc_1.CFG.listen_interface, '');
|
|
114
115
|
(0, config_1.subMultipleConfigs)(considerHttp, [exports.portCfg, listenInterface]);
|
|
115
116
|
function openAdmin() {
|
|
116
117
|
for (const srv of [httpSrv, httpsSrv]) {
|
|
@@ -123,7 +124,7 @@ function openAdmin() {
|
|
|
123
124
|
const baseUrl = `${srv.name}://${hostname}:${a.port}`;
|
|
124
125
|
(0, open_1.default)(baseUrl + const_1.ADMIN_URI, { wait: true }).catch(async (e) => {
|
|
125
126
|
console.debug(String(e));
|
|
126
|
-
console.warn("Cannot launch browser on this machine
|
|
127
|
+
console.warn("Cannot launch browser on this machine – open your browser and reach one of these (you may need a different address)", ...Object.values(await getUrls()).flat().map(x => '\n - ' + x + const_1.ADMIN_URI));
|
|
127
128
|
if (!(0, adminApis_1.anyAccountCanLoginAdmin)())
|
|
128
129
|
(0, consoleLog_1.consoleHint)(`you can enter this command: create-admin YOUR_PASSWORD`);
|
|
129
130
|
});
|
|
@@ -138,7 +139,8 @@ function getCertObject() {
|
|
|
138
139
|
const all = new crypto_1.X509Certificate(c);
|
|
139
140
|
const some = lodash_1.default.pick(all, ['subject', 'issuer', 'validFrom', 'validTo']);
|
|
140
141
|
const ret = lodash_1.default.mapValues(some, v => v?.includes('=') ? Object.fromEntries(v.split('\n').map(x => x.split('='))) : v);
|
|
141
|
-
return Object.assign(ret, { altNames: all.subjectAltName?.
|
|
142
|
+
return Object.assign(ret, { altNames: all.subjectAltName?.split(/, */)
|
|
143
|
+
.map(x => x.replace(/^(?:DNS:|IP Address:)/, '')) });
|
|
142
144
|
}
|
|
143
145
|
const considerHttps = (0, misc_1.debounceAsync)(async () => {
|
|
144
146
|
await readyToListen;
|
|
@@ -160,7 +162,6 @@ const considerHttps = (0, misc_1.debounceAsync)(async () => {
|
|
|
160
162
|
const cn = certObj.subject?.CN;
|
|
161
163
|
if (cn)
|
|
162
164
|
console.log("Certificate loaded for", certObj.altNames?.join(' + ') || cn);
|
|
163
|
-
const now = new Date();
|
|
164
165
|
const from = new Date(certObj.validFrom);
|
|
165
166
|
const to = new Date(certObj.validTo);
|
|
166
167
|
updateError(); // error will change at from and to dates of the certificate
|
|
@@ -173,6 +174,7 @@ const considerHttps = (0, misc_1.debounceAsync)(async () => {
|
|
|
173
174
|
function updateError() {
|
|
174
175
|
if (!httpsSrv)
|
|
175
176
|
return;
|
|
177
|
+
const now = new Date();
|
|
176
178
|
httpsSrv.error = from > now ? "certificate not valid yet" : to < now ? "certificate expired" : undefined;
|
|
177
179
|
}
|
|
178
180
|
}
|
|
@@ -205,8 +207,8 @@ const considerHttps = (0, misc_1.debounceAsync)(async () => {
|
|
|
205
207
|
nat_1.defaultBaseUrl.proto = 'https';
|
|
206
208
|
nat_1.defaultBaseUrl.port = getCurrentPort(httpsSrv) ?? 0;
|
|
207
209
|
}, { wait: 200 }); // give time to have key and cert ready
|
|
208
|
-
exports.cert = (0, config_1.defineConfig)(
|
|
209
|
-
exports.privateKey = (0, config_1.defineConfig)(
|
|
210
|
+
exports.cert = (0, config_1.defineConfig)(misc_1.CFG.cert, '', load);
|
|
211
|
+
exports.privateKey = (0, config_1.defineConfig)(misc_1.CFG.private_key, '', load);
|
|
210
212
|
const httpsNeeds = [exports.cert, exports.privateKey];
|
|
211
213
|
function load(v, { object }) {
|
|
212
214
|
object.watcher?.unwatch();
|
|
@@ -216,7 +218,7 @@ function load(v, { object }) {
|
|
|
216
218
|
object.watcher = (0, watchLoad_1.watchLoad)(v, x => object.setCompiled(x), { immediateFirst: true });
|
|
217
219
|
return '';
|
|
218
220
|
}
|
|
219
|
-
exports.httpsPortCfg = (0, config_1.defineConfig)(
|
|
221
|
+
exports.httpsPortCfg = (0, config_1.defineConfig)(misc_1.CFG.https_port, const_1.PORT_DISABLED);
|
|
220
222
|
(0, config_1.subMultipleConfigs)(considerHttps, [exports.httpsPortCfg, listenInterface, ...httpsNeeds]);
|
|
221
223
|
const genericInterfaceNames = {
|
|
222
224
|
'0.0.0.0': "any IPv4",
|
|
@@ -273,12 +275,14 @@ function startServer(srv, { port, host }) {
|
|
|
273
275
|
srv.error = String(e);
|
|
274
276
|
srv.busy = undefined;
|
|
275
277
|
const { code } = e;
|
|
276
|
-
|
|
278
|
+
// share the lookup with status readers, but classify the error from its resolved result
|
|
279
|
+
if (code === 'EADDRINUSE' || code === 'EACCES')
|
|
277
280
|
srv.busy = (0, find_process_1.default)('port', port).then(res => res?.map(x => (0, misc_1.prefix)("Service", x.name === 'svchost.exe' && x.cmd.split(x.name)[1]?.trim()) || x.name).join(' + '), () => '');
|
|
278
|
-
|
|
281
|
+
const busy = await srv.busy;
|
|
282
|
+
if (code === 'EACCES' && port < 1024 && !busy) // on Windows, when port is used by a service, we get EACCES
|
|
279
283
|
srv.error = `lacking permission on port ${port}, try with permission (${const_1.IS_WINDOWS ? 'administrator' : 'sudo'}) or port > 1024`;
|
|
280
|
-
if (code === 'EADDRINUSE' ||
|
|
281
|
-
srv.error = `port ${port} busy: ${
|
|
284
|
+
if (code === 'EADDRINUSE' || busy)
|
|
285
|
+
srv.error = `port ${port} busy: ${busy || "unknown process"}`;
|
|
282
286
|
if (!silence)
|
|
283
287
|
console.error(srv.name, srv.error);
|
|
284
288
|
resolve(0);
|
package/src/log.js
CHANGED
|
@@ -82,8 +82,14 @@ class Logger {
|
|
|
82
82
|
this.reopen();
|
|
83
83
|
}
|
|
84
84
|
reopen() {
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
const { path } = this;
|
|
86
|
+
const s = this.stream = (0, util_files_1.createFileWithPath)(path, { flags: 'a' });
|
|
87
|
+
s?.on('error', e => {
|
|
88
|
+
if (this.stream === s) // a late error from an old stream must not detach its replacement
|
|
89
|
+
this.stream = undefined;
|
|
90
|
+
console.error("Cannot write log file", path, String(e));
|
|
91
|
+
});
|
|
92
|
+
return s;
|
|
87
93
|
}
|
|
88
94
|
}
|
|
89
95
|
// we'll have names same as config keys. These are used also by the get_log api.
|
|
@@ -103,6 +109,7 @@ const logRotation = (0, config_1.defineConfig)(misc_1.CFG.log_rotation, 'weekly'
|
|
|
103
109
|
const dontLogNet = (0, config_1.defineConfig)(misc_1.CFG.dont_log_net, '127.0.0.1|::1', v => (0, misc_1.makeNetMatcher)(v));
|
|
104
110
|
const logUA = (0, config_1.defineConfig)(misc_1.CFG.log_ua, false);
|
|
105
111
|
const logSpam = (0, config_1.defineConfig)(misc_1.CFG.log_spam, false);
|
|
112
|
+
const logHost = (0, config_1.defineConfig)(misc_1.CFG.log_host, false);
|
|
106
113
|
const debounce = lodash_1.default.debounce(cb => cb(), 1000); // with this technique, i'll be able to debounce some code respecting the references in its closure
|
|
107
114
|
const logMw = async (ctx, next) => {
|
|
108
115
|
const reqStart = new Date(); // request start
|
|
@@ -176,6 +183,8 @@ const logMw = async (ctx, next) => {
|
|
|
176
183
|
ctx.logExtra({ country: conn.country });
|
|
177
184
|
if (logUA.get())
|
|
178
185
|
ctx.logExtra({ ua: ctx.get('user-agent') || undefined });
|
|
186
|
+
if (logHost.get())
|
|
187
|
+
ctx.logExtra({ host: ctx.get('host') || undefined });
|
|
179
188
|
const extra = ctx.state.logExtra;
|
|
180
189
|
if (events_2.default.anyListener(logger.name)) // small optimization: this event can happen often, while most times there's no listener, and the parameters object is constructed pointlessly. A benchmark measured it 20% faster (just the line), while maybe it was not necessary.
|
|
181
190
|
events_2.default.emit(logger.name, { ctx, length, user, ts: reqEnd, uri, extra });
|
package/src/middlewares.js
CHANGED
|
@@ -21,10 +21,10 @@ const config_1 = require("./config");
|
|
|
21
21
|
const koa_session_1 = __importDefault(require("koa-session"));
|
|
22
22
|
const index_1 = require("./index");
|
|
23
23
|
const events_1 = __importDefault(require("./events"));
|
|
24
|
-
const forceHttps = (0, config_1.defineConfig)(
|
|
25
|
-
(0, config_1.defineConfig)(
|
|
26
|
-
const allowAuthorizationHeader = (0, config_1.defineConfig)(
|
|
27
|
-
exports.sessionDuration = (0, config_1.defineConfig)(
|
|
24
|
+
const forceHttps = (0, config_1.defineConfig)(misc_1.CFG.force_https, true);
|
|
25
|
+
(0, config_1.defineConfig)(misc_1.CFG.ignore_proxies, false);
|
|
26
|
+
const allowAuthorizationHeader = (0, config_1.defineConfig)(misc_1.CFG.authorization_header, true);
|
|
27
|
+
exports.sessionDuration = (0, config_1.defineConfig)(misc_1.CFG.session_duration, Number(process.env.SESSION_DURATION) || misc_1.DAY / 1000, v => v * 1000);
|
|
28
28
|
exports.gzipper = (0, koa_compress_1.default)({
|
|
29
29
|
threshold: 2048,
|
|
30
30
|
gzip: { flush: zlib_1.constants.Z_SYNC_FLUSH }, // flush is necessary for SSE, at least in Chrome145
|
|
@@ -142,9 +142,11 @@ const prepareState = async (ctx, next) => {
|
|
|
142
142
|
};
|
|
143
143
|
exports.prepareState = prepareState;
|
|
144
144
|
function failAllowNet(ctx, a) {
|
|
145
|
-
|
|
145
|
+
// a cached mask is valid only for the identity that stored it
|
|
146
|
+
const sameAccount = ctx.session?.username === (0, perm_1.normalizeUsername)(a?.username || '');
|
|
147
|
+
const cached = sameAccount ? ctx.session?.allowNet : undefined;
|
|
146
148
|
const mask = cached ?? (0, perm_1.getFromAccount)(a || '', a => a.allow_net);
|
|
147
|
-
if (!cached && mask
|
|
149
|
+
if (sameAccount && !cached && mask)
|
|
148
150
|
ctx.session.allowNet = mask; // must be deleted on logout by setLoggedIn
|
|
149
151
|
const ret = mask && !(0, misc_1.netMatches)(ctx.ip, mask, true);
|
|
150
152
|
if (ret)
|
package/src/misc.js
CHANGED
|
@@ -120,15 +120,15 @@ function asyncGeneratorToReadable(generator) {
|
|
|
120
120
|
const iterator = generator[Symbol.asyncIterator]();
|
|
121
121
|
return new stream_1.Readable({
|
|
122
122
|
objectMode: true,
|
|
123
|
-
destroy() {
|
|
124
|
-
|
|
123
|
+
destroy(error, callback) {
|
|
124
|
+
Promise.resolve(iterator.return?.()).then(() => callback(error), callback);
|
|
125
125
|
},
|
|
126
126
|
read() {
|
|
127
127
|
iterator.next().then(it => {
|
|
128
128
|
if (it.done)
|
|
129
129
|
this.emit('ending');
|
|
130
130
|
return this.push(it.done ? null : it.value);
|
|
131
|
-
});
|
|
131
|
+
}, e => this.destroy(e));
|
|
132
132
|
}
|
|
133
133
|
});
|
|
134
134
|
}
|
package/src/multipartUpload.js
CHANGED
|
@@ -5,7 +5,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.handleMultipartUpload = handleMultipartUpload;
|
|
7
7
|
const busboy_1 = __importDefault(require("busboy"));
|
|
8
|
-
const events_1 = require("events");
|
|
9
8
|
const vfs_1 = require("./vfs");
|
|
10
9
|
const path_1 = require("path");
|
|
11
10
|
const upload_1 = require("./upload");
|
|
@@ -46,7 +45,7 @@ async function handleMultipartUpload(ctx, node) {
|
|
|
46
45
|
ctx.status = cross_const_1.HTTP_BAD_REQUEST;
|
|
47
46
|
});
|
|
48
47
|
ctx.req.pipe(bb);
|
|
49
|
-
await (0,
|
|
48
|
+
await new Promise(res => (0, first_1.onFirstEvent)(bb, ['finish', 'error'], res)); // parser errors are handled above as 400 and must complete the request without rejecting
|
|
50
49
|
await Promise.all(fileJobs);
|
|
51
50
|
if (!ctx.state.uploads?.length) {
|
|
52
51
|
if (!errors.length)
|
package/src/nat.js
CHANGED
|
@@ -33,7 +33,7 @@ exports.defaultBaseUrl = (0, valtio_1.proxy)({
|
|
|
33
33
|
return `${this.proto}://${(0, cross_1.ipForUrl)(ip || 'localhost')}${!port || port === defPort ? '' : ':' + port}`;
|
|
34
34
|
}
|
|
35
35
|
});
|
|
36
|
-
exports.mappedPort = (0, config_1.defineConfig)(
|
|
36
|
+
exports.mappedPort = (0, config_1.defineConfig)(cross_1.CFG.mapped_port, 0);
|
|
37
37
|
exports.upnpEnabled = (0, config_1.defineConfig)(cross_1.CFG.upnp_enabled, true);
|
|
38
38
|
let upnpClient;
|
|
39
39
|
// poll external ip – when UPnP is enabled, asking the modem is inexpensive, so it can be done often
|
|
@@ -144,8 +144,10 @@ function findGateway() {
|
|
|
144
144
|
return new Promise((resolve, reject) => (0, child_process_1.exec)(const_1.IS_WINDOWS || const_1.IS_MAC ? 'netstat -rn' : 'route -n', (err, out) => {
|
|
145
145
|
if (err)
|
|
146
146
|
return reject(err);
|
|
147
|
-
if (!const_1.IS_WINDOWS)
|
|
148
|
-
|
|
147
|
+
if (!const_1.IS_WINDOWS) {
|
|
148
|
+
// linux route output starts with headers, so its default-route pattern must be multiline
|
|
149
|
+
return resolve(out.match(const_1.IS_MAC ? /default +([\d.]+)/ : /^0\.0\.0\.0 +([\d.]+)/m)?.[1]);
|
|
150
|
+
}
|
|
149
151
|
const sortedByMetric = lodash_1.default.sortBy([...out.matchAll(/(?:0\.0\.0\.0 +){2}([\d.]+)\s+[\d.]+\s+(\d+)/g)], x => Number(x[2]));
|
|
150
152
|
resolve(sortedByMetric[0]?.[1]); // take ip with lowest metric
|
|
151
153
|
}));
|
package/src/outboundProxy.js
CHANGED
|
@@ -5,7 +5,15 @@ const util_http_1 = require("./util-http");
|
|
|
5
5
|
const util_os_1 = require("./util-os");
|
|
6
6
|
const const_1 = require("./const");
|
|
7
7
|
const cross_1 = require("./cross");
|
|
8
|
+
const node_net_1 = require("node:net");
|
|
9
|
+
(0, config_1.defineConfig)(cross_1.CFG.outbound_interface, '', v => {
|
|
10
|
+
if (!v || (0, node_net_1.isIP)(v))
|
|
11
|
+
return util_http_1.httpStream.defaultLocalAddress = v || undefined;
|
|
12
|
+
console.warn("Invalid outbound interface IP", v);
|
|
13
|
+
util_http_1.httpStream.defaultLocalAddress = undefined;
|
|
14
|
+
});
|
|
8
15
|
const outboundProxy = (0, config_1.defineConfig)(cross_1.CFG.outbound_proxy, '', v => {
|
|
16
|
+
util_http_1.httpStream.defaultProxy = undefined;
|
|
9
17
|
if (!v)
|
|
10
18
|
return;
|
|
11
19
|
try {
|
package/src/perm.js
CHANGED
|
@@ -59,7 +59,7 @@ function getAccount(username, normalize = true) {
|
|
|
59
59
|
function saveSrpInfo(account, salt, verifier) {
|
|
60
60
|
account.srp = String(salt) + '|' + String(verifier);
|
|
61
61
|
}
|
|
62
|
-
const createAdminConfig = (0, config_1.defineConfig)('create-admin', '');
|
|
62
|
+
const createAdminConfig = (0, config_1.defineConfig)(misc_1.CFG['create-admin'], '');
|
|
63
63
|
createAdminConfig.sub(v => {
|
|
64
64
|
if (!v)
|
|
65
65
|
return;
|
|
@@ -79,7 +79,9 @@ async function updateAccount(account, change) {
|
|
|
79
79
|
await change?.(account);
|
|
80
80
|
else {
|
|
81
81
|
const u = normalizeUsername(change.username || '');
|
|
82
|
-
if (u
|
|
82
|
+
if (!u)
|
|
83
|
+
delete change.username;
|
|
84
|
+
else if (u !== usernameWas && getAccount(u))
|
|
83
85
|
throw "username already exists";
|
|
84
86
|
Object.assign(account, lodash_1.default.mapValues(change, x => x || undefined));
|
|
85
87
|
}
|
|
@@ -111,7 +113,7 @@ async function updateAccount(account, change) {
|
|
|
111
113
|
saveAccountsAsap();
|
|
112
114
|
}
|
|
113
115
|
const saveAccountsAsap = config_1.saveConfigAsap;
|
|
114
|
-
exports.accounts = (0, config_1.defineConfig)(
|
|
116
|
+
exports.accounts = (0, config_1.defineConfig)(misc_1.CFG.accounts, {});
|
|
115
117
|
exports.accounts.sub(lodash_1.default.debounce(obj => {
|
|
116
118
|
// consider some validation here, in case of manual edit of the config
|
|
117
119
|
lodash_1.default.each(obj, (rec, k) => {
|