mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-11-15 20:52:53 +08:00
update 2026-10-25 16:53:21
This commit is contained in:
1 parent
91f217be10
commit
7fca8e9a3a
74 files changed
+1429
-918
No files matched your search
@@ -5,6 +5,7 @@
|
||||
'require poll';
|
||||
'require view';
|
||||
'require view.honk.rpc as honk';
|
||||
'require uci';
|
||||
|
||||
function getNetworkNames(networks) {
|
||||
if (!networks)
|
||||
@@ -81,9 +82,10 @@ return view.extend({
|
||||
load: function() {
|
||||
return Promise.all([
|
||||
honk.status().then(function(status) { return { status: status }; }).catch(function(error) { return { error: error.message || String(error) }; }),
|
||||
network.getNetworks().then(getNetworkNames).then(function(networks) { return { networks: networks }; }).catch(function() { return { networks: [] }; })
|
||||
network.getNetworks().then(getNetworkNames).then(function(networks) { return { networks: networks }; }).catch(function() { return { networks: [] }; }),
|
||||
uci.load('honk').then(function() { return { clash_secret: uci.get('honk', 'main', 'clash_api_secret') || '' }; }).catch(function() { return { clash_secret: '' }; })
|
||||
]).then(function(results) {
|
||||
return Object.assign({}, results[0], results[1]);
|
||||
return Object.assign({}, results[0], results[1], results[2]);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -94,6 +96,7 @@ return view.extend({
|
||||
const actionMessage = E('p', { 'class': 'honk-status-msg', 'role': 'status' }, '');
|
||||
const setupArea = E('div');
|
||||
let currentStatus = data.status;
|
||||
const clashSecret = data.clash_secret || '';
|
||||
let busy = false;
|
||||
let setupBusy = false;
|
||||
let settingsBusy = false;
|
||||
@@ -128,7 +131,7 @@ return view.extend({
|
||||
'type': webUi ? null : 'button',
|
||||
'disabled': webUi ? null : true
|
||||
}, _('Open Doona'));
|
||||
const clashUi = honk.localClashUi(status);
|
||||
const clashUi = honk.localClashUi(status, clashSecret);
|
||||
const openClash = E(clashUi ? 'a' : 'button', {
|
||||
'class': 'cbi-button cbi-button-action',
|
||||
'href': clashUi || null,
|
||||
@@ -211,7 +214,8 @@ return view.extend({
|
||||
const bootEnabledInput = E('input', { 'type': 'checkbox', 'name': 'boot_enabled', 'id': 'honk-boot-enabled' });
|
||||
const clashEnabledInput = E('input', { 'type': 'checkbox', 'name': 'clash_api_enabled', 'id': 'honk-clash-enabled' });
|
||||
const clashPortInput = E('input', { 'class': 'cbi-input-text', 'type': 'number', 'name': 'clash_api_port', 'id': 'honk-clash-port', 'min': '1024', 'max': '65535', 'step': '1' });
|
||||
const clashSecretInput = E('input', { 'class': 'cbi-input-password', 'type': 'password', 'name': 'clash_api_secret', 'id': 'honk-clash-secret', 'autocomplete': 'new-password' });
|
||||
const clashSecretInput = E('input', { 'class': 'cbi-input-password', 'type': 'password', 'name': 'clash_api_secret', 'id': 'honk-clash-secret', 'autocomplete': 'new-password', 'readonly': 'readonly' });
|
||||
clashSecretInput.addEventListener('focus', function() { clashSecretInput.removeAttribute('readonly'); });
|
||||
const message = E('p', { 'class': 'honk-status-msg', 'role': 'status' }, '');
|
||||
const save = E('button', { 'class': 'cbi-button cbi-button-positive', 'type': 'submit' }, _('Save service settings'));
|
||||
|
||||
@@ -235,7 +239,7 @@ return view.extend({
|
||||
form.appendChild(field(_('Start Honk at boot'), bootEnabledInput));
|
||||
form.appendChild(field(_('Enable Clash API and Zashboard'), clashEnabledInput));
|
||||
form.appendChild(field(_('Clash API port'), clashPortInput));
|
||||
form.appendChild(field(_('Clash API secret'), clashSecretInput, status.clash_api_secret_set ? _('A secret is set. Leave blank to keep it.') : _('Required when enabling. Use 16–128 letters, numbers, underscores or hyphens.')));
|
||||
form.appendChild(field(_('Clash API secret'), clashSecretInput, status.clash_api_secret_set ? _('A secret is set. Leave blank to keep it.') : _('Required when enabling. Use 6–128 letters, numbers, dots, underscores or hyphens.')));
|
||||
form.appendChild(E('p', { 'class': 'honk-note' }, _('Use your existing HTTPS reverse proxy for external access. Enter the secret in Zashboard when connecting.')));
|
||||
form.appendChild(E('div', { 'class': 'cbi-page-actions' }, save));
|
||||
form.appendChild(message);
|
||||
@@ -248,10 +252,20 @@ return view.extend({
|
||||
message.textContent = _('Choose a LAN network and a port from 1024 to 65535.');
|
||||
return;
|
||||
}
|
||||
if (!Number.isInteger(clashPort) || clashPort < 1024 || clashPort > 65535 ||
|
||||
clashEnabledInput.checked && (clashPort === port || !status.clash_api_secret_set && !clashSecret ||
|
||||
!!clashSecret && !/^[A-Za-z0-9_-]{16,128}$/.test(clashSecret))) {
|
||||
message.textContent = _('Choose a different Clash API port and enter a valid secret.');
|
||||
if (!Number.isInteger(clashPort) || clashPort < 1024 || clashPort > 65535) {
|
||||
message.textContent = _('Clash API port must be between 1024 and 65535.');
|
||||
return;
|
||||
}
|
||||
if (clashEnabledInput.checked && clashPort === port) {
|
||||
message.textContent = _('The Clash API port must differ from the listen port.');
|
||||
return;
|
||||
}
|
||||
if (clashEnabledInput.checked && !status.clash_api_secret_set && !clashSecret) {
|
||||
message.textContent = _('A secret is required when enabling Clash API.');
|
||||
return;
|
||||
}
|
||||
if (clashEnabledInput.checked && clashSecret && !/^[A-Za-z0-9._-]{6,128}$/.test(clashSecret)) {
|
||||
message.textContent = _('The secret must be 6-128 letters, numbers, dots, underscores or hyphens.');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -122,10 +122,27 @@ function localWebUi(status) {
|
||||
}
|
||||
}
|
||||
|
||||
function localClashUi(status) {
|
||||
function localClashUi(status, secret) {
|
||||
if (!status || !status.clash_api_enabled || !status.clash_api_ready || !status.clash_ui_ready)
|
||||
return null;
|
||||
return localWebUi(Object.assign({}, status, { api_url: status.clash_api_url, api_ready: true }));
|
||||
const base = localWebUi(Object.assign({}, status, { api_url: status.clash_api_url, api_ready: true }));
|
||||
if (!base)
|
||||
return null;
|
||||
try {
|
||||
const url = new URL(status.clash_api_url);
|
||||
const host = url.hostname.replace(/^\[|\]$/g, '').toLowerCase();
|
||||
const port = status.clash_api_port || url.port;
|
||||
const query = [
|
||||
'host=' + encodeURIComponent(host),
|
||||
'hostname=' + encodeURIComponent(host),
|
||||
'port=' + encodeURIComponent(port),
|
||||
'secret=' + encodeURIComponent(secret || '')
|
||||
].join('&');
|
||||
return base + '?' + query + '#/proxies';
|
||||
}
|
||||
catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function tokenMessage(token) {
|
||||
@@ -205,7 +222,7 @@ function tokenMessage(token) {
|
||||
lan_network_unavailable: _('The selected LAN network is unavailable.'),
|
||||
listen_port_occupied: _('The listen port is already in use.'),
|
||||
clash_api_port_occupied: _('The Clash API port is already in use.'),
|
||||
invalid_clash_api_settings: _('Enter a different Clash API port and a secret of 16–128 letters, numbers, underscores or hyphens.'),
|
||||
invalid_clash_api_settings: _('Enter a different Clash API port and a secret of 6–128 letters, numbers, dots, underscores or hyphens.'),
|
||||
invalid_listen_port: _('The listen port is invalid.'),
|
||||
initialize_before_enabling_service: _('Complete initial setup before enabling Honk.'),
|
||||
system_config_unavailable: _('Honk system configuration is unavailable.'),
|
||||
|
||||
@@ -51,7 +51,8 @@ return view.extend({
|
||||
const bootEnabledInput = E('input', { 'type': 'checkbox', 'name': 'boot_enabled', 'id': 'honk-boot-enabled' });
|
||||
const clashEnabledInput = E('input', { 'type': 'checkbox', 'name': 'clash_api_enabled', 'id': 'honk-clash-enabled' });
|
||||
const clashPortInput = E('input', { 'class': 'cbi-input-text', 'type': 'number', 'name': 'clash_api_port', 'id': 'honk-clash-port', 'min': '1024', 'max': '65535', 'step': '1' });
|
||||
const clashSecretInput = E('input', { 'class': 'cbi-input-password', 'type': 'password', 'name': 'clash_api_secret', 'id': 'honk-clash-secret', 'autocomplete': 'new-password' });
|
||||
const clashSecretInput = E('input', { 'class': 'cbi-input-password', 'type': 'password', 'name': 'clash_api_secret', 'id': 'honk-clash-secret', 'autocomplete': 'new-password', 'readonly': 'readonly' });
|
||||
clashSecretInput.addEventListener('focus', function() { clashSecretInput.removeAttribute('readonly'); });
|
||||
const message = E('p', { 'class': 'honk-status-msg', 'role': 'status' }, '');
|
||||
const save = E('button', { 'class': 'cbi-button cbi-button-positive', 'type': 'submit' }, _('Save settings'));
|
||||
save.disabled = !!data.statusError;
|
||||
@@ -81,7 +82,7 @@ return view.extend({
|
||||
section.appendChild(field(_('Enable Clash API and Zashboard'), clashEnabledInput));
|
||||
section.appendChild(field(_('Clash API port'), clashPortInput));
|
||||
section.appendChild(field(_('Clash API secret'), clashSecretInput));
|
||||
section.appendChild(E('p', { 'class': 'honk-note' }, data.status && data.status.clash_api_secret_set ? _('A secret is set. Leave blank to keep it. Use your existing HTTPS reverse proxy for external access.') : _('A secret is required when enabling Clash API. Use 16–128 letters, numbers, underscores or hyphens.')));
|
||||
section.appendChild(E('p', { 'class': 'honk-note' }, data.status && data.status.clash_api_secret_set ? _('A secret is set. Leave blank to keep it. Use your existing HTTPS reverse proxy for external access.') : _('A secret is required when enabling Clash API. Use 6–128 letters, numbers, dots, underscores or hyphens.')));
|
||||
section.appendChild(E('div', { 'class': 'cbi-page-actions' }, save));
|
||||
section.appendChild(message);
|
||||
section.addEventListener('submit', function(ev) {
|
||||
@@ -93,10 +94,20 @@ return view.extend({
|
||||
message.textContent = _('Choose a LAN network and a port from 1024 to 65535.');
|
||||
return;
|
||||
}
|
||||
if (!Number.isInteger(clashPort) || clashPort < 1024 || clashPort > 65535 ||
|
||||
clashEnabledInput.checked && (clashPort === port || !(data.status && data.status.clash_api_secret_set) && !clashSecret ||
|
||||
!!clashSecret && !/^[A-Za-z0-9_-]{16,128}$/.test(clashSecret))) {
|
||||
message.textContent = _('Choose a different Clash API port and enter a valid secret.');
|
||||
if (!Number.isInteger(clashPort) || clashPort < 1024 || clashPort > 65535) {
|
||||
message.textContent = _('Clash API port must be between 1024 and 65535.');
|
||||
return;
|
||||
}
|
||||
if (clashEnabledInput.checked && clashPort === port) {
|
||||
message.textContent = _('The Clash API port must differ from the listen port.');
|
||||
return;
|
||||
}
|
||||
if (clashEnabledInput.checked && !(data.status && data.status.clash_api_secret_set) && !clashSecret) {
|
||||
message.textContent = _('A secret is required when enabling Clash API.');
|
||||
return;
|
||||
}
|
||||
if (clashEnabledInput.checked && clashSecret && !/^[A-Za-z0-9._-]{6,128}$/.test(clashSecret)) {
|
||||
message.textContent = _('The secret must be 6-128 letters, numbers, dots, underscores or hyphens.');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user