hfs 0.52.1 → 0.52.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
- import{g as OF,c as UF}from"./index-8g-iaFW1.js";function gF(sF,hF){for(var eF=0;eF<hF.length;eF++){const tF=hF[eF];if(typeof tF!="string"&&!Array.isArray(tF)){for(const w in tF)if(w!=="default"&&!(w in sF)){const lF=Object.getOwnPropertyDescriptor(tF,w);lF&&Object.defineProperty(sF,w,lF.get?lF:{enumerable:!0,get:()=>tF[w]})}}}return Object.freeze(Object.defineProperty(sF,Symbol.toStringTag,{value:"Module"}))}var dF={exports:{}};/*
1
+ import{g as OF,c as UF}from"./index-SdT-xAgy.js";function gF(sF,hF){for(var eF=0;eF<hF.length;eF++){const tF=hF[eF];if(typeof tF!="string"&&!Array.isArray(tF)){for(const w in tF)if(w!=="default"&&!(w in sF)){const lF=Object.getOwnPropertyDescriptor(tF,w);lF&&Object.defineProperty(sF,w,lF.get?lF:{enumerable:!0,get:()=>tF[w]})}}}return Object.freeze(Object.defineProperty(sF,Symbol.toStringTag,{value:"Module"}))}var dF={exports:{}};/*
2
2
  * [js-sha512]{@link https://github.com/emn178/js-sha512}
3
3
  *
4
4
  * @version 0.8.0
package/admin/index.html CHANGED
@@ -6,7 +6,7 @@
6
6
  <script async src='https://unpkg.com/node-forge@1.3.1/dist/forge.min.js'></script>
7
7
  <title>HFS Admin-panel</title>
8
8
  <link rel="icon" type="image/svg+xml" href="/hfs-logo-icon.svg" />
9
- <script type="module" crossorigin src="/assets/index-8g-iaFW1.js"></script>
9
+ <script type="module" crossorigin src="/assets/index-SdT-xAgy.js"></script>
10
10
  <link rel="stylesheet" crossorigin href="/assets/index-sCDewjON.css">
11
11
  </head>
12
12
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hfs",
3
- "version": "0.52.1",
3
+ "version": "0.52.2",
4
4
  "description": "HTTP File Server",
5
5
  "keywords": [
6
6
  "file server",
@@ -9,6 +9,7 @@ const perm_1 = require("./perm");
9
9
  const lodash_1 = __importDefault(require("lodash"));
10
10
  const const_1 = require("./const");
11
11
  const auth_1 = require("./auth");
12
+ const misc_1 = require("./misc");
12
13
  function prepareAccount(ac) {
13
14
  return ac && {
14
15
  ...lodash_1.default.omit(ac, ['password', 'hashed_password', 'srp']),
@@ -34,6 +35,7 @@ exports.default = {
34
35
  },
35
36
  async set_account({ username, changes }, ctx) {
36
37
  var _a;
38
+ (0, misc_1.apiAssertTypes)({ string: { username } });
37
39
  const acc = (0, perm_1.getAccount)(username);
38
40
  if (!acc)
39
41
  return new apiMiddleware_1.ApiError(const_1.HTTP_BAD_REQUEST);
@@ -43,9 +45,10 @@ exports.default = {
43
45
  return lodash_1.default.pick(acc, 'username');
44
46
  },
45
47
  async add_account({ overwrite, username, ...rest }) {
48
+ (0, misc_1.apiAssertTypes)({ string: { username } });
46
49
  const existing = (0, perm_1.getAccount)(username);
47
50
  if (existing) {
48
- if (overwrite)
51
+ if (!overwrite)
49
52
  return new apiMiddleware_1.ApiError(const_1.HTTP_CONFLICT);
50
53
  await (0, perm_1.updateAccount)(existing, rest);
51
54
  return lodash_1.default.pick(existing, 'username');
@@ -54,13 +57,16 @@ exports.default = {
54
57
  return acc ? lodash_1.default.pick(acc, 'username') : new apiMiddleware_1.ApiError(const_1.HTTP_BAD_REQUEST);
55
58
  },
56
59
  del_account({ username }) {
60
+ (0, misc_1.apiAssertTypes)({ string: { username } });
57
61
  return (0, perm_1.delAccount)(username) ? {} : new apiMiddleware_1.ApiError(const_1.HTTP_BAD_REQUEST);
58
62
  },
59
63
  invalidate_sessions({ username }) {
64
+ (0, misc_1.apiAssertTypes)({ string: { username } });
60
65
  auth_1.invalidSessions.add(username);
61
66
  return {};
62
67
  },
63
68
  async change_srp({ username, salt, verifier }) {
69
+ (0, misc_1.apiAssertTypes)({ string: { username, salt, verifier } });
64
70
  const a = (0, perm_1.getAccount)(username);
65
71
  return a ? (0, perm_1.changeSrpHelper)(a, salt, verifier)
66
72
  : new apiMiddleware_1.ApiError(const_1.HTTP_NOT_FOUND);
@@ -29,7 +29,7 @@ function apiMiddleware(apis) {
29
29
  const safe = isPost && ctx.get('x-hfs-anti-csrf') // POST is safe because browser will enforce SameSite cookie
30
30
  || apiName.startsWith('get_'); // "get_" apis are safe because they make no change
31
31
  if (!safe)
32
- return send(const_1.HTTP_FOOL);
32
+ return send(const_1.HTTP_FOOL, "missing header x-hfs-anti-csrf=1");
33
33
  const apiFun = apis.hasOwnProperty(apiName) && apis[apiName];
34
34
  if (!apiFun)
35
35
  return send(const_1.HTTP_NOT_FOUND, 'invalid api');
package/src/consoleLog.js CHANGED
@@ -11,6 +11,8 @@ for (const k of ['log', 'warn', 'error']) {
11
11
  console[k] = (...args) => {
12
12
  const rec = { ts: new Date(), k, msg: args.join(' ') };
13
13
  exports.consoleLog.push(rec);
14
+ if (exports.consoleLog.length > 100000) // limit to avoid infinite space
15
+ exports.consoleLog.splice(0, 1000);
14
16
  events_1.default.emit('console', rec);
15
17
  return original(...args);
16
18
  };
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-04-17T14:23:55.148Z";
48
+ exports.BUILD_TIMESTAMP = "2024-04-20T19:09:36.991Z";
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('-');
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "author": "Club Microtel Vernon",
3
- "version": 1.3,
4
- "hfs_version": "0.47.1",
3
+ "version": "1.5",
4
+ "hfs_version": "0.52.1",
5
5
  "translate": {
6
6
  "Select": "Selectionner",
7
7
  "n_files": "{n,plural, one{# fichier} other{# fichiers}}",
@@ -126,6 +126,38 @@
126
126
  "showHelp_space_body": "Sélectionner",
127
127
  "showHelp_D_body": "Télécharger",
128
128
  "showHelp_Z_body": "Modes de zoom",
129
- "showHelp_F_body": "Plein écran"
129
+ "showHelp_F_body": "Plein écran",
130
+ "Destination": "Destination",
131
+ "in_queue": "{n} en file d'attente",
132
+ "enter_comment": "Saisissez un commentaire pour ce fichier",
133
+ "Comment": "Commentaire",
134
+ "upload_dd_hint": "Vous pouvez télé-verser des fichiers en les faisant glisser vers la liste principale",
135
+ "Upload not available": "Télé-versement non disponible",
136
+ "Cut": "Couper",
137
+ "n_items": "{n,plural, one{# élément dans le presse-papiers} other{# éléments dans le presse-papiers}}",
138
+ "good_bad": "{good} transféré, {bad} en échec",
139
+ "after_cut": "Votre sélection est maintenant dans le presse-papiers.\nAllez dans le dossier de destination pour coller.",
140
+ "Cancel clipboard": "Annuler le presse-papiers",
141
+ "to_clipboard_source": "Retour au dossier source",
142
+ "Paste": "Coller",
143
+ "clipboard_list": "Eléments dans le presse-papiers:",
144
+ "Close": "Fermer",
145
+ "Folder": "Dossier",
146
+ "Web page": "Page Web",
147
+ "Link": "Lien",
148
+ "Auto-play": "Lecture automatique",
149
+ "autoplay_seconds": "Secondes d’attente pour afficher les images",
150
+ "Select all": "Tout sélectionner",
151
+ "go_first": "Remonter au début",
152
+ "go_last": "Aller à la fin",
153
+ "Shuffle": "Lecture aléatoire",
154
+ "Repeat": "Répéter",
155
+ "showHelpListShortcut": "Afficher le raccourci de la liste d’aide",
156
+ "Invalid value": "Valeur non valide",
157
+ "upload_skipped": "{n} télé-versement(s)ignoré(s)",
158
+ "Overwrite policy": "Stratégie de remplacement",
159
+ "Rename to avoid overwriting": "Renommer pour éviter l'écrasement",
160
+ "Overwrite existing files": "Écraser les fichiers existants",
161
+ "Menu": "Menu"
130
162
  }
131
163
  }
@@ -1,25 +1,25 @@
1
1
  {
2
2
  "author": "Phoenix",
3
3
  "version": 1.0,
4
- "hfs_version": "0.43.0",
4
+ "hfs_version": "0.52.0",
5
5
  "translate": {
6
6
  "Select": "選擇",
7
7
  "n_files": "{n,plural,one{# 個檔案} other{# 個檔案}}",
8
8
  "n_folders": "{n,plural,one{# 個資料夾} other{# 個資料夾}}",
9
9
  "filter_count": "{n,plural, one{# 已過濾} other{# 已過濾}}",
10
10
  "select_count": "{n,plural, one{# 已選擇} other{# 已選擇}}",
11
- "filter_placeholder": "輸入內容,過濾下方列表",
12
- "Select some files": "選擇一些檔案",
11
+ "filter_placeholder": "輸入內容,過濾下方清單",
12
+ "Select some files": "選擇檔案",
13
13
  "zip_checkboxes": "使用選擇來複選檔案,然後再次使用Zip壓縮",
14
14
  "zip_tooltip_selected": "將所選檔案下載為單一Zip壓縮檔",
15
- "zip_tooltip_whole": "將整個列表(未過濾)作為單一Zip壓縮檔下載.如果選擇了一些檔案,則只會下載那些檔案",
15
+ "zip_tooltip_whole": "將整個清單(未過濾)作為單一Zip壓縮檔下載.如果選擇了一些檔案,則只會下載那些檔案",
16
16
  "zip_confirm_search": "將此搜尋的所有結果下載為Zip壓縮檔?",
17
17
  "zip_confirm_folder": "確認將整個資料夾下載為Zip壓縮檔?",
18
- "select_tooltip": "選擇適用於\"Zip\"和\"刪除\"(如果有的話),也可以過濾列表",
18
+ "select_tooltip": "選擇適用於\"Zip\"和\"刪除\"(如果有的話),也可以過濾清單",
19
19
  "delete_hint": "請先點擊“選擇”某些項目,才能執行刪除.",
20
20
  "delete_confirm": "確認刪除 {n,plural, one{# 項} other{# 項}}?",
21
21
  "delete_completed": "刪除: {n} 完成",
22
- "delete_failed": ", {n,plural, one{# 失敗} other{# 失敗}}",
22
+ "delete_failed": ", {n,plural, one{# 個失敗} other{# 個失敗}}",
23
23
  "delete_select": "選擇要刪除的項目",
24
24
  "Delete": "刪除",
25
25
  "Options": "選項",
@@ -31,7 +31,7 @@
31
31
  "Clear search": "清除搜尋條件",
32
32
  "Interrupted": "中止",
33
33
  "stopped_before": "已停止",
34
- "empty_list": "空列表",
34
+ "empty_list": "空清單",
35
35
  "filter_none": "過濾後無找到",
36
36
  "Admin-panel": "管理面板",
37
37
  "Login": "登入",
@@ -57,7 +57,7 @@
57
57
  "Create folder": "建立資料夾",
58
58
  "Pick files": "選擇檔案",
59
59
  "Pick folder": "選擇資料夾",
60
- "send_files": "開始上傳 {n,plural,one{# 檔案} other{# 檔案}}, {size}",
60
+ "send_files": "開始上傳 {n,plural,one{# 個檔案} other{# 個檔案}}, {size}",
61
61
  "Clear": "清空",
62
62
  "failed_upload": "無法上傳 {name}",
63
63
  "confirm_resume": "繼續上傳?",
@@ -95,12 +95,65 @@
95
95
  "upload_finished": "{n} 個檔案完成 ({size})",
96
96
  "upload_errors": "{n} 失敗",
97
97
  "upload_file_rejected": "部分檔案不被允許",
98
- "download counter": "下載次數",
99
98
  "File menu": "檔案選單",
100
99
  "Folder menu": "資料夾選單",
101
100
  "Name": "名稱",
102
101
  "file_open": "開啟",
103
102
  "Download": "下載",
104
- "Missing permission": "權限不足"
103
+ "Missing permission": "缺少權限",
104
+ "Reload": "重新載入",
105
+ "Get list": "取得清單",
106
+ "Skip existing files": "跳過已存在的檔案",
107
+ "Size": "大小",
108
+ "Timestamp": "時間戳",
109
+ "Show": "顯示",
110
+ "Loading failed": "載入失敗",
111
+ "Rename": "重新命名",
112
+ "Tiles mode:": "平鋪模式:",
113
+ "off": "關閉",
114
+ "Operation successful": "操作成功",
115
+ "Uploader": "上傳者",
116
+ "Download counter": "下載次數",
117
+ "Switch zoom mode": "切換縮放模式",
118
+ "Full screen": "全螢幕",
119
+ "File Show help": "檔案幫助",
120
+ "showHelpMain": "您可以使用鍵盤執行以下操作:",
121
+ "showHelp_←/→": "←/→",
122
+ "showHelp_↑/↓": "↑/↓",
123
+ "showHelp_space": "空白",
124
+ "showHelp_←/→_body": "上一個/下一個檔案",
125
+ "showHelp_↑/↓_body": "滾動長圖片",
126
+ "Destination": "目的地",
127
+ "in_queue": "{n} 在隊列中",
128
+ "enter_comment": "對 {name} 檔案評論",
129
+ "Comment": "評論",
130
+ "upload_dd_hint": "將檔案拖放到這裡即可上傳到此清單",
131
+ "Upload not available": "無法上傳",
132
+ "Cut": "剪下",
133
+ "n_items": "{n,plural, one{# 項} other{# 項}}",
134
+ "good_bad": "{good} 個已移動, {bad} 個失敗",
135
+ "after_cut": "您的選擇現在已在剪貼簿中\n到目標資料夾貼上",
136
+ "Cancel clipboard": "取消剪貼簿",
137
+ "to_clipboard_source": "返回來源資料夾",
138
+ "Paste": "貼上",
139
+ "clipboard_list": "剪貼簿中的項目:",
140
+ "Close": "關閉",
141
+ "Folder": "資料夾",
142
+ "Web page": "網頁",
143
+ "Link": "連結",
144
+ "Auto-play": "自動播放",
145
+ "autoplay_seconds": "自動播放間隔秒數",
146
+ "Select all": "全選",
147
+ "go_first": "第一項",
148
+ "go_last": "最後一項",
149
+ "Shuffle": "隨機播放",
150
+ "Repeat": "重複播放",
151
+ "showHelpListShortcut": "在檔案清單中,按一下 {key} 即可快速顯示",
152
+ "Invalid value": "無效值",
153
+ "upload_skipped": "{n} 跳過",
154
+ "Overwrite policy": "覆蓋規則",
155
+ "Rename to avoid overwriting": "重新命名以避免覆蓋",
156
+ "Overwrite existing files": "覆蓋已存在的檔案",
157
+ "Menu": "選單"
105
158
  }
106
159
  }
package/src/perm.js CHANGED
@@ -132,6 +132,7 @@ function addAccount(username, props) {
132
132
  return;
133
133
  const copy = (0, misc_1.setHidden)(lodash_1.default.pickBy(props, Boolean), { username }); // have the field in the object but hidden so that stringification won't include it
134
134
  exports.accountsConfig.set(accounts => Object.assign(accounts, { [username]: copy }));
135
+ saveAccountsAsap();
135
136
  return copy;
136
137
  }
137
138
  exports.addAccount = addAccount;