hfs 0.53.0-alpha1 → 0.53.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/admin/assets/{index-ClcJhcGU.js → index-Dsv2tjnU.js} +68 -68
- package/admin/assets/{sha512-BBuEMQr3.js → sha512-BjLhiBem.js} +1 -1
- package/admin/index.html +1 -1
- package/frontend/assets/{index-legacy-DBpnLaOV.js → index-legacy-C21Ot_ue.js} +2 -2
- package/frontend/assets/{sha512-legacy-C1fsQ1Io.js → sha512-legacy-DYmEZJfO.js} +1 -1
- package/frontend/index.html +1 -1
- package/package.json +1 -1
- package/plugins/antibrute/plugin.js +2 -3
- package/src/api.plugins.js +21 -18
- package/src/const.js +1 -1
- package/src/github.js +21 -5
- package/src/plugins.js +5 -5
- package/src/serveGuiFiles.js +7 -10
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
System.register(["./index-legacy-
|
|
1
|
+
System.register(["./index-legacy-C21Ot_ue.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
|
*
|
package/frontend/index.html
CHANGED
|
@@ -11,6 +11,6 @@
|
|
|
11
11
|
<div id="root"></div>
|
|
12
12
|
<script nomodule>document.getElementById('root').innerText = "Please use a newer browser"</script>
|
|
13
13
|
<script crossorigin id="vite-legacy-polyfill" src="/assets/polyfills-legacy-DMrMt_pQ.js"></script>
|
|
14
|
-
<script crossorigin id="vite-legacy-entry" data-src="/assets/index-legacy-
|
|
14
|
+
<script crossorigin id="vite-legacy-entry" data-src="/assets/index-legacy-C21Ot_ue.js">System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))</script>
|
|
15
15
|
</body>
|
|
16
16
|
</html>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
exports.version = 3
|
|
2
2
|
exports.description = "Introduce increasing delays between login attempts."
|
|
3
|
-
exports.apiRequired = 8.
|
|
3
|
+
exports.apiRequired = 8.8 // attemptingLogin
|
|
4
4
|
|
|
5
5
|
exports.config = {
|
|
6
6
|
increment: { type: 'number', min: 1, defaultValue: 5, unit: "seconds", helperText: "How longer user must wait for each login attempt" },
|
|
@@ -30,7 +30,6 @@ exports.init = api => {
|
|
|
30
30
|
if (rec.attempts > api.getConfig('blockAfter') && !isLocalHost(ctx)) {
|
|
31
31
|
const hours = api.getConfig('blockForHours')
|
|
32
32
|
const newRule = { ip, comment: "From antibrute plugin", expire: hours ? new Date(now.getTime() + hours * HOUR) : undefined }
|
|
33
|
-
console.log({ hours, newRule })
|
|
34
33
|
block.set(x => [...x, newRule])
|
|
35
34
|
}
|
|
36
35
|
clearTimeout(rec.timer)
|
|
@@ -39,7 +38,7 @@ exports.init = api => {
|
|
|
39
38
|
ctx.set('x-anti-brute-force', wait)
|
|
40
39
|
await new Promise(resolve => setTimeout(resolve, wait))
|
|
41
40
|
}
|
|
42
|
-
rec.timer = setTimeout(() => delete byIp[ip],
|
|
41
|
+
rec.timer = setTimeout(() => delete byIp[ip], 24 * HOUR) // no memory leak
|
|
43
42
|
},
|
|
44
43
|
login: ctx => {
|
|
45
44
|
if (ctx.state.account)
|
package/src/api.plugins.js
CHANGED
|
@@ -10,7 +10,6 @@ const lodash_1 = __importDefault(require("lodash"));
|
|
|
10
10
|
const assert_1 = __importDefault(require("assert"));
|
|
11
11
|
const misc_1 = require("./misc");
|
|
12
12
|
const apiMiddleware_1 = require("./apiMiddleware");
|
|
13
|
-
const events_1 = __importDefault(require("./events"));
|
|
14
13
|
const promises_1 = require("fs/promises");
|
|
15
14
|
const github_1 = require("./github");
|
|
16
15
|
const const_1 = require("./const");
|
|
@@ -91,29 +90,33 @@ const apis = {
|
|
|
91
90
|
get_online_plugins({ text }, ctx) {
|
|
92
91
|
return new SendList_1.SendListReadable({
|
|
93
92
|
async doAtStart(list) {
|
|
93
|
+
const repos = [];
|
|
94
|
+
list.events(ctx, {
|
|
95
|
+
pluginInstalled: p => {
|
|
96
|
+
if (repos.includes(p.repo))
|
|
97
|
+
list.update({ id: p.repo }, { installed: true });
|
|
98
|
+
},
|
|
99
|
+
pluginUninstalled: folder => {
|
|
100
|
+
const repo = (0, github_1.getFolder2repo)()[folder];
|
|
101
|
+
if (typeof repo !== 'string')
|
|
102
|
+
return; // custom repo
|
|
103
|
+
if (repos.includes(repo))
|
|
104
|
+
list.update({ id: repo }, { installed: false });
|
|
105
|
+
},
|
|
106
|
+
pluginDownload({ id, status }) {
|
|
107
|
+
if (repos.includes(id))
|
|
108
|
+
list.update({ id }, { downloading: status !== null && status !== void 0 ? status : null });
|
|
109
|
+
}
|
|
110
|
+
});
|
|
94
111
|
try {
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
ctx.req.once('close', () => undo.forEach(x => x()));
|
|
98
|
-
const folder2repo = (0, github_1.getFolder2repo)();
|
|
99
|
-
for await (const pl of await (0, github_1.searchPlugins)(text)) {
|
|
112
|
+
const already = Object.values((0, github_1.getFolder2repo)()).map(String);
|
|
113
|
+
for await (const pl of await (0, github_1.searchPlugins)(text, { skipRepos: already })) {
|
|
100
114
|
const repo = pl.repo || pl.id; // .repo property can be more trustworthy in case github user renamed and left the previous link in 'repo'
|
|
101
|
-
if (lodash_1.default.includes(folder2repo, repo))
|
|
102
|
-
continue; // don't include installed plugins
|
|
103
115
|
const missing = await (0, plugins_1.getMissingDependencies)(pl);
|
|
104
116
|
if (missing.length)
|
|
105
117
|
pl.missing = missing;
|
|
106
118
|
list.add(pl);
|
|
107
|
-
|
|
108
|
-
undo.push(lodash_1.default.flow(events_1.default.on('pluginInstalled', p => {
|
|
109
|
-
if (p.repo === repo)
|
|
110
|
-
list.update({ id: repo }, { installed: true });
|
|
111
|
-
}), events_1.default.on('pluginUninstalled', folder => {
|
|
112
|
-
if (repo === (0, github_1.getFolder2repo)()[folder])
|
|
113
|
-
list.update({ id: repo }, { installed: false });
|
|
114
|
-
}), events_1.default.on('pluginDownload_' + repo, status => {
|
|
115
|
-
list.update({ id: repo }, { downloading: status !== null && status !== void 0 ? status : null });
|
|
116
|
-
})));
|
|
119
|
+
repos.push(repo);
|
|
117
120
|
}
|
|
118
121
|
}
|
|
119
122
|
catch (err) {
|
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-05-
|
|
48
|
+
exports.BUILD_TIMESTAMP = "2024-05-08T10:54:50.461Z";
|
|
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/github.js
CHANGED
|
@@ -21,7 +21,7 @@ function downloadProgress(id, status) {
|
|
|
21
21
|
delete downloading[id];
|
|
22
22
|
else
|
|
23
23
|
downloading[id] = status;
|
|
24
|
-
events_1.default.emit('
|
|
24
|
+
events_1.default.emit('pluginDownload', { id, status });
|
|
25
25
|
}
|
|
26
26
|
// determine default branch, possibly without consuming api quota
|
|
27
27
|
async function getGithubDefaultBranch(repo) {
|
|
@@ -161,13 +161,29 @@ async function apiGithub(uri) {
|
|
|
161
161
|
: e;
|
|
162
162
|
});
|
|
163
163
|
}
|
|
164
|
-
async function
|
|
164
|
+
async function* apiGithubPaginated(uri) {
|
|
165
|
+
const PAGE_SIZE = 100;
|
|
166
|
+
let page = 1;
|
|
167
|
+
let n = 0;
|
|
168
|
+
while (1) {
|
|
169
|
+
const res = await apiGithub(uri + `&page=${page++}&per_page=${PAGE_SIZE}`);
|
|
170
|
+
for (const x of res.items)
|
|
171
|
+
yield x;
|
|
172
|
+
const now = res.items.length;
|
|
173
|
+
n += now;
|
|
174
|
+
if (!now || n >= res.total_count)
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
async function searchPlugins(text = '', { skipRepos = [''] } = {}) {
|
|
165
179
|
const projectInfo = await (0, exports.getProjectInfo)();
|
|
166
|
-
const list = await
|
|
167
|
-
|
|
180
|
+
const list = await Promise.all(['', 'user:'].map(specifier => // search text with multiple specifiers
|
|
181
|
+
(0, misc_1.asyncGeneratorToArray)(apiGithubPaginated(`search/repositories?q=topic:hfs-plugin+${specifier}${encodeURI(text)}`))))
|
|
182
|
+
.then(all => all.flat()); // make it a single array
|
|
183
|
+
return new misc_1.AsapStream(list.map(async (it) => {
|
|
168
184
|
var _a, _b;
|
|
169
185
|
const repo = it.full_name;
|
|
170
|
-
if ((_a = projectInfo === null || projectInfo === void 0 ? void 0 : projectInfo.plugins_blacklist) === null || _a === void 0 ? void 0 : _a.includes(repo))
|
|
186
|
+
if (((_a = projectInfo === null || projectInfo === void 0 ? void 0 : projectInfo.plugins_blacklist) === null || _a === void 0 ? void 0 : _a.includes(repo)) || skipRepos.includes(repo))
|
|
171
187
|
return;
|
|
172
188
|
const pl = await readOnlineCompatiblePlugin(repo, it.default_branch).catch(() => undefined);
|
|
173
189
|
if (!pl)
|
package/src/plugins.js
CHANGED
|
@@ -27,7 +27,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
27
27
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
28
28
|
};
|
|
29
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
-
exports.getMissingDependencies = exports.parsePluginSource = exports.rescan = exports.pluginsConfig = exports.enablePlugins = exports.pluginsWatcher = exports.getAvailablePlugins = exports.mapPlugins = exports.Plugin = exports.pluginsMiddleware = exports.getPluginConfigFields = exports.findPluginByRepo = exports.getPluginInfo = exports.setPluginConfig = exports.startPlugin = exports.stopPlugin = exports.enablePlugin = exports.isPluginEnabled = exports.isPluginRunning = exports.STORAGE_FOLDER = exports.DISABLING_SUFFIX = exports.PATH = void 0;
|
|
30
|
+
exports.getMissingDependencies = exports.parsePluginSource = exports.rescan = exports.pluginsConfig = exports.enablePlugins = exports.pluginsWatcher = exports.getAvailablePlugins = exports.mapPlugins = exports.SERVER_CODE_ID = exports.Plugin = exports.pluginsMiddleware = exports.getPluginConfigFields = exports.findPluginByRepo = exports.getPluginInfo = exports.setPluginConfig = exports.startPlugin = exports.stopPlugin = exports.enablePlugin = exports.isPluginEnabled = exports.isPluginRunning = exports.STORAGE_FOLDER = exports.DISABLING_SUFFIX = exports.PATH = void 0;
|
|
31
31
|
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
32
32
|
const watchLoad_1 = require("./watchLoad");
|
|
33
33
|
const lodash_1 = __importDefault(require("lodash"));
|
|
@@ -232,7 +232,7 @@ class Plugin {
|
|
|
232
232
|
const { id } = this;
|
|
233
233
|
try {
|
|
234
234
|
await ((_b = (_a = this.data) === null || _a === void 0 ? void 0 : _a.unload) === null || _b === void 0 ? void 0 : _b.call(_a));
|
|
235
|
-
if (!reloading && id !== SERVER_CODE_ID) // we already printed 'reloading'
|
|
235
|
+
if (!reloading && id !== exports.SERVER_CODE_ID) // we already printed 'reloading'
|
|
236
236
|
console.log('unloaded plugin', id);
|
|
237
237
|
}
|
|
238
238
|
catch (e) {
|
|
@@ -244,12 +244,12 @@ class Plugin {
|
|
|
244
244
|
}
|
|
245
245
|
}
|
|
246
246
|
exports.Plugin = Plugin;
|
|
247
|
-
|
|
247
|
+
exports.SERVER_CODE_ID = '.'; // a name that will surely be not found among plugin folders
|
|
248
248
|
const serverCode = (0, config_1.defineConfig)('server_code', '', async (script, { k }) => {
|
|
249
249
|
const res = {};
|
|
250
250
|
try {
|
|
251
251
|
new Function('exports', script)(res); // parse
|
|
252
|
-
return new Plugin(SERVER_CODE_ID, '', await initPlugin(res), lodash_1.default.noop);
|
|
252
|
+
return new Plugin(exports.SERVER_CODE_ID, '', await initPlugin(res), lodash_1.default.noop);
|
|
253
253
|
}
|
|
254
254
|
catch (e) {
|
|
255
255
|
return console.error(k + ':', e.message || String(e));
|
|
@@ -260,7 +260,7 @@ serverCode.sub(() => { var _a; return (_a = serverCode.compiled()) === null || _
|
|
|
260
260
|
function mapPlugins(cb, includeServerCode = true) {
|
|
261
261
|
const entries = Object.entries(plugins);
|
|
262
262
|
return entries.map(([plName, pl]) => {
|
|
263
|
-
if (!includeServerCode && plName === SERVER_CODE_ID)
|
|
263
|
+
if (!includeServerCode && plName === exports.SERVER_CODE_ID)
|
|
264
264
|
return;
|
|
265
265
|
try {
|
|
266
266
|
return cb(pl, plName);
|
package/src/serveGuiFiles.js
CHANGED
|
@@ -91,7 +91,7 @@ async function treatIndex(ctx, filesUri, body) {
|
|
|
91
91
|
ctx.set('etag', '');
|
|
92
92
|
ctx.set('Cache-Control', 'no-store, no-cache, must-revalidate');
|
|
93
93
|
ctx.type = 'html';
|
|
94
|
-
const isFrontend = filesUri === const_1.FRONTEND_URI;
|
|
94
|
+
const isFrontend = filesUri === const_1.FRONTEND_URI ? ' ' : ''; // as a string will allow neater code later
|
|
95
95
|
const pub = ctx.state.revProxyPath + const_1.PLUGINS_PUB_URI;
|
|
96
96
|
// expose plugins' configs that are declared with 'frontend' attribute
|
|
97
97
|
const plugins = Object.fromEntries((0, misc_1.onlyTruthy)((0, plugins_1.mapPlugins)((pl, name) => {
|
|
@@ -114,7 +114,7 @@ async function treatIndex(ctx, filesUri, body) {
|
|
|
114
114
|
const isOpen = !isClose;
|
|
115
115
|
if (isHead && isOpen)
|
|
116
116
|
return all + `
|
|
117
|
-
${
|
|
117
|
+
${isFrontend && `
|
|
118
118
|
<title>${adminApis_1.title.get()}</title>
|
|
119
119
|
<link rel="shortcut icon" href="/favicon.ico?${timestamp}" />
|
|
120
120
|
` + (0, customHtml_1.getSection)('htmlHead')}
|
|
@@ -125,6 +125,7 @@ async function treatIndex(ctx, filesUri, body) {
|
|
|
125
125
|
SPECIAL_URI: const_1.SPECIAL_URI, PLUGINS_PUB_URI: const_1.PLUGINS_PUB_URI, FRONTEND_URI: const_1.FRONTEND_URI,
|
|
126
126
|
session: session instanceof apiMiddleware_1.ApiError ? null : session,
|
|
127
127
|
plugins,
|
|
128
|
+
loadScripts: Object.fromEntries((0, plugins_1.mapPlugins)((p, id) => { var _a; return [id, (_a = p.frontend_js) === null || _a === void 0 ? void 0 : _a.map(f => f.includes('//') ? f : pub + id + '/' + f)]; })),
|
|
128
129
|
prefixUrl: ctx.state.revProxyPath,
|
|
129
130
|
dontOverwriteUploading: upload_1.dontOverwriteUploading.get(),
|
|
130
131
|
customHtml: lodash_1.default.omit(Object.fromEntries(customHtml_1.customHtmlState.sections), ['top', 'bottom']),
|
|
@@ -136,20 +137,16 @@ async function treatIndex(ctx, filesUri, body) {
|
|
|
136
137
|
`;
|
|
137
138
|
if (isBody && isOpen)
|
|
138
139
|
return all + `
|
|
139
|
-
${
|
|
140
|
+
${isFrontend && (0, customHtml_1.getSection)('top')}
|
|
140
141
|
<style>
|
|
141
142
|
:root {
|
|
142
|
-
${lodash_1.default.map(plugins, (configs, pluginName) =>
|
|
143
|
+
${lodash_1.default.map(plugins, (configs, pluginName) => // make plugin configs accessible via css
|
|
144
|
+
lodash_1.default.map(configs, (v, k) => `--${pluginName}-${k}: ${serializeCss(v)};`).join('\n')).join('')}
|
|
143
145
|
}
|
|
144
146
|
</style>
|
|
145
|
-
${
|
|
147
|
+
${isFrontend && (0, plugins_1.mapPlugins)((plug, id) => {
|
|
146
148
|
var _a;
|
|
147
149
|
return (_a = plug.frontend_css) === null || _a === void 0 ? void 0 : _a.map(f => `<link rel='stylesheet' type='text/css' href='${f.includes('//') ? f : pub + id + '/' + f}' plugin=${JSON.stringify(id)}/>`);
|
|
148
|
-
})
|
|
149
|
-
.flat().filter(Boolean).join('\n')}
|
|
150
|
-
${!isFrontend ? '' : (0, plugins_1.mapPlugins)((plug, id) => {
|
|
151
|
-
var _a;
|
|
152
|
-
return (_a = plug.frontend_js) === null || _a === void 0 ? void 0 : _a.map(f => `<script defer plugin=${JSON.stringify(id)} src='${f.includes('//') ? f : pub + id + '/' + f}'></script>`);
|
|
153
150
|
})
|
|
154
151
|
.flat().filter(Boolean).join('\n')}
|
|
155
152
|
`;
|