hfs 3.2.0-rc7 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/admin/assets/{af-ChNqX4hQ.js → af-BcngPxum.js} +1 -1
  2. package/admin/assets/{am-BjFtueiH.js → am-DtFo7gXc.js} +1 -1
  3. package/admin/assets/{ar-D-43QXnv.js → ar-B_EQ0gOA.js} +1 -1
  4. package/admin/assets/{ar-dz-C8VVHyNZ.js → ar-dz-C7XYleW9.js} +1 -1
  5. package/admin/assets/{ar-iq-CKmgtu1N.js → ar-iq-BfQJc2dx.js} +1 -1
  6. package/admin/assets/{ar-kw-ClkacMxD.js → ar-kw-0U1JfQOh.js} +1 -1
  7. package/admin/assets/{ar-ly-aLe8xUWv.js → ar-ly-zXio0U_R.js} +1 -1
  8. package/admin/assets/{ar-ma-Cmy_9gim.js → ar-ma-RnCHj7rY.js} +1 -1
  9. package/admin/assets/{ar-sa-QkSOWVHV.js → ar-sa-CMO7zpcn.js} +1 -1
  10. package/admin/assets/{ar-tn-DRqs1RVC.js → ar-tn-BKftC1Mu.js} +1 -1
  11. package/admin/assets/{az-CheoE9qy.js → az-AiZRgUb5.js} +1 -1
  12. package/admin/assets/{be-DYX-A0EV.js → be-y6bzPWFN.js} +1 -1
  13. package/admin/assets/{bg-DulQmCnv.js → bg-BisLARft.js} +1 -1
  14. package/admin/assets/{bi-sXSY6Z-Y.js → bi-48sz9hUu.js} +1 -1
  15. package/admin/assets/{bm-DZH2Z1aA.js → bm-Bs6BVzFS.js} +1 -1
  16. package/admin/assets/{bn-Bt7DRG1U.js → bn-CyEiX_eK.js} +1 -1
  17. package/admin/assets/{bn-bd-DjnJjDbD.js → bn-bd-_Q2I_DOn.js} +1 -1
  18. package/admin/assets/{bo-DxZ6w_m-.js → bo-Ue1q-9BD.js} +1 -1
  19. package/admin/assets/{br-nx-cDa8u.js → br-Bb9l-ihS.js} +1 -1
  20. package/admin/assets/{bs-DPpnb77H.js → bs-BPmB5n9t.js} +1 -1
  21. package/admin/assets/{ca-DX4yoBal.js → ca-B_r4lj3j.js} +1 -1
  22. package/admin/assets/{cs-9WHoqMlY.js → cs-CyhhYDkg.js} +1 -1
  23. package/admin/assets/{cv-0eJI5pfF.js → cv-ulbhiGq8.js} +1 -1
  24. package/admin/assets/{cy-CA7_BoTT.js → cy-C3WqFe_5.js} +1 -1
  25. package/admin/assets/{da-D665uDBy.js → da-DZLHh8Xm.js} +1 -1
  26. package/admin/assets/{de-at--PMhXgqq.js → de-at-CCxj6Bp4.js} +1 -1
  27. package/admin/assets/{de-ch-D4RpimnV.js → de-ch-CM8icK9J.js} +1 -1
  28. package/admin/assets/{de-BdinBjB5.js → de-clnjk21u.js} +1 -1
  29. package/admin/assets/{dist-DuN_bSFE.js → dist-Cvm-5z2_.js} +1 -1
  30. package/admin/assets/{dv-CXsTNQun.js → dv-X1dg-Sap.js} +1 -1
  31. package/admin/assets/{el-Dl09YDqZ.js → el-Df4pHDZ3.js} +1 -1
  32. package/admin/assets/{en-au-_I-HW2KA.js → en-au-Ct_0mddK.js} +1 -1
  33. package/admin/assets/{en-ca-D_VojBrX.js → en-ca-CQqkpac1.js} +1 -1
  34. package/admin/assets/{en-in-IJiykx5a.js → en-gb-BL2mYabO.js} +1 -1
  35. package/admin/assets/{en-ie-CC236qsJ.js → en-ie-CFOYG_Tt.js} +1 -1
  36. package/admin/assets/{en-il-B-u-HwaM.js → en-il-DgoPI8Zb.js} +1 -1
  37. package/admin/assets/{en-tt-BHGzBxdn.js → en-in-DVbA81wM.js} +1 -1
  38. package/admin/assets/{en-nz-DwJKQp8B.js → en-nz-D4INWdbm.js} +1 -1
  39. package/admin/assets/{en-CBSdvf96.js → en-rCfYK-2n.js} +1 -1
  40. package/admin/assets/{en-sg-DoIn_GVI.js → en-sg-_a9wehQB.js} +1 -1
  41. package/admin/assets/{en-gb-CPvoJu-O.js → en-tt-BAyEMcr3.js} +1 -1
  42. package/admin/assets/{eo-1cIWQbm1.js → eo-CMQMiEUh.js} +1 -1
  43. package/admin/assets/{es-DqhiELfd.js → es-B7YOeh-c.js} +1 -1
  44. package/admin/assets/{es-do-DuMx3SkF.js → es-do-Mq8WNgVk.js} +1 -1
  45. package/admin/assets/{es-mx-HO31d1Y6.js → es-mx-B_RMTunI.js} +1 -1
  46. package/admin/assets/{es-pr-mJJdhxuA.js → es-pr-uqTuZpUr.js} +1 -1
  47. package/admin/assets/{es-us-BBkaLkVh.js → es-us-D598JSxH.js} +1 -1
  48. package/admin/assets/{esm-DDoh4r_E.js → esm-C8k0V7Wx.js} +1 -1
  49. package/admin/assets/{et-CwiZ3ooQ.js → et-B6n19kok.js} +1 -1
  50. package/admin/assets/{eu-DdN35uBq.js → eu-CNx2Jk1_.js} +1 -1
  51. package/admin/assets/{fa-Bv4nYsAf.js → fa-DGIot4qi.js} +1 -1
  52. package/admin/assets/{fi-c2OfDzeC.js → fi-DaJl-Yrn.js} +1 -1
  53. package/admin/assets/{fo-C62mMzt2.js → fo-DgxLc8Be.js} +1 -1
  54. package/admin/assets/{fr-D0bFR-U7.js → fr-DoSFLSk1.js} +1 -1
  55. package/admin/assets/{fr-ca-DfK_ohBt.js → fr-ca-XcVXSZm2.js} +1 -1
  56. package/admin/assets/{fr-ch-B55WjN5s.js → fr-ch-CY_qBJu6.js} +1 -1
  57. package/admin/assets/{fy-RTCxb-xz.js → fy-CwP6pdZi.js} +1 -1
  58. package/admin/assets/{ga-D3YPWmA9.js → ga-BtKmIiqR.js} +1 -1
  59. package/admin/assets/{gd-DGy1L0Ce.js → gd-BdHmijxR.js} +1 -1
  60. package/admin/assets/{gl-BnbDJ-cD.js → gl-C5lGSMcI.js} +1 -1
  61. package/admin/assets/{gom-latn-DaoXVqRf.js → gom-latn-DLun_Cyc.js} +1 -1
  62. package/admin/assets/{gu-D4exbB_g.js → gu-BBxROGEb.js} +1 -1
  63. package/admin/assets/{he-BJkMJuxS.js → he-DseTadyh.js} +1 -1
  64. package/admin/assets/{hi-NiKhlWJ4.js → hi-DM8DF6aA.js} +1 -1
  65. package/admin/assets/{hr-DCGm41fv.js → hr-Dcrr0w28.js} +1 -1
  66. package/admin/assets/{ht-9PxpBdcR.js → ht-B6ek9t1g.js} +1 -1
  67. package/admin/assets/{hu-DcAh8Q1o.js → hu-TGqjozNS.js} +1 -1
  68. package/admin/assets/{hy-am-CzkEComP.js → hy-am-D5nMz6Yy.js} +1 -1
  69. package/admin/assets/{id-BjmYaT4V.js → id-B9LrfD64.js} +1 -1
  70. package/admin/assets/index-BGZpazPR.css +1 -0
  71. package/admin/assets/{index-it4YES4N.js → index-CMfN0pC5.js} +8 -8
  72. package/admin/assets/{is-DJobXFZO.js → is-CHPxwKd7.js} +1 -1
  73. package/admin/assets/{it-D011VfLu.js → it-D1Dtu0nW.js} +1 -1
  74. package/admin/assets/{it-ch-CSqhnZAP.js → it-ch-C1zLR1pY.js} +1 -1
  75. package/admin/assets/{ja-XLoEifLy.js → ja-DNNRQqi9.js} +1 -1
  76. package/admin/assets/{jv-OeWvfXO2.js → jv-ByMRyHLP.js} +1 -1
  77. package/admin/assets/{ka-vxfsZHIu.js → ka-BaIaZhNb.js} +1 -1
  78. package/admin/assets/{kk-DgQLaj-M.js → kk-CdG5pC8o.js} +1 -1
  79. package/admin/assets/{km-BBTAUfZA.js → km-CQGImLMP.js} +1 -1
  80. package/admin/assets/{kn-C3MvNcEn.js → kn-i6v2JbuU.js} +1 -1
  81. package/admin/assets/{ko-DwIbgyA4.js → ko-B7ZMJY_D.js} +1 -1
  82. package/admin/assets/{ku-Do__Mt_N.js → ku-Du7Lj5Ai.js} +1 -1
  83. package/admin/assets/{ky-ChrqV98h.js → ky-BFcjDu3n.js} +1 -1
  84. package/admin/assets/{lb-BUYOdep8.js → lb-kUg2Mh9U.js} +1 -1
  85. package/admin/assets/{lo-BJglNG-5.js → lo-CP6L0V2h.js} +1 -1
  86. package/admin/assets/{lt-BO4SMpW1.js → lt-BIgC7Saa.js} +1 -1
  87. package/admin/assets/{lv-UBaju8El.js → lv-BOs7b0pg.js} +1 -1
  88. package/admin/assets/{me-Dhp2pN-l.js → me-DYHaVe93.js} +1 -1
  89. package/admin/assets/{mi-7RIOsaf-.js → mi-Drez7lLe.js} +1 -1
  90. package/admin/assets/{mk-B68Lk_2S.js → mk-BK-ldTLL.js} +1 -1
  91. package/admin/assets/{ml-BuVY-qhR.js → ml-DaF3pZLU.js} +1 -1
  92. package/admin/assets/{mn-yZhW1Fad.js → mn-nHbNPFAG.js} +1 -1
  93. package/admin/assets/{mr-BKsd0V-1.js → mr-Wwf63eZM.js} +1 -1
  94. package/admin/assets/{ms-Bo82cPWt.js → ms-BIXjE3b0.js} +1 -1
  95. package/admin/assets/{ms-my-GD3KkYVL.js → ms-my-CMG5GLpT.js} +1 -1
  96. package/admin/assets/{mt-C4AkYVMX.js → mt-SRQPZ5le.js} +1 -1
  97. package/admin/assets/{my-D4enXJiP.js → my-DQYSisI9.js} +1 -1
  98. package/admin/assets/{nb-CwWYDxQD.js → nb-BU06Sx9X.js} +1 -1
  99. package/admin/assets/{ne-oEPn-U_p.js → ne-BMChpdeq.js} +1 -1
  100. package/admin/assets/{nl-D4eVW0Ta.js → nl-CXWGdKg5.js} +1 -1
  101. package/admin/assets/{nl-be-BSE-tctP.js → nl-be-fI6vO9FU.js} +1 -1
  102. package/admin/assets/{nn-COYOhXYj.js → nn-CkojFw3N.js} +1 -1
  103. package/admin/assets/{oc-lnc-QfWotTsB.js → oc-lnc-BKfjK0lp.js} +1 -1
  104. package/admin/assets/{pa-in-Cv2-1w3m.js → pa-in-BT8DvsfB.js} +1 -1
  105. package/admin/assets/{pl-Cx5VGDkU.js → pl-D0Cpx-wE.js} +1 -1
  106. package/admin/assets/{pt-BFcMT_HF.js → pt-DD7k0D3o.js} +1 -1
  107. package/admin/assets/{pt-br-CVLlsO9j.js → pt-br-DPY09O20.js} +1 -1
  108. package/admin/assets/{rn-QdNijJlB.js → rn-DWaRj8UF.js} +1 -1
  109. package/admin/assets/{ro-BUbWPmG0.js → ro-X4IcZOVs.js} +1 -1
  110. package/admin/assets/{ru-BgF0tPG6.js → ru-DqdQ6YYP.js} +1 -1
  111. package/admin/assets/{rw-BopM7qvB.js → rw-q8Mu5eAK.js} +1 -1
  112. package/admin/assets/{sd-WUO1O-J_.js → sd-WzFJ-b9p.js} +1 -1
  113. package/admin/assets/{se-BfYWrejk.js → se-B0Nt39h7.js} +1 -1
  114. package/admin/assets/{sha512-rx5ALN8t.js → sha512-ChZ-ZgQF.js} +1 -1
  115. package/admin/assets/{si-DHmSYwAw.js → si-D7WSpsGm.js} +1 -1
  116. package/admin/assets/{sk-CsKf3OOS.js → sk-wIcTcNYq.js} +1 -1
  117. package/admin/assets/{sl-Oa9PyN_G.js → sl-k_cEMlZY.js} +1 -1
  118. package/admin/assets/{sq-BH1h9voV.js → sq-D145xgL0.js} +1 -1
  119. package/admin/assets/{sr-cyrl-CHV9rE5o.js → sr-cyrl-CEGYotNk.js} +1 -1
  120. package/admin/assets/{sr-F6A1nFQl.js → sr-hqDfAF1G.js} +1 -1
  121. package/admin/assets/{ss-BgnifXyo.js → ss-DnoCncEs.js} +1 -1
  122. package/admin/assets/{sv-DLJrR7ks.js → sv-DB81pVMk.js} +1 -1
  123. package/admin/assets/{sv-fi-DYAUC7Oh.js → sv-fi-DYpZcfvJ.js} +1 -1
  124. package/admin/assets/{sw-ugKcNvo_.js → sw-DjXd57gN.js} +1 -1
  125. package/admin/assets/{ta-MmY2jlJ5.js → ta-C3wYK0Z3.js} +1 -1
  126. package/admin/assets/{te-UXUUgSgi.js → te-BD4lPDF4.js} +1 -1
  127. package/admin/assets/{tet-_IC6psQY.js → tet-BDurv1U8.js} +1 -1
  128. package/admin/assets/{tg-Ch7_zd9k.js → tg-Bm80AbZW.js} +1 -1
  129. package/admin/assets/{th-BtS533XI.js → th-DflYkQDK.js} +1 -1
  130. package/admin/assets/{tk-DEI_Lsn_.js → tk-rvsm_JbC.js} +1 -1
  131. package/admin/assets/{tl-ph-DOYss52w.js → tl-ph-Bwc5zmby.js} +1 -1
  132. package/admin/assets/{tlh-B51tXaQv.js → tlh-HKfEoZ7k.js} +1 -1
  133. package/admin/assets/{tr-CeXmTdxI.js → tr-VizeBtG6.js} +1 -1
  134. package/admin/assets/{tzl-BZ9_HPjT.js → tzl-BwO5wCIa.js} +1 -1
  135. package/admin/assets/{tzm-iNKjQcg0.js → tzm-BG7lewWS.js} +1 -1
  136. package/admin/assets/{tzm-latn-f7Pea1t0.js → tzm-latn-CrnUHIcs.js} +1 -1
  137. package/admin/assets/{ug-cn-By4p8svK.js → ug-cn-BK--SUxc.js} +1 -1
  138. package/admin/assets/{uk-Byeqw2Wr.js → uk-AJsAkG20.js} +1 -1
  139. package/admin/assets/{ur-B7IjRPc0.js → ur-vO2PrLFV.js} +1 -1
  140. package/admin/assets/{uz-C-W3XxRf.js → uz-CU8j0C84.js} +1 -1
  141. package/admin/assets/{uz-latn-BIQ4pRgP.js → uz-latn-B1U_SldD.js} +1 -1
  142. package/admin/assets/{vi-DLqQk35n.js → vi-Br-FE8zw.js} +1 -1
  143. package/admin/assets/{x-pseudo-CDaSWh6b.js → x-pseudo-BEc6ucZj.js} +1 -1
  144. package/admin/assets/{yo-Cv-olgqy.js → yo-DL2G7So6.js} +1 -1
  145. package/admin/assets/{zh-SiBGR2oS.js → zh-DNL75MTZ.js} +1 -1
  146. package/admin/assets/{zh-cn-D9CP5PQQ.js → zh-cn-BBd_VD1y.js} +1 -1
  147. package/admin/assets/{zh-hk-DWLC0iAa.js → zh-hk-CNn_dGjQ.js} +1 -1
  148. package/admin/assets/{zh-tw-BrsFXhOk.js → zh-tw-B7cjw6lq.js} +1 -1
  149. package/admin/index.html +2 -2
  150. package/frontend/assets/{dist-legacy-BaWYNjA6.js → dist-legacy-CFPnugjA.js} +1 -1
  151. package/frontend/assets/index-legacy-CCOgiwQJ.js +1 -0
  152. package/frontend/assets/{lib-legacy-DKUc98Ib.js → lib-legacy-CCULxbTk.js} +1 -1
  153. package/frontend/assets/{sha512-legacy-Drx4F1hz.js → sha512-legacy-D8zcvvqa.js} +1 -1
  154. package/frontend/index.html +1 -1
  155. package/npm-shrinkwrap.json +35 -35
  156. package/package.json +1 -1
  157. package/src/comments.js +1 -1
  158. package/src/frontEndApis.js +26 -29
  159. package/src/index.js +1 -0
  160. package/src/plugins.js +1 -1
  161. package/src/serveFile.js +10 -10
  162. package/src/serveGuiAndSharedFiles.js +1 -1
  163. package/src/serveGuiFiles.js +31 -10
  164. package/src/upload.js +1 -1
  165. package/src/util-files.js +20 -12
  166. package/src/webdav.js +1 -4
  167. package/admin/assets/index-CdJ2GK-i.css +0 -1
  168. package/frontend/assets/index-legacy-DKhdXq5m.js +0 -1
