hfs 0.34.1 → 0.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/admin/assets/index-0859bb0d.js +415 -0
- package/{frontend/assets/sha512-5a1708b3.js → admin/assets/sha512-1ab69ff8.js} +1 -1
- package/admin/index.html +1 -1
- package/frontend/assets/index-21e40dc5.js +85 -0
- package/frontend/assets/index-c4c325e9.css +1 -0
- package/{admin/assets/sha512-9460fa50.js → frontend/assets/sha512-5cf58050.js} +1 -1
- package/frontend/index.html +2 -2
- package/package.json +3 -2
- package/plugins/antibrute/plugin.js +1 -1
- package/plugins/download-counter/public/main.js +2 -2
- package/plugins/download-counter/public/style.css +0 -1
- package/src/adminApis.js +2 -0
- package/src/api.lang.js +59 -0
- package/src/const.js +1 -1
- package/src/frontEndApis.js +23 -0
- package/src/serveGuiFiles.js +1 -1
- package/admin/assets/index-e198a951.js +0 -414
- package/frontend/assets/index-78793e0f.js +0 -85
- package/frontend/assets/index-993f3e4d.css +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@charset "UTF-8";:root{height:100dvh;--bg: #fff;--text: #555;--ghost-contrast: #8882;--faint-contrast: #8884;--mild-contrast: #8886;--good-contrast: #000a;--button-bg: #68a;--button-text: #fff;--focus-color: #468}:root .theme-dark{--bg: #000;--text: #999;--good-contrast: #fffa;--button-bg: #345;--button-text: #999;color-scheme:dark}: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;margin-left:-1px;font-size:95%}: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: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{max-width:50em;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]),select{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=checkbox]{transform:scale(1.7);accent-color:var(--button-bg)}label input[type=checkbox]{margin-right:.8em}select{text-align:center}.hidden{display:none!important}.icon{font-size:1.2em}.icon.mirror:before{transform:scaleX(-1)}a{text-decoration:none;color:#57a}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}button.toggled{color:#444;text-shadow:0 0 2px var(--good-contrast)}button:focus-visible,.breadcrumb:focus-visible{outline:3px solid var(--focus-color)}a>button{width:100%}input:focus-visible,select:focus-visible,ul a:focus-visible{border-radius:.3em;border-color:transparent;outline:2px solid var(--focus-color)}.error-msg{background-color:#faa;color:#833;padding:.5em 1em}header{position:sticky;top:0;background:var(--bg);padding:.2em;z-index:1}.before-sliding{width:0!important;flex:0!important;margin:0!important;height:0!important;padding:0!important;overflow:hidden!important;transition:all .5s}.show-sliding{transition:all .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}.icon.emoji.spinner{display:inline-block}.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:.4em 0 0 .5em;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 11px;height:1.8em}#filter-bar input[type=checkbox]{margin-top:.5em}#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:0 .8em}ul.dir li a{word-break:break-word;padding-right:.3em}ul.dir li a .icon{margin-right:.3em}ul.dir li a.container-folder:hover{text-decoration:underline}ul.dir li .entry-props{float:right;font-size:90%;margin-left:4px;margin-top:.3em;font-variant-numeric:tabular-nums}ul.dir li .entry-props .entry-size-unit{display:inline-block;margin-left:.3em;width:1.5em}ul.dir li>div:last-of-type{clear:both}ul.dir li.page-separator{margin-top:1em;position:relative}ul.dir li.page-separator:before{content:attr(label);position:absolute;top:-1.8em;font-size:smaller;margin-left:calc(50% - 1em);opacity:.9}#menu-panel{margin-bottom:.2em}#menu-bar{display:flex;justify-content:space-evenly;flex-wrap:wrap}#menu-bar>*{flex:1;margin:.1em}#menu-bar button{padding-left:0;padding-right: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:.5em}.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:10em;--color: var(--button-bg)}#paging{position:sticky;bottom:0;display:flex;gap:.1em;background:var(--bg);padding:0 .2em .2em}#paging,#paging>button{box-shadow:0 0 .3em .3em #0003;z-index:1}#paging #paging-middle{padding:0 .5em;margin:0 -.3em;display:flex;gap:.5em;flex:1;overflow-x:auto}#paging *::-webkit-scrollbar{height:8px}#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-progress:before{content:" \2013 "}.upload-progress{min-width:4em;display:inline-block;margin-left:.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}.dialog-login form{display:flex;flex-direction:column;gap:1.2em}.dialog-login label{display:block;margin-bottom:.5em;margin-left:.1em}*{scrollbar-width:thin;scrollbar-color:var(--button-bg) var(--ghost-contrast)}*::-webkit-scrollbar{width:12px}*::-webkit-scrollbar-track{background:var(--ghost-contrast)}*::-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}}.dialog-backdrop{position:fixed;inset:0;background:#888a;display:flex;justify-content:center;align-items:center;z-index:1000}.dialog{background:#fff;background:var(--bg);padding:max(.5em,1vw);border-radius:1em;position:relative;margin:0 3vw;overflow:hidden;max-height:calc(100vh - 2em)}.dialog-icon{color:#fff;background-color:var(--color);position:absolute;top:0;width:1.8em;height:1.7em;text-align:center;border-radius:.8em 0}.dialog-title{margin-top:-.4em;font-size:110%}.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:2em}.dialog-type{left:0;top:0;overflow:hidden;line-height:1.7em;opacity:.8}.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: 50em){.dialog-closer{font-size:120%}.dialog-icon~.dialog-content{margin-top:2em}}.dialog-prompt label{display:block;margin-bottom:.5em;margin-left:.1em}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as SF}from"./index-
|
|
1
|
+
import{c as SF}from"./index-21e40dc5.js";function OF(iF,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 iF)){const lF=Object.getOwnPropertyDescriptor(tF,w);lF&&Object.defineProperty(iF,w,lF.get?lF:{enumerable:!0,get:()=>tF[w]})}}}return Object.freeze(Object.defineProperty(iF,Symbol.toStringTag,{value:"Module"}))}var EF={},UF={get exports(){return EF},set exports(iF){EF=iF}};/*
|
|
2
2
|
* [js-sha512]{@link https://github.com/emn178/js-sha512}
|
|
3
3
|
*
|
|
4
4
|
* @version 0.8.0
|
package/frontend/index.html
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
<link rel="icon"/>
|
|
8
8
|
<script>SESSION = _HFS_SESSION_</script>
|
|
9
9
|
<title>File Server</title>
|
|
10
|
-
<script type="module" crossorigin src="/assets/index-
|
|
11
|
-
<link rel="stylesheet" href="/assets/index-
|
|
10
|
+
<script type="module" crossorigin src="/assets/index-21e40dc5.js"></script>
|
|
11
|
+
<link rel="stylesheet" href="/assets/index-c4c325e9.css">
|
|
12
12
|
</head>
|
|
13
13
|
<body>
|
|
14
14
|
<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.35.0",
|
|
4
4
|
"description": "HTTP File Server",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"file server",
|
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
"pub": "cd dist && npm publish",
|
|
26
26
|
"dist": "npm run build-all && npm run dist-bin",
|
|
27
27
|
"dist-bin": "npm run dist-modules && cd dist && pkg . -C gzip && mv -f hfs-win-x64.exe hfs.exe && zip hfs-windows.zip hfs.exe -r plugins && cp -f hfs-linux-x64 hfs && zip hfs-linux.zip hfs -r plugins && cp -f hfs-macos-x64 hfs && zip hfs-mac.zip hfs -r plugins && cp -f hfs-macos-arm64 hfs && zip hfs-mac-arm.zip hfs -r plugins && rm hfs",
|
|
28
|
-
"dist-modules": "cp package*.json dist && cd dist && npm ci --omit=dev && npm
|
|
28
|
+
"dist-modules": "cp package*.json dist && cd dist && npm ci --omit=dev && npm run dist-crclib && rm package-lock.json && cd .. && node prune_modules",
|
|
29
|
+
"dist-crclib": "npm i -f --no-save --omit=dev @node-rs/crc32-win32-x64-msvc @node-rs/crc32-darwin-arm64 @node-rs/crc32-darwin-x64 ",
|
|
29
30
|
"dist-win": "npm run dist-modules && cd dist && pkg . -C gzip -t node16-win-x64 && zip hfs-windows.zip hfs.exe -r plugins",
|
|
30
31
|
"dist-node": "npm run dist-modules && cd dist && zip hfs-node.zip -r * -x *.zip *.exe hfs-* *.log logs"
|
|
31
32
|
},
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
HFS.onEvent('additionalEntryProps', ({ entry: { hits } }) =>
|
|
2
|
-
hits && '<span class="download-counter">' + hits + '</span>')
|
|
1
|
+
HFS.onEvent('additionalEntryProps', ({ entry: { hits } }, { t }) =>
|
|
2
|
+
hits && '<span class="download-counter">' + t`Hits: ` + hits + '</span>')
|
package/src/adminApis.js
CHANGED
|
@@ -36,6 +36,7 @@ const api_vfs_1 = __importDefault(require("./api.vfs"));
|
|
|
36
36
|
const api_accounts_1 = __importDefault(require("./api.accounts"));
|
|
37
37
|
const api_plugins_1 = __importDefault(require("./api.plugins"));
|
|
38
38
|
const api_monitor_1 = __importDefault(require("./api.monitor"));
|
|
39
|
+
const api_lang_1 = __importDefault(require("./api.lang"));
|
|
39
40
|
const connections_1 = require("./connections");
|
|
40
41
|
const misc_1 = require("./misc");
|
|
41
42
|
const lodash_1 = __importDefault(require("lodash"));
|
|
@@ -53,6 +54,7 @@ exports.adminApis = {
|
|
|
53
54
|
...api_accounts_1.default,
|
|
54
55
|
...api_plugins_1.default,
|
|
55
56
|
...api_monitor_1.default,
|
|
57
|
+
...api_lang_1.default,
|
|
56
58
|
async set_config({ values: v }) {
|
|
57
59
|
var _a, _b;
|
|
58
60
|
if (v) {
|
package/src/api.lang.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const apiMiddleware_1 = require("./apiMiddleware");
|
|
8
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
9
|
+
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
10
|
+
const promises_1 = require("fs/promises");
|
|
11
|
+
const util_files_1 = require("./util-files");
|
|
12
|
+
const const_1 = require("./const");
|
|
13
|
+
const PREFIX = 'hfs-lang-';
|
|
14
|
+
const SUFFIX = '.json';
|
|
15
|
+
const apis = {
|
|
16
|
+
get_langs() {
|
|
17
|
+
return new apiMiddleware_1.SendListReadable({
|
|
18
|
+
doAtStart: async (list) => {
|
|
19
|
+
for await (let name of fast_glob_1.default.stream(code2file('*'))) {
|
|
20
|
+
name = String(name);
|
|
21
|
+
const code = name.slice(PREFIX.length, -SUFFIX.length);
|
|
22
|
+
try {
|
|
23
|
+
const data = JSON.parse(await (0, promises_1.readFile)(name, 'utf8'));
|
|
24
|
+
list.add({ code, ...lodash_1.default.omit(data, 'translate') });
|
|
25
|
+
}
|
|
26
|
+
catch (_a) { }
|
|
27
|
+
}
|
|
28
|
+
list.close();
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
},
|
|
32
|
+
async del_lang({ code }) {
|
|
33
|
+
validateCode(code);
|
|
34
|
+
try {
|
|
35
|
+
await (0, promises_1.rm)(code2file(code));
|
|
36
|
+
return {};
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
return new apiMiddleware_1.ApiError(e.code || const_1.HTTP_SERVER_ERROR, e);
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
async add_langs({ langs }) {
|
|
43
|
+
for (let [code, content] of Object.entries(langs)) {
|
|
44
|
+
if (code.endsWith(SUFFIX)) // filename, actually
|
|
45
|
+
code = code.slice(PREFIX.length, -SUFFIX.length);
|
|
46
|
+
validateCode(code);
|
|
47
|
+
await (0, promises_1.writeFile)(code2file(code), String(content), 'utf8');
|
|
48
|
+
}
|
|
49
|
+
return {};
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
exports.default = apis;
|
|
53
|
+
function code2file(code) {
|
|
54
|
+
return PREFIX + code.toLowerCase() + SUFFIX;
|
|
55
|
+
}
|
|
56
|
+
function validateCode(code) {
|
|
57
|
+
if (!(0, util_files_1.isValidFileName)(code) || (0, util_files_1.dirTraversal)(code))
|
|
58
|
+
throw new apiMiddleware_1.ApiError(const_1.HTTP_BAD_REQUEST, 'bad code');
|
|
59
|
+
}
|
package/src/const.js
CHANGED
|
@@ -38,7 +38,7 @@ exports.DEV = process.env.DEV || exports.argv.dev ? 'DEV' : '';
|
|
|
38
38
|
exports.ORIGINAL_CWD = process.cwd();
|
|
39
39
|
exports.HFS_STARTED = new Date();
|
|
40
40
|
const PKG_PATH = (0, path_1.join)(__dirname, '..', 'package.json');
|
|
41
|
-
exports.BUILD_TIMESTAMP = "2023-02-
|
|
41
|
+
exports.BUILD_TIMESTAMP = "2023-02-20T11:41:13.654Z";
|
|
42
42
|
const pkg = JSON.parse(fs.readFileSync(PKG_PATH, 'utf8'));
|
|
43
43
|
exports.VERSION = pkg.version;
|
|
44
44
|
exports.DAY = 86400000;
|
package/src/frontEndApis.js
CHANGED
|
@@ -38,6 +38,7 @@ const const_1 = require("./const");
|
|
|
38
38
|
const vfs_1 = require("./vfs");
|
|
39
39
|
const promises_1 = require("fs/promises");
|
|
40
40
|
const path_1 = require("path");
|
|
41
|
+
const misc_1 = require("./misc");
|
|
41
42
|
const customHeader = (0, config_1.defineConfig)('custom_header');
|
|
42
43
|
exports.frontEndApis = {
|
|
43
44
|
file_list: api_file_list_1.file_list,
|
|
@@ -90,6 +91,28 @@ exports.frontEndApis = {
|
|
|
90
91
|
throw new apiMiddleware_1.ApiError(e.code || const_1.HTTP_SERVER_ERROR, e);
|
|
91
92
|
}
|
|
92
93
|
},
|
|
94
|
+
async load_lang({ lang }) {
|
|
95
|
+
const ret = {};
|
|
96
|
+
const langs = (0, misc_1.wantArray)(lang);
|
|
97
|
+
const tried = [];
|
|
98
|
+
for (let k of langs) {
|
|
99
|
+
k = k.toLowerCase();
|
|
100
|
+
while (1) {
|
|
101
|
+
if (tried.includes(k))
|
|
102
|
+
break;
|
|
103
|
+
tried.push(k);
|
|
104
|
+
try {
|
|
105
|
+
ret[k] = JSON.parse(await (0, promises_1.readFile)(`hfs-lang-${k}.json`, 'utf8'));
|
|
106
|
+
}
|
|
107
|
+
catch (_a) { }
|
|
108
|
+
const i = k.lastIndexOf('-');
|
|
109
|
+
if (ret[k] || i < 0)
|
|
110
|
+
break;
|
|
111
|
+
k = k.slice(0, i);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return ret;
|
|
115
|
+
}
|
|
93
116
|
};
|
|
94
117
|
function notifyClient(ctx, name, data) {
|
|
95
118
|
const { notificationChannel } = ctx.query;
|
package/src/serveGuiFiles.js
CHANGED
|
@@ -81,7 +81,7 @@ async function treatIndex(ctx, body, filesUri) {
|
|
|
81
81
|
ctx.set('etag', '');
|
|
82
82
|
return body
|
|
83
83
|
.replace(/((?:src|href) *= *['"])\/?(?![a-z]+:\/\/)/g, '$1' + filesUri)
|
|
84
|
-
.replace('<link rel="icon"/>', `<link rel="icon" href="${adminApis_1.favicon.get() ? '/favicon.ico' : 'data
|
|
84
|
+
.replace('<link rel="icon"/>', `<link rel="icon" href="${adminApis_1.favicon.get() ? '/favicon.ico' : 'data:;'}" />`)
|
|
85
85
|
.replace('_HFS_SESSION_', session instanceof apiMiddleware_1.ApiError ? 'null' : JSON.stringify(session))
|
|
86
86
|
// replacing this text allow us to avoid injecting in frontends that don't support plugins. Don't use a <--comment--> or it will be removed by webpack
|
|
87
87
|
.replace('_HFS_PLUGINS_', pluginsInjection);
|