hfs 0.53.1 → 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.
@@ -1,4 +1,4 @@
1
- System.register(["./index-legacy-CL0zGDuA.js"],(function(h,t){"use strict";var i,s;return{setters:[function(h){i=h.g,s=h.c}],execute:function(){function t(h,t){for(var i=function(){var i=t[s];if("string"!=typeof i&&!Array.isArray(i)){var r=function(t){if("default"!==t&&!(t in h)){var s=Object.getOwnPropertyDescriptor(i,t);s&&Object.defineProperty(h,t,s.get?s:{enumerable:!0,get:function(){return i[t]}})}};for(var e in i)r(e)}},s=0;s<t.length;s++)i();return Object.freeze(Object.defineProperty(h,Symbol.toStringTag,{value:"Module"}))}var r={exports:{}};
1
+ System.register(["./index-legacy-BehBxMeJ.js"],(function(h,t){"use strict";var i,s;return{setters:[function(h){i=h.g,s=h.c}],execute:function(){function t(h,t){for(var i=function(){var i=t[s];if("string"!=typeof i&&!Array.isArray(i)){var r=function(t){if("default"!==t&&!(t in h)){var s=Object.getOwnPropertyDescriptor(i,t);s&&Object.defineProperty(h,t,s.get?s:{enumerable:!0,get:function(){return i[t]}})}};for(var e in i)r(e)}},s=0;s<t.length;s++)i();return Object.freeze(Object.defineProperty(h,Symbol.toStringTag,{value:"Module"}))}var r={exports:{}};
2
2
  /*
3
3
  * [js-sha512]{@link https://github.com/emn178/js-sha512}
4
4
  *
@@ -9,6 +9,6 @@
9
9
  <body>
10
10
  <div id="root">Wait for loading or <a href="?get=basic">use basic interface now</a></div>
11
11
  <script crossorigin id="vite-legacy-polyfill" src="/assets/polyfills-legacy-DMrMt_pQ.js"></script>
12
- <script crossorigin id="vite-legacy-entry" data-src="/assets/index-legacy-CL0zGDuA.js">System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))</script>
12
+ <script crossorigin id="vite-legacy-entry" data-src="/assets/index-legacy-BehBxMeJ.js">System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))</script>
13
13
  </body>
14
14
  </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hfs",
3
- "version": "0.53.1",
3
+ "version": "0.53.2",
4
4
  "description": "HTTP File Server",
5
5
  "keywords": [
6
6
  "file server",
@@ -87,7 +87,7 @@
87
87
  "limiter": "^2.1.0",
88
88
  "lodash": "^4.17.21",
89
89
  "minimist": "^1.2.6",
90
- "nat-upnp-rejetto": "^2.0.2",
90
+ "nat-upnp-rejetto": "^2.1.0",
91
91
  "open": "^8.4.0",
92
92
  "qr-creator": "^1.0.0",
93
93
  "picomatch": "^3.0.1",
@@ -1,7 +1,7 @@
1
1
  // other plugins can use ctx.state.download_counter_ignore to mark downloads that shouldn't be counted
2
2
 
3
3
  exports.description = "Counts downloads for each file, and displays the total in the list or file menu"
4
- exports.version = 6 // new format
4
+ exports.version = 6.1 // fix
5
5
  exports.apiRequired = 8.89 // openDb
6
6
 
7
7
  exports.config = {
@@ -43,7 +43,7 @@ exports.init = async api => {
43
43
  : ctx.state.originalStream?.getArchiveEntries?.().filter(x => x.at(-1) !== '/').map(x => key + uri2key(x))
44
44
  if (!entries) return
45
45
  for (const k of entries)
46
- db.put(k, db.getSync(k) + 1)
46
+ db.put(k, db.getSync(k) + 1 || 1)
47
47
  })
48
48
  },
49
49
  onDirEntry({ entry, listUri }) {
@@ -8,6 +8,6 @@
8
8
 
9
9
  HFS.onEvent('fileMenu', ({ entry, props }) => {
10
10
  if (!entry.isFolder)
11
- props.push([label, entry.hits || 0])
11
+ props.push({ id: 'download-counter', label, value: entry.hits || 0 })
12
12
  })
13
13
  }
package/src/api.net.js CHANGED
@@ -46,20 +46,20 @@ const apis = {
46
46
  async map_port({ external, internal }) {
47
47
  const { upnp, externalPort, internalPort } = await (0, nat_1.getNatInfo)();
48
48
  if (!upnp)
49
- return new apiMiddleware_1.ApiError(const_1.HTTP_SERVICE_UNAVAILABLE, 'upnp failed');
49
+ return new apiMiddleware_1.ApiError(const_1.HTTP_SERVICE_UNAVAILABLE, "upnp failed");
50
50
  if (!internalPort)
51
- return new apiMiddleware_1.ApiError(const_1.HTTP_FAILED_DEPENDENCY, 'no internal port');
51
+ return new apiMiddleware_1.ApiError(const_1.HTTP_FAILED_DEPENDENCY, "no internal port");
52
52
  if (externalPort)
53
53
  try {
54
54
  await nat_1.upnpClient.removeMapping({ public: { host: '', port: externalPort } });
55
55
  }
56
56
  catch (e) {
57
- return new apiMiddleware_1.ApiError(const_1.HTTP_SERVER_ERROR, 'removeMapping failed: ' + String(e));
57
+ return new apiMiddleware_1.ApiError(const_1.HTTP_SERVER_ERROR, "removeMapping failed: " + String(e));
58
58
  }
59
59
  if (external) // must use the object form of 'public' to work around a bug of the library
60
60
  await nat_1.upnpClient.createMapping({ private: internal || internalPort, public: { host: '', port: external }, description: 'hfs', ttl: 0 })
61
61
  .catch(res => {
62
- throw new apiMiddleware_1.ApiError(res.errorCode, res.errorCode === 718 ? "Port not available" : res.errorDescription);
62
+ throw new apiMiddleware_1.ApiError(res.errorCode || res.statusCode, res.errorCode === 718 ? "Port not available" : res.errorDescription || "unknown error");
63
63
  });
64
64
  return {};
65
65
  },
package/src/api.vfs.js CHANGED
@@ -221,12 +221,12 @@ const apis = {
221
221
  const url = h.srv.name + '://localhost:' + h.port;
222
222
  for (const k of ['*', 'Directory']) {
223
223
  await reg('add', WINDOWS_REG_KEY.replace('*', k), '/ve', '/f', '/d', 'Add to HFS (new)');
224
- await reg('add', WINDOWS_REG_KEY.replace('*', k) + '\\command', '/ve', '/f', '/d', `powershell -Command "
224
+ await reg('add', WINDOWS_REG_KEY.replace('*', k) + '\\command', '/ve', '/f', '/d', `powershell -WindowStyle Hidden -Command "
225
225
  $wsh = New-Object -ComObject Wscript.Shell;
226
226
  $j = @{parent=@'\n${parent}\n'@; source=@'\n%1\n'@} | ConvertTo-Json -Compress
227
227
  $j = [System.Text.Encoding]::UTF8.GetBytes($j);
228
228
  try {
229
- $res = Invoke-WebRequest -Uri '${url}/~/api/add_vfs' -Method POST -Headers @{ 'x-hfs-anti-csrf' = '1' } -ContentType 'application/json' -TimeoutSec 1 -Body $j;
229
+ $res = Invoke-WebRequest -Uri '${url}/~/api/add_vfs' -Method POST -Headers @{ 'x-hfs-anti-csrf' = '1' } -ContentType 'application/json' -TimeoutSec 2 -Body $j;
230
230
  $json = $res.Content | ConvertFrom-Json; $link = $json.link; $link | Set-Clipboard;
231
231
  $wsh.Popup('The link is ready to be pasted');
232
232
  } catch { $wsh.Popup('Server is down', 0, 'Error', 16); }"`);
package/src/const.js CHANGED
@@ -45,7 +45,7 @@ exports.DEV = process.env.DEV || exports.argv.dev ? 'DEV' : '';
45
45
  exports.ORIGINAL_CWD = process.cwd();
46
46
  exports.HFS_STARTED = new Date();
47
47
  const PKG_PATH = (0, path_1.join)(__dirname, '..', 'package.json');
48
- exports.BUILD_TIMESTAMP = "2024-09-28T16:00:41.759Z";
48
+ exports.BUILD_TIMESTAMP = "2024-10-25T17:06:39.884Z";
49
49
  const pkg = JSON.parse(fs.readFileSync(PKG_PATH, 'utf8'));
50
50
  exports.VERSION = pkg.version;
51
51
  exports.RUNNING_BETA = exports.VERSION.includes('-');
package/src/cross.js CHANGED
@@ -351,7 +351,7 @@ function isEqualLax(a, b) {
351
351
  return a == b //eslint-disable-line
352
352
  || (a && b && typeof a === 'object' && typeof b === 'object'
353
353
  && Object.entries(a).every(([k, v]) => isEqualLax(v, b[k]))
354
- && Object.entries(b).every(([k, v]) => Object.hasOwn(a, k) || isEqualLax(v, a[k])));
354
+ && Object.entries(b).every(([k, v]) => k in a || isEqualLax(v, a[k])));
355
355
  }
356
356
  exports.isEqualLax = isEqualLax;
357
357
  function xlate(input, table) {
@@ -364,7 +364,7 @@ function isIpLocalHost(ip) {
364
364
  }
365
365
  exports.isIpLocalHost = isIpLocalHost;
366
366
  function isIpLan(ip) {
367
- return /^(?:10\..*|172\.(1[6-9]|2\d|3[01])\..*|192\.168\..*)$/.test(ip);
367
+ return /^(?:10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.|fe80::)/.test(ip);
368
368
  }
369
369
  exports.isIpLan = isIpLan;
370
370
  function ipForUrl(ip) {
@@ -382,7 +382,7 @@ async function promiseBestEffort(promises) {
382
382
  }
383
383
  exports.promiseBestEffort = promiseBestEffort;
384
384
  function pathEncode(s) {
385
- return encodeURI(s).replace(/#/g, encodeURIComponent);
385
+ return encodeURI(s).replace(/#/g, escape);
386
386
  }
387
387
  exports.pathEncode = pathEncode;
388
388
  //unused function pathDecode(s: string) { return decodeURI(s).replace(/%23/g, '#') }
@@ -490,11 +490,3 @@ const BROWSERS = {
490
490
  Xbox: /xbox/i,
491
491
  UC: /UCBrowser/i,
492
492
  };
493
- setHidden(Object.prototype, {
494
- __log(pause = false) {
495
- const val = this instanceof Number || this instanceof String || this instanceof Boolean ? this.valueOf() : this;
496
- if (pause)
497
- debugger;
498
- return _log(val);
499
- }
500
- });
package/src/github.js CHANGED
@@ -100,7 +100,8 @@ async function downloadPlugin(repo, { branch = '', overwrite = false } = {}) {
100
100
  await (0, promises_1.rename)(tempInstallPath, installPath)
101
101
  .catch(e => { throw e.code !== 'ENOENT' ? e : new apiMiddleware_1.ApiError(const_1.HTTP_NOT_ACCEPTABLE, "missing main file"); });
102
102
  if (wasEnabled)
103
- void (0, plugins_1.startPlugin)(folder); // don't wait, in case it fails to start
103
+ void (0, plugins_1.startPlugin)(folder) // don't wait, in case it fails to start
104
+ .catch(() => { }); // it will possibly fail (with 'miss') because the plugin has probably not been loaded yet.
104
105
  return folder;
105
106
  }
106
107
  }
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const hfs_lang_it_json_1 = __importDefault(require("./hfs-lang-it.json"));
7
7
  const hfs_lang_zh_json_1 = __importDefault(require("./hfs-lang-zh.json"));
8
8
  const hfs_lang_ru_json_1 = __importDefault(require("./hfs-lang-ru.json"));
9
+ const hfs_lang_ro_json_1 = __importDefault(require("./hfs-lang-ro.json"));
9
10
  const hfs_lang_sr_json_1 = __importDefault(require("./hfs-lang-sr.json"));
10
11
  const hfs_lang_ko_json_1 = __importDefault(require("./hfs-lang-ko.json"));
11
12
  const hfs_lang_ms_json_1 = __importDefault(require("./hfs-lang-ms.json"));
@@ -23,4 +24,4 @@ const hfs_lang_ja_json_1 = __importDefault(require("./hfs-lang-ja.json"));
23
24
  const hfs_lang_tr_json_1 = __importDefault(require("./hfs-lang-tr.json"));
24
25
  const hfs_lang_th_json_1 = __importDefault(require("./hfs-lang-th.json"));
25
26
  const hfs_lang_uk_json_1 = __importDefault(require("./hfs-lang-uk.json"));
26
- exports.default = { it: hfs_lang_it_json_1.default, zh: hfs_lang_zh_json_1.default, ru: hfs_lang_ru_json_1.default, sr: hfs_lang_sr_json_1.default, ko: hfs_lang_ko_json_1.default, ms: hfs_lang_ms_json_1.default, 'zh-tw': hfs_lang_zh_tw_json_1.default, fr: hfs_lang_fr_json_1.default, 'pt-br': hfs_lang_pt_br_json_1.default, vi: hfs_lang_vi_json_1.default, es: hfs_lang_es_json_1.default, nl: hfs_lang_nl_json_1.default, el: hfs_lang_el_json_1.default, de: hfs_lang_de_json_1.default, fi: hfs_lang_fi_json_1.default, hu: hfs_lang_hu_json_1.default, ja: hfs_lang_ja_json_1.default, tr: hfs_lang_tr_json_1.default, th: hfs_lang_th_json_1.default, uk: hfs_lang_uk_json_1.default };
27
+ exports.default = { it: hfs_lang_it_json_1.default, zh: hfs_lang_zh_json_1.default, ru: hfs_lang_ru_json_1.default, sr: hfs_lang_sr_json_1.default, ko: hfs_lang_ko_json_1.default, ms: hfs_lang_ms_json_1.default, 'zh-tw': hfs_lang_zh_tw_json_1.default, fr: hfs_lang_fr_json_1.default, 'pt-br': hfs_lang_pt_br_json_1.default, vi: hfs_lang_vi_json_1.default, es: hfs_lang_es_json_1.default, nl: hfs_lang_nl_json_1.default, el: hfs_lang_el_json_1.default, de: hfs_lang_de_json_1.default, fi: hfs_lang_fi_json_1.default, hu: hfs_lang_hu_json_1.default, ja: hfs_lang_ja_json_1.default, ro: hfs_lang_ro_json_1.default, tr: hfs_lang_tr_json_1.default, th: hfs_lang_th_json_1.default, uk: hfs_lang_uk_json_1.default };
@@ -0,0 +1,166 @@
1
+ {
2
+ "author": "Ovidiu",
3
+ "version": 1.0,
4
+ "hfs_version": "0.53.0",
5
+ "translate": {
6
+ "Select": "Selectează",
7
+ "n_files": "{n,plural,one{# fișier} other{# fișiere}}",
8
+ "n_folders": "{n,plural,one{# folder} other{# foldere}}",
9
+ "filter_count": "{n,plural, one{# filtrat} other{# filtrate}}",
10
+ "select_count": "{n,plural, one{# selectat} other{# selectate}}",
11
+ "filter_placeholder": "Tastează aici pentru a filtra lista de mai jos (caută după cuvinte cheie)",
12
+ "Select some files": "Selectează câteva fișiere",
13
+ "zip_checkboxes": "Folosește căsuțele de selectare pentru a alege fișierele, apoi poți folosi Zip din nou",
14
+ "zip_tooltip_selected": "Descarcă elementele selectate ca un singur fișier zip",
15
+ "zip_tooltip_whole": "Descarcă întreaga listă (nefiltrată) ca un singur fișier zip. Dacă selectezi câteva elemente, doar acelea vor fi descărcate.",
16
+ "zip_confirm_search": "Ești sigur că vrei să descarci TOATE rezultatele acestei căutări sub formă de arhivă ZIP?",
17
+ "zip_confirm_folder": "Ești sigur că vrei să descarci ÎNTREGUL folder sub formă de arhivă ZIP?",
18
+ "select_tooltip": "Selecția se aplică pentru \"Zip\" și \"Șterge\" (când sunt disponibile), dar poți, de asemenea, filtra lista",
19
+ "delete_hint": "Pentru a șterge, prima dată fă clic pe Selectează",
20
+ "delete_confirm": "Ștergi {n,plural, one{# element} other{# elemente}}?",
21
+ "delete_completed": "Ștergere: {n} completată",
22
+ "delete_failed": ", {n,plural, one{# eșuat} other{# eșuate}}",
23
+ "delete_select": "Selectează ceva de șters",
24
+ "Delete": "Șterge",
25
+ "Options": "Opțiuni",
26
+ "Search": "Căutare",
27
+ "Zip": "Zip",
28
+ "search_msg": "Caută în acest folder și în sub-foldere",
29
+ "Searching": "Căutare",
30
+ "Searched": "Căutat",
31
+ "Clear search": "Șterge căutarea",
32
+ "Interrupted": "Intrerupt",
33
+ "stopped_before": "Oprit înainte de a găsi ceva",
34
+ "empty_list": "Lista este goală. Nu este nimic aici",
35
+ "filter_none": "Niciun rezultat pentru filtrul aplicat",
36
+ "Admin-panel": "Panoul de administrare",
37
+ "Login": "Autentificare",
38
+ "Username": "Nume utilizator",
39
+ "Password": "Parolă",
40
+ "login_untrusted": "Autentificare anulată: identitatea serverului nu poate fi de încredere",
41
+ "login_bad_credentials": "Numele de utilizator sau parola sunt incorecte. Te rugăm să re-efectuezi logarea.",
42
+ "login_bad_cookies": "Cookies nefuncționale - autentificare eșuată",
43
+ "User panel": "Panoul utilizatorului",
44
+ "Change password": "Schimbă parola",
45
+ "enter_pass": "Introdu noua parolă",
46
+ "enter_pass2": "RE-introdu aceeași parolă nouă",
47
+ "pass2_mismatch": "A doua parolă introdusă nu se potrivește cu prima. Procedura a fost anulată.",
48
+ "password_changed": "Parola a fost schimbată cu succes",
49
+ "Logout": "Deconectare",
50
+ "connection error": "eroare de conexiune",
51
+ "Full timestamp:": "Marcaj complet de timp:",
52
+ "Search was interrupted": "Căutarea a fost întreruptă",
53
+ "Stop list": "Oprire listă",
54
+ "download_starting": "Descărcarea ar trebui să înceapă acum",
55
+ "wrong_account": "Contul {u} nu are acces, încearcă alt cont care are drepturi.",
56
+ "no_upload_here": "Nicio permisiune de încărcare pentru folderul curent",
57
+ "Create folder": "Creează folder",
58
+ "Pick files": "Selectează fișiere",
59
+ "Pick folder": "Selectează folder",
60
+ "send_files": "Trimite {n,plural,one{# fișier} other{# fișiere}}, {size}",
61
+ "Clear": "Șterge",
62
+ "failed_upload": "Nu s-a putut încărca {name}",
63
+ "confirm_resume": "Continuă încărcarea?",
64
+ "file too large": "Fișierul este prea mare",
65
+ "Enter folder name": "Introdu numele folderului",
66
+ "Successfully created": "Creat cu succes",
67
+ "enter_folder": "Intră în folder",
68
+ "folder_exists": "Există deja un folderul cu același nume",
69
+ "Sort by:": "Sortați după: {by}",
70
+ "name": "nume",
71
+ "extension": "extensie",
72
+ "size": "dimensiune",
73
+ "time": "dată",
74
+ "Invert order": "Inversează ordinea",
75
+ "Folders first": "Folderele mai întâi",
76
+ "Numeric names": "Nume numerice",
77
+ "theme:": "temă:",
78
+ "auto": "automat",
79
+ "light": "luminos",
80
+ "dark": "întunecat",
81
+ "parent folder": "Folder sursă",
82
+ "home": "acasă",
83
+ "Continue": "Continuă",
84
+ "Confirm": "Confirmă",
85
+ "Don't": "Nu",
86
+ "Warning": "Atenție",
87
+ "Error": "Eroare",
88
+ "Info": "Informații",
89
+ "Unauthorized": "Neautorizat",
90
+ "Forbidden": "Interzis",
91
+ "Not found": "Nu a fost găsit",
92
+ "Server error": "Eroare de server",
93
+ "Upload": "Încărcare",
94
+ "upload_concluded": "Încărcare încheiată:",
95
+ "upload_finished": "{n} terminat ({size})",
96
+ "upload_errors": "{n} eșuat",
97
+ "upload_file_rejected": "Unele fișiere nu au fost acceptate",
98
+ "File menu": "Meniu fișier",
99
+ "Folder menu": "Meniu folder",
100
+ "Name": "Nume",
101
+ "file_open": "Deschide",
102
+ "Download": "Descarcă",
103
+ "Missing permission": "Permisiune lipsă",
104
+ "Reload": "Reîncarcă",
105
+ "Get list": "Obține lista",
106
+ "Skip existing files": "Sari peste fișierele deja existente",
107
+ "Size": "Dimensiune",
108
+ "Timestamp": "Data încărcării",
109
+ "Show": "Arată",
110
+ "Loading failed": "Încărcare eșuată",
111
+ "Rename": "Redenumește",
112
+ "Tiles mode:": "Dimensiunea iconițelor:",
113
+ "off": "0",
114
+ "Operation successful": "Operațiune reușită",
115
+ "Uploader": "Încărcător",
116
+ "Download counter": "Contor descărcări",
117
+ "Switch zoom mode": "Comută pe modul zoom",
118
+ "Full screen": "Ecran complet",
119
+ "File Show help": "Ajutor afișare fișier",
120
+ "showHelpMain": "Poți folosi tastatura pentru anumite acțiuni:",
121
+ "showHelp_←/→": "←/→",
122
+ "showHelp_↑/↓": "↑/↓",
123
+ "showHelp_space": "spațiu",
124
+ "showHelp_←/→_body": "Mergi la fișierul anterior/următor",
125
+ "showHelp_↑/↓_body": "Derulează imagini înalte",
126
+ "Destination": "Destinație",
127
+ "in_queue": "{n} în așteptare",
128
+ "enter_comment": "Comentariu pentru {name}",
129
+ "Comment": "Comentariu",
130
+ "upload_dd_hint": "Poți încărca fișiere făcând drag&drop pe lista de fișiere",
131
+ "Upload not available": "Încărcarea nu este disponibilă",
132
+ "Cut": "Decupează",
133
+ "n_items": "{n,plural, one{# element} other{# elemente}}",
134
+ "good_bad": "{good} mutat, {bad} eșuat",
135
+ "after_cut": "Selecția ta este acum în clipboard.\nMergi în folderul destinație pentru a lipi.",
136
+ "Cancel clipboard": "Anulează clipboard",
137
+ "to_clipboard_source": "Înapoi la folderul sursă",
138
+ "Paste": "Lipește",
139
+ "clipboard_list": "Elemente în clipboard:",
140
+ "Close": "Închide",
141
+ "Folder": "Folder",
142
+ "Web page": "Pagini web",
143
+ "Link": "Link",
144
+ "Auto-play": "Redare automată",
145
+ "autoplay_seconds": "Redare automată pe interval de secunde",
146
+ "Select all": "Selectează tot",
147
+ "go_first": "Mergi la primul element",
148
+ "go_last": "Mergi la ultimul element",
149
+ "Shuffle": "Amestecă",
150
+ "Repeat": "Repetă",
151
+ "showHelpListShortcut": "Din lista de fișiere, fă clic ținând apăsat {key} pentru a arăta rapid",
152
+ "Invalid value": "Valoare invalidă",
153
+ "upload_skipped": "{n} sărit",
154
+ "Overwrite policy": "Politică de suprascriere",
155
+ "Rename to avoid overwriting": "Redenumește pentru a evita suprascrierea",
156
+ "Overwrite existing files": "Suprascrie fișierele existente",
157
+ "Menu": "Meniu",
158
+ "clipboard": "Clipboard ({content})",
159
+ "to_clipboard_source_tooltip": "Mergi la folderul unde se află conținutul clipboard-ului",
160
+ "more_items": "{n} mai multe element(e)",
161
+ "Show details": "Arată detalii",
162
+ "upload_conflict": "deja există",
163
+ "Logged in": "Autentificat cu succes",
164
+ "Logged out": "Deconectat cu succes"
165
+ }
166
+ }
package/src/listen.js CHANGED
@@ -174,9 +174,9 @@ for (const cfg of httpsNeeds) {
174
174
  return considerHttps();
175
175
  // v is a path
176
176
  httpsOptions[k] = '';
177
- unwatch = (0, watchLoad_1.watchLoad)(v, data => {
177
+ unwatch = (0, watchLoad_1.watchLoad)(v, async (data) => {
178
178
  httpsOptions[k] = data;
179
- considerHttps();
179
+ await considerHttps();
180
180
  }, { immediateFirst: true }).unwatch;
181
181
  await considerHttps();
182
182
  });
@@ -281,7 +281,8 @@ async function getServerStatus(includeSrv = true) {
281
281
  }
282
282
  exports.getServerStatus = getServerStatus;
283
283
  const ignore = /^(lo|.*loopback.*|virtualbox.*|.*\(wsl\).*|llw\d|awdl\d|utun\d|anpi\d)$/i; // avoid giving too much information
284
- const isLinkLocal = (0, misc_1.makeNetMatcher)('169.254.0.0/16|FE80::/16');
284
+ // AKA auto-ip https://en.wikipedia.org/wiki/Link-local_address
285
+ const isLinkLocal = (0, misc_1.makeNetMatcher)('169.254.0.0/16|FE80::/10');
285
286
  async function getIps(external = true) {
286
287
  const ips = (0, misc_1.onlyTruthy)(Object.entries((0, os_1.networkInterfaces)()).flatMap(([name, nets]) => nets && !ignore.test(name) && nets.map(net => !net.internal && net.address)));
287
288
  const e = external && nat_1.defaultBaseUrl.externalIp;
package/src/misc.js CHANGED
@@ -51,6 +51,7 @@ function makeNetMatcher(mask, emptyMaskReturns = false) {
51
51
  var _a;
52
52
  if (!mask)
53
53
  return () => emptyMaskReturns;
54
+ mask = mask.replaceAll(' ', '');
54
55
  if (!mask.includes('/'))
55
56
  return (0, cross_1.makeMatcher)(mask);
56
57
  const all = mask.split('|');
package/src/nat.js CHANGED
@@ -70,11 +70,11 @@ exports.getNatInfo = (0, debounceAsync_1.debounceAsync)(async () => {
70
70
  const res = await (0, cross_1.haveTimeout)(10000, exports.upnpClient.getGateway()).catch(() => null);
71
71
  const status = await (0, listen_1.getServerStatus)();
72
72
  const mappings = res && await (0, cross_1.haveTimeout)(5000, exports.upnpClient.getMappings()).catch(() => null);
73
- console.debug('mappings found', mappings === null || mappings === void 0 ? void 0 : mappings.map(x => x.description));
73
+ console.debug("mappings found", (mappings === null || mappings === void 0 ? void 0 : mappings.map(x => x.description)) || "none");
74
74
  const gatewayIp = res && (0, cross_1.try_)(() => new URL(res.gateway.description).hostname, () => { var _a; return console.debug('unexpected upnp gw', (_a = res.gateway) === null || _a === void 0 ? void 0 : _a.description); })
75
75
  || await findGateway().catch(() => undefined);
76
76
  const localIps = await (0, listen_1.getIps)(false);
77
- const localIp = (res === null || res === void 0 ? void 0 : res.address) || gatewayIp ? lodash_1.default.maxBy(localIps, x => (0, cross_1.inCommon)(x, gatewayIp)) : localIps[0];
77
+ const localIp = (res === null || res === void 0 ? void 0 : res.address) || (gatewayIp ? lodash_1.default.maxBy(localIps, x => (0, cross_1.inCommon)(x, gatewayIp)) : localIps[0]);
78
78
  const internalPort = ((_a = status === null || status === void 0 ? void 0 : status.https) === null || _a === void 0 ? void 0 : _a.listening) && status.https.port || ((_b = status === null || status === void 0 ? void 0 : status.http) === null || _b === void 0 ? void 0 : _b.listening) && status.http.port || undefined;
79
79
  const mapped = lodash_1.default.find(mappings, x => x.private.host === localIp && x.private.port === internalPort);
80
80
  const externalPort = mapped === null || mapped === void 0 ? void 0 : mapped.public.port;
@@ -96,10 +96,12 @@ exports.getNatInfo = (0, debounceAsync_1.debounceAsync)(async () => {
96
96
  (0, exports.getNatInfo)();
97
97
  function findGateway() {
98
98
  return new Promise((resolve, reject) => (0, child_process_1.exec)(const_1.IS_WINDOWS || const_1.IS_MAC ? 'netstat -rn' : 'route -n', (err, out) => {
99
- var _a;
99
+ var _a, _b;
100
100
  if (err)
101
101
  return reject(err);
102
- const re = const_1.IS_WINDOWS ? /(?:0\.0\.0\.0 +){2}([\d.]+)/ : const_1.IS_MAC ? /default +([\d.]+)/ : /^0\.0\.0\.0 +([\d.]+)/;
103
- resolve((_a = re.exec(out)) === null || _a === void 0 ? void 0 : _a[1]);
102
+ if (!const_1.IS_WINDOWS)
103
+ return resolve((_a = out.match(const_1.IS_MAC ? /default +([\d.]+)/ : /^0\.0\.0\.0 +([\d.]+)/)) === null || _a === void 0 ? void 0 : _a[1]);
104
+ const sortedByMetric = lodash_1.default.sortBy([...out.matchAll(/(?:0\.0\.0\.0 +){2}([\d.]+)\s+[\d.]+\s+(\d+)/g)], x => Number(x[2]));
105
+ resolve((_b = sortedByMetric[0]) === null || _b === void 0 ? void 0 : _b[1]); // take ip with lowest metric
104
106
  }));
105
107
  }
package/src/perm.js CHANGED
@@ -176,7 +176,7 @@ function allDisabled(account) {
176
176
  var _a;
177
177
  return Boolean(account.disabled
178
178
  || account.expire < Date.now()
179
- || ((_a = account.belongs) === null || _a === void 0 ? void 0 : _a.map(u => getAccount(u, false)).every(a => a && allDisabled(a))));
179
+ || ((_a = account.belongs) === null || _a === void 0 ? void 0 : _a.length) && account.belongs.map(u => getAccount(u, false)).every(a => a && allDisabled(a))); // every() returns true on empty arrays
180
180
  }
181
181
  function accountCanLoginAdmin(account) {
182
182
  return accountCanLogin(account) && Boolean(getFromAccount(account, a => a.admin));
package/src/vfs.js CHANGED
@@ -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;