hfs 0.53.0 → 0.53.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/admin/assets/index-BhNzAjVl.js +805 -0
- package/admin/assets/{sha512-rpja4qx0.js → sha512-CoF03Jtg.js} +1 -1
- package/admin/index.html +2 -2
- package/frontend/assets/index-legacy-BehBxMeJ.js +60 -0
- package/frontend/assets/{sha512-legacy-pz5im6D1.js → sha512-legacy-BnTMdNDu.js} +1 -1
- package/frontend/index.html +2 -2
- package/package.json +4 -4
- package/plugins/download-counter/plugin.js +2 -2
- package/plugins/download-counter/public/main.js +1 -1
- package/src/api.net.js +7 -4
- package/src/api.vfs.js +2 -2
- package/src/basicWeb.js +1 -1
- package/src/const.js +3 -5
- package/src/cross.js +3 -3
- package/src/github.js +2 -1
- package/src/langs/embedded.js +5 -1
- package/src/langs/hfs-lang-fi.json +5 -3
- package/src/langs/hfs-lang-hu.json +27 -19
- package/src/langs/hfs-lang-ro.json +166 -0
- package/src/langs/hfs-lang-th.json +166 -0
- package/src/langs/hfs-lang-tr.json +166 -0
- package/src/langs/hfs-lang-uk.json +170 -0
- package/src/langs/hfs-lang-vi.json +5 -5
- package/src/listen.js +4 -3
- package/src/misc.js +1 -0
- package/src/nat.js +7 -5
- package/src/perm.js +1 -1
- package/src/serveFile.js +1 -1
- package/src/upload.js +19 -13
- package/src/util-files.js +1 -1
- package/src/vfs.js +6 -6
- package/admin/assets/index-Ly9xr1F6.js +0 -811
- package/frontend/assets/index-legacy-5MEl9EM8.js +0 -60
- /package/admin/assets/{index-gNE0rRfC.css → index-CA0TStF8.css} +0 -0
- /package/frontend/assets/{polyfills-legacy-31b7nyOi.js → polyfills-legacy-DMrMt_pQ.js} +0 -0
package/src/upload.js
CHANGED
|
@@ -61,9 +61,9 @@ function uploadWriter(base, path, ctx) {
|
|
|
61
61
|
else
|
|
62
62
|
try {
|
|
63
63
|
// refer to the source of the closest node that actually belongs to the vfs, so that cache is more effective
|
|
64
|
-
let closestVfsNode = base;
|
|
65
|
-
while (closestVfsNode && !closestVfsNode.original)
|
|
66
|
-
closestVfsNode = closestVfsNode.parent;
|
|
64
|
+
let closestVfsNode = base; // if base=root, there's no parent and no original
|
|
65
|
+
while ((closestVfsNode === null || closestVfsNode === void 0 ? void 0 : closestVfsNode.parent) && !closestVfsNode.original)
|
|
66
|
+
closestVfsNode = closestVfsNode.parent; // if it's not original, it surely has a parent
|
|
67
67
|
const statDir = closestVfsNode.source;
|
|
68
68
|
if (!Object.hasOwn(diskSpaceCache, statDir)) {
|
|
69
69
|
const c = diskSpaceCache[statDir] = (0, util_os_1.getDiskSpaceSync)(statDir);
|
|
@@ -88,12 +88,12 @@ function uploadWriter(base, path, ctx) {
|
|
|
88
88
|
openFiles.add(fullPath);
|
|
89
89
|
try {
|
|
90
90
|
// if upload creates a folder, then add meta to it too
|
|
91
|
-
if (fs_1.default.mkdirSync(dir, { recursive: true }))
|
|
91
|
+
if (!dir.endsWith(':\\') && fs_1.default.mkdirSync(dir, { recursive: true }))
|
|
92
92
|
setUploadMeta(dir, ctx);
|
|
93
93
|
// use temporary name while uploading
|
|
94
94
|
const keepName = (0, path_1.basename)(fullPath).slice(-200);
|
|
95
95
|
let tempName = (0, path_1.join)(dir, 'hfs$upload-' + keepName);
|
|
96
|
-
const resumable = fs_1.default.existsSync(tempName) && !openFiles.has(tempName) && tempName;
|
|
96
|
+
const resumable = fs_1.default.existsSync(tempName) && !openFiles.has(tempName) && tempName; // resumable is temp-file-1
|
|
97
97
|
if (resumable)
|
|
98
98
|
tempName = (0, path_1.join)(dir, 'hfs$upload2-' + keepName);
|
|
99
99
|
// checks for resume feature
|
|
@@ -101,15 +101,19 @@ function uploadWriter(base, path, ctx) {
|
|
|
101
101
|
const size = resumable && (0, misc_1.try_)(() => fs_1.default.statSync(resumable).size);
|
|
102
102
|
if (size === undefined) // stat failed
|
|
103
103
|
return fail(const_1.HTTP_SERVER_ERROR);
|
|
104
|
-
if (resume > size)
|
|
104
|
+
if (lodash_1.default.isNumber(size) && resume > size)
|
|
105
105
|
return fail(const_1.HTTP_RANGE_NOT_SATISFIABLE);
|
|
106
106
|
// warn frontend about resume possibility
|
|
107
|
+
let resumableLost = false;
|
|
107
108
|
if (!resume && resumable) {
|
|
108
109
|
const timeout = 30;
|
|
109
110
|
(0, frontEndApis_1.notifyClient)(ctx, 'upload.resumable', { [path]: size, expires: Date.now() + timeout * 1000 });
|
|
110
|
-
delayedDelete(resumable, timeout, () =>
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
delayedDelete(resumable, timeout, () => // if user resumes, this upload is interrupted, and next upload will cancel this delayedDelete
|
|
112
|
+
fs_1.default.rename(tempName, resumable, err => {
|
|
113
|
+
if (err)
|
|
114
|
+
return;
|
|
115
|
+
tempName = resumable;
|
|
116
|
+
resumableLost = true;
|
|
113
117
|
}));
|
|
114
118
|
}
|
|
115
119
|
// append if resuming
|
|
@@ -136,9 +140,10 @@ function uploadWriter(base, path, ctx) {
|
|
|
136
140
|
const lockMiddleware = (0, misc_1.pendingPromise)(); // outside we need to know when all operations stopped
|
|
137
141
|
writeStream.once('close', async () => {
|
|
138
142
|
try {
|
|
143
|
+
await new Promise(res => fileStream.close(res)); // this only seem to be necessary on Windows
|
|
139
144
|
if (ctx.req.aborted) {
|
|
140
|
-
if (resumable) // we don't want to be left with 2 temp files
|
|
141
|
-
return
|
|
145
|
+
if (resumable && !resumableLost && !resuming) // we don't want to be left with 2 temp files
|
|
146
|
+
return (0, promises_1.rm)(tempName);
|
|
142
147
|
const sec = exports.deleteUnfinishedUploadsAfter.get();
|
|
143
148
|
return lodash_1.default.isNumber(sec) && delayedDelete(tempName, sec);
|
|
144
149
|
}
|
|
@@ -153,12 +158,13 @@ function uploadWriter(base, path, ctx) {
|
|
|
153
158
|
}
|
|
154
159
|
try {
|
|
155
160
|
await (0, promises_1.rename)(tempName, dest);
|
|
161
|
+
cancelDeletion(tempName); // not necessary, as deletion's failure is silent, but still
|
|
156
162
|
ctx.state.uploadDestinationPath = dest;
|
|
157
163
|
setUploadMeta(dest, ctx);
|
|
158
164
|
if (ctx.query.comment)
|
|
159
165
|
void (0, comments_1.setCommentFor)(dest, String(ctx.query.comment));
|
|
160
|
-
if (resumable)
|
|
161
|
-
|
|
166
|
+
if (resumable && !resuming) // this happens if user decided to not resume and the new upload finished before delayedDelete
|
|
167
|
+
(0, promises_1.rm)(resumable).catch(console.warn);
|
|
162
168
|
events_1.default.emit('uploadFinished', obj);
|
|
163
169
|
if (resEvent)
|
|
164
170
|
for (const cb of resEvent)
|
package/src/util-files.js
CHANGED
|
@@ -154,7 +154,7 @@ function createFileWithPath(path, options) {
|
|
|
154
154
|
}
|
|
155
155
|
exports.createFileWithPath = createFileWithPath;
|
|
156
156
|
function isValidFileName(name) {
|
|
157
|
-
return
|
|
157
|
+
return !(const_1.IS_WINDOWS ? /[/:"*?<>|\\]/ : /\//).test(name) && !dirTraversal(name);
|
|
158
158
|
}
|
|
159
159
|
exports.isValidFileName = isValidFileName;
|
|
160
160
|
function exists(path) {
|
package/src/vfs.js
CHANGED
|
@@ -103,8 +103,6 @@ async function urlToNode(url, ctx, parent = exports.vfs, getRest) {
|
|
|
103
103
|
exports.urlToNode = urlToNode;
|
|
104
104
|
async function getNodeByName(name, parent) {
|
|
105
105
|
var _a;
|
|
106
|
-
if (!(0, misc_1.isValidFileName)(name))
|
|
107
|
-
return;
|
|
108
106
|
// does the tree node have a child that goes by this name, otherwise attempt disk
|
|
109
107
|
const child = ((_a = parent.children) === null || _a === void 0 ? void 0 : _a.find(isSameFilenameAs(name))) || childFromDisk();
|
|
110
108
|
return child && applyParentToChild(child, parent, name);
|
|
@@ -121,6 +119,8 @@ async function getNodeByName(name, parent) {
|
|
|
121
119
|
}
|
|
122
120
|
ret.rename = renameUnderPath(parent.rename, name);
|
|
123
121
|
}
|
|
122
|
+
if (!(0, misc_1.isValidFileName)(onDisk))
|
|
123
|
+
return;
|
|
124
124
|
ret.source = (0, path_1.join)(parent.source, onDisk);
|
|
125
125
|
ret.original = undefined; // overwrite in applyParentToChild, so we know this is not part of the vfs
|
|
126
126
|
return ret;
|
|
@@ -233,7 +233,7 @@ async function* walkNode(parent, { ctx, depth = Infinity, prefixPath = '', requi
|
|
|
233
233
|
const name = prefixPath + nodeName;
|
|
234
234
|
took === null || took === void 0 ? void 0 : took.add(normalizeFilename(name));
|
|
235
235
|
const item = { ...child, name };
|
|
236
|
-
if (!canSee(item))
|
|
236
|
+
if (!await canSee(item))
|
|
237
237
|
continue;
|
|
238
238
|
if (item.source) // real items must be accessible
|
|
239
239
|
try {
|
|
@@ -279,7 +279,7 @@ async function* walkNode(parent, { ctx, depth = Infinity, prefixPath = '', requi
|
|
|
279
279
|
};
|
|
280
280
|
if (isFolder) // store it even if we can't see it (masks), as its children can be produced by dirStream
|
|
281
281
|
parentsCache.set(name, item);
|
|
282
|
-
if (canSee(item))
|
|
282
|
+
if (await canSee(item))
|
|
283
283
|
yield item;
|
|
284
284
|
}
|
|
285
285
|
}
|
|
@@ -287,9 +287,9 @@ async function* walkNode(parent, { ctx, depth = Infinity, prefixPath = '', requi
|
|
|
287
287
|
console.debug('glob', source, e); // ENOTDIR, or lacking permissions
|
|
288
288
|
}
|
|
289
289
|
// item will be changed, so be sure to pass a temp node
|
|
290
|
-
function canSee(item) {
|
|
290
|
+
async function canSee(item) {
|
|
291
291
|
// we basename for depth>0 where we already have the rest of the path in the parent's url, and would be duplicated
|
|
292
|
-
maskApplier(item, (0, path_1.basename)(getNodeName(item)));
|
|
292
|
+
await maskApplier(item, (0, path_1.basename)(getNodeName(item)));
|
|
293
293
|
inheritFromParent(parent, item);
|
|
294
294
|
if (ctx && !hasPermission(item, 'can_see', ctx))
|
|
295
295
|
return;
|