hfs 3.0.7 → 3.1.0-alpha2
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 +1 -1
- package/admin/assets/index-CDiYkO8j.css +1 -0
- package/admin/assets/index-Dm5BN1iZ.js +1 -0
- package/admin/assets/index-P5i8LyWl.js +822 -0
- package/admin/assets/{sha512-gDcjPgJS.js → sha512-DG-ElrDe.js} +1 -1
- package/admin/flags/freakflags.css +284 -0
- package/admin/flags/sprite.png +0 -0
- package/admin/index.html +3 -2
- package/frontend/assets/index-legacy-CG_og8xL.js +1 -0
- package/frontend/assets/index-legacy-DDLKWGcm.js +9 -0
- package/frontend/assets/{sha512-legacy-BBwwadDl.js → sha512-legacy-D1zEZzDe.js} +1 -1
- package/frontend/fontello.css +3 -1
- package/frontend/fontello.woff2 +0 -0
- package/frontend/index.html +1 -1
- package/npm-shrinkwrap.json +16409 -0
- package/package.json +12 -11
- package/plugins/antibrute/plugin.js +14 -3
- package/src/AsapStream.js +49 -0
- package/src/ThrottledStream.js +1 -1
- package/src/adminApis.js +16 -5
- package/src/api.accounts.js +1 -6
- package/src/api.auth.js +103 -100
- package/src/api.get_file_list.js +7 -0
- package/src/api.lang.js +1 -0
- package/src/api.log.js +5 -3
- package/src/api.monitor.js +5 -0
- package/src/api.net.js +5 -0
- package/src/api.plugins.js +13 -2
- package/src/api.vfs.js +41 -28
- package/src/apiMiddleware.js +5 -4
- package/src/auth.js +39 -6
- package/src/commands.js +16 -27
- package/src/comments.js +4 -4
- package/src/config.js +5 -2
- package/src/const.js +2 -16
- package/src/cross-const.js +5 -2
- package/src/cross.js +21 -15
- package/src/expiringCache.js +16 -5
- package/src/fileAttr.js +1 -1
- package/src/first.js +7 -4
- package/src/frontEndApis.js +88 -102
- package/src/github.js +32 -21
- package/src/ips.js +1 -1
- package/src/log.js +5 -3
- package/src/middlewares.js +2 -1
- package/src/misc.js +2 -20
- package/src/perm.js +27 -12
- package/src/persistence.js +1 -1
- package/src/plugins.js +12 -6
- package/src/serveFile.js +3 -3
- package/src/serveGuiAndSharedFiles.js +3 -0
- package/src/serveGuiFiles.js +2 -1
- package/src/srp.js +5 -6
- package/src/stat.js +4 -1
- package/src/update.js +18 -25
- package/src/upload.js +4 -3
- package/src/util-files.js +2 -1
- package/src/util-http.js +3 -3
- package/src/vfs.js +4 -2
- package/src/webdav.js +297 -0
- package/admin/assets/index-Bj9Dk3JN.js +0 -822
- package/admin/assets/index-Byv1_NxP.css +0 -1
- package/admin/flags/ad.png +0 -0
- package/admin/flags/ae.png +0 -0
- package/admin/flags/af.png +0 -0
- package/admin/flags/ag.png +0 -0
- package/admin/flags/ai.png +0 -0
- package/admin/flags/al.png +0 -0
- package/admin/flags/am.png +0 -0
- package/admin/flags/ao.png +0 -0
- package/admin/flags/aq.png +0 -0
- package/admin/flags/ar.png +0 -0
- package/admin/flags/as.png +0 -0
- package/admin/flags/at.png +0 -0
- package/admin/flags/au.png +0 -0
- package/admin/flags/aw.png +0 -0
- package/admin/flags/ax.png +0 -0
- package/admin/flags/az.png +0 -0
- package/admin/flags/ba.png +0 -0
- package/admin/flags/bb.png +0 -0
- package/admin/flags/bd.png +0 -0
- package/admin/flags/be.png +0 -0
- package/admin/flags/bf.png +0 -0
- package/admin/flags/bg.png +0 -0
- package/admin/flags/bh.png +0 -0
- package/admin/flags/bi.png +0 -0
- package/admin/flags/bj.png +0 -0
- package/admin/flags/bl.png +0 -0
- package/admin/flags/bm.png +0 -0
- package/admin/flags/bn.png +0 -0
- package/admin/flags/bo.png +0 -0
- package/admin/flags/bq.png +0 -0
- package/admin/flags/br.png +0 -0
- package/admin/flags/bs.png +0 -0
- package/admin/flags/bt.png +0 -0
- package/admin/flags/bv.png +0 -0
- package/admin/flags/bw.png +0 -0
- package/admin/flags/by.png +0 -0
- package/admin/flags/bz.png +0 -0
- package/admin/flags/ca.png +0 -0
- package/admin/flags/cc.png +0 -0
- package/admin/flags/cd.png +0 -0
- package/admin/flags/cf.png +0 -0
- package/admin/flags/cg.png +0 -0
- package/admin/flags/ch.png +0 -0
- package/admin/flags/ci.png +0 -0
- package/admin/flags/ck.png +0 -0
- package/admin/flags/cl.png +0 -0
- package/admin/flags/cm.png +0 -0
- package/admin/flags/cn.png +0 -0
- package/admin/flags/co.png +0 -0
- package/admin/flags/cr.png +0 -0
- package/admin/flags/cu.png +0 -0
- package/admin/flags/cv.png +0 -0
- package/admin/flags/cw.png +0 -0
- package/admin/flags/cx.png +0 -0
- package/admin/flags/cy.png +0 -0
- package/admin/flags/cz.png +0 -0
- package/admin/flags/de.png +0 -0
- package/admin/flags/dj.png +0 -0
- package/admin/flags/dk.png +0 -0
- package/admin/flags/dm.png +0 -0
- package/admin/flags/do.png +0 -0
- package/admin/flags/dz.png +0 -0
- package/admin/flags/ec.png +0 -0
- package/admin/flags/ee.png +0 -0
- package/admin/flags/eg.png +0 -0
- package/admin/flags/eh.png +0 -0
- package/admin/flags/er.png +0 -0
- package/admin/flags/es.png +0 -0
- package/admin/flags/et.png +0 -0
- package/admin/flags/fi.png +0 -0
- package/admin/flags/fj.png +0 -0
- package/admin/flags/fk.png +0 -0
- package/admin/flags/fm.png +0 -0
- package/admin/flags/fo.png +0 -0
- package/admin/flags/fr.png +0 -0
- package/admin/flags/ga.png +0 -0
- package/admin/flags/gb-eng.png +0 -0
- package/admin/flags/gb-nir.png +0 -0
- package/admin/flags/gb-sct.png +0 -0
- package/admin/flags/gb-wls.png +0 -0
- package/admin/flags/gb.png +0 -0
- package/admin/flags/gd.png +0 -0
- package/admin/flags/ge.png +0 -0
- package/admin/flags/gf.png +0 -0
- package/admin/flags/gg.png +0 -0
- package/admin/flags/gh.png +0 -0
- package/admin/flags/gi.png +0 -0
- package/admin/flags/gl.png +0 -0
- package/admin/flags/gm.png +0 -0
- package/admin/flags/gn.png +0 -0
- package/admin/flags/gp.png +0 -0
- package/admin/flags/gq.png +0 -0
- package/admin/flags/gr.png +0 -0
- package/admin/flags/gs.png +0 -0
- package/admin/flags/gt.png +0 -0
- package/admin/flags/gu.png +0 -0
- package/admin/flags/gw.png +0 -0
- package/admin/flags/gy.png +0 -0
- package/admin/flags/hk.png +0 -0
- package/admin/flags/hm.png +0 -0
- package/admin/flags/hn.png +0 -0
- package/admin/flags/hr.png +0 -0
- package/admin/flags/ht.png +0 -0
- package/admin/flags/hu.png +0 -0
- package/admin/flags/id.png +0 -0
- package/admin/flags/ie.png +0 -0
- package/admin/flags/il.png +0 -0
- package/admin/flags/im.png +0 -0
- package/admin/flags/in.png +0 -0
- package/admin/flags/io.png +0 -0
- package/admin/flags/iq.png +0 -0
- package/admin/flags/ir.png +0 -0
- package/admin/flags/is.png +0 -0
- package/admin/flags/it.png +0 -0
- package/admin/flags/je.png +0 -0
- package/admin/flags/jm.png +0 -0
- package/admin/flags/jo.png +0 -0
- package/admin/flags/jp.png +0 -0
- package/admin/flags/ke.png +0 -0
- package/admin/flags/kg.png +0 -0
- package/admin/flags/kh.png +0 -0
- package/admin/flags/ki.png +0 -0
- package/admin/flags/km.png +0 -0
- package/admin/flags/kn.png +0 -0
- package/admin/flags/kp.png +0 -0
- package/admin/flags/kr.png +0 -0
- package/admin/flags/kw.png +0 -0
- package/admin/flags/ky.png +0 -0
- package/admin/flags/kz.png +0 -0
- package/admin/flags/la.png +0 -0
- package/admin/flags/lb.png +0 -0
- package/admin/flags/lc.png +0 -0
- package/admin/flags/li.png +0 -0
- package/admin/flags/lk.png +0 -0
- package/admin/flags/lr.png +0 -0
- package/admin/flags/ls.png +0 -0
- package/admin/flags/lt.png +0 -0
- package/admin/flags/lu.png +0 -0
- package/admin/flags/lv.png +0 -0
- package/admin/flags/ly.png +0 -0
- package/admin/flags/ma.png +0 -0
- package/admin/flags/mc.png +0 -0
- package/admin/flags/md.png +0 -0
- package/admin/flags/me.png +0 -0
- package/admin/flags/mf.png +0 -0
- package/admin/flags/mg.png +0 -0
- package/admin/flags/mh.png +0 -0
- package/admin/flags/mk.png +0 -0
- package/admin/flags/ml.png +0 -0
- package/admin/flags/mm.png +0 -0
- package/admin/flags/mn.png +0 -0
- package/admin/flags/mo.png +0 -0
- package/admin/flags/mp.png +0 -0
- package/admin/flags/mq.png +0 -0
- package/admin/flags/mr.png +0 -0
- package/admin/flags/ms.png +0 -0
- package/admin/flags/mt.png +0 -0
- package/admin/flags/mu.png +0 -0
- package/admin/flags/mv.png +0 -0
- package/admin/flags/mw.png +0 -0
- package/admin/flags/mx.png +0 -0
- package/admin/flags/my.png +0 -0
- package/admin/flags/mz.png +0 -0
- package/admin/flags/na.png +0 -0
- package/admin/flags/nc.png +0 -0
- package/admin/flags/ne.png +0 -0
- package/admin/flags/nf.png +0 -0
- package/admin/flags/ng.png +0 -0
- package/admin/flags/ni.png +0 -0
- package/admin/flags/nl.png +0 -0
- package/admin/flags/no.png +0 -0
- package/admin/flags/np.png +0 -0
- package/admin/flags/nr.png +0 -0
- package/admin/flags/nu.png +0 -0
- package/admin/flags/nz.png +0 -0
- package/admin/flags/om.png +0 -0
- package/admin/flags/pa.png +0 -0
- package/admin/flags/pe.png +0 -0
- package/admin/flags/pf.png +0 -0
- package/admin/flags/pg.png +0 -0
- package/admin/flags/ph.png +0 -0
- package/admin/flags/pk.png +0 -0
- package/admin/flags/pl.png +0 -0
- package/admin/flags/pm.png +0 -0
- package/admin/flags/pn.png +0 -0
- package/admin/flags/pr.png +0 -0
- package/admin/flags/ps.png +0 -0
- package/admin/flags/pt.png +0 -0
- package/admin/flags/pw.png +0 -0
- package/admin/flags/py.png +0 -0
- package/admin/flags/qa.png +0 -0
- package/admin/flags/re.png +0 -0
- package/admin/flags/ro.png +0 -0
- package/admin/flags/rs.png +0 -0
- package/admin/flags/ru.png +0 -0
- package/admin/flags/rw.png +0 -0
- package/admin/flags/sa.png +0 -0
- package/admin/flags/sb.png +0 -0
- package/admin/flags/sc.png +0 -0
- package/admin/flags/sd.png +0 -0
- package/admin/flags/se.png +0 -0
- package/admin/flags/sg.png +0 -0
- package/admin/flags/sh.png +0 -0
- package/admin/flags/si.png +0 -0
- package/admin/flags/sj.png +0 -0
- package/admin/flags/sk.png +0 -0
- package/admin/flags/sl.png +0 -0
- package/admin/flags/sm.png +0 -0
- package/admin/flags/sn.png +0 -0
- package/admin/flags/so.png +0 -0
- package/admin/flags/sr.png +0 -0
- package/admin/flags/ss.png +0 -0
- package/admin/flags/st.png +0 -0
- package/admin/flags/sv.png +0 -0
- package/admin/flags/sx.png +0 -0
- package/admin/flags/sy.png +0 -0
- package/admin/flags/sz.png +0 -0
- package/admin/flags/tc.png +0 -0
- package/admin/flags/td.png +0 -0
- package/admin/flags/tf.png +0 -0
- package/admin/flags/tg.png +0 -0
- package/admin/flags/th.png +0 -0
- package/admin/flags/tj.png +0 -0
- package/admin/flags/tk.png +0 -0
- package/admin/flags/tl.png +0 -0
- package/admin/flags/tm.png +0 -0
- package/admin/flags/tn.png +0 -0
- package/admin/flags/to.png +0 -0
- package/admin/flags/tr.png +0 -0
- package/admin/flags/tt.png +0 -0
- package/admin/flags/tv.png +0 -0
- package/admin/flags/tw.png +0 -0
- package/admin/flags/tz.png +0 -0
- package/admin/flags/ua.png +0 -0
- package/admin/flags/ug.png +0 -0
- package/admin/flags/um.png +0 -0
- package/admin/flags/us.png +0 -0
- package/admin/flags/uy.png +0 -0
- package/admin/flags/uz.png +0 -0
- package/admin/flags/va.png +0 -0
- package/admin/flags/vc.png +0 -0
- package/admin/flags/ve.png +0 -0
- package/admin/flags/vg.png +0 -0
- package/admin/flags/vi.png +0 -0
- package/admin/flags/vn.png +0 -0
- package/admin/flags/vu.png +0 -0
- package/admin/flags/wf.png +0 -0
- package/admin/flags/ws.png +0 -0
- package/admin/flags/xk.png +0 -0
- package/admin/flags/ye.png +0 -0
- package/admin/flags/yt.png +0 -0
- package/admin/flags/za.png +0 -0
- package/admin/flags/zm.png +0 -0
- package/admin/flags/zw.png +0 -0
- package/frontend/assets/index-legacy-COBT1YmS.js +0 -50
package/src/api.plugins.js
CHANGED
|
@@ -7,7 +7,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
exports.checkDependencies = checkDependencies;
|
|
8
8
|
const plugins_1 = require("./plugins");
|
|
9
9
|
const lodash_1 = __importDefault(require("lodash"));
|
|
10
|
-
const assert_1 = __importDefault(require("assert"));
|
|
11
10
|
const misc_1 = require("./misc");
|
|
12
11
|
const apiMiddleware_1 = require("./apiMiddleware");
|
|
13
12
|
const promises_1 = require("fs/promises");
|
|
@@ -72,6 +71,7 @@ const apis = {
|
|
|
72
71
|
});
|
|
73
72
|
},
|
|
74
73
|
async start_plugin({ id }) {
|
|
74
|
+
assertPluginId(id);
|
|
75
75
|
if ((0, plugins_1.isPluginRunning)(id))
|
|
76
76
|
return { msg: 'already running' };
|
|
77
77
|
if (plugins_1.suspendPlugins.get())
|
|
@@ -80,13 +80,14 @@ const apis = {
|
|
|
80
80
|
return (0, plugins_1.startPlugin)(id).then(() => ({}), e => new apiMiddleware_1.ApiError(const_1.HTTP_SERVER_ERROR, e.message));
|
|
81
81
|
},
|
|
82
82
|
async stop_plugin({ id }) {
|
|
83
|
+
assertPluginId(id);
|
|
83
84
|
if (!(0, plugins_1.isPluginRunning)(id))
|
|
84
85
|
return { msg: 'already stopped' };
|
|
85
86
|
await (0, plugins_1.stopPlugin)(id);
|
|
86
87
|
return {};
|
|
87
88
|
},
|
|
88
89
|
async set_plugin({ id, enabled, config }) {
|
|
89
|
-
(
|
|
90
|
+
assertPluginId(id);
|
|
90
91
|
if (config)
|
|
91
92
|
(0, plugins_1.setPluginConfig)(id, config);
|
|
92
93
|
if (enabled !== undefined)
|
|
@@ -94,6 +95,7 @@ const apis = {
|
|
|
94
95
|
return {};
|
|
95
96
|
},
|
|
96
97
|
async get_plugin({ id }) {
|
|
98
|
+
assertPluginId(id);
|
|
97
99
|
return {
|
|
98
100
|
enabled: plugins_1.enablePlugins.get().includes(id),
|
|
99
101
|
config: {
|
|
@@ -103,6 +105,8 @@ const apis = {
|
|
|
103
105
|
};
|
|
104
106
|
},
|
|
105
107
|
get_online_plugins({ text }, ctx) {
|
|
108
|
+
if (text !== undefined && !lodash_1.default.isString(text))
|
|
109
|
+
return new apiMiddleware_1.ApiError(const_1.HTTP_BAD_REQUEST, 'bad text');
|
|
106
110
|
return new SendList_1.SendListReadable({
|
|
107
111
|
async doAtStart(list) {
|
|
108
112
|
const repos = [];
|
|
@@ -142,6 +146,7 @@ const apis = {
|
|
|
142
146
|
});
|
|
143
147
|
},
|
|
144
148
|
async download_plugin({ id, branch, stop }) {
|
|
149
|
+
assertPluginId(id);
|
|
145
150
|
await checkDependencies(await (0, github_1.readOnlinePlugin)(id, branch));
|
|
146
151
|
const folder = await (0, github_1.downloadPlugin)(id, { branch });
|
|
147
152
|
if (stop) // be sure this is not automatically started
|
|
@@ -150,6 +155,7 @@ const apis = {
|
|
|
150
155
|
|| new apiMiddleware_1.ApiError(const_1.HTTP_SERVER_ERROR);
|
|
151
156
|
},
|
|
152
157
|
async update_plugin({ id }) {
|
|
158
|
+
assertPluginId(id);
|
|
153
159
|
const found = (0, plugins_1.getPluginInfo)(id);
|
|
154
160
|
if (!found)
|
|
155
161
|
return new apiMiddleware_1.ApiError(const_1.HTTP_NOT_FOUND);
|
|
@@ -161,6 +167,7 @@ const apis = {
|
|
|
161
167
|
return {};
|
|
162
168
|
},
|
|
163
169
|
async uninstall_plugin({ id, deleteConfig }) {
|
|
170
|
+
assertPluginId(id);
|
|
164
171
|
await (0, plugins_1.stopPlugin)(id);
|
|
165
172
|
await (0, promises_1.rm)(plugins_1.PATH + '/' + id, { recursive: true, force: true });
|
|
166
173
|
if (deleteConfig)
|
|
@@ -168,6 +175,7 @@ const apis = {
|
|
|
168
175
|
return {};
|
|
169
176
|
},
|
|
170
177
|
get_plugin_log({ id }, ctx) {
|
|
178
|
+
assertPluginId(id);
|
|
171
179
|
const p = (0, plugins_1.getPluginInfo)(id);
|
|
172
180
|
if (!p)
|
|
173
181
|
return new apiMiddleware_1.ApiError(const_1.HTTP_NOT_FOUND);
|
|
@@ -178,6 +186,9 @@ const apis = {
|
|
|
178
186
|
},
|
|
179
187
|
};
|
|
180
188
|
exports.default = apis;
|
|
189
|
+
function assertPluginId(id) {
|
|
190
|
+
(0, misc_1.apiAssertTypes)({ string: { id } });
|
|
191
|
+
}
|
|
181
192
|
function serialize(p) {
|
|
182
193
|
let o = 'getData' in p ? Object.assign(lodash_1.default.pick(p, ['id', 'started']), p.getData())
|
|
183
194
|
: { ...p }; // _.defaults mutates object, and we don't want that
|
package/src/api.vfs.js
CHANGED
|
@@ -22,8 +22,6 @@ async function urlToNodeOriginal(uri) {
|
|
|
22
22
|
const n = await (0, vfs_1.urlToNode)(uri);
|
|
23
23
|
return n?.isTemp ? n.original : n;
|
|
24
24
|
}
|
|
25
|
-
const ALLOWED_KEYS = ['name', 'source', 'masks', 'default', 'accept', 'rename', 'mime', 'url',
|
|
26
|
-
'target', 'comment', 'icon', 'order', ...misc_1.PERM_KEYS];
|
|
27
25
|
exports.default = {
|
|
28
26
|
async get_vfs() {
|
|
29
27
|
return { root: await recur() };
|
|
@@ -44,7 +42,7 @@ exports.default = {
|
|
|
44
42
|
...node.original || node,
|
|
45
43
|
inherited,
|
|
46
44
|
byMasks: lodash_1.default.isEmpty(byMasks) ? undefined : byMasks,
|
|
47
|
-
website:
|
|
45
|
+
website: node.children?.some((0, vfs_1.isSameFilenameAs)('index.html'))
|
|
48
46
|
|| isFolder && source && await (0, misc_1.statWithTimeout)((0, path_1.join)(source, 'index.html')).then(() => true, () => undefined)
|
|
49
47
|
|| undefined,
|
|
50
48
|
name: (0, vfs_1.getNodeName)(node),
|
|
@@ -53,6 +51,25 @@ exports.default = {
|
|
|
53
51
|
};
|
|
54
52
|
}
|
|
55
53
|
},
|
|
54
|
+
async set_vfs({ uri, props }) {
|
|
55
|
+
const n = uri && await urlToNodeOriginal(uri);
|
|
56
|
+
if (!n)
|
|
57
|
+
return new apiMiddleware_1.ApiError(const_1.HTTP_NOT_FOUND, 'path not found');
|
|
58
|
+
if (props.name && props.name !== (0, vfs_1.getNodeName)(n)) {
|
|
59
|
+
if (!(0, misc_1.isValidFileName)(props.name))
|
|
60
|
+
return new apiMiddleware_1.ApiError(const_1.HTTP_BAD_REQUEST, 'bad name');
|
|
61
|
+
// check for siblings with the same name
|
|
62
|
+
const parent = await urlToNodeOriginal((0, path_1.dirname)(uri));
|
|
63
|
+
if (parent?.children?.find(x => (0, vfs_1.getNodeName)(x) === props.name))
|
|
64
|
+
return new apiMiddleware_1.ApiError(const_1.HTTP_CONFLICT, 'name already present');
|
|
65
|
+
}
|
|
66
|
+
Object.assign(n, sanitizeVfsProps(props));
|
|
67
|
+
simplifyName(n);
|
|
68
|
+
n.isFolder = undefined; // reset field, it will be set by saveVfs
|
|
69
|
+
await (0, vfs_1.saveVfs)();
|
|
70
|
+
return n;
|
|
71
|
+
},
|
|
72
|
+
// legacy – not currently used by the UI
|
|
56
73
|
async move_vfs({ from, parent }) {
|
|
57
74
|
if (!from || !parent)
|
|
58
75
|
return new apiMiddleware_1.ApiError(const_1.HTTP_BAD_REQUEST);
|
|
@@ -71,35 +88,19 @@ exports.default = {
|
|
|
71
88
|
return new apiMiddleware_1.ApiError(const_1.HTTP_CONFLICT, 'item with same name already present in destination');
|
|
72
89
|
const oldParent = await urlToNodeOriginal((0, path_1.dirname)(from));
|
|
73
90
|
lodash_1.default.pull(oldParent.children, fromNode);
|
|
74
|
-
if (lodash_1.default.isEmpty(oldParent.children))
|
|
91
|
+
if (lodash_1.default.isEmpty(oldParent.children)) {
|
|
75
92
|
delete oldParent.children;
|
|
93
|
+
}
|
|
94
|
+
;
|
|
76
95
|
(parentNode.children ||= []).push(fromNode);
|
|
77
96
|
await (0, vfs_1.saveVfs)();
|
|
78
97
|
return {};
|
|
79
98
|
},
|
|
80
|
-
|
|
81
|
-
const n = await urlToNodeOriginal(uri);
|
|
82
|
-
if (!n)
|
|
83
|
-
return new apiMiddleware_1.ApiError(const_1.HTTP_NOT_FOUND, 'path not found');
|
|
84
|
-
if (props.name && props.name !== (0, vfs_1.getNodeName)(n)) {
|
|
85
|
-
if (!(0, misc_1.isValidFileName)(props.name))
|
|
86
|
-
return new apiMiddleware_1.ApiError(const_1.HTTP_BAD_REQUEST, 'bad name');
|
|
87
|
-
const parent = await urlToNodeOriginal((0, path_1.dirname)(uri));
|
|
88
|
-
if (parent?.children?.find(x => (0, vfs_1.getNodeName)(x) === props.name))
|
|
89
|
-
return new apiMiddleware_1.ApiError(const_1.HTTP_CONFLICT, 'name already present');
|
|
90
|
-
}
|
|
91
|
-
if (props.masks && typeof props.masks !== 'object')
|
|
92
|
-
delete props.masks;
|
|
93
|
-
Object.assign(n, pickProps(props, ALLOWED_KEYS));
|
|
94
|
-
simplifyName(n);
|
|
95
|
-
n.isFolder = undefined; // reset field, it will be set by saveVfs
|
|
96
|
-
await (0, vfs_1.saveVfs)();
|
|
97
|
-
return n;
|
|
98
|
-
},
|
|
99
|
+
// legacy – not currently used by the UI
|
|
99
100
|
async add_vfs({ parent, source, name, ...rest }) {
|
|
100
101
|
if (!source && !name)
|
|
101
102
|
return new apiMiddleware_1.ApiError(const_1.HTTP_BAD_REQUEST, 'name or source required');
|
|
102
|
-
if (!(0, misc_1.isValidFileName)(name))
|
|
103
|
+
if (name && !(0, misc_1.isValidFileName)(name))
|
|
103
104
|
return new apiMiddleware_1.ApiError(const_1.HTTP_BAD_REQUEST, 'bad name');
|
|
104
105
|
const parentNode = parent ? await urlToNodeOriginal(parent) : vfs_1.vfs;
|
|
105
106
|
if (!parentNode)
|
|
@@ -111,7 +112,7 @@ exports.default = {
|
|
|
111
112
|
const isFolder = source && await (0, misc_1.isDirectory)(source);
|
|
112
113
|
if (source && isFolder === undefined)
|
|
113
114
|
return new apiMiddleware_1.ApiError(const_1.HTTP_NOT_FOUND, 'source not found');
|
|
114
|
-
const child = { source, name, ...
|
|
115
|
+
const child = { source, name, ...sanitizeVfsProps(rest) };
|
|
115
116
|
name = (0, vfs_1.getNodeName)(child); // could be not given as input
|
|
116
117
|
const ext = (0, path_1.extname)(name);
|
|
117
118
|
const noExt = ext ? name.slice(0, -ext.length) : name;
|
|
@@ -128,6 +129,7 @@ exports.default = {
|
|
|
128
129
|
+ (isFolder ? '/' : '');
|
|
129
130
|
return { name, link };
|
|
130
131
|
},
|
|
132
|
+
// legacy – not currently used by the UI
|
|
131
133
|
async del_vfs({ uris }) {
|
|
132
134
|
if (!uris || !Array.isArray(uris))
|
|
133
135
|
return new apiMiddleware_1.ApiError(const_1.HTTP_BAD_REQUEST, 'bad uris');
|
|
@@ -169,7 +171,7 @@ exports.default = {
|
|
|
169
171
|
return {};
|
|
170
172
|
},
|
|
171
173
|
get_disk_spaces: util_os_1.getDiskSpaces,
|
|
172
|
-
get_ls({ path, files, fileMask }, ctx) {
|
|
174
|
+
get_ls({ path, files = true, fileMask }, ctx) {
|
|
173
175
|
return new SendList_1.SendListReadable({
|
|
174
176
|
async doAtStart(list) {
|
|
175
177
|
if (!path && const_1.IS_WINDOWS) {
|
|
@@ -253,11 +255,22 @@ exports.default = {
|
|
|
253
255
|
function pickProps(o, keys) {
|
|
254
256
|
const ret = {};
|
|
255
257
|
if (o && typeof o === 'object')
|
|
256
|
-
for (const k
|
|
257
|
-
if (k
|
|
258
|
+
for (const k in o)
|
|
259
|
+
if (keys.includes(k))
|
|
258
260
|
ret[k] = o[k] === null || o[k] === '' ? undefined : o[k];
|
|
259
261
|
return ret;
|
|
260
262
|
}
|
|
263
|
+
function sanitizeVfsProps(props) {
|
|
264
|
+
const ret = pickProps(props, misc_1.VFS_STORED_KEYS);
|
|
265
|
+
if (ret.masks && typeof ret.masks !== 'object')
|
|
266
|
+
ret.masks = undefined;
|
|
267
|
+
if (props?.children === null)
|
|
268
|
+
delete ret.children;
|
|
269
|
+
else if (Array.isArray(props?.children))
|
|
270
|
+
ret.children = !props.children.length ? undefined
|
|
271
|
+
: props.children.map(sanitizeVfsProps);
|
|
272
|
+
return ret;
|
|
273
|
+
}
|
|
261
274
|
function simplifyName(node) {
|
|
262
275
|
const { name, ...noName } = node;
|
|
263
276
|
if ((0, vfs_1.getNodeName)(noName) === name)
|
package/src/apiMiddleware.js
CHANGED
|
@@ -29,10 +29,11 @@ function apiMiddleware(apis) {
|
|
|
29
29
|
const params = isPost ? ctx.state.params || {} : ctx.query;
|
|
30
30
|
const apiName = ctx.path;
|
|
31
31
|
console.debug('API', ctx.method, apiName, { ...params });
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|| apiName.startsWith('get_')
|
|
35
|
-
|
|
32
|
+
const csrfSafe = !isPost
|
|
33
|
+
|| ctx.get('x-hfs-anti-csrf') // automatic browser actions won't carry this header
|
|
34
|
+
|| apiName.startsWith('get_') // "get_" apis are safe because they make no change
|
|
35
|
+
|| /^(curl|wget|python|go-|java|axios|postman|httpie|insomnia|bruno)/i.test(ctx.get('user-agent') || ''); // only browser are subject to CSRF
|
|
36
|
+
if (!csrfSafe)
|
|
36
37
|
return send(const_1.HTTP_FOOL, "missing header x-hfs-anti-csrf=1");
|
|
37
38
|
const customApiRest = apiName.startsWith(const_1.PLUGIN_CUSTOM_REST_PREFIX) && apiName.slice(const_1.PLUGIN_CUSTOM_REST_PREFIX.length);
|
|
38
39
|
const apiFun = customApiRest && (0, plugins_1.firstPlugin)(pl => pl.getData().customRest?.[customApiRest])
|
package/src/auth.js
CHANGED
|
@@ -1,4 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
37
|
};
|
|
@@ -11,20 +44,20 @@ exports.clearTextLogin = clearTextLogin;
|
|
|
11
44
|
exports.setLoggedIn = setLoggedIn;
|
|
12
45
|
const perm_1 = require("./perm");
|
|
13
46
|
const cross_const_1 = require("./cross-const");
|
|
14
|
-
const
|
|
47
|
+
const srp = __importStar(require("tssrp6a"));
|
|
15
48
|
const srp_1 = require("./srp");
|
|
16
49
|
const cross_1 = require("./cross");
|
|
17
50
|
const expiringCache_1 = require("./expiringCache");
|
|
18
51
|
const node_crypto_1 = require("node:crypto");
|
|
19
52
|
const events_1 = __importDefault(require("./events"));
|
|
20
|
-
const srp6aNimbusRoutines = new
|
|
53
|
+
const srp6aNimbusRoutines = new srp.SRPRoutines(new srp.SRPParameters());
|
|
21
54
|
async function srpServerStep1(account) {
|
|
22
55
|
if (!account.srp)
|
|
23
56
|
throw cross_const_1.HTTP_NOT_ACCEPTABLE;
|
|
24
57
|
const [salt, verifier] = account.srp.split('|');
|
|
25
58
|
if (!salt || !verifier)
|
|
26
59
|
throw Error("malformed account");
|
|
27
|
-
const srpSession = new
|
|
60
|
+
const srpSession = new srp.SRPServerSession(srp6aNimbusRoutines);
|
|
28
61
|
const srpServer = await srpSession.step1(account.username, BigInt(salt), BigInt(verifier));
|
|
29
62
|
return { srpServer, salt, pubKey: String(srpServer.B) }; // cast to string cause bigint can't be jsonized
|
|
30
63
|
}
|
|
@@ -36,7 +69,7 @@ async function srpCheck(username, password) {
|
|
|
36
69
|
const k = (0, node_crypto_1.createHash)('sha256').update(username + password + account.srp).digest("hex");
|
|
37
70
|
const good = await cache.try(k, async () => {
|
|
38
71
|
const { srpServer, salt, pubKey } = await srpServerStep1(account);
|
|
39
|
-
const client = await (0, srp_1.srpClientPart)(username, password, salt, pubKey);
|
|
72
|
+
const client = await (0, srp_1.srpClientPart)(srp, username, password, salt, pubKey);
|
|
40
73
|
return srpServer.step2(client.A, client.M1).then(() => true, () => false);
|
|
41
74
|
});
|
|
42
75
|
return good ? account : undefined;
|
|
@@ -65,10 +98,10 @@ async function setLoggedIn(ctx, username) {
|
|
|
65
98
|
if (s.username)
|
|
66
99
|
events_1.default.emit('logout', ctx);
|
|
67
100
|
delete ctx.state.account;
|
|
68
|
-
|
|
69
|
-
delete s.allowNet;
|
|
101
|
+
ctx.session = null;
|
|
70
102
|
return;
|
|
71
103
|
}
|
|
104
|
+
delete s.loggingIn; // clear pending SRP handshake state
|
|
72
105
|
const a = ctx.state.account = (0, perm_1.getAccount)(username);
|
|
73
106
|
if (!a)
|
|
74
107
|
return;
|
package/src/commands.js
CHANGED
|
@@ -19,8 +19,7 @@ const github_1 = require("./github");
|
|
|
19
19
|
const cross_1 = require("./cross");
|
|
20
20
|
const api_monitor_1 = __importDefault(require("./api.monitor"));
|
|
21
21
|
const argv_1 = require("./argv");
|
|
22
|
-
const
|
|
23
|
-
const debounceAsync_1 = require("./debounceAsync");
|
|
22
|
+
const listen_2 = require("./listen");
|
|
24
23
|
if (!argv_1.argv.updating && !config_1.showHelp) {
|
|
25
24
|
try {
|
|
26
25
|
// Not sure if the try is necessary for when stdin is unavailable, but someone reported a problem using nohup https://github.com/rejetto/hfs/issues/74 and I've found this example try-catching https://github.com/DefinitelyTyped/DefinitelyTyped/blob/dda83a906914489e09ca28afea12948529015d4a/types/node/readline.d.ts#L489
|
|
@@ -29,55 +28,43 @@ if (!argv_1.argv.updating && !config_1.showHelp) {
|
|
|
29
28
|
.on('line', x => parseCommandLine(x).then(showPrompt))
|
|
30
29
|
.on('SIGINT', () => process.emit('SIGINT')); // readline swallows the first ctrl+c unless we forward it to process-level handlers
|
|
31
30
|
let isClean = true;
|
|
32
|
-
|
|
33
|
-
const showPrompt = tty && (0, debounceAsync_1.debounceAsync)(async () => {
|
|
34
|
-
await cleaning;
|
|
31
|
+
const showPrompt = tty && lodash_1.default.debounce(() => {
|
|
35
32
|
if (first_1.quitting || !tty)
|
|
36
33
|
return;
|
|
37
34
|
prompter.prompt(true);
|
|
38
35
|
isClean = false;
|
|
39
|
-
},
|
|
36
|
+
}, 100);
|
|
40
37
|
function clean() {
|
|
41
38
|
if (isClean)
|
|
42
39
|
return;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
cleaning = undefined;
|
|
47
|
-
isClean = true;
|
|
48
|
-
});
|
|
49
|
-
});
|
|
40
|
+
// keep console methods synchronous: reposition the cursor immediately and let stream ordering preserve output sequence
|
|
41
|
+
(0, node_readline_1.cursorTo)(process.stdout, 0); // we don't need to clean as long as the prompt is never longer than the printed line
|
|
42
|
+
isClean = true;
|
|
50
43
|
}
|
|
51
44
|
showPrompt?.();
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
printHintOnce = undefined; // never more
|
|
56
|
-
}, 2000);
|
|
57
|
-
setTimeout(() => lodash_1.default.each(console, (v, k) => {
|
|
58
|
-
if (!lodash_1.default.isFunction(v))
|
|
59
|
-
return;
|
|
60
|
-
console[k] = async (...args) => {
|
|
45
|
+
for (const k of ['log', 'warn', 'error', 'debug']) {
|
|
46
|
+
const v = console[k];
|
|
47
|
+
console[k] = (...args) => {
|
|
61
48
|
if (!first_1.quitting && tty)
|
|
62
|
-
|
|
49
|
+
clean();
|
|
63
50
|
try {
|
|
64
51
|
v(...args);
|
|
65
52
|
}
|
|
66
53
|
finally {
|
|
67
54
|
showPrompt?.();
|
|
68
|
-
printHintOnce?.();
|
|
69
55
|
}
|
|
70
56
|
};
|
|
71
|
-
}
|
|
57
|
+
}
|
|
72
58
|
}
|
|
73
59
|
catch {
|
|
74
60
|
console.log("console commands not available");
|
|
75
61
|
}
|
|
76
62
|
}
|
|
77
63
|
async function parseCommandLine(line) {
|
|
78
|
-
|
|
64
|
+
const tokens = Array.from(line.trim().matchAll(/"((?:\\.|[^"\\])*)"|'((?:\\.|[^'\\])*)'|((?:\\.|[^\s"'\\])+)/g)).map(m => (m[1] ?? m[2] ?? m[3] ?? '').replace(/\\([\\ "'"])/g, '$1')); // unescape
|
|
65
|
+
if (!tokens.length)
|
|
79
66
|
return;
|
|
80
|
-
let [name, ...params] =
|
|
67
|
+
let [name, ...params] = tokens;
|
|
81
68
|
name = aliases[name] || name;
|
|
82
69
|
let cmd = commands[name];
|
|
83
70
|
if (cmd?.alias)
|
|
@@ -195,6 +182,8 @@ const commands = {
|
|
|
195
182
|
status: {
|
|
196
183
|
params: '',
|
|
197
184
|
async cb() {
|
|
185
|
+
const ports = await (0, listen_2.getServerStatus)(false);
|
|
186
|
+
console.log(lodash_1.default.map(ports, (x, k) => `${k.toUpperCase()} ${x.configuredPort < 0 ? "disabled" : x.listening ? `on port ${x.port}` : (x.error || "not working")}`).join(" – "));
|
|
198
187
|
const conn = (await api_monitor_1.default.get_connection_stats().next()).value;
|
|
199
188
|
if (conn) {
|
|
200
189
|
const { sent_got: sg } = conn;
|
package/src/comments.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.DESCRIPT_ION = void 0;
|
|
6
|
+
exports.DESCRIPT_ION_ALT = exports.DESCRIPT_ION = void 0;
|
|
7
7
|
exports.usingDescriptIon = usingDescriptIon;
|
|
8
8
|
exports.getCommentFor = getCommentFor;
|
|
9
9
|
exports.setCommentFor = setCommentFor;
|
|
@@ -17,7 +17,7 @@ const lodash_1 = __importDefault(require("lodash"));
|
|
|
17
17
|
const iconv_lite_1 = __importDefault(require("iconv-lite"));
|
|
18
18
|
const promises_1 = require("node:fs/promises");
|
|
19
19
|
exports.DESCRIPT_ION = 'descript.ion';
|
|
20
|
-
|
|
20
|
+
exports.DESCRIPT_ION_ALT = 'DESCRIPT.ION';
|
|
21
21
|
const commentsStorage = (0, config_1.defineConfig)(cross_1.CFG.comments_storage, '', v => ['', 'attr+ion'].includes(v)); // compiled tell us if we are using descript.ion
|
|
22
22
|
(0, config_1.defineConfig)('descript_ion', true, (v, more) => {
|
|
23
23
|
if (!v && more.version?.olderThan('0.57.0-alpha1'))
|
|
@@ -77,7 +77,7 @@ function areCommentsEnabled() {
|
|
|
77
77
|
}
|
|
78
78
|
async function filePathHelper(folder) {
|
|
79
79
|
const main = (0, path_1.join)(folder, exports.DESCRIPT_ION);
|
|
80
|
-
const alt = (0, path_1.join)(folder, DESCRIPT_ION_ALT);
|
|
80
|
+
const alt = (0, path_1.join)(folder, exports.DESCRIPT_ION_ALT);
|
|
81
81
|
return await (0, util_files_1.exists)(alt) && !await (0, util_files_1.exists)(main) ? alt : main;
|
|
82
82
|
}
|
|
83
83
|
const MULTILINE_SUFFIX = Buffer.from([4, 0xC2]);
|
|
@@ -102,6 +102,6 @@ async function readDescriptIon(path) {
|
|
|
102
102
|
}
|
|
103
103
|
descriptIonEncoding.sub(() => {
|
|
104
104
|
for (const k of util_files_1.parseFileCache.keys())
|
|
105
|
-
if (k.endsWith(exports.DESCRIPT_ION) || k.endsWith(DESCRIPT_ION_ALT))
|
|
105
|
+
if (k.endsWith(exports.DESCRIPT_ION) || k.endsWith(exports.DESCRIPT_ION_ALT))
|
|
106
106
|
util_files_1.parseFileCache.delete(k);
|
|
107
107
|
});
|
package/src/config.js
CHANGED
|
@@ -181,8 +181,11 @@ const saveDebounced = (0, debounceAsync_1.debounceAsync)(async () => {
|
|
|
181
181
|
const aWeekAgo = Date.now() - cross_1.DAY * 7;
|
|
182
182
|
if (await (0, util_files_1.statWithTimeout)(bak).then(x => aWeekAgo > x.mtimeMs, () => true))
|
|
183
183
|
await (0, promises_1.copyFile)(filePath, bak).catch(() => { }); // ignore errors
|
|
184
|
-
await exports.configFile.save(stringify({
|
|
185
|
-
|
|
184
|
+
await exports.configFile.save(stringify({
|
|
185
|
+
...state,
|
|
186
|
+
version: const_1.VERSION,
|
|
187
|
+
platform: `${process.platform}-${process.arch}${(0, cross_1.prefix)('-', !const_1.IS_BINARY && (0, path_1.basename)(process.execPath))}`,
|
|
188
|
+
})).catch(err => console.error('Failed at saving config file, please ensure it is writable.', String(err)));
|
|
186
189
|
});
|
|
187
190
|
const saveConfigAsap = () => void saveDebounced();
|
|
188
191
|
exports.saveConfigAsap = saveConfigAsap;
|
package/src/const.js
CHANGED
|
@@ -36,30 +36,16 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
36
36
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
37
37
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
38
38
|
};
|
|
39
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
40
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
41
|
-
};
|
|
42
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
-
exports.CONFIG_FILE = exports.MIME_AUTO = exports.APP_PATH = exports.IS_BINARY = exports.IS_MAC = exports.IS_WINDOWS = exports.RUNNING_BETA = exports.VERSION = exports.BUILD_TIMESTAMP = exports.HFS_STARTED = exports.ORIGINAL_CWD = exports.DEV = exports.
|
|
44
|
-
const minimist_1 = __importDefault(require("minimist"));
|
|
40
|
+
exports.CONFIG_FILE = exports.MIME_AUTO = exports.APP_PATH = exports.IS_BINARY = exports.IS_MAC = exports.IS_WINDOWS = exports.RUNNING_BETA = exports.VERSION = exports.BUILD_TIMESTAMP = exports.HFS_STARTED = exports.ORIGINAL_CWD = exports.DEV = exports.COMPATIBLE_API_VERSION = exports.API_VERSION = void 0;
|
|
45
41
|
const fs = __importStar(require("fs"));
|
|
46
42
|
const os_1 = require("os");
|
|
47
|
-
const lodash_1 = __importDefault(require("lodash"));
|
|
48
43
|
const path_1 = require("path");
|
|
49
44
|
const cross_1 = require("./cross");
|
|
50
45
|
const argv_1 = require("./argv");
|
|
51
46
|
__exportStar(require("./cross-const"), exports);
|
|
52
|
-
exports.API_VERSION =
|
|
47
|
+
exports.API_VERSION = 13;
|
|
53
48
|
exports.COMPATIBLE_API_VERSION = 1; // the day we break with the past, we'll update this
|
|
54
|
-
// you can add arguments with this file, currently used for the update process on mac/linux
|
|
55
|
-
exports.ARGS_FILE = (0, path_1.join)((0, os_1.homedir)(), 'hfs-args');
|
|
56
|
-
try {
|
|
57
|
-
const s = fs.readFileSync(exports.ARGS_FILE, 'utf-8');
|
|
58
|
-
console.log('additional arguments', s);
|
|
59
|
-
lodash_1.default.defaults(argv_1.argv, (0, minimist_1.default)(JSON.parse(s)));
|
|
60
|
-
fs.unlinkSync(exports.ARGS_FILE);
|
|
61
|
-
}
|
|
62
|
-
catch { }
|
|
63
49
|
exports.DEV = process.env.DEV ? 'DEV' : '';
|
|
64
50
|
exports.ORIGINAL_CWD = process.cwd();
|
|
65
51
|
exports.HFS_STARTED = new Date();
|
package/src/cross-const.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.HTTP_MESSAGES = exports.HTTP_INSUFFICIENT_STORAGE = 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.EMBEDDED_LANGUAGE = exports.HIDE_IN_TESTS = exports.ALLOW_SESSION_IP_CHANGE = exports.PREVIOUS_TAG = exports.MTIME_CHECK = exports.UPLOAD_TEMP_HASH = exports.HFS_REPO = exports.PLUGIN_CUSTOM_REST_PREFIX = exports.NBSP = exports.PORT_DISABLED = exports.ICONS_URI = exports.PLUGINS_PUB_URI = exports.API_URI = exports.ADMIN_URI = exports.FRONTEND_URI = exports.SPECIAL_URI = void 0;
|
|
3
|
+
exports.HTTP_MESSAGES = exports.HTTP_INSUFFICIENT_STORAGE = exports.HTTP_SERVICE_UNAVAILABLE = exports.HTTP_SERVER_ERROR = exports.HTTP_TOO_MANY_REQUESTS = exports.HTTP_FAILED_DEPENDENCY = exports.HTTP_LOCKED = 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_CREATED = exports.HTTP_OK = exports.EMBEDDED_LANGUAGE = exports.MASK_IN_TESTS = exports.HIDE_IN_TESTS = exports.ALLOW_SESSION_IP_CHANGE = exports.PREVIOUS_TAG = exports.MTIME_CHECK = exports.UPLOAD_TEMP_HASH = exports.HFS_REPO = exports.PLUGIN_CUSTOM_REST_PREFIX = exports.NBSP = exports.PORT_DISABLED = exports.ICONS_URI = exports.PLUGINS_PUB_URI = exports.API_URI = exports.ADMIN_URI = exports.FRONTEND_URI = exports.SPECIAL_URI = void 0;
|
|
4
4
|
exports.SPECIAL_URI = '/~/';
|
|
5
5
|
exports.FRONTEND_URI = exports.SPECIAL_URI + 'frontend/';
|
|
6
6
|
exports.ADMIN_URI = exports.SPECIAL_URI + 'admin/';
|
|
@@ -16,8 +16,10 @@ exports.MTIME_CHECK = 'x-mtime-check';
|
|
|
16
16
|
exports.PREVIOUS_TAG = 'previous';
|
|
17
17
|
exports.ALLOW_SESSION_IP_CHANGE = 'allow_session_ip_change';
|
|
18
18
|
exports.HIDE_IN_TESTS = 'hideInTests'; // elements that have variable size, where masking would produce changes, must be hidden
|
|
19
|
-
exports.
|
|
19
|
+
exports.MASK_IN_TESTS = 'maskInTests';
|
|
20
|
+
exports.EMBEDDED_LANGUAGE = 'en'; // frontend includes this language in the code, and not need to import the translation-json
|
|
20
21
|
exports.HTTP_OK = 200;
|
|
22
|
+
exports.HTTP_CREATED = 201;
|
|
21
23
|
exports.HTTP_NO_CONTENT = 204;
|
|
22
24
|
exports.HTTP_PARTIAL_CONTENT = 206;
|
|
23
25
|
exports.HTTP_MOVED_PERMANENTLY = 301;
|
|
@@ -34,6 +36,7 @@ exports.HTTP_PRECONDITION_FAILED = 412;
|
|
|
34
36
|
exports.HTTP_PAYLOAD_TOO_LARGE = 413;
|
|
35
37
|
exports.HTTP_RANGE_NOT_SATISFIABLE = 416;
|
|
36
38
|
exports.HTTP_FOOL = 418;
|
|
39
|
+
exports.HTTP_LOCKED = 423;
|
|
37
40
|
exports.HTTP_FAILED_DEPENDENCY = 424;
|
|
38
41
|
exports.HTTP_TOO_MANY_REQUESTS = 429;
|
|
39
42
|
exports.HTTP_SERVER_ERROR = 500;
|
package/src/cross.js
CHANGED
|
@@ -17,7 +17,7 @@ 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.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 = exports.WEBSITE = void 0;
|
|
20
|
+
exports.VFS_STORED_KEYS = 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 = exports.WEBSITE = void 0;
|
|
21
21
|
exports.isWhoObject = isWhoObject;
|
|
22
22
|
exports.formatBytes = formatBytes;
|
|
23
23
|
exports.formatSpeed = formatSpeed;
|
|
@@ -44,8 +44,6 @@ exports.wantArray = wantArray;
|
|
|
44
44
|
exports._log = _log;
|
|
45
45
|
exports._dbg = _dbg;
|
|
46
46
|
exports.pendingPromise = pendingPromise;
|
|
47
|
-
exports.basename = basename;
|
|
48
|
-
exports.dirname = dirname;
|
|
49
47
|
exports.tryJson = tryJson;
|
|
50
48
|
exports.swap = swap;
|
|
51
49
|
exports.isOrderedEqual = isOrderedEqual;
|
|
@@ -59,6 +57,7 @@ exports.typedKeys = typedKeys;
|
|
|
59
57
|
exports.typedEntries = typedEntries;
|
|
60
58
|
exports.hasProp = hasProp;
|
|
61
59
|
exports.throw_ = throw_;
|
|
60
|
+
exports.isAsyncIterable = isAsyncIterable;
|
|
62
61
|
exports.filterMapGenerator = filterMapGenerator;
|
|
63
62
|
exports.asyncGeneratorToArray = asyncGeneratorToArray;
|
|
64
63
|
exports.repeat = repeat;
|
|
@@ -109,6 +108,7 @@ exports.MAX_TILE_SIZE = 10;
|
|
|
109
108
|
exports.FRONTEND_OPTIONS = {
|
|
110
109
|
file_menu_on_link: true,
|
|
111
110
|
tile_size: 0,
|
|
111
|
+
page_size: 100,
|
|
112
112
|
sort_by: 'name',
|
|
113
113
|
invert_order: false,
|
|
114
114
|
folders_first: true,
|
|
@@ -125,7 +125,7 @@ exports.CFG = constMap(['geo_enable', 'geo_allow', 'geo_list', 'geo_allow_unknow
|
|
|
125
125
|
'log', 'error_log', 'log_rotation', 'dont_log_net', 'log_gui', 'log_api', 'log_ua', 'log_spam', 'track_ips',
|
|
126
126
|
'max_downloads', 'max_downloads_per_ip', 'max_downloads_per_account', 'roots', 'force_address', 'split_uploads',
|
|
127
127
|
'force_lang', 'suspend_plugins', 'base_url', 'size_1024', 'disable_custom_html', 'comments_storage',
|
|
128
|
-
'outbound_proxy']);
|
|
128
|
+
'force_webdav_login', 'webdav_initial_auth', 'outbound_proxy']);
|
|
129
129
|
exports.LIST = { add: '+', remove: '-', update: '=', props: 'props', ready: 'ready', error: 'e' };
|
|
130
130
|
exports.WHO_ANYONE = true;
|
|
131
131
|
exports.WHO_NO_ONE = false;
|
|
@@ -139,6 +139,8 @@ exports.defaultPerms = {
|
|
|
139
139
|
can_archive: 'can_read'
|
|
140
140
|
};
|
|
141
141
|
exports.PERM_KEYS = typedKeys(exports.defaultPerms);
|
|
142
|
+
exports.VFS_STORED_KEYS = ['name', 'source', 'masks', 'default', 'accept', 'rename',
|
|
143
|
+
'mime', 'url', 'target', 'comment', 'icon', 'order', 'children', ...exports.PERM_KEYS];
|
|
142
144
|
function constMap(a) {
|
|
143
145
|
return Object.fromEntries(a.map(x => [x, x]));
|
|
144
146
|
}
|
|
@@ -256,12 +258,6 @@ function pendingPromise() {
|
|
|
256
258
|
const ret = new Promise((resolve, reject) => takeOut = { resolve, reject });
|
|
257
259
|
return Object.assign(ret, takeOut);
|
|
258
260
|
}
|
|
259
|
-
function basename(path) {
|
|
260
|
-
return path.match(/([^\\/]+)[\\/]*$/)?.[1] || '';
|
|
261
|
-
}
|
|
262
|
-
function dirname(path) {
|
|
263
|
-
return path.slice(0, Math.max(0, path.lastIndexOf('/', path.length - 1)));
|
|
264
|
-
}
|
|
265
261
|
function tryJson(s, except) {
|
|
266
262
|
try {
|
|
267
263
|
return s && JSON.parse(s);
|
|
@@ -328,6 +324,9 @@ async function waitFor(cb, { interval = 200, timeout = Infinity } = {}) {
|
|
|
328
324
|
}
|
|
329
325
|
}
|
|
330
326
|
function getOrSet(o, k, creator) {
|
|
327
|
+
if (o instanceof Map)
|
|
328
|
+
return o.get(k)
|
|
329
|
+
|| with_(creator(), x => o.set(k, x) && x);
|
|
331
330
|
return k in o ? o[k]
|
|
332
331
|
: (o[k] = creator());
|
|
333
332
|
}
|
|
@@ -359,6 +358,9 @@ function hasProp(obj, key) {
|
|
|
359
358
|
function throw_(err) {
|
|
360
359
|
throw err;
|
|
361
360
|
}
|
|
361
|
+
function isAsyncIterable(iterable) {
|
|
362
|
+
return Symbol.asyncIterator in iterable;
|
|
363
|
+
}
|
|
362
364
|
async function* filterMapGenerator(generator, filterMap) {
|
|
363
365
|
for await (const x of generator) {
|
|
364
366
|
const res = await filterMap(x);
|
|
@@ -449,8 +451,8 @@ async function promiseBestEffort(promises) {
|
|
|
449
451
|
return res.filter(x => x.status === 'fulfilled').map((x) => x.value);
|
|
450
452
|
}
|
|
451
453
|
// encode paths leaving / separator unencoded (not like encodeURIComponent), but still encode #
|
|
452
|
-
function pathEncode(s) {
|
|
453
|
-
return s.replace(/[:&#'"% ?\\]/g, escape); // escape() is not utf8, but we are encoding only ascii chars
|
|
454
|
+
function pathEncode(s, all = false) {
|
|
455
|
+
return all ? encodeURI(s).replace(/#/g, escape) : s.replace(/[:&#'"% ?\\]/g, escape); // escape() is not utf8, but we are encoding only ascii chars
|
|
454
456
|
}
|
|
455
457
|
function pathDecode(s) { return decodeURI(s).replace(/%23/g, '#'); }
|
|
456
458
|
// run at a specific point in time, also solving the limit of setTimeout, which doesn't work with +32bit delays
|
|
@@ -498,11 +500,12 @@ function inCommon(a, b) {
|
|
|
498
500
|
i++;
|
|
499
501
|
return i;
|
|
500
502
|
}
|
|
501
|
-
function mapFilter(arr, map, filter
|
|
503
|
+
function mapFilter(arr, map, filter, invert = false) {
|
|
504
|
+
const keep = filter ?? ((x) => x !== undefined);
|
|
502
505
|
return arr[invert ? 'reduceRight' : 'reduce']((ret, x, idx) => {
|
|
503
506
|
const y = map(x, idx);
|
|
504
|
-
if (
|
|
505
|
-
ret.push(y); // push is much faster than unshift, therefore invert using reduceRight https://measurethat.net/Benchmarks/Show/29/0/array-push-vs-unshift
|
|
507
|
+
if (keep(y))
|
|
508
|
+
ret.push(y); // push is much faster than unshift, therefore, invert using reduceRight https://measurethat.net/Benchmarks/Show/29/0/array-push-vs-unshift
|
|
506
509
|
return ret;
|
|
507
510
|
}, []);
|
|
508
511
|
}
|
|
@@ -573,4 +576,7 @@ const BROWSERS = {
|
|
|
573
576
|
PS: /playstation/i,
|
|
574
577
|
Xbox: /xbox/i,
|
|
575
578
|
UC: /UCBrowser/i,
|
|
579
|
+
Finder: /WebDAVFS.+Darwin|WebDAVLib/,
|
|
580
|
+
Cyberduck: /^Cyberduck/,
|
|
581
|
+
ForkLift: /^ForkLift/,
|
|
576
582
|
};
|