mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-02 17:33:56 +08:00
🌴 Sync 2026-10-06 02:20:56
This commit is contained in:
1 parent
5c201dd3af
commit
487c4fad50
111 files changed
+4641
-746
No files matched your search
@@ -85,6 +85,41 @@ function tableKeys(file, name) {
|
||||
return keys;
|
||||
}
|
||||
|
||||
/* Protocols whose table entry names `password`, for tables whose depth-1
|
||||
* entries are single lines (arrays in adapter.uc, objects in model.uc). */
|
||||
function tableKeysWith(file, name, field) {
|
||||
const keys = tableKeys(file, name);
|
||||
const lines = fs.readFileSync(file, 'utf8').split('\n');
|
||||
const head = new RegExp('^export const ' + name + '\\s*=\\s*\\{');
|
||||
const found = [];
|
||||
let start = -1, depth = 0;
|
||||
|
||||
for (let i = 0; i < lines.length; i++)
|
||||
if (head.test(lines[i])) { start = i; depth = 1; break; }
|
||||
if (start === -1)
|
||||
throw new Error('table ' + name + ' not found');
|
||||
|
||||
for (let i = start + 1; i < lines.length; i++) {
|
||||
if (depth === 1) {
|
||||
const m = /^\t([A-Za-z0-9_]+)\s*:/.exec(lines[i]);
|
||||
if (m && keys.includes(m[1]) && new RegExp('(^|[^A-Za-z_])' + field + '([^A-Za-z_]|$)').test(lines[i]))
|
||||
found.push(m[1]);
|
||||
}
|
||||
for (const ch of lines[i]) {
|
||||
if (ch === '{') depth++;
|
||||
else if (ch === '}') depth--;
|
||||
}
|
||||
if (depth <= 0) break;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
function validatorTypes(file) {
|
||||
const src = fs.readFileSync(file, 'utf8');
|
||||
const m = src.match(/validatePassword\(\s*\[([^\]]+)\]/);
|
||||
return m ? m[1].split(',').map((t) => t.trim().replace(/^['"]|['"]$/g, '')).filter(Boolean) : [];
|
||||
}
|
||||
|
||||
let checks = 0, failures = 0;
|
||||
function check(what, ok, detail) {
|
||||
checks++;
|
||||
@@ -183,6 +218,36 @@ for (const type of unmapped) {
|
||||
'models it in the backend but no form offers it');
|
||||
}
|
||||
|
||||
/* --- the required-credential surface must be enforced before save ---------
|
||||
*
|
||||
* A protocol whose backend entry requires a password but whose form validator
|
||||
* does not check it can be saved empty; generation then dies and the user sees
|
||||
* "my setting did not take". That is how hysteria2/tuic slipped through: the
|
||||
* empty password was accepted at save time and OutboundFactory.create() die()d
|
||||
* at generation time. The validator lists live in the two view files, so they
|
||||
* are compared against the backend tables here. */
|
||||
const clientNeedsPassword = new Set(tableKeysWith(path.join(scripts, 'config/adapter.uc'), 'REQUIRED_CREDENTIALS', 'password'));
|
||||
const serverNeedsPassword = new Set(tableKeysWith(path.join(scripts, 'config/model.uc'), 'INBOUND_CREDENTIALS', 'password'));
|
||||
const clientValidated = new Set(validatorTypes(path.join(root, 'htdocs/luci-static/resources/view/homeproxy-pro/node.js')));
|
||||
const serverValidated = new Set(validatorTypes(path.join(root, 'htdocs/luci-static/resources/view/homeproxy-pro/server.js')));
|
||||
|
||||
check('adapter.uc REQUIRED_CREDENTIALS parsed for the password field', clientNeedsPassword.size > 0, [ ...clientNeedsPassword ].join(' '));
|
||||
check('model.uc INBOUND_CREDENTIALS parsed for the password field', serverNeedsPassword.size > 0, [ ...serverNeedsPassword ].join(' '));
|
||||
|
||||
for (const type of clientList) {
|
||||
if (!clientNeedsPassword.has(type))
|
||||
continue;
|
||||
check(`client form validates the password that ${type} requires`, clientValidated.has(type),
|
||||
`${type} needs a password in adapter.uc but is missing from node.js's validatePassword list`);
|
||||
}
|
||||
|
||||
for (const type of serverList) {
|
||||
if (!serverNeedsPassword.has(type))
|
||||
continue;
|
||||
check(`server form validates the password that ${type} requires`, serverValidated.has(type),
|
||||
`${type} needs a password in model.uc but is missing from server.js's validatePassword list`);
|
||||
}
|
||||
|
||||
console.log(`frontend protocol inventory: ${checks} checks, ${failures} failures`);
|
||||
console.log(` client: ${clientList.join(' ')}`);
|
||||
console.log(` server: ${serverList.join(' ')}`);
|
||||
|
||||
Reference in new issue
Block a user