hfs 0.50.4 → 0.51.0-beta4
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-101ecc9e.js +808 -0
- package/admin/assets/{index-bb75b3fc.css → index-65d16f45.css} +1 -1
- package/{frontend/assets/sha512-e82b909a.js → admin/assets/sha512-a1b6cce6.js} +1 -1
- package/admin/index.html +2 -2
- package/frontend/assets/index-a452a199.css +1 -0
- package/frontend/assets/index-dea364e7.js +95 -0
- package/{admin/assets/sha512-1694c0eb.js → frontend/assets/sha512-6365fe60.js} +1 -1
- package/frontend/fontello.css +4 -1
- package/frontend/fontello.woff2 +0 -0
- package/frontend/index.html +2 -2
- package/package.json +3 -2
- package/src/adminApis.js +3 -1
- package/src/api.auth.js +6 -1
- package/src/{api.file_list.js → api.get_file_list.js} +11 -7
- package/src/api.monitor.js +1 -34
- package/src/api.vfs.js +2 -5
- package/src/apiMiddleware.js +1 -1
- package/src/comments.js +1 -1
- package/src/const.js +5 -2
- package/src/cross-const.js +3 -4
- package/src/cross.js +56 -7
- package/src/debounceAsync.js +3 -3
- package/src/errorPages.js +1 -1
- package/src/frontEndApis.js +21 -2
- package/src/index.js +2 -0
- package/src/lang.js +10 -2
- package/src/langs/hfs-lang-it.json +10 -6
- package/src/listen.js +1 -2
- package/src/log.js +20 -5
- package/src/middlewares.js +12 -6
- package/src/misc.js +4 -14
- package/src/roots.js +47 -0
- package/src/serveFile.js +40 -4
- package/src/serveGuiFiles.js +2 -2
- package/src/update.js +7 -6
- package/src/upload.js +10 -5
- package/src/util-files.js +7 -6
- package/src/vfs.js +38 -28
- package/src/zip.js +2 -2
- package/admin/assets/index-a24642bd.js +0 -807
- package/frontend/assets/index-b90320b6.css +0 -1
- package/frontend/assets/index-e6ecc47c.js +0 -94
- package/plugins/vhosting/plugin.js +0 -62
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{g as OF,c as UF}from"./index-
|
|
1
|
+
import{g as OF,c as UF}from"./index-dea364e7.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/fontello.css
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
@font-face {
|
|
2
2
|
font-family: 'fontello';
|
|
3
|
-
src: url('fontello.woff2?
|
|
3
|
+
src: url('fontello.woff2?39711600') format('woff2');
|
|
4
4
|
font-weight: normal;
|
|
5
5
|
font-style: normal;
|
|
6
6
|
}
|
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
.fa-left:before { content: '\e816'; } /* '' */
|
|
65
65
|
.fa-lock:before { content: '\e817'; } /* '' */
|
|
66
66
|
.fa-reload:before { content: '\e818'; } /* '' */
|
|
67
|
+
.fa-cut:before { content: '\e819'; } /* '' */
|
|
67
68
|
.fa-spin6:before { content: '\e839'; } /* '' */
|
|
68
69
|
.fa-crown:before { content: '\e844'; } /* '' */
|
|
69
70
|
.fa-download:before { content: '\f02e'; } /* '' */
|
|
@@ -71,8 +72,10 @@
|
|
|
71
72
|
.fa-link:before { content: '\f08e'; } /* '' */
|
|
72
73
|
.fa-filter:before { content: '\f0b0'; } /* '' */
|
|
73
74
|
.fa-zoom:before { content: '\f0b2'; } /* '' */
|
|
75
|
+
.copy:before { content: '\f0c5'; } /* '' */
|
|
74
76
|
.fa-menu:before { content: '\f0c9'; } /* '' */
|
|
75
77
|
.fa-comment:before { content: '\f0e5'; } /* '' */
|
|
78
|
+
.fa-paste:before { content: '\f0ea'; } /* '' */
|
|
76
79
|
.fa-fullscreen:before { content: '\f108'; } /* '' */
|
|
77
80
|
.fa-quote:before { content: '\f10d'; } /* '' */
|
|
78
81
|
.fa-unlink:before { content: '\f127'; } /* '' */
|
package/frontend/fontello.woff2
CHANGED
|
Binary file
|
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-dea364e7.js"></script>
|
|
9
|
+
<link rel="stylesheet" href="/assets/index-a452a199.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.51.0-beta4",
|
|
4
4
|
"description": "HTTP File Server",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"file server",
|
|
@@ -82,6 +82,7 @@
|
|
|
82
82
|
"minimist": "^1.2.6",
|
|
83
83
|
"nat-upnp-ts": "^2.0.1",
|
|
84
84
|
"open": "^8.4.0",
|
|
85
|
+
"picomatch": "^3.0.1",
|
|
85
86
|
"tssrp6a": "^3.0.0",
|
|
86
87
|
"unzip-stream": "^0.3.1",
|
|
87
88
|
"valtio": "^1.10.3",
|
|
@@ -97,11 +98,11 @@
|
|
|
97
98
|
"@types/koa-mount": "^4.0.1",
|
|
98
99
|
"@types/koa-session": "^5.10.4",
|
|
99
100
|
"@types/lodash": "^4.14.178",
|
|
100
|
-
"@types/micromatch": "^4.0.2",
|
|
101
101
|
"@types/mime-types": "^2.1.1",
|
|
102
102
|
"@types/minimist": "^1.2.2",
|
|
103
103
|
"@types/mocha": "^9.0.0",
|
|
104
104
|
"@types/node": "^18.17.14",
|
|
105
|
+
"@types/picomatch": "^2.3.3",
|
|
105
106
|
"@types/tough-cookie": "^4.0.2",
|
|
106
107
|
"@types/unzipper": "^0.10.5",
|
|
107
108
|
"cross-env": "^7.0.3",
|
package/src/adminApis.js
CHANGED
|
@@ -56,6 +56,7 @@ const consoleLog_1 = require("./consoleLog");
|
|
|
56
56
|
const path_1 = require("path");
|
|
57
57
|
const errorPages_1 = require("./errorPages");
|
|
58
58
|
const geo_1 = require("./geo");
|
|
59
|
+
const roots_1 = require("./roots");
|
|
59
60
|
exports.adminApis = {
|
|
60
61
|
...api_vfs_1.default,
|
|
61
62
|
...api_accounts_1.default,
|
|
@@ -124,6 +125,7 @@ exports.adminApis = {
|
|
|
124
125
|
urls: await (0, listen_1.getUrls)(),
|
|
125
126
|
ips: await (0, listen_1.getIps)(false),
|
|
126
127
|
baseUrl: (0, listen_1.getBaseUrlOrDefault)(),
|
|
128
|
+
roots: roots_1.roots.get(),
|
|
127
129
|
updatePossible: !(0, update_1.updateSupported)() ? false : await (0, update_1.localUpdateAvailable)() ? 'local' : true,
|
|
128
130
|
proxyDetected: (0, middlewares_1.getProxyDetected)(),
|
|
129
131
|
frpDetected: exports.localhostAdmin.get() && !(0, middlewares_1.getProxyDetected)()
|
|
@@ -216,7 +218,7 @@ exports.title = (0, config_1.defineConfig)('title', "File server");
|
|
|
216
218
|
function ctxAdminAccess(ctx) {
|
|
217
219
|
return !ctx.ips.length // we consider localhost_admin only if no proxy is being used
|
|
218
220
|
&& exports.localhostAdmin.get() && (0, misc_1.isLocalHost)(ctx)
|
|
219
|
-
|| (0, perm_1.
|
|
221
|
+
|| ctx.state.account && (0, perm_1.accountCanLoginAdmin)(ctx.state.account);
|
|
220
222
|
}
|
|
221
223
|
exports.ctxAdminAccess = ctxAdminAccess;
|
|
222
224
|
const frpDebounced = (0, misc_1.debounceAsync)(async () => {
|
package/src/api.auth.js
CHANGED
|
@@ -39,8 +39,11 @@ const loginSrp1 = async ({ username }, ctx) => {
|
|
|
39
39
|
const account = (0, perm_1.getAccount)(username);
|
|
40
40
|
if (!ctx.session)
|
|
41
41
|
return new apiMiddleware_1.ApiError(const_1.HTTP_SERVER_ERROR);
|
|
42
|
-
if (!account || !(0, perm_1.accountCanLogin)(account)) // TODO simulate fake account to prevent knowing valid usernames
|
|
42
|
+
if (!account || !(0, perm_1.accountCanLogin)(account)) { // TODO simulate fake account to prevent knowing valid usernames
|
|
43
|
+
ctx.logExtra({ u: username });
|
|
44
|
+
ctx.state.dontLog = false; // log even if log_api is false
|
|
43
45
|
return new apiMiddleware_1.ApiError(const_1.HTTP_UNAUTHORIZED);
|
|
46
|
+
}
|
|
44
47
|
try {
|
|
45
48
|
const { step1, ...rest } = await (0, auth_1.srpStep1)(account);
|
|
46
49
|
const sid = Math.random();
|
|
@@ -75,6 +78,8 @@ const loginSrp2 = async ({ pubKey, proof }, ctx) => {
|
|
|
75
78
|
};
|
|
76
79
|
}
|
|
77
80
|
catch (e) {
|
|
81
|
+
ctx.logExtra({ u: username });
|
|
82
|
+
ctx.state.dontLog = false; // log even if log_api is false
|
|
78
83
|
return new apiMiddleware_1.ApiError(const_1.HTTP_UNAUTHORIZED, String(e));
|
|
79
84
|
}
|
|
80
85
|
finally {
|
|
@@ -11,12 +11,15 @@ const const_1 = require("./const");
|
|
|
11
11
|
const comments_1 = require("./comments");
|
|
12
12
|
const path_1 = require("path");
|
|
13
13
|
const connections_1 = require("./connections");
|
|
14
|
-
const
|
|
14
|
+
const adminApis_1 = require("./adminApis");
|
|
15
|
+
const upload_1 = require("./upload");
|
|
16
|
+
const get_file_list = async ({ uri, offset, limit, search, c, onlyFolders, admin }, ctx) => {
|
|
15
17
|
const node = await (0, vfs_1.urlToNode)(uri || '/', ctx);
|
|
16
18
|
const list = ctx.get('accept') === 'text/event-stream' ? new apiMiddleware_1.SendListReadable() : undefined;
|
|
17
19
|
if (!node)
|
|
18
20
|
return fail(const_1.HTTP_NOT_FOUND);
|
|
19
|
-
|
|
21
|
+
admin && (admin = (0, adminApis_1.ctxAdminAccess)(ctx)); // validate 'admin' flag
|
|
22
|
+
if (!admin && (0, vfs_1.statusCodeForMissingPerm)(node, 'can_list', ctx))
|
|
20
23
|
return fail();
|
|
21
24
|
if ((0, misc_1.dirTraversal)(search))
|
|
22
25
|
return fail(const_1.HTTP_FOOL);
|
|
@@ -25,14 +28,15 @@ const get_file_list = async ({ uri, offset, limit, search, c }, ctx) => {
|
|
|
25
28
|
offset = Number(offset);
|
|
26
29
|
limit = Number(limit);
|
|
27
30
|
const filter = (0, misc_1.pattern2filter)(search);
|
|
28
|
-
const walker = (0, vfs_1.walkNode)(node, ctx, search ? Infinity : 0);
|
|
31
|
+
const walker = (0, vfs_1.walkNode)(node, { ctx: admin ? undefined : ctx, onlyFolders, depth: search ? Infinity : 0 });
|
|
29
32
|
const onDirEntryHandlers = (0, plugins_1.mapPlugins)(plug => plug.onDirEntry);
|
|
30
|
-
const can_upload = (0, vfs_1.hasPermission)(node, 'can_upload', ctx);
|
|
33
|
+
const can_upload = admin || (0, vfs_1.hasPermission)(node, 'can_upload', ctx);
|
|
31
34
|
const fakeChild = (0, vfs_1.applyParentToChild)({}, node); // we want to know if we want to delete children
|
|
32
|
-
const can_delete = (0, vfs_1.hasPermission)(fakeChild, 'can_delete', ctx);
|
|
33
|
-
const can_archive = (0, vfs_1.hasPermission)(fakeChild, 'can_archive', ctx);
|
|
35
|
+
const can_delete = admin || (0, vfs_1.hasPermission)(fakeChild, 'can_delete', ctx);
|
|
36
|
+
const can_archive = admin || (0, vfs_1.hasPermission)(fakeChild, 'can_archive', ctx);
|
|
34
37
|
const can_comment = can_upload && (0, comments_1.areCommentsEnabled)();
|
|
35
|
-
const
|
|
38
|
+
const can_overwrite = can_upload && (can_delete || !upload_1.dontOverwriteUploading.get());
|
|
39
|
+
const props = { can_archive, can_upload, can_delete, can_overwrite, accept: node.accept, can_comment };
|
|
36
40
|
if (!list)
|
|
37
41
|
return { ...props, list: await (0, misc_1.asyncGeneratorToArray)(produceEntries()) };
|
|
38
42
|
setTimeout(async () => {
|
package/src/api.monitor.js
CHANGED
|
@@ -89,7 +89,7 @@ const apis = {
|
|
|
89
89
|
|| (ctx.fileSource || ctx.state.archive) && decodeURIComponent(ctx.path); // downloads
|
|
90
90
|
return {
|
|
91
91
|
user: (0, auth_1.getCurrentUsername)(ctx),
|
|
92
|
-
agent:
|
|
92
|
+
agent: (0, misc_1.shortenAgent)(ctx.get('user-agent')),
|
|
93
93
|
archive: ctx.state.archive,
|
|
94
94
|
upload: ctx.state.uploadProgress,
|
|
95
95
|
...path && { path },
|
|
@@ -119,36 +119,3 @@ function getConnAddress(conn) {
|
|
|
119
119
|
port: conn.socket.remotePort,
|
|
120
120
|
};
|
|
121
121
|
}
|
|
122
|
-
function getBrowser(agent) {
|
|
123
|
-
for (const [name, re] of Object.entries(BROWSERS))
|
|
124
|
-
if (re.test(agent))
|
|
125
|
-
return name;
|
|
126
|
-
return '';
|
|
127
|
-
}
|
|
128
|
-
const BROWSERS = {
|
|
129
|
-
YaBrowser: /yabrowser/i,
|
|
130
|
-
AlamoFire: /alamofire/i,
|
|
131
|
-
Edge: /edge|edga|edgios|edg/i,
|
|
132
|
-
PhantomJS: /phantomjs/i,
|
|
133
|
-
Konqueror: /konqueror/i,
|
|
134
|
-
Amaya: /amaya/i,
|
|
135
|
-
Epiphany: /epiphany/i,
|
|
136
|
-
SeaMonkey: /seamonkey/i,
|
|
137
|
-
Flock: /flock/i,
|
|
138
|
-
OmniWeb: /omniweb/i,
|
|
139
|
-
Opera: /opera|OPR\//i,
|
|
140
|
-
Chromium: /chromium/i,
|
|
141
|
-
Facebook: /FBA[NV]/,
|
|
142
|
-
Chrome: /chrome|crios/i,
|
|
143
|
-
WinJs: /msapphost/i,
|
|
144
|
-
IE: /msie|trident/i,
|
|
145
|
-
Firefox: /firefox|fxios/i,
|
|
146
|
-
Safari: /safari/i,
|
|
147
|
-
PS5: /playstation 5/i,
|
|
148
|
-
PS4: /playstation 4/i,
|
|
149
|
-
PS3: /playstation 3/i,
|
|
150
|
-
PSP: /playstation portable/i,
|
|
151
|
-
PS: /playstation/i,
|
|
152
|
-
Xbox: /xbox/i,
|
|
153
|
-
UC: /UCBrowser/i,
|
|
154
|
-
};
|
package/src/api.vfs.js
CHANGED
|
@@ -207,14 +207,14 @@ const apis = {
|
|
|
207
207
|
}
|
|
208
208
|
});
|
|
209
209
|
},
|
|
210
|
-
async windows_integration() {
|
|
210
|
+
async windows_integration({ parent }) {
|
|
211
211
|
const status = await (0, listen_1.getServerStatus)(true);
|
|
212
212
|
const h = status.http.listening ? status.http : status.https;
|
|
213
213
|
const url = h.srv.name + '://localhost:' + h.port;
|
|
214
214
|
for (const k of ['*', 'Directory']) {
|
|
215
215
|
await reg('add', WINDOWS_REG_KEY.replace('*', k), '/ve', '/f', '/d', 'Add to HFS (new)');
|
|
216
216
|
await reg('add', WINDOWS_REG_KEY.replace('*', k) + '\\command', '/ve', '/f', '/d', `powershell -Command "
|
|
217
|
-
$j = '{ \\"source\\": "' + ('%1'|convertTo-json) + '" }'; $j = [System.Text.Encoding]::UTF8.GetBytes($j); $wsh = New-Object -ComObject Wscript.Shell;
|
|
217
|
+
$j = '{ \\"parent\\": \\"${parent}\\", \\"source\\": "' + ('%1'|convertTo-json) + '" }'; $j = [System.Text.Encoding]::UTF8.GetBytes($j); $wsh = New-Object -ComObject Wscript.Shell;
|
|
218
218
|
try { $res = Invoke-WebRequest -Uri '${url}/~/api/add_vfs' -Method POST -Headers @{ 'x-hfs-anti-csrf' = '1' } -ContentType 'application/json' -TimeoutSec 1 -Body $j;
|
|
219
219
|
$json = $res.Content | ConvertFrom-Json; $link = $json.link; $link | Set-Clipboard; } catch { $wsh.Popup('Server is down', 0, 'Error', 16); }"`);
|
|
220
220
|
}
|
|
@@ -248,9 +248,6 @@ function simplifyName(node) {
|
|
|
248
248
|
delete node.name;
|
|
249
249
|
}
|
|
250
250
|
const WINDOWS_REG_KEY = 'HKCU\\Software\\Classes\\*\\shell\\AddToHFS3';
|
|
251
|
-
if (const_1.IS_WINDOWS) // legacy 0.49.0-beta7 2023-10-27. Remove in 0.50
|
|
252
|
-
for (const k of ['*', 'Directory'])
|
|
253
|
-
reg('delete', `HKCR\\${k}\\shell\\AddToHFS3`, '/f').catch(() => { });
|
|
254
251
|
function reg(...pars) {
|
|
255
252
|
return (0, util_1.promisify)(child_process_1.execFile)('reg', pars);
|
|
256
253
|
}
|
package/src/apiMiddleware.js
CHANGED
|
@@ -23,7 +23,7 @@ const logApi = (0, config_1.defineConfig)('log_api', true);
|
|
|
23
23
|
function apiMiddleware(apis) {
|
|
24
24
|
return async (ctx) => {
|
|
25
25
|
if (!logApi.get())
|
|
26
|
-
ctx.state.
|
|
26
|
+
ctx.state.dontLog = true;
|
|
27
27
|
const isPost = ctx.params;
|
|
28
28
|
const params = isPost ? ctx.params || {} : ctx.query;
|
|
29
29
|
const apiName = ctx.path;
|
package/src/comments.js
CHANGED
|
@@ -20,7 +20,7 @@ async function getCommentFor(path) {
|
|
|
20
20
|
: readDescription((0, path_1.dirname)(path)).then(x => x.get((0, cross_1.basename)(path)), () => undefined);
|
|
21
21
|
}
|
|
22
22
|
exports.getCommentFor = getCommentFor;
|
|
23
|
-
exports.setCommentFor = (0, misc_1.
|
|
23
|
+
exports.setCommentFor = (0, misc_1.singleWorkerFromBatchWorker)(async (jobs) => {
|
|
24
24
|
const byFolder = lodash_1.default.groupBy(jobs, job => (0, path_1.dirname)(job[0]));
|
|
25
25
|
return Promise.allSettled(lodash_1.default.map(byFolder, async (jobs, folder) => {
|
|
26
26
|
const comments = await readDescription(folder).catch(() => new Map());
|
package/src/const.js
CHANGED
|
@@ -30,19 +30,22 @@ 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.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;
|
|
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 = exports.HFS_REPO = exports.COMPATIBLE_API_VERSION = exports.API_VERSION = void 0;
|
|
34
34
|
const minimist_1 = __importDefault(require("minimist"));
|
|
35
35
|
const fs = __importStar(require("fs"));
|
|
36
36
|
const os_1 = require("os");
|
|
37
37
|
const fs_1 = require("fs");
|
|
38
38
|
const path_1 = require("path");
|
|
39
39
|
__exportStar(require("./cross-const"), exports);
|
|
40
|
+
exports.API_VERSION = 8.62;
|
|
41
|
+
exports.COMPATIBLE_API_VERSION = 1; // while changes in the api are not breaking, this number stays the same, otherwise it is made equal to API_VERSION
|
|
42
|
+
exports.HFS_REPO = 'rejetto/hfs';
|
|
40
43
|
exports.argv = (0, minimist_1.default)(process.argv.slice(2));
|
|
41
44
|
exports.DEV = process.env.DEV || exports.argv.dev ? 'DEV' : '';
|
|
42
45
|
exports.ORIGINAL_CWD = process.cwd();
|
|
43
46
|
exports.HFS_STARTED = new Date();
|
|
44
47
|
const PKG_PATH = (0, path_1.join)(__dirname, '..', 'package.json');
|
|
45
|
-
exports.BUILD_TIMESTAMP = "2023-12-
|
|
48
|
+
exports.BUILD_TIMESTAMP = "2023-12-21T13:46:51.866Z";
|
|
46
49
|
const pkg = JSON.parse(fs.readFileSync(PKG_PATH, 'utf8'));
|
|
47
50
|
exports.VERSION = pkg.version;
|
|
48
51
|
exports.RUNNING_BETA = exports.VERSION.includes('-');
|
package/src/cross-const.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.HTTP_MESSAGES = exports.HTTP_SERVICE_UNAVAILABLE = exports.HTTP_SERVER_ERROR = exports.HTTP_FAILED_DEPENDENCY = exports.HTTP_FOOL = exports.HTTP_RANGE_NOT_SATISFIABLE = exports.HTTP_PAYLOAD_TOO_LARGE = exports.HTTP_PRECONDITION_FAILED = exports.HTTP_CONFLICT = exports.HTTP_NOT_ACCEPTABLE = exports.HTTP_METHOD_NOT_ALLOWED = exports.HTTP_NOT_FOUND = exports.HTTP_FORBIDDEN = exports.HTTP_UNAUTHORIZED = exports.HTTP_BAD_REQUEST = exports.HTTP_NOT_MODIFIED = exports.HTTP_TEMPORARY_REDIRECT = exports.HTTP_MOVED_PERMANENTLY = exports.HTTP_PARTIAL_CONTENT = exports.HTTP_NO_CONTENT = exports.HTTP_OK = exports.PORT_DISABLED = exports.PLUGINS_PUB_URI = exports.API_URI = exports.ADMIN_URI = exports.FRONTEND_URI = exports.SPECIAL_URI =
|
|
4
|
-
exports.API_VERSION = 8.4;
|
|
5
|
-
exports.COMPATIBLE_API_VERSION = 1; // while changes in the api are not breaking, this number stays the same, otherwise it is made equal to API_VERSION
|
|
6
|
-
exports.HFS_REPO = 'rejetto/hfs';
|
|
3
|
+
exports.HTTP_MESSAGES = exports.HTTP_SERVICE_UNAVAILABLE = exports.HTTP_SERVER_ERROR = exports.HTTP_TOO_MANY_REQUESTS = exports.HTTP_FAILED_DEPENDENCY = exports.HTTP_FOOL = exports.HTTP_RANGE_NOT_SATISFIABLE = exports.HTTP_PAYLOAD_TOO_LARGE = exports.HTTP_PRECONDITION_FAILED = exports.HTTP_CONFLICT = exports.HTTP_NOT_ACCEPTABLE = exports.HTTP_METHOD_NOT_ALLOWED = exports.HTTP_NOT_FOUND = exports.HTTP_FORBIDDEN = exports.HTTP_UNAUTHORIZED = exports.HTTP_BAD_REQUEST = exports.HTTP_NOT_MODIFIED = exports.HTTP_TEMPORARY_REDIRECT = exports.HTTP_MOVED_PERMANENTLY = exports.HTTP_PARTIAL_CONTENT = exports.HTTP_NO_CONTENT = exports.HTTP_OK = exports.PORT_DISABLED = exports.PLUGINS_PUB_URI = exports.API_URI = exports.ADMIN_URI = exports.FRONTEND_URI = exports.SPECIAL_URI = void 0;
|
|
7
4
|
exports.SPECIAL_URI = '/~/';
|
|
8
5
|
exports.FRONTEND_URI = exports.SPECIAL_URI + 'frontend/';
|
|
9
6
|
exports.ADMIN_URI = exports.SPECIAL_URI + 'admin/';
|
|
@@ -28,6 +25,7 @@ exports.HTTP_PAYLOAD_TOO_LARGE = 413;
|
|
|
28
25
|
exports.HTTP_RANGE_NOT_SATISFIABLE = 416;
|
|
29
26
|
exports.HTTP_FOOL = 418;
|
|
30
27
|
exports.HTTP_FAILED_DEPENDENCY = 424;
|
|
28
|
+
exports.HTTP_TOO_MANY_REQUESTS = 429;
|
|
31
29
|
exports.HTTP_SERVER_ERROR = 500;
|
|
32
30
|
exports.HTTP_SERVICE_UNAVAILABLE = 503;
|
|
33
31
|
exports.HTTP_MESSAGES = {
|
|
@@ -35,4 +33,5 @@ exports.HTTP_MESSAGES = {
|
|
|
35
33
|
[exports.HTTP_FORBIDDEN]: "Forbidden",
|
|
36
34
|
[exports.HTTP_NOT_FOUND]: "Not found",
|
|
37
35
|
[exports.HTTP_SERVER_ERROR]: "Server error",
|
|
36
|
+
[exports.HTTP_TOO_MANY_REQUESTS]: "Too many requests",
|
|
38
37
|
};
|
package/src/cross.js
CHANGED
|
@@ -17,11 +17,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
17
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
18
|
};
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.
|
|
21
|
-
exports.runAt = exports.promiseBestEffort = exports.escapeHTML = exports.ipForUrl = exports.ipLocalHost = exports.xlate = exports.isEqualLax = exports.isWindowsDrive = exports.isIP = exports.isPrimitive = exports.formatTimestamp = exports.repeat = exports.asyncGeneratorToArray = exports.filterMapGenerator = void 0;
|
|
20
|
+
exports.hasProp = exports.typedEntries = exports.typedKeys = exports.objRenameKey = exports.randomId = exports.getOrSet = exports.waitFor = exports.newObj = exports.findDefined = exports.isOrderedEqual = exports.swap = exports.tryJson = exports.dirname = exports.basename = exports.pendingPromise = exports._dbg = exports._log = exports.wantArray = exports.formatPerc = exports.with_ = exports.try_ = exports.setHidden = exports.onlyTruthy = exports.truthy = exports.splitAt = exports.removeStarting = exports.enforceFinal = exports.objSameKeys = exports.haveTimeout = exports.wait = exports.prefix = exports.formatSpeed = exports.formatBytes = exports.isWhoObject = exports.PERM_KEYS = exports.defaultPerms = exports.WHO_ANY_ACCOUNT = exports.WHO_NO_ONE = exports.WHO_ANYONE = exports.LIST = exports.CFG = exports.THEME_OPTIONS = exports.SORT_BY_OPTIONS = exports.FRONTEND_OPTIONS = exports.MAX_TILE_SIZE = exports.DAY = exports.HOUR = exports.MINUTE = exports.WIKI_URL = exports.REPO_URL = void 0;
|
|
21
|
+
exports.shortenAgent = exports.matches = exports.makeMatcher = exports.runAt = exports.promiseBestEffort = exports.escapeHTML = exports.ipForUrl = exports.ipLocalHost = exports.xlate = exports.isEqualLax = exports.isWindowsDrive = exports.isIP = exports.isPrimitive = exports.formatTimestamp = exports.repeat = exports.asyncGeneratorToArray = exports.filterMapGenerator = exports.throw_ = void 0;
|
|
22
22
|
// This file is part of HFS - Copyright 2021-2023, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
|
|
23
23
|
// all content here is shared between client and server
|
|
24
24
|
const lodash_1 = __importDefault(require("lodash"));
|
|
25
|
+
const picomatch_1 = __importDefault(require("picomatch/lib/picomatch")); // point directly to the browser-compatible source
|
|
25
26
|
__exportStar(require("./cross-const"), exports);
|
|
26
27
|
exports.REPO_URL = 'https://github.com/rejetto/hfs/';
|
|
27
28
|
exports.WIKI_URL = exports.REPO_URL + 'wiki/';
|
|
@@ -40,7 +41,8 @@ exports.FRONTEND_OPTIONS = {
|
|
|
40
41
|
};
|
|
41
42
|
exports.SORT_BY_OPTIONS = ['name', 'extension', 'size', 'time'];
|
|
42
43
|
exports.THEME_OPTIONS = { auto: '', light: 'light', dark: 'dark' };
|
|
43
|
-
exports.CFG = constMap(['geo_enable', 'geo_allow', 'geo_list', 'geo_allow_unknown'
|
|
44
|
+
exports.CFG = constMap(['geo_enable', 'geo_allow', 'geo_list', 'geo_allow_unknown',
|
|
45
|
+
'max_downloads', 'max_downloads_per_ip', 'max_downloads_per_account', 'roots', 'roots_mandatory']);
|
|
44
46
|
exports.LIST = { add: '+', remove: '-', update: '=', props: 'props', ready: 'ready', error: 'e' };
|
|
45
47
|
exports.WHO_ANYONE = true;
|
|
46
48
|
exports.WHO_NO_ONE = false;
|
|
@@ -97,6 +99,10 @@ function enforceFinal(sub, s, evenEmpty = false) {
|
|
|
97
99
|
return !evenEmpty && !s || s.endsWith(sub) ? s : s + sub;
|
|
98
100
|
}
|
|
99
101
|
exports.enforceFinal = enforceFinal;
|
|
102
|
+
function removeStarting(sub, s) {
|
|
103
|
+
return s.startsWith(sub) ? s.slice(sub.length) : s;
|
|
104
|
+
}
|
|
105
|
+
exports.removeStarting = removeStarting;
|
|
100
106
|
function splitAt(sub, all) {
|
|
101
107
|
if (typeof sub === 'number')
|
|
102
108
|
return [all.slice(0, sub), all.slice(sub + 1)];
|
|
@@ -161,6 +167,10 @@ function basename(path) {
|
|
|
161
167
|
return path.slice(path.lastIndexOf('/') + 1 || path.lastIndexOf('\\') + 1);
|
|
162
168
|
}
|
|
163
169
|
exports.basename = basename;
|
|
170
|
+
function dirname(path) {
|
|
171
|
+
return path.slice(0, path.lastIndexOf('/', path.length - 1));
|
|
172
|
+
}
|
|
173
|
+
exports.dirname = dirname;
|
|
164
174
|
function tryJson(s, except) {
|
|
165
175
|
try {
|
|
166
176
|
return s && JSON.parse(s);
|
|
@@ -199,10 +209,6 @@ function findDefined(a, cb) {
|
|
|
199
209
|
}
|
|
200
210
|
}
|
|
201
211
|
exports.findDefined = findDefined;
|
|
202
|
-
function removeStarting(sub, s) {
|
|
203
|
-
return s.startsWith(sub) ? s.slice(sub.length) : s;
|
|
204
|
-
}
|
|
205
|
-
exports.removeStarting = removeStarting;
|
|
206
212
|
function newObj(src, returnNewValue, recur = false) {
|
|
207
213
|
if (!src)
|
|
208
214
|
return {};
|
|
@@ -363,3 +369,46 @@ function runAt(ts, cb) {
|
|
|
363
369
|
};
|
|
364
370
|
}
|
|
365
371
|
exports.runAt = runAt;
|
|
372
|
+
function makeMatcher(mask, emptyMaskReturns = false) {
|
|
373
|
+
return mask ? (0, picomatch_1.default)(mask.replace(/^(!)?/, '$1(') + ')', { nocase: true }) // adding () will allow us to use the pipe at root level
|
|
374
|
+
: () => emptyMaskReturns;
|
|
375
|
+
}
|
|
376
|
+
exports.makeMatcher = makeMatcher;
|
|
377
|
+
function matches(s, mask, emptyMaskReturns = false) {
|
|
378
|
+
return makeMatcher(mask, emptyMaskReturns)(s); // adding () will allow us to use the pipe at root level
|
|
379
|
+
}
|
|
380
|
+
exports.matches = matches;
|
|
381
|
+
function shortenAgent(agent) {
|
|
382
|
+
var _a;
|
|
383
|
+
return lodash_1.default.findKey(BROWSERS, re => re.test(agent))
|
|
384
|
+
|| ((_a = /^[^/(]+ ?/.exec(agent)) === null || _a === void 0 ? void 0 : _a[0])
|
|
385
|
+
|| agent;
|
|
386
|
+
}
|
|
387
|
+
exports.shortenAgent = shortenAgent;
|
|
388
|
+
const BROWSERS = {
|
|
389
|
+
YaBrowser: /yabrowser/i,
|
|
390
|
+
AlamoFire: /alamofire/i,
|
|
391
|
+
Edge: /edge|edga|edgios|edg/i,
|
|
392
|
+
PhantomJS: /phantomjs/i,
|
|
393
|
+
Konqueror: /konqueror/i,
|
|
394
|
+
Amaya: /amaya/i,
|
|
395
|
+
Epiphany: /epiphany/i,
|
|
396
|
+
SeaMonkey: /seamonkey/i,
|
|
397
|
+
Flock: /flock/i,
|
|
398
|
+
OmniWeb: /omniweb/i,
|
|
399
|
+
Opera: /opera|OPR\//i,
|
|
400
|
+
Chromium: /chromium/i,
|
|
401
|
+
Facebook: /FBA[NV]/,
|
|
402
|
+
Chrome: /chrome|crios/i,
|
|
403
|
+
WinJs: /msapphost/i,
|
|
404
|
+
IE: /msie|trident/i,
|
|
405
|
+
Firefox: /firefox|fxios/i,
|
|
406
|
+
Safari: /safari/i,
|
|
407
|
+
PS5: /playstation 5/i,
|
|
408
|
+
PS4: /playstation 4/i,
|
|
409
|
+
PS3: /playstation 3/i,
|
|
410
|
+
PSP: /playstation portable/i,
|
|
411
|
+
PS: /playstation/i,
|
|
412
|
+
Xbox: /xbox/i,
|
|
413
|
+
UC: /UCBrowser/i,
|
|
414
|
+
};
|
package/src/debounceAsync.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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.
|
|
4
|
+
exports.singleWorkerFromBatchWorker = exports.debounceAsync = void 0;
|
|
5
5
|
// like lodash.debounce, but also avoids async invocations to overlap
|
|
6
6
|
function debounceAsync(callback, wait = 100, options = {}) {
|
|
7
7
|
const { leading = false, maxWait = Infinity, cancelable = false, retain = 0, retainFailure } = options;
|
|
@@ -64,7 +64,7 @@ function debounceAsync(callback, wait = 100, options = {}) {
|
|
|
64
64
|
}
|
|
65
65
|
exports.debounceAsync = debounceAsync;
|
|
66
66
|
// given a function that works on a batch of requests, returns the function that works on a single request
|
|
67
|
-
function
|
|
67
|
+
function singleWorkerFromBatchWorker(batchWorker) {
|
|
68
68
|
let batch = [];
|
|
69
69
|
const debounced = debounceAsync(async () => {
|
|
70
70
|
const ret = batchWorker(batch);
|
|
@@ -76,4 +76,4 @@ function singleFromBatch(batchWorker) {
|
|
|
76
76
|
return debounced();
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
|
-
exports.
|
|
79
|
+
exports.singleWorkerFromBatchWorker = singleWorkerFromBatchWorker;
|
package/src/errorPages.js
CHANGED
|
@@ -4,7 +4,7 @@ exports.sendErrorPage = exports.getErrorSections = void 0;
|
|
|
4
4
|
const lang_1 = require("./lang");
|
|
5
5
|
const customHtml_1 = require("./customHtml");
|
|
6
6
|
const cross_1 = require("./cross");
|
|
7
|
-
const declaredErrorPages = [cross_1.HTTP_NOT_FOUND, cross_1.HTTP_FORBIDDEN].map(String);
|
|
7
|
+
const declaredErrorPages = [cross_1.HTTP_NOT_FOUND, cross_1.HTTP_FORBIDDEN, cross_1.HTTP_TOO_MANY_REQUESTS].map(String);
|
|
8
8
|
function getErrorSections() {
|
|
9
9
|
return declaredErrorPages;
|
|
10
10
|
}
|
package/src/frontEndApis.js
CHANGED
|
@@ -29,7 +29,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
29
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
30
|
exports.notifyClient = exports.frontEndApis = void 0;
|
|
31
31
|
const apiMiddleware_1 = require("./apiMiddleware");
|
|
32
|
-
const
|
|
32
|
+
const api_get_file_list_1 = require("./api.get_file_list");
|
|
33
33
|
const api_auth = __importStar(require("./api.auth"));
|
|
34
34
|
const events_1 = __importDefault(require("./events"));
|
|
35
35
|
const util_files_1 = require("./util-files");
|
|
@@ -41,7 +41,7 @@ const upload_1 = require("./upload");
|
|
|
41
41
|
const misc_1 = require("./misc");
|
|
42
42
|
const comments_1 = require("./comments");
|
|
43
43
|
exports.frontEndApis = {
|
|
44
|
-
get_file_list:
|
|
44
|
+
get_file_list: api_get_file_list_1.get_file_list,
|
|
45
45
|
...api_auth,
|
|
46
46
|
get_notifications({ channel }, ctx) {
|
|
47
47
|
(0, misc_1.apiAssertTypes)({ string: { channel } });
|
|
@@ -134,6 +134,25 @@ exports.frontEndApis = {
|
|
|
134
134
|
throw new apiMiddleware_1.ApiError(const_1.HTTP_SERVER_ERROR, e);
|
|
135
135
|
}
|
|
136
136
|
},
|
|
137
|
+
async move_files({ uri_from, uri_to }, ctx) {
|
|
138
|
+
(0, misc_1.apiAssertTypes)({ array: { uri_from }, string: { uri_to } });
|
|
139
|
+
const destNode = await (0, vfs_1.urlToNode)(uri_to, ctx);
|
|
140
|
+
const code = !destNode ? const_1.HTTP_NOT_FOUND : (0, vfs_1.statusCodeForMissingPerm)(destNode, 'can_upload', ctx);
|
|
141
|
+
if (code)
|
|
142
|
+
return new apiMiddleware_1.ApiError(code);
|
|
143
|
+
return {
|
|
144
|
+
errors: await Promise.all(uri_from.map(async (src) => {
|
|
145
|
+
if (typeof src !== 'string')
|
|
146
|
+
return const_1.HTTP_BAD_REQUEST;
|
|
147
|
+
const srcNode = await (0, vfs_1.urlToNode)(src, ctx);
|
|
148
|
+
if (!srcNode)
|
|
149
|
+
return const_1.HTTP_NOT_FOUND;
|
|
150
|
+
return (0, vfs_1.statusCodeForMissingPerm)(srcNode, 'can_delete', ctx)
|
|
151
|
+
|| (0, promises_1.rename)(srcNode.source, (0, path_1.join)(destNode.source, (0, path_1.basename)(srcNode.source)))
|
|
152
|
+
.catch(e => e.code || String(e));
|
|
153
|
+
}))
|
|
154
|
+
};
|
|
155
|
+
},
|
|
137
156
|
async comment({ uri, comment }, ctx) {
|
|
138
157
|
(0, misc_1.apiAssertTypes)({ string: { uri, comment } });
|
|
139
158
|
const node = await (0, vfs_1.urlToNode)(uri, ctx);
|
package/src/index.js
CHANGED
|
@@ -28,6 +28,7 @@ const selfCheck_1 = require("./selfCheck");
|
|
|
28
28
|
const acme_1 = require("./acme");
|
|
29
29
|
require("./geo");
|
|
30
30
|
const geo_1 = require("./geo");
|
|
31
|
+
const roots_1 = require("./roots");
|
|
31
32
|
const events_1 = __importDefault(require("./events"));
|
|
32
33
|
(0, assert_1.ok)(lodash_1.default.intersection(Object.keys(frontEndApis_1.frontEndApis), Object.keys(adminApis_1.adminApis)).length === 0); // they share same endpoints, don't clash
|
|
33
34
|
process.title = 'HFS ' + const_1.VERSION;
|
|
@@ -46,6 +47,7 @@ exports.app.use(middlewares_1.sessionMiddleware)
|
|
|
46
47
|
.use(middlewares_1.headRequests)
|
|
47
48
|
.use(log_1.logMw)
|
|
48
49
|
.use(throttler_1.throttler)
|
|
50
|
+
.use(roots_1.rootsMiddleware)
|
|
49
51
|
.use((0, koa_mount_1.default)(const_1.API_URI, (0, apiMiddleware_1.apiMiddleware)({ ...frontEndApis_1.frontEndApis, ...adminApis_1.adminApis })))
|
|
50
52
|
.use(middlewares_1.serveGuiAndSharedFiles)
|
|
51
53
|
.on('error', errorHandler);
|
package/src/lang.js
CHANGED
|
@@ -9,6 +9,9 @@ const promises_1 = require("fs/promises");
|
|
|
9
9
|
const config_1 = require("./config");
|
|
10
10
|
const watchLoad_1 = require("./watchLoad");
|
|
11
11
|
const embedded_1 = __importDefault(require("./langs/embedded"));
|
|
12
|
+
const plugins_1 = require("./plugins");
|
|
13
|
+
const path_1 = require("path");
|
|
14
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
12
15
|
const PREFIX = 'hfs-lang-';
|
|
13
16
|
const SUFFIX = '.json';
|
|
14
17
|
const EMBEDDED_LANGUAGE = 'en';
|
|
@@ -21,6 +24,7 @@ function file2code(fn) {
|
|
|
21
24
|
}
|
|
22
25
|
exports.file2code = file2code;
|
|
23
26
|
async function getLangData(ctx) {
|
|
27
|
+
var _a;
|
|
24
28
|
const param = String(ctx.query.lang || '');
|
|
25
29
|
if (!param && forceLangData)
|
|
26
30
|
return forceLangData;
|
|
@@ -32,10 +36,11 @@ async function getLangData(ctx) {
|
|
|
32
36
|
let k = langs[i] || ''; // shut up ts
|
|
33
37
|
if (!k || k === EMBEDDED_LANGUAGE)
|
|
34
38
|
break;
|
|
39
|
+
const fn = code2file(k);
|
|
35
40
|
try {
|
|
36
|
-
ret[k] = JSON.parse(await (0, promises_1.readFile)(
|
|
41
|
+
ret[k] = JSON.parse(await (0, promises_1.readFile)(fn, 'utf8'));
|
|
37
42
|
}
|
|
38
|
-
catch (
|
|
43
|
+
catch (_b) {
|
|
39
44
|
if ((0, misc_1.hasProp)(embedded_1.default, k))
|
|
40
45
|
ret[k] = embedded_1.default[k];
|
|
41
46
|
else {
|
|
@@ -48,6 +53,9 @@ async function getLangData(ctx) {
|
|
|
48
53
|
}
|
|
49
54
|
}
|
|
50
55
|
}
|
|
56
|
+
const fromPlugins = (0, misc_1.onlyTruthy)(await Promise.all((0, plugins_1.mapPlugins)(async (pl) => { var _a; return (_a = (0, misc_1.tryJson)(await (0, promises_1.readFile)((0, path_1.join)(pl.folder, fn), 'utf8').catch(() => ''))) === null || _a === void 0 ? void 0 : _a.translate; })));
|
|
57
|
+
if (fromPlugins.length)
|
|
58
|
+
lodash_1.default.defaults((_a = (ret[k] || (ret[k] = {}))).translate || (_a.translate = {}), ...fromPlugins); // be sure we have an entry for k
|
|
51
59
|
i++;
|
|
52
60
|
}
|
|
53
61
|
return ret;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": "Massimo Melina",
|
|
3
|
-
"version": 1.
|
|
4
|
-
"hfs_version": "0.
|
|
3
|
+
"version": 1.9,
|
|
4
|
+
"hfs_version": "0.51.0",
|
|
5
5
|
"translate": {
|
|
6
6
|
"Select": "Seleziona",
|
|
7
7
|
"n_files": "{n} file",
|
|
@@ -125,9 +125,13 @@
|
|
|
125
125
|
"Comment": "Comment",
|
|
126
126
|
"upload_dd_hint": "Puoi uploadare file trascinandoli sulla lista principale",
|
|
127
127
|
"Upload not available": "Upload non disponibile",
|
|
128
|
-
"
|
|
129
|
-
"
|
|
130
|
-
"
|
|
131
|
-
"
|
|
128
|
+
"Cut": "Taglia",
|
|
129
|
+
"n_items": "{n,plural, one{# elemento} other{# elementi}}",
|
|
130
|
+
"good_bad": "{good} spostati, {bad} falliti",
|
|
131
|
+
"after_cut": "Hai messo negli appunti, ora spostati fino alla destinazione e premi \"Incolla\".",
|
|
132
|
+
"Cancel clipboard": "Annulla appunti",
|
|
133
|
+
"to_clipboard_source": "Torna all'origine'",
|
|
134
|
+
"Paste": "Incolla",
|
|
135
|
+
"clipboard_list": "Elementi negli appunti"
|
|
132
136
|
}
|
|
133
137
|
}
|
package/src/listen.js
CHANGED
|
@@ -109,8 +109,7 @@ const considerHttps = (0, misc_1.debounceAsync)(async () => {
|
|
|
109
109
|
nat_1.defaultBaseUrl.port = (_a = getCurrentPort(httpSrv)) !== null && _a !== void 0 ? _a : 0;
|
|
110
110
|
let port = exports.httpsPortCfg.get();
|
|
111
111
|
try {
|
|
112
|
-
|
|
113
|
-
await (0, misc_1.wait)(100);
|
|
112
|
+
await (0, misc_1.waitFor)(() => index_1.app);
|
|
114
113
|
httpsSrv = Object.assign(https.createServer(port === const_1.PORT_DISABLED ? {} : { ...commonOptions, key: httpsOptions.private_key, cert: httpsOptions.cert }, index_1.app.callback()), { name: 'https' });
|
|
115
114
|
if (port >= 0) {
|
|
116
115
|
const cert = getCertObject();
|