hfs 0.49.2 → 0.50.0-alpha3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/admin/assets/{index-79c48481.js → index-18a6b5e2.js} +319 -61
- package/admin/assets/{index-1c2b890b.css → index-f3fd8783.css} +1 -1
- package/{frontend/assets/sha512-da48f0d4.js → admin/assets/sha512-58cb94a6.js} +1 -1
- package/admin/index.html +2 -2
- package/central.json +5 -0
- package/frontend/assets/index-629107cf.js +94 -0
- package/frontend/assets/{index-b50efd06.css → index-88f77c85.css} +1 -1
- package/{admin/assets/sha512-bdc531ce.js → frontend/assets/sha512-0e660b94.js} +1 -1
- package/frontend/index.html +2 -2
- package/package.json +3 -2
- package/plugins/antibrute/plugin.js +1 -1
- package/plugins/vhosting/plugin.js +3 -3
- package/src/adminApis.js +18 -12
- package/src/api.accounts.js +7 -1
- package/src/api.auth.js +7 -31
- package/src/api.file_list.js +6 -1
- package/src/api.monitor.js +10 -6
- package/src/api.vfs.js +6 -8
- package/src/apiMiddleware.js +12 -12
- package/src/auth.js +49 -0
- package/src/connections.js +6 -1
- package/src/const.js +3 -2
- package/src/cross.js +27 -3
- package/src/customHtml.js +1 -1
- package/src/geo.js +61 -0
- package/src/index.js +4 -1
- package/src/log.js +2 -2
- package/src/middlewares.js +24 -21
- package/src/perm.js +1 -6
- package/src/plugins.js +1 -3
- package/src/serveFile.js +2 -2
- package/src/serveGuiFiles.js +3 -6
- package/src/srp.js +22 -0
- package/src/upload.js +2 -2
- package/src/vfs.js +11 -16
- package/src/zip.js +2 -0
- package/frontend/assets/index-5f1c6cb8.js +0 -94
|
@@ -1 +1 @@
|
|
|
1
|
-
@charset "UTF-8";:root{height:100dvh;--bg: #fff;--text: #555;--ghost-contrast: #8882;--ghost-contrast-alt: #eee;--faint-contrast: #8884;--mild-contrast: #8886;--good-contrast: #000a;--button-bg: #6080aa;--button-text: #eaeaea;--focus-color: #468;--separator: " – "}:root .highlightedText,:root .file-menu a:hover{color:#0006;text-shadow:0 0 3px rgba(0,0,0,.4)}:root .theme-dark{--bg: #000;--text: #999;--ghost-contrast-alt: #181818;--good-contrast: #fffa;--button-bg: #345;--button-text: #999;color-scheme:dark}:root .theme-dark .highlightedText,:root .theme-dark .file-menu a:hover,:root .file-menu .theme-dark a:hover{color:#fff;text-shadow:0 0 3px #fff}:root .theme-dark a{color:#8ac}:root .theme-dark .dialog-closer{background:#633}:root .theme-dark .dialog-icon{color:#ccc}:root .theme-dark .dialog-icon .icon{color:#aaa}:root .theme-dark .dialog-backdrop{background:rgba(51,51,51,.7333333333)}:root .theme-dark .error-msg{color:#b88;background-color:#623}:root .theme-dark button.toggled{color:#eee}body{background-color:var(--bg);margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body,button,select,input{font-size:12pt}#root>div{max-width:54em;margin:auto;min-height:100vh;display:flex;flex-direction:column}body,input{color:var(--text)}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}input:not([type=checkbox],[type=range]),select,textarea{padding:.3em .4em;border-radius:.5em;background:var(--bg);border-color:var(--mild-contrast);color:var(--good-contrast);max-width:100%;box-sizing:border-box;width:100%}input[type=range]{width:calc(100% - 1px)}input[type=checkbox]{transform:scale(1.7);accent-color:var(--button-bg)}textarea{font-size:14pt}label input[type=checkbox]{margin-right:.8em}select{text-align:center}.hidden{display:none!important}[class^=fa-]:before,[class*=" fa-"]:before{margin:0}.icon{font-size:1.2em;height:1.2em;width:1.4em;display:inline-block;text-align:center}img.file-icon{height:1em}.file-icon{background-size:contain;background-repeat:no-repeat;background-position:center;vertical-align:text-bottom}.icon.mirror:before{transform:scaleX(-1)}a{text-decoration:none;color:var(--button-bg)}button{background-color:var(--button-bg);color:var(--button-text);padding:.5em 1em;border:transparent;text-decoration:none;border-radius:.3em;vertical-align:middle;cursor:pointer;transition:background-color .5s}button:hover{outline:1px solid var(--mild-contrast)}button[disabled]{background-color:var(--faint-contrast)}button.toggled{color:#fff;text-shadow:0 0 3px #fff}button:focus-visible,.breadcrumb:focus-visible{outline:3px solid var(--focus-color)}a>button{width:100%;height:100%}input:focus-visible,select:focus-visible,ul a:focus-visible{border-radius:.3em;border-color:transparent;outline:2px solid var(--focus-color)}.icon-button,ul.dir li .entry-panel .file-menu-button{font-size:.7em;padding:.2em .4em;margin-left:.4em;vertical-align:bottom}.error-msg{background-color:#faa;color:#833;padding:.5em 1em}.hide-back,.upload-toolbar,header{background-color:var(--bg)}header{position:sticky;top:0;padding:.2em .1em;z-index:3}kbd{background-color:#eee;border-radius:3px;border:1px solid #b4b4b4;box-shadow:0 1px 1px #0003,0 2px #ffffffb3 inset;color:#333;display:inline-block;font-size:.85em;font-weight:700;line-height:1;padding:2px 4px;white-space:nowrap;margin-right:.5em}.before-sliding{width:0!important;flex:0!important;margin:0!important;height:0!important;padding:0!important;overflow:hidden!important;transition:flex .5s}.show-sliding{transition:flex .5s;overflow:clip;flex:1;white-space:nowrap}.ani-working{animation:1s blink infinite}@keyframes blink{0%{opacity:1}50%{opacity:.2}}@keyframes spin{to{transform:rotate(360deg)}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}.spinner,.icon.spinner:before{animation:1.5s spin infinite linear;display:inline-flex;justify-content:center;align-items:center;width:min-content}.breadcrumb{padding:.1em .6em .2em;line-height:1.8em;border-radius:.7em;background-color:var(--button-bg);color:var(--button-text);border-top:1px solid #666;margin-right:-.1em}.breadcrumb:nth-child(-n+3) .icon{padding:0 .2em}#folder-stats,#filter-bar>span{font-size:90%}#folder-stats{margin-left:.5em;line-height:2em;float:right}#folder-stats .icon{margin-right:.3em}#filter{flex:1;box-sizing:border-box}#filter-bar{display:flex;align-items:center;gap:.8em;margin:.2em 0 0;padding:2px 0 1px 3px;height:1.8em}#filter-bar input[type=checkbox]{margin-top:.3em}#filter-bar span:empty{display:none}ul.dir{flex:1;padding:0;margin:0;clear:both}ul.dir>p{text-align:center}ul.dir li{display:block;list-style-type:none;padding:.3em .3em .4em;border-bottom:1px solid var(--faint-contrast)}ul.dir li:nth-of-type(odd){background-color:var(--ghost-contrast)}ul.dir li input[type=checkbox]{margin-right:1em}@media (hover: none){ul.dir li .link-wrapper .popup-menu-button{display:none}}@media (hover: hover){ul.dir li .link-wrapper:not(:hover) .popup-menu-button{display:none}ul.dir li .link-wrapper:hover{padding:1em;margin:-1em}}ul.dir li .link-wrapper a:last-of-type{word-break:break-word;padding-right:.3em}ul.dir li .link-wrapper a .icon{margin-right:.5em;vertical-align:text-bottom;display:inline-block;text-align:center}ul.dir li .link-wrapper a:hover{text-decoration:underline}ul.dir li .entry-panel{float:right;padding-top:.3em;display:flex;align-items:center}ul.dir li .entry-panel .file-menu-button{margin:-3px 0 -3px .4em}ul.dir li .entry-panel .entry-details{font-size:90%;margin-left:4px;font-variant-numeric:tabular-nums}ul.dir li .entry-panel .entry-details .entry-size-unit{margin-left:.3em}ul.dir li>div:last-of-type{clear:both}ul.dir li.page-separator{margin-top:.7em;position:relative}ul.dir li.page-separator:before{content:attr(label);position:absolute;top:-1.5em;font-size:smaller;margin-left:calc(50% - 1em);opacity:.9}.entry-comment{display:inline;white-space:pre-wrap;word-break:break-word}.entry-comment:before,.entry-comment:after{font-size:1.5em;font-family:serif;line-height:1px;position:relative}.entry-comment:before{content:"“";margin-left:.5em;margin-right:.1em;top:.2em}.entry-comment:after{content:"„";top:-.1em;margin-left:.1em}#menu-bar{display:flex;justify-content:space-evenly;flex-wrap:wrap}#menu-bar>*{flex:1;margin:.1em}#menu-bar>*:first-child{margin-left:0}#menu-bar>*:last-child{margin-right:0}#menu-bar button{padding:min(1vh,.5em) 0}#searched{margin:.2em}#user-panel{display:flex;flex-direction:column;gap:1em}#user-panel a>button{width:100%}button label{cursor:inherit;margin-left:.4em}.dialog-backdrop.working{font-size:5em;animation:1s fade-in}.dialog-content{padding:.2em}.dialog-alert .dialog-content{text-align:center}.dialog-alert .dialog-content p{text-align:left;display:inline-block}.dialog{min-width:11em;--color: var(--button-bg)}.dialog-icon .icon{margin-left:-1px;font-size:95%;margin-top:.4em;border-radius:.6em 0}#paging{position:sticky;bottom:0;display:flex;gap:.1em;background-color:var(--bg);padding:0 .2em .2em}#paging>button{z-index:1}#paging button{box-shadow:0 0 .3em .3em #0003}#paging #paging-middle{padding:0 .5em;margin:0 -.3em;display:flex;gap:.5em;flex:1;overflow-x:auto}#paging #paging-middle>button{flex:1;padding-top:0;padding-bottom:0}#paging button{background:var(--button-bg);text-align:center;white-space:nowrap;padding:.5em}.upload-toolbar{position:sticky;top:-4px}.upload-progress:before{content:var(--separator)}.entry-size:after{content:var(--separator)}.upload-progress{min-width:4em;display:inline-block;margin-left:.5em}.upload-list{margin-top:.5em}.upload-list td:nth-child(1){width:0}.upload-list td:nth-child(2){text-align:right;width:0;white-space:nowrap;padding-left:.5em}.upload-list td:nth-child(3){padding:.2em .5em;word-break:break-word}.nowrap{white-space:nowrap}.dialog-login form{display:flex;flex-direction:column;gap:1.2em}.dialog-login label{display:block;margin-bottom:.5em;margin-left:.1em}.miss-perm{margin:0 .3em}.popup-menu-button{font-size:.8em;padding:.2em .3em;position:absolute;opacity:.8;white-space:nowrap}.popup-menu-button:hover{opacity:1}.file-dialog .dialog{min-width:13em}.file-dialog-properties{word-break:break-word;line-height:1.5em;margin:0}.file-dialog-properties dt{font-weight:700}.file-dialog-properties dd{margin-left:1.5em}.file-menu{margin-top:1em;padding-top:1em;border-top:1px solid var(--faint-contrast);display:flex;flex-direction:column;gap:1em}.file-menu a{display:flex;align-items:flex-start}.file-menu a label{margin-top:.1em}.file-menu a label small{display:block}.file-menu a .icon{margin-right:.5em}#root>.tiles-mode{max-width:none;margin:0 1em;--tile-size: 5;--name-lines: 3;--name-height: calc(4.7em + var(--tile-size) * .4em + 1.2em * var(--name-lines));--tile-width: calc(5em + 1em * var(--tile-size))}#root>.tiles-mode ul.dir{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--tile-width),1fr));grid-auto-rows:calc(var(--name-height) + 1.3em);gap:0 20px}#root>.tiles-mode ul.dir li{text-align:center;position:relative;display:flex;flex-direction:column;border-bottom:none;overflow-x:clip;padding:.5em 0 0}#root>.tiles-mode ul.dir li .link-wrapper:not(:hover){max-height:var(--name-height);display:block;display:-webkit-box;overflow:hidden;-webkit-line-clamp:calc(var(--name-lines) + 1);-webkit-box-orient:vertical}#root>.tiles-mode ul.dir li .link-wrapper a:last-of-type{padding:0}#root>.tiles-mode ul.dir li .link-wrapper a span{display:block}#root>.tiles-mode ul.dir li .link-wrapper a .icon.icon{font-size:calc(1.2rem + .6rem * var(--tile-size))}#root>.tiles-mode ul.dir li .link-wrapper a img.icon{width:auto;height:1em;padding:.1em 0}#root>.tiles-mode ul.dir li .link-wrapper a .icon{font-size:4rem;display:block;margin:auto}#root>.tiles-mode ul.dir li .link-wrapper:hover{overflow:visible;display:block;z-index:1}#root>.tiles-mode ul.dir li .link-wrapper:hover .icon:before{text-decoration:none}#root>.tiles-mode ul.dir li .link-wrapper:hover{padding:0;margin:0}#root>.tiles-mode ul.dir li:nth-of-type(odd){background-color:var(--bg)}#root>.tiles-mode ul.dir li .entry-panel{justify-content:center;font-size:10pt}#root>.tiles-mode ul.dir li .entry-details{font-size:80%}#root>.tiles-mode ul.dir li.page-separator:before{content:""}#root>.tiles-mode ul.dir li input[type=checkbox]{margin:0;position:absolute;top:.3em;right:1em}#root>.tiles-mode ul.dir li .link-wrapper a{display:inline}#root>.tiles-mode ul.dir li:hover{--bg: var(--ghost-contrast-alt);background:var(--bg)}#root>.tiles-mode ul.dir li:hover .link-wrapper,#root>.tiles-mode ul.dir li:hover .entry-panel{z-index:1;background:var(--bg)}#root>.tiles-mode ul.dir li:hover input[type=checkbox]{z-index:2}#root>.tiles-mode ul.dir li:hover .entry-panel{padding-bottom:.3em}#root>.tiles-mode .entry-size:after{content:none}#root>.tiles-mode .entry-ts{display:none}#root>.tiles-mode .popup-menu-button{position:absolute;top:0;left:0}#root>.tiles-mode #filter-bar{margin-bottom:1em}#root>.tiles-mode #paging{z-index:1}#root .file-show{--nav-size: min(25vh, 25vw)}#root .file-show>div{height:100%;width:100%}#root .file-show .showing-container{width:100%;height:100%;display:flex;justify-content:center;align-items:center}#root .file-show .showing{max-width:calc(100% - var(--nav-size) * 2);max-height:100%}#root .file-show img.showing{max-width:100%}#root .file-show .main{flex:1;position:relative;max-height:100%;overflow:hidden}#root .file-show .freeY .main,#root .file-show .fullWidth .main{overflow-y:auto}#root .file-show .freeY .showing,#root .file-show .fullWidth .showing{max-height:initial;margin:auto}#root .file-show .freeY .showing-container,#root .file-show .fullWidth .showing-container{overflow:auto;align-items:flex-start}#root .file-show .fullWidth .showing-container,#root .file-show .fullWidth .showing{width:100%}#root .file-show .nav{position:absolute;margin:-.4em;font-size:var(--nav-size);cursor:pointer;opacity:.3;-webkit-text-stroke:2px black;user-select:none;transition:opacity .3s}#root .file-show .nav:hover{opacity:.7}#root .file-show .nav.nav-hidden{opacity:0}#root .file-show .bar{padding:.5em 1em;background:var(--bg);opacity:.8;display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:.5em 1.5em}#root .file-show .bar .entry-details{font-size:smaller}#root .file-show .bar .entry-ts{display:inherit}#root .file-show .bar .entry-size:after{display:none}.file-show-help kbd{margin:.5em}.file-show-help kbd:first-of-type{margin-top:1em}@media (min-width: 42em){body{scrollbar-width:thin;scrollbar-color:var(--button-bg) var(--ghost-contrast)}body::-webkit-scrollbar{width:12px}body::-webkit-scrollbar-track{background:var(--ghost-contrast)}body::-webkit-scrollbar-thumb{background-color:var(--button-bg);border-radius:20px;border:1px solid var(--ghost-contrast)}}@media (max-width: 42em){:root{--ghost-contrast: #8883}body,button,select{font-size:14pt}#menu-bar button label,#filter-bar button label{display:none}#filter-bar{margin-top:.4em}#filter-bar button{width:17.6vw;height:2.3em}.breadcrumb{word-break:break-all}.breadcrumb .icon{font-size:24px}#root>.tiles-mode{margin:0}}@media (max-height: 600px){.file-dialog .dialog-content{display:flex;gap:3em;margin:1em}.file-dialog .dialog-content .file-menu{margin-top:0;padding-top:0;border-top:none;margin-left:2em;padding-left:2em;border-left:1px solid var(--faint-contrast)}}@media (pointer: coarse){#root>.tiles-mode .file-menu-button{font-size:1em;margin-top:.3em}}.dialog-backdrop{position:fixed;inset:0;background:#8886;backdrop-filter:blur(2px);display:flex;justify-content:center;align-items:center;z-index:1000}.dialog{background:#fff;background:var(--bg);padding:max(.5em,1vw,2vh);padding-top:0;border-radius:1em;position:relative;margin:0 3vw;overflow:hidden;max-height:calc(100vh - 2em);display:flex;flex-direction:column;justify-content:center}.dialog-icon{color:#fff;background-color:var(--color);position:absolute;top:0;width:2em;height:1.8em;text-align:center;border-radius:.8em 0}.dialog-icon-text{display:flex;align-items:center;justify-content:center}.dialog-title{font-size:120%;margin:.3em 0;padding:0 .5em;min-height:1.2em}.dialog-closer~.dialog-title{margin-right:2em}.dialog-type~.dialog-title{margin-left:2em}.dialog-icon~.dialog-title{text-align:center}.dialog-closer{border-radius:0 .8em;right:0;padding:0;background-color:#c88}.dialog-icon~.dialog-content{margin-top:1em}.dialog-type{left:0;top:0;overflow:hidden;opacity:.7}.dialog-content{overflow:auto;max-height:calc(100vh - 4.5em)}.dialog-content p{white-space:pre-wrap;margin:.5em 0}.dialog-confirm .dialog-content button{margin-top:1em}.dialog-alert-info{--color: #282 }.dialog-alert-warning{--color: #c91 }.dialog-alert-error{--color: #822}@media (max-width: 42em){.dialog-icon{font-size:120%}.dialog-icon~.dialog-content{margin-top:1.5em}}.dialog-prompt label{display:block;margin:.5em .1em}
|
|
1
|
+
@charset "UTF-8";:root{height:100dvh;--bg: #fff;--text: #555;--ghost-contrast: #8882;--ghost-contrast-alt: #eee;--faint-contrast: #8884;--mild-contrast: #8886;--good-contrast: #000a;--button-bg: #6080aa;--button-text: #eaeaea;--focus-color: #468;--separator: " – "}:root .highlightedText,:root .file-menu a:hover{color:#0006;text-shadow:0 0 3px rgba(0,0,0,.4)}:root .theme-dark{--bg: #000;--text: #999;--ghost-contrast-alt: #181818;--good-contrast: #fffa;--button-bg: #345;--button-text: #999;color-scheme:dark}:root .theme-dark .highlightedText,:root .theme-dark .file-menu a:hover,:root .file-menu .theme-dark a:hover{color:#fff;text-shadow:0 0 3px #fff}:root .theme-dark a{color:#8ac}:root .theme-dark .dialog-closer{background:#633}:root .theme-dark .dialog-icon{color:#ccc}:root .theme-dark .dialog-icon .icon{color:#aaa}:root .theme-dark .dialog-backdrop{background:rgba(51,51,51,.7333333333)}:root .theme-dark .error-msg{color:#b88;background-color:#623}:root .theme-dark button.toggled{color:#eee}body{background-color:var(--bg);margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body,button,select,input{font-size:12pt}#root>div{max-width:54em;margin:auto;min-height:100vh;display:flex;flex-direction:column}body,input{color:var(--text)}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}input:not([type=checkbox],[type=range]),select,textarea{padding:.3em .4em;border-radius:.5em;background:var(--bg);border-color:var(--mild-contrast);color:var(--good-contrast);max-width:100%;box-sizing:border-box;width:100%}input[type=range]{width:calc(100% - 1px)}input[type=checkbox]{transform:scale(1.7);accent-color:var(--button-bg)}textarea{font-size:14pt}label input[type=checkbox]{margin-right:.8em}select{text-align:center}.hidden{display:none!important}[class^=fa-]:before,[class*=" fa-"]:before{margin:0}.icon{font-size:1.2em;height:1.2em;width:1.4em;display:inline-block;text-align:center}img.file-icon{height:1em}.file-icon{background-size:contain;background-repeat:no-repeat;background-position:center;vertical-align:text-bottom}.icon.mirror:before{transform:scaleX(-1)}a{text-decoration:none;color:var(--button-bg)}button{background-color:var(--button-bg);color:var(--button-text);padding:.5em 1em;border:transparent;text-decoration:none;border-radius:.3em;vertical-align:middle;cursor:pointer;transition:background-color .5s}button:hover{outline:1px solid var(--mild-contrast)}button[disabled]{background-color:var(--faint-contrast)}button.toggled{color:#fff;text-shadow:0 0 3px #fff}button:focus-visible,.breadcrumb:focus-visible{outline:3px solid var(--focus-color)}a>button{width:100%;height:100%}input:focus-visible,select:focus-visible,ul a:focus-visible{border-radius:.3em;border-color:transparent;outline:2px solid var(--focus-color)}.icon-button,ul.dir li .entry-panel .file-menu-button{font-size:.7em;padding:.2em .4em;margin-left:.4em;vertical-align:bottom}.error-msg{background-color:#faa;color:#833;padding:.5em 1em}.hide-back,.upload-toolbar,header{background-color:var(--bg)}header{position:sticky;top:0;padding:.2em .1em;z-index:3}kbd{background-color:#eee;border-radius:3px;border:1px solid #b4b4b4;box-shadow:0 1px 1px #0003,0 2px #ffffffb3 inset;color:#333;display:inline-block;font-size:.85em;font-weight:700;line-height:1;padding:2px 4px;white-space:nowrap;margin-right:.5em}.before-sliding{width:0!important;flex:0!important;margin:0!important;height:0!important;padding:0!important;overflow:hidden!important;transition:flex .5s}.show-sliding{transition:flex .5s;overflow:clip;flex:1;white-space:nowrap}.ani-working{animation:1s blink infinite}@keyframes blink{0%{opacity:1}50%{opacity:.2}}@keyframes spin{to{transform:rotate(360deg)}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}.spinner,.icon.spinner:before{animation:1.5s spin infinite linear;display:inline-flex;justify-content:center;align-items:center;width:min-content}.breadcrumb{padding:.1em .6em .2em;line-height:1.8em;border-radius:.7em;background-color:var(--button-bg);color:var(--button-text);border-top:1px solid #666;margin-right:-.1em}.breadcrumb:nth-child(-n+3) .icon{padding:0 .2em}#folder-stats,#filter-bar>span{font-size:90%}#folder-stats{margin-left:.5em;line-height:2em;float:right}#folder-stats .icon{margin-right:.3em}#filter{flex:1;box-sizing:border-box}#filter-bar{display:flex;align-items:center;gap:.8em;margin:.2em 0 0;padding:2px 0 1px 3px;height:1.8em}#filter-bar input[type=checkbox]{margin-top:.3em}#filter-bar span:empty{display:none}ul.dir{flex:1;padding:0;margin:0;clear:both}ul.dir>p{text-align:center}ul.dir li{display:block;list-style-type:none;padding:.3em .3em .4em;border-bottom:1px solid var(--faint-contrast)}ul.dir li:nth-of-type(odd){background-color:var(--ghost-contrast)}ul.dir li input[type=checkbox]{margin-right:1em}@media (hover: none){ul.dir li .link-wrapper .popup-menu-button{display:none}}@media (hover: hover){ul.dir li .link-wrapper:not(:hover) .popup-menu-button{display:none}ul.dir li .link-wrapper:hover{padding:1em;margin:-1em}}ul.dir li .link-wrapper a:last-of-type{word-break:break-word;padding-right:.3em}ul.dir li .link-wrapper a .icon{margin-right:.5em;vertical-align:text-bottom;display:inline-block;text-align:center}ul.dir li .link-wrapper a:hover{text-decoration:underline}ul.dir li .entry-panel{float:right;padding-top:.3em;display:flex;align-items:center}ul.dir li .entry-panel .file-menu-button{margin:-3px 0 -3px .4em}ul.dir li .entry-panel .entry-details{font-size:90%;margin-left:4px;font-variant-numeric:tabular-nums}ul.dir li .entry-panel .entry-details .entry-size-unit{margin-left:.3em}ul.dir li>div:last-of-type{clear:both}ul.dir li.page-separator{margin-top:.7em;position:relative}ul.dir li.page-separator:before{content:attr(label);position:absolute;top:-1.5em;font-size:smaller;margin-left:calc(50% - 1em);opacity:.9}.entry-comment{display:inline;white-space:pre-wrap;word-break:break-word}.entry-comment:before,.entry-comment:after{font-size:1.5em;font-family:serif;line-height:1px;position:relative}.entry-comment:before{content:"“";margin-left:.5em;margin-right:.1em;top:.2em}.entry-comment:after{content:"„";top:-.1em;margin-left:.1em}#menu-bar{display:flex;justify-content:space-evenly;flex-wrap:wrap}#menu-bar>*{flex:1;margin:.1em}#menu-bar>*:first-child{margin-left:0}#menu-bar>*:last-child{margin-right:0}#menu-bar button{padding:min(1vh,.5em) 0}#searched{margin:.2em}#user-panel{display:flex;flex-direction:column;gap:1em}#user-panel a>button{width:100%}button label{cursor:inherit;margin-left:.4em}.dialog-backdrop.working{font-size:5em;animation:1s fade-in}.dialog-content{padding:.2em}.dialog-alert .dialog-content{text-align:center}.dialog-alert .dialog-content p{text-align:left;display:inline-block}.dialog{min-width:11em;--color: var(--button-bg)}.dialog-icon .icon{margin-left:-1px;font-size:95%;margin-top:.4em;border-radius:.6em 0}#paging{position:sticky;bottom:0;display:flex;gap:.1em;background-color:var(--bg);padding:0 .2em .2em}#paging>button{z-index:1}#paging button{box-shadow:0 0 .3em .3em #0003}#paging #paging-middle{padding:0 .5em;margin:0 -.3em;display:flex;gap:.5em;flex:1;overflow-x:auto}#paging #paging-middle>button{flex:1;padding-top:0;padding-bottom:0}#paging button{background:var(--button-bg);text-align:center;white-space:nowrap;padding:.5em}.upload-toolbar{position:sticky;top:-4px}.upload-progress:before{content:var(--separator)}.entry-size:after{content:var(--separator)}.upload-progress{min-width:4em;display:inline-block;margin-left:.5em}.upload-list{margin-top:.5em}.upload-list td:nth-child(1){width:0}.upload-list td:nth-child(2){text-align:right;width:0;white-space:nowrap;padding-left:.5em}.upload-list td:nth-child(3){padding:.2em .5em;word-break:break-word}.nowrap{white-space:nowrap}.dialog-login form{display:flex;flex-direction:column;gap:1.2em}.dialog-login label{display:block;margin-bottom:.5em;margin-left:.1em}.miss-perm{margin:0 .3em}.popup-menu-button{font-size:.8em;padding:.2em .3em;position:absolute;opacity:.8;white-space:nowrap}.popup-menu-button:hover{opacity:1}.file-dialog .dialog{min-width:13em}.file-dialog-properties{word-break:break-word;line-height:1.5em;margin:0}.file-dialog-properties dt{font-weight:700}.file-dialog-properties dd{margin-left:1.5em}.file-menu{margin-top:1em;padding-top:1em;border-top:1px solid var(--faint-contrast);display:flex;flex-direction:column;gap:1em}.file-menu a{display:flex;align-items:flex-start}.file-menu a label{margin-top:.1em}.file-menu a label small{display:block}.file-menu a .icon{margin-right:.5em}.unauthorized{text-align:center}#root>.tiles-mode{max-width:none;margin:0 1em;--tile-size: 5;--name-lines: 3;--name-height: calc(4.7em + var(--tile-size) * .4em + 1.2em * var(--name-lines));--tile-width: calc(5em + 1em * var(--tile-size))}#root>.tiles-mode ul.dir{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--tile-width),1fr));grid-auto-rows:calc(var(--name-height) + 1.3em);gap:0 20px}#root>.tiles-mode ul.dir li{text-align:center;position:relative;display:flex;flex-direction:column;border-bottom:none;overflow-x:clip;padding:.5em 0 0}#root>.tiles-mode ul.dir li .link-wrapper:not(:hover){max-height:var(--name-height);display:block;display:-webkit-box;overflow:hidden;-webkit-line-clamp:calc(var(--name-lines) + 1);-webkit-box-orient:vertical}#root>.tiles-mode ul.dir li .link-wrapper a:last-of-type{padding:0}#root>.tiles-mode ul.dir li .link-wrapper a span{display:block}#root>.tiles-mode ul.dir li .link-wrapper a .icon.icon{font-size:calc(1.2rem + .6rem * var(--tile-size))}#root>.tiles-mode ul.dir li .link-wrapper a img.icon{width:auto;height:1em;padding:.1em 0}#root>.tiles-mode ul.dir li .link-wrapper a .icon{font-size:4rem;display:block;margin:auto}#root>.tiles-mode ul.dir li .link-wrapper:hover{overflow:visible;display:block;z-index:1}#root>.tiles-mode ul.dir li .link-wrapper:hover .icon:before{text-decoration:none}#root>.tiles-mode ul.dir li .link-wrapper:hover{padding:0;margin:0}#root>.tiles-mode ul.dir li:nth-of-type(odd){background-color:var(--bg)}#root>.tiles-mode ul.dir li .entry-panel{justify-content:center;font-size:10pt}#root>.tiles-mode ul.dir li .entry-details{font-size:80%}#root>.tiles-mode ul.dir li.page-separator:before{content:""}#root>.tiles-mode ul.dir li input[type=checkbox]{margin:0;position:absolute;top:.3em;right:1em}#root>.tiles-mode ul.dir li .link-wrapper a{display:inline}#root>.tiles-mode ul.dir li:hover{--bg: var(--ghost-contrast-alt);background:var(--bg)}#root>.tiles-mode ul.dir li:hover .link-wrapper,#root>.tiles-mode ul.dir li:hover .entry-panel{z-index:1;background:var(--bg)}#root>.tiles-mode ul.dir li:hover input[type=checkbox]{z-index:2}#root>.tiles-mode ul.dir li:hover .entry-panel{padding-bottom:.3em}#root>.tiles-mode .entry-size:after{content:none}#root>.tiles-mode .entry-ts{display:none}#root>.tiles-mode .popup-menu-button{position:absolute;top:0;left:0}#root>.tiles-mode #filter-bar{margin-bottom:1em}#root>.tiles-mode #paging{z-index:1}#root .file-show{--nav-size: min(25vh, 25vw)}#root .file-show>div{height:100%;width:100%}#root .file-show .showing-container{width:100%;height:100%;display:flex;justify-content:center;align-items:center}#root .file-show .showing{max-width:calc(100% - var(--nav-size) * 2);max-height:100%}#root .file-show img.showing{max-width:100%}#root .file-show .main{flex:1;position:relative;max-height:100%;overflow:hidden}#root .file-show .freeY .main,#root .file-show .fullWidth .main{overflow-y:auto}#root .file-show .freeY .showing,#root .file-show .fullWidth .showing{max-height:initial;margin:auto}#root .file-show .freeY .showing-container,#root .file-show .fullWidth .showing-container{overflow:auto;align-items:flex-start}#root .file-show .fullWidth .showing-container,#root .file-show .fullWidth .showing{width:100%}#root .file-show .nav{position:absolute;margin:-.4em;font-size:var(--nav-size);cursor:pointer;opacity:.3;-webkit-text-stroke:2px black;user-select:none;transition:opacity .3s}#root .file-show .nav:hover{opacity:.7}#root .file-show .nav.nav-hidden{opacity:0}#root .file-show .bar{padding:.5em 1em;background:var(--bg);opacity:.8;display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:.5em 1.5em}#root .file-show .bar .entry-details{font-size:smaller}#root .file-show .bar .entry-ts{display:inherit}#root .file-show .bar .entry-size:after{display:none}.file-show-help kbd{margin:.5em}.file-show-help kbd:first-of-type{margin-top:1em}@media (min-width: 42em){body{scrollbar-width:thin;scrollbar-color:var(--button-bg) var(--ghost-contrast)}body::-webkit-scrollbar{width:12px}body::-webkit-scrollbar-track{background:var(--ghost-contrast)}body::-webkit-scrollbar-thumb{background-color:var(--button-bg);border-radius:20px;border:1px solid var(--ghost-contrast)}}@media (max-width: 42em){:root{--ghost-contrast: #8883}body,button,select{font-size:14pt}#menu-bar button label,#filter-bar button label{display:none}#filter-bar{margin-top:.4em}#filter-bar button{width:17.6vw;height:2.3em}.breadcrumb{word-break:break-all}.breadcrumb .icon{font-size:24px}#root>.tiles-mode{margin:0}}@media (max-height: 600px){.file-dialog .dialog-content{display:flex;gap:3em;margin:1em}.file-dialog .dialog-content .file-menu{margin-top:0;padding-top:0;border-top:none;margin-left:2em;padding-left:2em;border-left:1px solid var(--faint-contrast)}}@media (pointer: coarse){#root>.tiles-mode .file-menu-button{font-size:1em;margin-top:.3em}}.dialog-backdrop{position:fixed;inset:0;background:#8886;backdrop-filter:blur(2px);display:flex;justify-content:center;align-items:center;z-index:1000}.dialog{background:#fff;background:var(--bg);padding:max(.5em,1vw,2vh);padding-top:0;border-radius:1em;position:relative;margin:0 3vw;overflow:hidden;max-height:calc(100vh - 2em);display:flex;flex-direction:column;justify-content:center}.dialog-icon{color:#fff;background-color:var(--color);position:absolute;top:0;width:2em;height:1.8em;text-align:center;border-radius:.8em 0}.dialog-icon-text{display:flex;align-items:center;justify-content:center}.dialog-title{font-size:120%;margin:.3em 0;padding:0 .5em;min-height:1.2em}.dialog-closer~.dialog-title{margin-right:2em}.dialog-type~.dialog-title{margin-left:2em}.dialog-icon~.dialog-title{text-align:center}.dialog-closer{border-radius:0 .8em;right:0;padding:0;background-color:#c88}.dialog-icon~.dialog-content{margin-top:1em}.dialog-type{left:0;top:0;overflow:hidden;opacity:.7}.dialog-content{overflow:auto;max-height:calc(100vh - 4.5em)}.dialog-content p{white-space:pre-wrap;margin:.5em 0}.dialog-confirm .dialog-content button{margin-top:1em}.dialog-alert-info{--color: #282 }.dialog-alert-warning{--color: #c91 }.dialog-alert-error{--color: #822}@media (max-width: 42em){.dialog-icon{font-size:120%}.dialog-icon~.dialog-content{margin-top:1.5em}}.dialog-prompt label{display:block;margin:.5em .1em}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{g as OF,c as UF}from"./index-
|
|
1
|
+
import{g as OF,c as UF}from"./index-629107cf.js";function gF(sF,hF){for(var eF=0;eF<hF.length;eF++){const tF=hF[eF];if(typeof tF!="string"&&!Array.isArray(tF)){for(const w in tF)if(w!=="default"&&!(w in sF)){const lF=Object.getOwnPropertyDescriptor(tF,w);lF&&Object.defineProperty(sF,w,lF.get?lF:{enumerable:!0,get:()=>tF[w]})}}}return Object.freeze(Object.defineProperty(sF,Symbol.toStringTag,{value:"Module"}))}var dF={exports:{}};/*
|
|
2
2
|
* [js-sha512]{@link https://github.com/emn178/js-sha512}
|
|
3
3
|
*
|
|
4
4
|
* @version 0.8.0
|
package/frontend/index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=0" />
|
|
6
6
|
<link href="/fontello.css" rel="stylesheet" />
|
|
7
7
|
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="stylesheet" href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-629107cf.js"></script>
|
|
9
|
+
<link rel="stylesheet" href="/assets/index-88f77c85.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hfs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.50.0-alpha3",
|
|
4
4
|
"description": "HTTP File Server",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"file server",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"watch-server-proxied": "cross-env FRONTEND_PROXY=3005 ADMIN_PROXY=3006 npm run watch-server",
|
|
16
16
|
"start-frontend": "npm run start --workspace=frontend",
|
|
17
17
|
"start-admin": "npm run start --workspace=admin",
|
|
18
|
-
"build-all": "
|
|
18
|
+
"build-all": "rm -rf dist && npm i && npm run build-server && npm run build-frontend && npm run build-admin && echo COMPLETED",
|
|
19
19
|
"build-server": "rm -rf dist/src dist/plugins && tsc --target es2018 && touch package.json && cp -v -r package.json central.json README* LICENSE* plugins dist && find dist -name .DS_Store -delete && node afterbuild.js",
|
|
20
20
|
"build-frontend": "npm run build --workspace=frontend",
|
|
21
21
|
"build-admin": "npm run build --workspace=admin",
|
|
@@ -72,6 +72,7 @@
|
|
|
72
72
|
"formidable": "^3.5.1",
|
|
73
73
|
"fs-x-attributes": "^1.0.2",
|
|
74
74
|
"iconv-lite": "^0.6.3",
|
|
75
|
+
"ip2location-nodejs": "^9.6.0",
|
|
75
76
|
"koa": "^2.13.4",
|
|
76
77
|
"koa-compress": "^5.1.0",
|
|
77
78
|
"koa-mount": "^4.0.0",
|
|
@@ -13,7 +13,7 @@ exports.configDialog = {
|
|
|
13
13
|
const byIp = {}
|
|
14
14
|
|
|
15
15
|
exports.init = api => {
|
|
16
|
-
const LOGIN_URI = api.
|
|
16
|
+
const LOGIN_URI = api.Const.API_URI + 'loginSrp1'
|
|
17
17
|
const { getOrSet } = api.require('./misc')
|
|
18
18
|
return {
|
|
19
19
|
async middleware(ctx) {
|
|
@@ -26,11 +26,11 @@ exports.init = api => {
|
|
|
26
26
|
return {
|
|
27
27
|
middleware(ctx) {
|
|
28
28
|
let params // undefined if we are not going to work on api parameters
|
|
29
|
-
if (ctx.path.startsWith(api.
|
|
30
|
-
if (!ctx.path.startsWith(api.
|
|
29
|
+
if (ctx.path.startsWith(api.Const.SPECIAL_URI)) { // special uris should be excluded...
|
|
30
|
+
if (!ctx.path.startsWith(api.Const.API_URI)) return // ...unless it's an api
|
|
31
31
|
let { referer } = ctx.headers
|
|
32
32
|
referer &&= new URL(referer).pathname
|
|
33
|
-
if (referer?.startsWith(ctx.state.revProxyPath + api.
|
|
33
|
+
if (referer?.startsWith(ctx.state.revProxyPath + api.Const.ADMIN_URI)) return // exclude apis for admin-panel
|
|
34
34
|
params = ctx.params || ctx.query // for api we'll translate params
|
|
35
35
|
}
|
|
36
36
|
|
package/src/adminApis.js
CHANGED
|
@@ -55,6 +55,7 @@ const update_1 = require("./update");
|
|
|
55
55
|
const consoleLog_1 = require("./consoleLog");
|
|
56
56
|
const path_1 = require("path");
|
|
57
57
|
const errorPages_1 = require("./errorPages");
|
|
58
|
+
const geo_1 = require("./geo");
|
|
58
59
|
exports.adminApis = {
|
|
59
60
|
...api_vfs_1.default,
|
|
60
61
|
...api_accounts_1.default,
|
|
@@ -62,19 +63,18 @@ exports.adminApis = {
|
|
|
62
63
|
...api_monitor_1.default,
|
|
63
64
|
...api_lang_1.default,
|
|
64
65
|
...api_net_1.default,
|
|
65
|
-
async set_config({ values
|
|
66
|
+
async set_config({ values }) {
|
|
66
67
|
var _a;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
68
|
+
(0, misc_1.apiAssertTypes)({ object: { values } });
|
|
69
|
+
(0, config_1.setConfig)(values);
|
|
70
|
+
if (values.port === 0 || values.https_port === 0)
|
|
71
|
+
return (_a = await (0, misc_1.waitFor)(async () => {
|
|
72
|
+
const st = await (0, listen_1.getServerStatus)();
|
|
73
|
+
// wait for all random ports to be done, so we communicate new numbers
|
|
74
|
+
if ((values.port !== 0 || st.http.listening)
|
|
75
|
+
&& (values.https_port !== 0 || st.https.listening))
|
|
76
|
+
return st;
|
|
77
|
+
}, { timeout: 1000 })) !== null && _a !== void 0 ? _a : new apiMiddleware_1.ApiError(const_1.HTTP_SERVER_ERROR, "something went wrong changing ports");
|
|
78
78
|
return {};
|
|
79
79
|
},
|
|
80
80
|
get_config: config_1.getWholeConfig,
|
|
@@ -90,6 +90,12 @@ exports.adminApis = {
|
|
|
90
90
|
async check_update() {
|
|
91
91
|
return { options: await (0, update_1.getUpdates)() };
|
|
92
92
|
},
|
|
93
|
+
async ip_country({ ips }) {
|
|
94
|
+
const res = await Promise.allSettled(ips.map(geo_1.ip2country));
|
|
95
|
+
return {
|
|
96
|
+
codes: res.map(x => x.status === 'rejected' || x.value === '-' ? '' : x.value)
|
|
97
|
+
};
|
|
98
|
+
},
|
|
93
99
|
get_custom_html() {
|
|
94
100
|
return {
|
|
95
101
|
sections: Object.fromEntries([
|
package/src/api.accounts.js
CHANGED
|
@@ -9,12 +9,14 @@ const apiMiddleware_1 = require("./apiMiddleware");
|
|
|
9
9
|
const perm_1 = require("./perm");
|
|
10
10
|
const lodash_1 = __importDefault(require("lodash"));
|
|
11
11
|
const const_1 = require("./const");
|
|
12
|
+
const auth_1 = require("./auth");
|
|
12
13
|
function prepareAccount(ac) {
|
|
13
14
|
return ac && {
|
|
14
15
|
...lodash_1.default.omit(ac, ['password', 'hashed_password', 'srp']),
|
|
15
16
|
username: ac.username,
|
|
16
17
|
hasPassword: (0, perm_1.accountHasPassword)(ac),
|
|
17
18
|
adminActualAccess: (0, perm_1.accountCanLoginAdmin)(ac),
|
|
19
|
+
invalidated: auth_1.invalidSessions.has(ac.username),
|
|
18
20
|
};
|
|
19
21
|
}
|
|
20
22
|
const apis = {
|
|
@@ -22,7 +24,7 @@ const apis = {
|
|
|
22
24
|
return { list: Object.keys(perm_1.accountsConfig.get()) };
|
|
23
25
|
},
|
|
24
26
|
get_account({ username }, ctx) {
|
|
25
|
-
return prepareAccount((0, perm_1.getAccount)(username || (0,
|
|
27
|
+
return prepareAccount((0, perm_1.getAccount)(username || (0, auth_1.getCurrentUsername)(ctx)))
|
|
26
28
|
|| new apiMiddleware_1.ApiError(const_1.HTTP_NOT_FOUND);
|
|
27
29
|
},
|
|
28
30
|
get_accounts() {
|
|
@@ -51,6 +53,10 @@ const apis = {
|
|
|
51
53
|
del_account({ username }) {
|
|
52
54
|
return (0, perm_1.delAccount)(username) ? {} : new apiMiddleware_1.ApiError(const_1.HTTP_BAD_REQUEST);
|
|
53
55
|
},
|
|
56
|
+
invalidate_sessions({ username }) {
|
|
57
|
+
auth_1.invalidSessions.add(username);
|
|
58
|
+
return {};
|
|
59
|
+
},
|
|
54
60
|
async change_password_others({ username, newPassword }) {
|
|
55
61
|
const a = (0, perm_1.getAccount)(username);
|
|
56
62
|
return a ? (0, api_helpers_1.changePasswordHelper)(a, newPassword)
|
package/src/api.auth.js
CHANGED
|
@@ -1,31 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// This file is part of HFS - Copyright 2021-2023, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.change_srp = exports.change_password = exports.refresh_session = exports.logout = exports.loginSrp2 = exports.
|
|
4
|
+
exports.change_srp = exports.change_password = exports.refresh_session = exports.logout = exports.loginSrp2 = exports.loginSrp1 = exports.login = void 0;
|
|
5
5
|
const perm_1 = require("./perm");
|
|
6
6
|
const crypt_1 = require("./crypt");
|
|
7
7
|
const apiMiddleware_1 = require("./apiMiddleware");
|
|
8
|
-
const tssrp6a_1 = require("tssrp6a");
|
|
9
8
|
const const_1 = require("./const");
|
|
10
9
|
const api_helpers_1 = require("./api.helpers");
|
|
11
10
|
const adminApis_1 = require("./adminApis");
|
|
12
11
|
const middlewares_1 = require("./middlewares");
|
|
12
|
+
const auth_1 = require("./auth");
|
|
13
13
|
const config_1 = require("./config");
|
|
14
|
-
const srp6aNimbusRoutines = new tssrp6a_1.SRPRoutines(new tssrp6a_1.SRPParameters());
|
|
15
14
|
const ongoingLogins = {}; // store data that doesn't fit session object
|
|
16
15
|
const keepSessionAlive = (0, config_1.defineConfig)('keep_session_alive', true);
|
|
17
|
-
// centralized log-in state
|
|
18
|
-
async function loggedIn(ctx, username) {
|
|
19
|
-
const s = ctx.session;
|
|
20
|
-
if (!s)
|
|
21
|
-
return ctx.throw(const_1.HTTP_SERVER_ERROR, 'session');
|
|
22
|
-
if (username === false) {
|
|
23
|
-
delete s.username;
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
s.username = (0, perm_1.normalizeUsername)(username);
|
|
27
|
-
await (0, middlewares_1.prepareState)(ctx, async () => { }); // updating the state is necessary to send complete session data so that frontend shows admin button
|
|
28
|
-
}
|
|
29
16
|
function makeExp() {
|
|
30
17
|
return !keepSessionAlive.get() ? undefined
|
|
31
18
|
: { exp: new Date(Date.now() + middlewares_1.sessionDuration.compiled()) };
|
|
@@ -42,7 +29,7 @@ const login = async ({ username, password }, ctx) => {
|
|
|
42
29
|
return new apiMiddleware_1.ApiError(const_1.HTTP_UNAUTHORIZED);
|
|
43
30
|
if (!ctx.session)
|
|
44
31
|
return new apiMiddleware_1.ApiError(const_1.HTTP_SERVER_ERROR);
|
|
45
|
-
await loggedIn(ctx, username);
|
|
32
|
+
await (0, auth_1.loggedIn)(ctx, username);
|
|
46
33
|
return { ...makeExp(), redirect: account.redirect };
|
|
47
34
|
};
|
|
48
35
|
exports.login = login;
|
|
@@ -55,7 +42,7 @@ const loginSrp1 = async ({ username }, ctx) => {
|
|
|
55
42
|
if (!account || !(0, perm_1.accountCanLogin)(account)) // TODO simulate fake account to prevent knowing valid usernames
|
|
56
43
|
return new apiMiddleware_1.ApiError(const_1.HTTP_UNAUTHORIZED);
|
|
57
44
|
try {
|
|
58
|
-
const { step1, ...rest } = await srpStep1(account);
|
|
45
|
+
const { step1, ...rest } = await (0, auth_1.srpStep1)(account);
|
|
59
46
|
const sid = Math.random();
|
|
60
47
|
ongoingLogins[sid] = step1;
|
|
61
48
|
setTimeout(() => delete ongoingLogins[sid], 60000);
|
|
@@ -67,17 +54,6 @@ const loginSrp1 = async ({ username }, ctx) => {
|
|
|
67
54
|
}
|
|
68
55
|
};
|
|
69
56
|
exports.loginSrp1 = loginSrp1;
|
|
70
|
-
async function srpStep1(account) {
|
|
71
|
-
if (!account.srp)
|
|
72
|
-
throw const_1.HTTP_NOT_ACCEPTABLE;
|
|
73
|
-
const [salt, verifier] = account.srp.split('|');
|
|
74
|
-
if (!salt || !verifier)
|
|
75
|
-
throw Error("malformed account");
|
|
76
|
-
const srpSession = new tssrp6a_1.SRPServerSession(srp6aNimbusRoutines);
|
|
77
|
-
const step1 = await srpSession.step1(account.username, BigInt(salt), BigInt(verifier));
|
|
78
|
-
return { step1, salt, pubKey: String(step1.B) }; // cast to string cause bigint can't be jsonized
|
|
79
|
-
}
|
|
80
|
-
exports.srpStep1 = srpStep1;
|
|
81
57
|
const loginSrp2 = async ({ pubKey, proof }, ctx) => {
|
|
82
58
|
var _a;
|
|
83
59
|
if (!ctx.session)
|
|
@@ -90,7 +66,7 @@ const loginSrp2 = async ({ pubKey, proof }, ctx) => {
|
|
|
90
66
|
return new apiMiddleware_1.ApiError(const_1.HTTP_NOT_FOUND);
|
|
91
67
|
try {
|
|
92
68
|
const M2 = await step1.step2(BigInt(pubKey), BigInt(proof));
|
|
93
|
-
await loggedIn(ctx, username);
|
|
69
|
+
await (0, auth_1.loggedIn)(ctx, username);
|
|
94
70
|
delete ctx.session.loggingIn;
|
|
95
71
|
return {
|
|
96
72
|
proof: String(M2),
|
|
@@ -109,14 +85,14 @@ exports.loginSrp2 = loginSrp2;
|
|
|
109
85
|
const logout = async ({}, ctx) => {
|
|
110
86
|
if (!ctx.session)
|
|
111
87
|
return new apiMiddleware_1.ApiError(const_1.HTTP_SERVER_ERROR);
|
|
112
|
-
await loggedIn(ctx, false);
|
|
88
|
+
await (0, auth_1.loggedIn)(ctx, false);
|
|
113
89
|
// 401 is a convenient code for OK: the browser clears a possible http authentication (hopefully), and Admin automatically triggers login dialog
|
|
114
90
|
return new apiMiddleware_1.ApiError(const_1.HTTP_UNAUTHORIZED);
|
|
115
91
|
};
|
|
116
92
|
exports.logout = logout;
|
|
117
93
|
const refresh_session = async ({}, ctx) => {
|
|
118
94
|
return !ctx.session ? new apiMiddleware_1.ApiError(const_1.HTTP_SERVER_ERROR) : {
|
|
119
|
-
username: (0,
|
|
95
|
+
username: (0, auth_1.getCurrentUsername)(ctx),
|
|
120
96
|
adminUrl: (0, adminApis_1.ctxAdminAccess)(ctx) ? ctx.state.revProxyPath + const_1.ADMIN_URI : undefined,
|
|
121
97
|
canChangePassword: canChangePassword(ctx.state.account),
|
|
122
98
|
...makeExp(),
|
package/src/api.file_list.js
CHANGED
|
@@ -10,6 +10,7 @@ const misc_1 = require("./misc");
|
|
|
10
10
|
const const_1 = require("./const");
|
|
11
11
|
const comments_1 = require("./comments");
|
|
12
12
|
const path_1 = require("path");
|
|
13
|
+
const connections_1 = require("./connections");
|
|
13
14
|
const get_file_list = async ({ uri, offset, limit, search, c }, ctx) => {
|
|
14
15
|
const node = await (0, vfs_1.urlToNode)(uri || '/', ctx);
|
|
15
16
|
const list = ctx.get('accept') === 'text/event-stream' ? new apiMiddleware_1.SendListReadable() : undefined;
|
|
@@ -35,6 +36,8 @@ const get_file_list = async ({ uri, offset, limit, search, c }, ctx) => {
|
|
|
35
36
|
if (!list)
|
|
36
37
|
return { ...props, list: await (0, misc_1.asyncGeneratorToArray)(produceEntries()) };
|
|
37
38
|
setTimeout(async () => {
|
|
39
|
+
ctx.state.browsing = uri;
|
|
40
|
+
(0, connections_1.updateConnection)((0, connections_1.getConnection)(ctx), { ctx });
|
|
38
41
|
list.props(props);
|
|
39
42
|
for await (const entry of produceEntries())
|
|
40
43
|
list.add(entry);
|
|
@@ -88,8 +91,10 @@ const get_file_list = async ({ uri, offset, limit, search, c }, ctx) => {
|
|
|
88
91
|
return node.default && await (0, vfs_1.urlToNode)(node.default, ctx, node);
|
|
89
92
|
}
|
|
90
93
|
async function nodeToDirEntry(ctx, node) {
|
|
91
|
-
let { source } = node;
|
|
94
|
+
let { source, url } = node;
|
|
92
95
|
const name = (0, vfs_1.getNodeName)(node);
|
|
96
|
+
if (url)
|
|
97
|
+
return name ? { n: name, url } : null;
|
|
93
98
|
if (!source)
|
|
94
99
|
return name ? { n: name + '/' } : null;
|
|
95
100
|
if (node.isFolder && await hasDefaultFile(node))
|
package/src/api.monitor.js
CHANGED
|
@@ -9,7 +9,7 @@ const connections_1 = require("./connections");
|
|
|
9
9
|
const misc_1 = require("./misc");
|
|
10
10
|
const apiMiddleware_1 = require("./apiMiddleware");
|
|
11
11
|
const throttler_1 = require("./throttler");
|
|
12
|
-
const
|
|
12
|
+
const auth_1 = require("./auth");
|
|
13
13
|
const apis = {
|
|
14
14
|
async disconnect({ ip, port, wait }) {
|
|
15
15
|
var _a, _b;
|
|
@@ -75,20 +75,24 @@ const apis = {
|
|
|
75
75
|
v: (((_a = socket.remoteFamily) === null || _a === void 0 ? void 0 : _a.endsWith('6')) ? 6 : 4),
|
|
76
76
|
got: socket.bytesRead,
|
|
77
77
|
sent: socket.bytesWritten,
|
|
78
|
-
...lodash_1.default.pick(conn, ['op', 'opTotal', 'opOffset', 'opProgress']),
|
|
78
|
+
...lodash_1.default.pick(conn, ['op', 'opTotal', 'opOffset', 'opProgress', 'country']),
|
|
79
79
|
started,
|
|
80
80
|
secure: (secure || undefined),
|
|
81
81
|
...fromCtx(conn.ctx),
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
84
|
function fromCtx(ctx) {
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
if (!ctx)
|
|
86
|
+
return;
|
|
87
|
+
const path = ctx.state.browsing && decodeURIComponent(ctx.state.browsing)
|
|
88
|
+
|| ctx.state.uploadPath && decodeURIComponent(ctx.state.uploadPath)
|
|
89
|
+
|| (ctx.fileSource || ctx.state.archive) && decodeURIComponent(ctx.path); // downloads
|
|
90
|
+
return {
|
|
91
|
+
user: (0, auth_1.getCurrentUsername)(ctx),
|
|
87
92
|
agent: getBrowser(ctx.get('user-agent')),
|
|
88
93
|
archive: ctx.state.archive,
|
|
89
94
|
upload: ctx.state.uploadProgress,
|
|
90
|
-
path
|
|
91
|
-
|| (ctx.fileSource || ctx.state.archive) && decodeURIComponent(ctx.path) // only uploads and downloads
|
|
95
|
+
...path && { path },
|
|
92
96
|
};
|
|
93
97
|
}
|
|
94
98
|
},
|
package/src/api.vfs.js
CHANGED
|
@@ -21,6 +21,7 @@ async function urlToNodeOriginal(uri) {
|
|
|
21
21
|
const n = await (0, vfs_1.urlToNode)(uri);
|
|
22
22
|
return (n === null || n === void 0 ? void 0 : n.isTemp) ? n.original : n;
|
|
23
23
|
}
|
|
24
|
+
const ALLOWED_KEYS = ['name', 'source', 'masks', 'default', 'accept', 'rename', 'mime', 'url', ...misc_1.PERM_KEYS];
|
|
24
25
|
const apis = {
|
|
25
26
|
async get_vfs() {
|
|
26
27
|
return { root: await recur() };
|
|
@@ -28,7 +29,7 @@ const apis = {
|
|
|
28
29
|
var _a;
|
|
29
30
|
const { source } = node;
|
|
30
31
|
const stats = Boolean(source) && await (0, promises_1.stat)(source).catch(() => false);
|
|
31
|
-
const isDir = !source || stats && stats.isDirectory();
|
|
32
|
+
const isDir = !(0, vfs_1.nodeIsLink)(node) && (!source || stats && stats.isDirectory());
|
|
32
33
|
const copyStats = stats ? lodash_1.default.pick(stats, ['size', 'ctime', 'mtime'])
|
|
33
34
|
: { size: source ? -1 : undefined };
|
|
34
35
|
if (copyStats.mtime && Number(copyStats.mtime) === Number(copyStats.ctime))
|
|
@@ -81,7 +82,7 @@ const apis = {
|
|
|
81
82
|
const n = await urlToNodeOriginal(uri);
|
|
82
83
|
if (!n)
|
|
83
84
|
return new apiMiddleware_1.ApiError(const_1.HTTP_NOT_FOUND, 'path not found');
|
|
84
|
-
props = pickProps(props,
|
|
85
|
+
props = pickProps(props, ALLOWED_KEYS); // sanitize
|
|
85
86
|
if (props.name && props.name !== (0, vfs_1.getNodeName)(n)) {
|
|
86
87
|
const parent = await urlToNodeOriginal((0, path_1.dirname)(uri));
|
|
87
88
|
if ((_a = parent === null || parent === void 0 ? void 0 : parent.children) === null || _a === void 0 ? void 0 : _a.find(x => (0, vfs_1.getNodeName)(x) === props.name))
|
|
@@ -94,7 +95,7 @@ const apis = {
|
|
|
94
95
|
(0, vfs_1.saveVfs)();
|
|
95
96
|
return n;
|
|
96
97
|
},
|
|
97
|
-
async add_vfs({ parent, source, name }) {
|
|
98
|
+
async add_vfs({ parent, source, name, ...rest }) {
|
|
98
99
|
var _a;
|
|
99
100
|
if (!source && !name)
|
|
100
101
|
return new apiMiddleware_1.ApiError(const_1.HTTP_BAD_REQUEST, 'name or source required');
|
|
@@ -108,7 +109,7 @@ const apis = {
|
|
|
108
109
|
const isDir = source && await (0, misc_1.isDirectory)(source);
|
|
109
110
|
if (source && isDir === undefined)
|
|
110
111
|
return new apiMiddleware_1.ApiError(const_1.HTTP_NOT_FOUND, 'source not found');
|
|
111
|
-
const child = { source, name };
|
|
112
|
+
const child = { source, name, ...pickProps(rest, ALLOWED_KEYS) };
|
|
112
113
|
name = (0, vfs_1.getNodeName)(child); // could be not given as input
|
|
113
114
|
const ext = (0, path_1.extname)(name);
|
|
114
115
|
const noExt = ext ? name.slice(0, -ext.length) : name;
|
|
@@ -119,7 +120,7 @@ const apis = {
|
|
|
119
120
|
simplifyName(child);
|
|
120
121
|
(parentNode.children || (parentNode.children = [])).unshift(child);
|
|
121
122
|
(0, vfs_1.saveVfs)();
|
|
122
|
-
const link = (0, listen_1.getBaseUrlOrDefault)()
|
|
123
|
+
const link = rest.url ? undefined : (0, listen_1.getBaseUrlOrDefault)()
|
|
123
124
|
+ (parent ? (0, misc_1.enforceFinal)('/', parent) : '/')
|
|
124
125
|
+ encodeURIComponent((0, vfs_1.getNodeName)(child))
|
|
125
126
|
+ (isDir ? '/' : '');
|
|
@@ -239,9 +240,6 @@ function simplifyName(node) {
|
|
|
239
240
|
delete node.name;
|
|
240
241
|
}
|
|
241
242
|
const WINDOWS_REG_KEY = 'HKCU\\Software\\Classes\\*\\shell\\AddToHFS3';
|
|
242
|
-
if (const_1.IS_WINDOWS) // legacy 0.49.0-beta7 2023-10-27. Remove in 0.50
|
|
243
|
-
for (const k of ['*', 'Directory'])
|
|
244
|
-
reg('delete', `HKCR\\${k}\\shell\\AddToHFS3`, '/f').catch(() => { });
|
|
245
243
|
async function windowsIntegration() {
|
|
246
244
|
const status = await (0, listen_1.getServerStatus)();
|
|
247
245
|
const url = 'http://localhost:' + status.http.port;
|
package/src/apiMiddleware.js
CHANGED
|
@@ -106,21 +106,21 @@ class SendListReadable extends stream_1.Readable {
|
|
|
106
106
|
this.processBuffer();
|
|
107
107
|
}
|
|
108
108
|
add(rec) {
|
|
109
|
-
this._push([
|
|
109
|
+
this._push([misc_1.LIST.add, rec]);
|
|
110
110
|
}
|
|
111
111
|
remove(search) {
|
|
112
112
|
const match = lodash_1.default.matches(search);
|
|
113
113
|
const idx = lodash_1.default.findIndex(this.buffer, x => match(x[1]));
|
|
114
114
|
const found = this.buffer[idx];
|
|
115
115
|
const op = found === null || found === void 0 ? void 0 : found[0];
|
|
116
|
-
if (op ===
|
|
116
|
+
if (op === misc_1.LIST.remove)
|
|
117
117
|
return;
|
|
118
118
|
if (found) {
|
|
119
119
|
this.buffer.splice(idx, 1);
|
|
120
|
-
if (op ===
|
|
120
|
+
if (op === misc_1.LIST.add)
|
|
121
121
|
return;
|
|
122
122
|
}
|
|
123
|
-
this._push([
|
|
123
|
+
this._push([misc_1.LIST.remove, search]);
|
|
124
124
|
}
|
|
125
125
|
update(search, change) {
|
|
126
126
|
if (lodash_1.default.isEmpty(change))
|
|
@@ -128,23 +128,23 @@ class SendListReadable extends stream_1.Readable {
|
|
|
128
128
|
const match = lodash_1.default.matches(search);
|
|
129
129
|
const found = lodash_1.default.find(this.buffer, x => match(x[1]));
|
|
130
130
|
const op = found === null || found === void 0 ? void 0 : found[0];
|
|
131
|
-
if (op ===
|
|
131
|
+
if (op === misc_1.LIST.remove)
|
|
132
132
|
return;
|
|
133
|
-
if (op ===
|
|
134
|
-
return Object.assign(found[op ===
|
|
135
|
-
return this._push([
|
|
133
|
+
if (op === misc_1.LIST.add || op === misc_1.LIST.update)
|
|
134
|
+
return Object.assign(found[op === misc_1.LIST.add ? 1 : 2], change);
|
|
135
|
+
return this._push([misc_1.LIST.update, search, change]);
|
|
136
136
|
}
|
|
137
137
|
ready() {
|
|
138
|
-
this._push([
|
|
138
|
+
this._push([misc_1.LIST.ready]);
|
|
139
139
|
}
|
|
140
140
|
custom(name, data) {
|
|
141
|
-
this._push([name, data]);
|
|
141
|
+
this._push(data === undefined ? [name] : [name, data]);
|
|
142
142
|
}
|
|
143
143
|
props(props) {
|
|
144
|
-
this._push([
|
|
144
|
+
this._push([misc_1.LIST.props, props]);
|
|
145
145
|
}
|
|
146
146
|
error(msg, close = false, props) {
|
|
147
|
-
this._push([
|
|
147
|
+
this._push([misc_1.LIST.error, msg, props]);
|
|
148
148
|
this.lastError = msg;
|
|
149
149
|
if (close)
|
|
150
150
|
this.close();
|
package/src/auth.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.invalidSessions = exports.loggedIn = exports.getCurrentUsername = exports.srpCheck = exports.srpStep1 = void 0;
|
|
4
|
+
const perm_1 = require("./perm");
|
|
5
|
+
const cross_const_1 = require("./cross-const");
|
|
6
|
+
const tssrp6a_1 = require("tssrp6a");
|
|
7
|
+
const middlewares_1 = require("./middlewares");
|
|
8
|
+
const srp_1 = require("./srp");
|
|
9
|
+
const srp6aNimbusRoutines = new tssrp6a_1.SRPRoutines(new tssrp6a_1.SRPParameters());
|
|
10
|
+
async function srpStep1(account) {
|
|
11
|
+
if (!account.srp)
|
|
12
|
+
throw cross_const_1.HTTP_NOT_ACCEPTABLE;
|
|
13
|
+
const [salt, verifier] = account.srp.split('|');
|
|
14
|
+
if (!salt || !verifier)
|
|
15
|
+
throw Error("malformed account");
|
|
16
|
+
const srpSession = new tssrp6a_1.SRPServerSession(srp6aNimbusRoutines);
|
|
17
|
+
const step1 = await srpSession.step1(account.username, BigInt(salt), BigInt(verifier));
|
|
18
|
+
return { step1, salt, pubKey: String(step1.B) }; // cast to string cause bigint can't be jsonized
|
|
19
|
+
}
|
|
20
|
+
exports.srpStep1 = srpStep1;
|
|
21
|
+
async function srpCheck(username, password) {
|
|
22
|
+
const account = (0, perm_1.getAccount)(username);
|
|
23
|
+
if (!(account === null || account === void 0 ? void 0 : account.srp) || !password)
|
|
24
|
+
return;
|
|
25
|
+
const { step1, salt, pubKey } = await srpStep1(account);
|
|
26
|
+
const client = await (0, srp_1.srpClientPart)(username, password, salt, pubKey);
|
|
27
|
+
return await step1.step2(client.A, client.M1).then(() => account, () => { });
|
|
28
|
+
}
|
|
29
|
+
exports.srpCheck = srpCheck;
|
|
30
|
+
function getCurrentUsername(ctx) {
|
|
31
|
+
var _a;
|
|
32
|
+
return ((_a = ctx.state.account) === null || _a === void 0 ? void 0 : _a.username) || '';
|
|
33
|
+
}
|
|
34
|
+
exports.getCurrentUsername = getCurrentUsername;
|
|
35
|
+
// centralized log-in state
|
|
36
|
+
async function loggedIn(ctx, username) {
|
|
37
|
+
const s = ctx.session;
|
|
38
|
+
if (!s)
|
|
39
|
+
return ctx.throw(cross_const_1.HTTP_SERVER_ERROR, 'session');
|
|
40
|
+
if (username === false) {
|
|
41
|
+
delete s.username;
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
exports.invalidSessions.delete(username);
|
|
45
|
+
s.username = (0, perm_1.normalizeUsername)(username);
|
|
46
|
+
await (0, middlewares_1.prepareState)(ctx, async () => { }); // updating the state is necessary to send complete session data so that frontend shows admin button
|
|
47
|
+
}
|
|
48
|
+
exports.loggedIn = loggedIn;
|
|
49
|
+
exports.invalidSessions = new Set(); // since session are currently stored in cookies, we need to memorize this until we meet again
|
package/src/connections.js
CHANGED
|
@@ -4,8 +4,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
5
|
};
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.updateConnection = exports.socket2connection = exports.getConnections = exports.newConnection = exports.normalizeIp = exports.Connection = void 0;
|
|
7
|
+
exports.updateConnection = exports.getConnection = exports.socket2connection = exports.getConnections = exports.newConnection = exports.normalizeIp = exports.Connection = void 0;
|
|
8
8
|
const events_1 = __importDefault(require("./events"));
|
|
9
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
9
10
|
class Connection {
|
|
10
11
|
constructor(socket) {
|
|
11
12
|
this.socket = socket;
|
|
@@ -47,6 +48,10 @@ function socket2connection(socket) {
|
|
|
47
48
|
&& x.socket.remoteAddress === socket.remoteAddress);
|
|
48
49
|
}
|
|
49
50
|
exports.socket2connection = socket2connection;
|
|
51
|
+
function getConnection(ctx) {
|
|
52
|
+
return lodash_1.default.find(all, { ctx });
|
|
53
|
+
}
|
|
54
|
+
exports.getConnection = getConnection;
|
|
50
55
|
function updateConnection(conn, change) {
|
|
51
56
|
var _a;
|
|
52
57
|
if (change.op)
|
package/src/const.js
CHANGED
|
@@ -30,7 +30,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
30
30
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
31
31
|
};
|
|
32
32
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
|
-
exports.APP_PATH = exports.IS_BINARY = exports.IS_MAC = exports.IS_WINDOWS = exports.HFS_REPO_BRANCH = exports.RUNNING_BETA = exports.VERSION = exports.BUILD_TIMESTAMP = exports.HFS_STARTED = exports.ORIGINAL_CWD = exports.DEV = exports.argv = void 0;
|
|
33
|
+
exports.MIME_AUTO = exports.APP_PATH = exports.IS_BINARY = exports.IS_MAC = exports.IS_WINDOWS = exports.HFS_REPO_BRANCH = exports.RUNNING_BETA = exports.VERSION = exports.BUILD_TIMESTAMP = exports.HFS_STARTED = exports.ORIGINAL_CWD = exports.DEV = exports.argv = void 0;
|
|
34
34
|
const minimist_1 = __importDefault(require("minimist"));
|
|
35
35
|
const fs = __importStar(require("fs"));
|
|
36
36
|
const os_1 = require("os");
|
|
@@ -42,7 +42,7 @@ exports.DEV = process.env.DEV || exports.argv.dev ? 'DEV' : '';
|
|
|
42
42
|
exports.ORIGINAL_CWD = process.cwd();
|
|
43
43
|
exports.HFS_STARTED = new Date();
|
|
44
44
|
const PKG_PATH = (0, path_1.join)(__dirname, '..', 'package.json');
|
|
45
|
-
exports.BUILD_TIMESTAMP = "2023-11-
|
|
45
|
+
exports.BUILD_TIMESTAMP = "2023-11-12T12:36:23.349Z";
|
|
46
46
|
const pkg = JSON.parse(fs.readFileSync(PKG_PATH, 'utf8'));
|
|
47
47
|
exports.VERSION = pkg.version;
|
|
48
48
|
exports.RUNNING_BETA = exports.VERSION.includes('-');
|
|
@@ -51,6 +51,7 @@ exports.IS_WINDOWS = process.platform === 'win32';
|
|
|
51
51
|
exports.IS_MAC = process.platform === 'darwin';
|
|
52
52
|
exports.IS_BINARY = !(0, path_1.basename)(process.execPath).includes('node'); // this won't be node if pkg was used
|
|
53
53
|
exports.APP_PATH = (0, path_1.dirname)(exports.IS_BINARY ? process.execPath : __dirname);
|
|
54
|
+
exports.MIME_AUTO = 'auto';
|
|
54
55
|
// we want this to be the first stuff to be printed, then we print it in this module, that is executed at the beginning
|
|
55
56
|
if (exports.DEV)
|
|
56
57
|
console.clear();
|