@@ -12,6 +12,7 @@ const plugins_1 = require("./plugins");
12
12
  const api_auth_1 = require("./api.auth");
13
13
  const apiMiddleware_1 = require("./apiMiddleware");
14
14
  const path_1 = require("path");
15
+ const promises_1 = require("fs/promises");
15
16
  const misc_1 = require("./misc");
16
17
  const adminApis_1 = require("./adminApis");
17
18
  const customHtml_1 = require("./customHtml");
@@ -27,6 +28,9 @@ exports.logGui = (0, config_1.defineConfig)(misc_1.CFG.log_gui, false);
27
28
  lodash_1.default.each(misc_1.FRONTEND_OPTIONS, (v, k) => (0, config_1.defineConfig)(k, v)); // define default values
28
29
  function serveStatic(uri) {
29
30
  const folder = (const_1.DEV ? 'dist/' : '') + uri.slice(2, -1);
31
+ const root = (0, path_1.join)(__dirname, '..', folder);
32
+ prewarmGuiAssets(root) // keep pkg snapshot files in memory before the reported runtime access loss can happen
33
+ .catch(e => console.error(`GUI asset prewarm failed: ${e?.code || e}`));
30
34
  return async (ctx) => {
31
35
  if (!exports.logGui.get())
32
36
  ctx.state.dontLog = true;
@@ -38,20 +42,37 @@ function serveStatic(uri) {
38
42
  if (ctx.method !== 'GET')
39
43
  return ctx.status = const_1.HTTP_METHOD_NOT_ALLOWED;
40
44
  const serveApp = shouldServeApp(ctx);
41
- const fullPath = (0, path_1.join)(__dirname, '..', folder, serveApp ? '/index.html' : ctx.path);
42
- const content = await (0, misc_1.parseFile)(fullPath, raw => serveApp || !raw.length ? raw : adjustBundlerLinks(ctx, uri, raw), 1000)
45
+ const fullPath = (0, path_1.join)(root, serveApp ? '/index.html' : ctx.path);
46
+ const cached = await parseGuiFile(fullPath)
43
47
  .catch(e => {
44
- if (e?.code !== 'ENOENT') // not supposed to happen, and yet a user reported a strange behavior
48
+ if (!/^(?:ENOENT|EISDIR)$/.test(e?.code)) // not supposed to happen, and yet a user reported a strange behavior
45
49
  console.error(`serveStatic/parseFile: ${String(e)}`);
46
50
  return null;
47
51
  });
48
- if (content === null)
52
+ if (cached === null)
49
53
  return ctx.status = const_1.HTTP_NOT_FOUND;
50
- if (!serveApp)
51
- return (0, serveFile_1.serveFile)(ctx, fullPath, const_1.MIME_AUTO, content);
54
+ if (!serveApp) {
55
+ const c = cached.content;
56
+ return (0, serveFile_1.serveFile)(ctx, fullPath, const_1.MIME_AUTO, { ...cached, content: !c.length ? c : adjustBundlerLinks(ctx, uri, c) });
57
+ }
52
58
  // we don't cache the index as it's small and may prevent plugins change to apply
53
- ctx.body = await treatIndex(ctx, uri, String(content));
59
+ ctx.body = await treatIndex(ctx, uri, String(cached.content));
54
60
  };
61
+ async function prewarmGuiAssets(dir) {
62
+ for (const entry of await (0, promises_1.readdir)(dir, { withFileTypes: true })) {
63
+ const fullPath = (0, path_1.join)(dir, entry.name);
64
+ if (entry.isDirectory()) {
65
+ await prewarmGuiAssets(fullPath);
66
+ continue;
67
+ }
68
+ if (!entry.isFile())
69
+ continue;
70
+ await parseGuiFile(fullPath);
71
+ }
72
+ }
73
+ function parseGuiFile(fullPath) {
74
+ return (0, misc_1.parseFile)(fullPath, x => x, const_1.DEV ? 1000 : Infinity); // cache raw bytes so reverse-proxy URL rewriting can still use the current request context
75
+ }
55
76
  }
56
77
  function shouldServeApp(ctx) {
57
78
  return ctx.state.serveApp ||= ctx.path.endsWith('/') && !ctx.headers.upgrade; // skip websockets
@@ -61,7 +82,7 @@ function adjustBundlerLinks(ctx, uri, data) {
61
82
  const filesUri = ctx.state.revProxyPath + uri;
62
83
  return ext && !ext.match(/\.(css|html|js|ts|scss)/) ? data
63
84
  : String(data).replace(/((?:import[ (]| from )['"])\//g, `$1${filesUri}`)
64
- .replace(/(assetsURL=function\(([^)]+)\)\{return)"\/"\+\2\}/g, `$1${JSON.stringify(filesUri)}+$2}`); // vite's preload helper uses the configured absolute base for dependency hints
85
+ .replace(/(=function\(([\w$]+)\)\{return)[`'"]\/[`'"]\+\2\}/g, `$1${JSON.stringify(filesUri)}+$2}`); // vite's preload helper uses the configured absolute base for dynamic dependency hints
65
86
  }
66
87
  const getFaviconTimestamp = (0, misc_1.debounceAsync)(async () => {
67
88
  const f = adminApis_1.favicon.get();
@@ -174,12 +195,12 @@ function serveProxied(port, uri) {
174
195
  proxy = lib.default('127.0.0.1:' + port, {
175
196
  parseReqBody: false, // the dev GUI proxy serves app/assets, so avoid koa-better-http-proxy trying to reread ctx.req
176
197
  proxyReqPathResolver: (ctx) => shouldServeApp(ctx) ? '/' : ctx.path,
177
- userResDecorator(res, data, ctx) {
198
+ userResDecorator(_res, data, ctx) {
178
199
  return shouldServeApp(ctx) ? treatIndex(ctx, uri, String(data))
179
200
  : adjustBundlerLinks(ctx, uri, data);
180
201
  }
181
202
  }));
182
- return function (ctx, next) {
203
+ return function (ctx, _next) {
183
204
  if (!exports.logGui.get())
184
205
  ctx.state.dontLog = true;
185
206
  return proxy(ctx, async () => { });
package/src/upload.js CHANGED
@@ -197,7 +197,7 @@ function uploadWriter(base, baseUri, filename, ctx) {
197
197
  if (mtime) // so we use it to touch the file
198
198
  await (0, promises_1.utimes)(dest, Date.now() / 1000, mtime / 1000);
199
199
  cancelDeletion(tempName); // not necessary, as deletion's failure is silent, but still
200
- ctx.state.uploadDestinationPath = dest;
200
+ obj.fullPath = ctx.state.uploadDestinationPath = dest;
201
201
  void setUploadMeta(dest, ctx);
202
202
  if (ctx.query.comment)
203
203
  void (0, comments_1.setCommentFor)(dest, String(ctx.query.comment));
package/src/util-files.js CHANGED
@@ -17,6 +17,7 @@ exports.ensureParentFolder = ensureParentFolder;
17
17
  exports.createFileWithPath = createFileWithPath;
18
18
  exports.createSafeWriteStream = createSafeWriteStream;
19
19
  exports.isValidFileName = isValidFileName;
20
+ exports.isValidWindowsFileName = isValidWindowsFileName;
20
21
  exports.exists = exists;
21
22
  exports.loadFileCached = loadFileCached;
22
23
  exports.parseFile = parseFile;
@@ -110,6 +111,8 @@ async function unzip(stream, cb) {
110
111
  .on('error', reject)
111
112
  .on('entry', (entry) => chain = chain.then(async () => {
112
113
  const { path, type } = entry;
114
+ if (hasDirTraversal(path))
115
+ return entry.autodrain().promise();
113
116
  const dest = await (0, cross_1.try_)(() => cb(path), e => console.warn(String(e)));
114
117
  if (!dest || type !== 'File')
115
118
  return entry.autodrain().promise();
@@ -174,31 +177,36 @@ async function createSafeWriteStream(path, options) {
174
177
  });
175
178
  }
176
179
  function isValidFileName(name, acceptUnreadable = false) {
177
- return name && name !== '.' && !(const_1.IS_WINDOWS ? /[/:"*?<>|\\]/ : /\//).test(name) && !hasDirTraversal(name)
180
+ return name && name !== '.' && !(const_1.IS_WINDOWS ? !isValidWindowsFileName(name) : /\//.test(name)) && !hasDirTraversal(name)
178
181
  && (acceptUnreadable || !/[\u0000-\u001F\u007F]/.test(name));
179
182
  }
183
+ function isValidWindowsFileName(name) {
184
+ return !/[/:"*?<>|\\]/.test(name)
185
+ && !/[. ]$/.test(name)
186
+ // windows treats these legacy DOS device names as device paths even when an extension is present
187
+ && !/^(?:con|prn|aux|nul|conin\$|conout\$|com[1-9\u00b9\u00b2\u00b3]|lpt[1-9\u00b9\u00b2\u00b3])(?:\..*)?$/i.test(name);
188
+ }
180
189
  function exists(path) {
181
190
  return (0, promises_1.access)(path).then(() => true, () => false);
182
191
  }
183
- // parse a file, caching unless timestamp has changed
184
192
  exports.parseFileCache = new Map();
185
193
  async function loadFileCached(path, loader, minInterval = 0) {
186
194
  const cached = exports.parseFileCache.get(path);
187
195
  const now = Date.now();
188
196
  if (cached && now - cached.lastCheck < minInterval)
189
- return cached.parsed;
190
- const ts = await statWithTimeout(path).then(x => x.mtime, e => {
191
- if (e?.message !== 'timeout')
192
- throw e;
193
- return cached?.ts || new Date(0); // on timeout (e.g. thread pool saturated), serve cache if any, or attempt the loader
197
+ return { stats: cached.stats, content: await cached.content };
198
+ const stats = await statWithTimeout(path).catch(e => {
199
+ if (e?.message === 'timeout' && cached)
200
+ return cached.stats; // on timeout (e.g. thread pool saturated), serve cache if any
201
+ throw e;
194
202
  });
195
203
  if (cached)
196
204
  cached.lastCheck = now;
197
- if (cached && Number(ts) === Number(cached.ts))
198
- return cached.parsed;
199
- const parsed = loader(path);
200
- exports.parseFileCache.set(path, { ts, parsed, lastCheck: now });
201
- return parsed;
205
+ if (cached && Number(stats.mtime) === Number(cached.stats.mtime))
206
+ return { stats, content: await cached.content };
207
+ const content = Promise.resolve(loader(path));
208
+ exports.parseFileCache.set(path, { stats, content, lastCheck: now });
209
+ return { stats, content: await content };
202
210
  }
203
211
  async function parseFile(path, parse, skipStatIfFresherThan = 0) {
204
212
  return loadFileCached(path, () => (0, promises_1.readFile)(path).then(parse), skipStatIfFresherThan);
package/src/webdav.js CHANGED
@@ -206,10 +206,7 @@ const webdav = async (ctx, next) => {
206
206
  if ((0, path_1.dirname)(path) === (0, path_1.dirname)(dest)) // rename case. `path` is is encoded, so we test before decoding `dest`
207
207
  try {
208
208
  // decode the single path segment so reserved chars like %2C become their real name on rename
209
- const newName = (0, cross_1.safeDecodeURIComponent)((0, path_1.basename)(dest), '');
210
- if (!newName)
211
- return ctx.status = cross_1.HTTP_BAD_REQUEST;
212
- await (0, frontEndApis_1.requestedRename)(node, newName, ctx);
209
+ await (0, frontEndApis_1.requestedRename)(node, (0, cross_1.safeDecodeURIComponent)((0, path_1.basename)(dest), ''), ctx);
213
210
  releaseWebdavLock(path); // RFC 4918 says MOVE must not carry locks to destination, so clear source lock on success
214
211
  return ctx.status = cross_1.HTTP_CREATED;
215
212
  }
@@ -1 +0,0 @@
1
- .ariaOnly{clip-path:rect(1px 1px 1px 1px);clip:rect(1px, 1px, 1px, 1px);position:absolute}.icon{text-align:center;width:1.4em;height:1.2em;font-size:1.2em;display:inline-block}@keyframes blink{0%{opacity:1}50%{opacity:.3}}:root{--success:#5c5;height:100dvh}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background:#000;height:100vh;margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}#root{min-height:100%;display:flex}main{word-break:break-word}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}img.flag{vertical-align:text-top;width:1.5em;height:1em;margin-top:1px}.icon-w-text{margin-right:.5em}form{max-width:100%}.MuiSvgIcon-root{vertical-align:bottom}div.MuiTreeItem-content{padding-top:1px;padding-bottom:0}.MuiDataGrid-columnHeaders{background-color:rgba(136,136,136,.133)}.MuiDataGrid-virtualScrollerRenderZone .MuiDataGrid-row .MuiDataGrid-cell{align-items:center;line-height:1.2em;display:flex}.MuiDataGrid-filterForm{flex-wrap:wrap;justify-content:space-evenly;row-gap:1em}.wrap[role=cell]{white-space:normal!important}ol,ul{margin-top:.2em;margin-bottom:.2em;padding-left:1.5em}h2.MuiDialogTitle-root{padding-top:2px;padding-bottom:2px}.dialog-alert .MuiDialogContent-root{white-space:pre-wrap;max-width:45em;padding:.5em 1em}.release code{background-color:rgba(136,136,136,.2);border-radius:.2em;padding:0 .2em;font-size:95%}.MuiAppBar-root .MuiAlert-standardInfo .MuiAlert-icon{color:rgba(255,255,255,.533)!important}.MuiAppBar-root .MuiAlert-standardInfo .MuiAlert-message{color:rgba(255,255,255,.667)!important}.MuiAppBar-root .MuiAlert-colorWarning .MuiAlert-icon{color:rgba(255,255,0,.533)!important}.MuiAppBar-root .MuiAlert-colorWarning .MuiAlert-message{color:rgba(255,255,0,.667)!important}.animated-dashed-line{background-image:linear-gradient(90deg,currentColor 50%,transparent 50%);background-size:10px 100%;width:100%;height:2px;animation:1s linear infinite alternate animate-dash}@keyframes animate-dash{to{background-position:20px 0}}@keyframes success{50%{color:var(--success);transform:scale(1.3)}to{transform:inherit;color:inherit}}::-webkit-scrollbar{width:4px}::-webkit-scrollbar-thumb{background:rgba(136,136,136,.533)}::-webkit-scrollbar-track{background:rgba(136,136,136,.133)}.token.operator{background:unset!important}.fflag{vertical-align:bottom;border:none;width:26px;height:17px}code[class*=language-],pre[class*=language-]{color:#657b83;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;-moz-tab-size:4;tab-size:4;-webkit-hyphens:none;-ms-hyphens:none;hyphens:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;line-height:1.5}pre[class*=language-]::-moz-selection{background:#073642}pre[class*=language-] ::-moz-selection{background:#073642}code[class*=language-]::-moz-selection{background:#073642}code[class*=language-] ::-moz-selection{background:#073642}pre[class*=language-]::-moz-selection{background:#073642}pre[class*=language-]::selection{background:#073642}pre[class*=language-] ::-moz-selection{background:#073642}pre[class*=language-] ::selection{background:#073642}code[class*=language-]::-moz-selection{background:#073642}code[class*=language-]::selection{background:#073642}code[class*=language-] ::-moz-selection{background:#073642}code[class*=language-] ::selection{background:#073642}pre[class*=language-]{border-radius:.3em;margin:.5em 0;padding:1em;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background-color:#fdf6e3}:not(pre)>code[class*=language-]{border-radius:.3em;padding:.1em}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:#93a1a1}.token.punctuation{color:#586e75}.token.namespace{opacity:.7}.token.property,.token.tag,.token.boolean,.token.number,.token.constant,.token.symbol,.token.deleted{color:#268bd2}.token.selector,.token.attr-name,.token.string,.token.char,.token.builtin,.token.url,.token.inserted{color:#2aa198}.token.entity{color:#657b83;background:#eee8d5}.token.atrule,.token.attr-value,.token.keyword{color:#859900}.token.function,.token.class-name{color:#b58900}.token.regex,.token.important,.token.variable{color:#cb4b16}.token.important,.token.bold{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}