mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-30 02:35:13 +08:00
🍕 Sync 2026-09-14 23:30:37
This commit is contained in:
1 parent
0603b094cf
commit
81fe4cd866
214 files changed
+10806
-2630
No files matched your search
@@ -545,7 +545,7 @@ return view.extend({
|
||||
};
|
||||
|
||||
o = addOption('scheme', form.Value, 'listen_https_port', _('HTTPS listen port'),
|
||||
_('The upstream default is -1 (disabled). Set a valid port number to enable HTTPS.'));
|
||||
_('Set to -1 to disable HTTPS, or 1-65535 to enable it. Leave both certificate paths empty to use an automatically generated self-signed certificate.'));
|
||||
o.datatype = 'integer';
|
||||
o.default = '-1';
|
||||
o.rmempty = false;
|
||||
@@ -554,14 +554,15 @@ return view.extend({
|
||||
return validateListenPort(value);
|
||||
};
|
||||
|
||||
o = addOption('scheme', form.Flag, 'force_https', _('Force HTTPS'));
|
||||
o = addOption('scheme', form.Flag, 'force_https', _('Force HTTPS'),
|
||||
_('Redirect HTTP requests to HTTPS. The HTTPS listen port enables HTTPS independently of this option.'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = addOption('scheme', form.Value, 'ssl_cert', _('SSL cert'),
|
||||
_('SSL certificate file path'));
|
||||
_('Leave both paths empty to manage a self-signed certificate in the TLS subdirectory of the data directory. It is reused and renewed at startup when fewer than 30 days remain. Browsers do not trust self-signed certificates automatically.'));
|
||||
|
||||
o = addOption('scheme', form.Value, 'ssl_key', _('SSL key'),
|
||||
_('SSL key file path'));
|
||||
_('For custom TLS, specify both certificate and private key paths. The certificate must be currently valid and match its private key. Custom files are never overwritten automatically.'));
|
||||
|
||||
o = addOption('scheme', form.Value, 'listen_unix_file', _('Unix socket file'));
|
||||
|
||||
@@ -572,7 +573,7 @@ return view.extend({
|
||||
o.rmempty = false;
|
||||
|
||||
o = addOption('scheme', form.Flag, 'listen_enable_h3', _('Enable HTTP/3/QUIC'),
|
||||
_('Enable HTTP/3 over QUIC on the HTTPS listen port. HTTPS must be enabled and certificate files must be configured.'));
|
||||
_('Enable HTTP/3 over QUIC on the HTTPS listen port. HTTPS must be enabled. Certificate settings are shared with HTTPS.'));
|
||||
o.rmempty = false;
|
||||
|
||||
// tasks
|
||||
@@ -698,7 +699,8 @@ return view.extend({
|
||||
o.default = 5246;
|
||||
o.rmempty = false;
|
||||
|
||||
o = addOption('s3', form.Flag, 's3_ssl', _('Enable SSL'));
|
||||
o = addOption('s3', form.Flag, 's3_ssl', _('Enable SSL'),
|
||||
_('Use the same custom or automatically generated certificate as HTTPS. Configure certificate paths on the Web Protocol tab.'));
|
||||
o.rmempty = false;
|
||||
|
||||
// ftp
|
||||
@@ -708,7 +710,8 @@ return view.extend({
|
||||
_('Ports or ranges to allow from WAN, for example 50000-50100. They must match the listening ports in OpenList passive port mapping. Empty means passive ports must be allowed manually.'));
|
||||
o.placeholder = '50000-50100';
|
||||
o.depends({ ftp: '1', allow_wan: '1' });
|
||||
o = addOption('ftp', form.Flag, 'ftp', _('Enabled FTP'));
|
||||
o = addOption('ftp', form.Flag, 'ftp', _('Enabled FTP'),
|
||||
_('Enable FTP/SFTP access for the OpenList account in Management > Users. Also grant FTP/SFTP management permission to allow uploads and changes.'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = addOption('ftp', form.Value, 'ftp_port', _('FTP Port'));
|
||||
@@ -749,7 +752,8 @@ return view.extend({
|
||||
o.rmempty = false;
|
||||
|
||||
// sftp
|
||||
o = addOption('sftp', form.Flag, 'sftp', _('Enabled SFTP'));
|
||||
o = addOption('sftp', form.Flag, 'sftp', _('Enabled SFTP'),
|
||||
_('Enable FTP/SFTP access for the OpenList account in Management > Users. Also grant FTP/SFTP management permission to allow uploads and changes.'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = addOption('sftp', form.Value, 'sftp_port', _('SFTP Port'));
|
||||
@@ -764,7 +768,7 @@ return view.extend({
|
||||
|
||||
|
||||
o = addOption('mcp', form.DummyValue, '_mcp_endpoint', _('MCP endpoint'),
|
||||
_('Use Streamable HTTP with Authorization: TOKEN, without a Bearer prefix. Use an OpenList user login token; retain MCP-Session-Id for subsequent requests.'));
|
||||
_('Use Streamable HTTP with Authorization: TOKEN, without a Bearer prefix. Use an OpenList administrator login token; retain MCP-Session-Id for subsequent requests.'));
|
||||
o.depends('mcp', '1');
|
||||
o.renderWidget = () => E('div', {}, [
|
||||
E('code', {}, backendUrl('mcp') || _('Configure a web port or Site URL.')),
|
||||
@@ -793,26 +797,48 @@ return view.extend({
|
||||
if (dist && (containsPath(dist, data) || containsPath(dist, cache) ||
|
||||
containsPath(cache, dist) || containsPath(dist, index) || containsPath(index, dist)))
|
||||
return _('Frontend files must be separate from private data, cache and index files.');
|
||||
if (tlsRequired(section_id) && !fieldValue(section_id, 'ssl_cert') && !fieldValue(section_id, 'ssl_key')) {
|
||||
const tls = data + '/tls';
|
||||
for (const directory of [cache, index, dist].filter(Boolean))
|
||||
if (containsPath(tls, directory) || containsPath(directory, tls))
|
||||
return _('Automatic TLS directory must be separate from cache, index and public frontend directories.');
|
||||
}
|
||||
return true;
|
||||
};
|
||||
for (const name of ['data_dir', 'temp_dir', 'bleve_dir', 'dist_dir'])
|
||||
fields[name].validate = (section_id, value) => validateDirectories(section_id, name, value);
|
||||
|
||||
const tlsRequired = section_id => isEnabledPort(fieldValue(section_id, 'listen_https_port', '-1')) ||
|
||||
(fieldValue(section_id, 's3') === '1' && fieldValue(section_id, 's3_ssl') === '1');
|
||||
for (const name of ['ssl_cert', 'ssl_key']) {
|
||||
fields[name].validate = (section_id, value) => {
|
||||
if (tlsRequired(section_id) && !String(value || '').trim())
|
||||
return _('Certificate and key paths are required for HTTPS or S3 SSL.');
|
||||
return validateAbsolutePath(value, false);
|
||||
};
|
||||
}
|
||||
const tlsRequired = section_id => {
|
||||
const httpsPort = fieldValue(section_id, 'listen_https_port', '-1');
|
||||
const s3Enabled = fieldValue(section_id, 's3') === '1';
|
||||
const s3Ssl = fieldValue(section_id, 's3_ssl') === '1';
|
||||
return isEnabledPort(httpsPort) || (s3Enabled && s3Ssl);
|
||||
};
|
||||
const validateCertificatePaths = (section_id, changed, value) => {
|
||||
if (!tlsRequired(section_id))
|
||||
return true;
|
||||
const cert = changed === 'ssl_cert' ? value : fieldValue(section_id, 'ssl_cert');
|
||||
const key = changed === 'ssl_key' ? value : fieldValue(section_id, 'ssl_key');
|
||||
if (!cert && !key)
|
||||
return true;
|
||||
if (!cert || !key)
|
||||
return _('Leave both certificate paths empty for automatic TLS, or provide both custom certificate and key paths.');
|
||||
for (const path of [cert, key]) {
|
||||
const valid = validateAbsolutePath(path, true);
|
||||
if (valid !== true)
|
||||
return valid;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
for (const name of ['ssl_cert', 'ssl_key'])
|
||||
fields[name].validate = (section_id, value) => validateCertificatePaths(section_id, name, value);
|
||||
// LuCI passes input.value (always "1") for checkbox validation.
|
||||
// Read formvalue() to distinguish checked and unchecked flags.
|
||||
for (const name of ['force_https', 'listen_enable_h3'])
|
||||
fields[name].validate = (section_id, value) => value !== '1' || isEnabledPort(fieldValue(section_id, 'listen_https_port', '-1'))
|
||||
fields[name].validate = section_id => fieldValue(section_id, name) !== '1' || isEnabledPort(fieldValue(section_id, 'listen_https_port', '-1'))
|
||||
? true : _('Force HTTPS and HTTP/3 require an enabled HTTPS port.');
|
||||
fields.s3_ssl.validate = (section_id, value) => value !== '1' || fieldValue(section_id, 's3') !== '1' ||
|
||||
(fieldValue(section_id, 'ssl_cert').trim() && fieldValue(section_id, 'ssl_key').trim())
|
||||
? true : _('Certificate and key paths are required for HTTPS or S3 SSL.');
|
||||
fields.s3_ssl.validate = section_id => fieldValue(section_id, 's3') !== '1' || fieldValue(section_id, 's3_ssl') !== '1'
|
||||
? true : validateCertificatePaths(section_id);
|
||||
fields.listen_unix_file.validate = (section_id, value) => validateAbsolutePath(value, false);
|
||||
fields.listen_unix_file_perm.validate = (section_id, value) => !value || /^[0-7]{3,4}$/.test(value)
|
||||
? true : _('Use 3 or 4 octal digits, for example 660 or 0660.');
|
||||
@@ -857,6 +883,17 @@ return view.extend({
|
||||
};
|
||||
for (const name of ['listen_http_port', 'listen_https_port', 's3_port', 'ftp_port', 'sftp_port', 'ftp_pasv_ports'])
|
||||
fields[name].validate = (section_id, value) => validatePorts(section_id, name, value);
|
||||
const protocolFields = ['listen_http_port', 'listen_https_port', 'force_https', 'listen_enable_h3',
|
||||
'ssl_cert', 'ssl_key', 's3', 's3_ssl', 's3_port', 'ftp', 'ftp_port', 'sftp', 'sftp_port',
|
||||
'ftp_pasv_ports', 'allow_wan', 'data_dir', 'temp_dir', 'bleve_dir', 'dist_dir'];
|
||||
const revalidateProtocolFields = (event, section_id) => {
|
||||
for (const name of protocolFields)
|
||||
if (fields[name].isActive(section_id))
|
||||
fields[name].triggerValidation(section_id);
|
||||
ui.tabs.updateTabs(event, m.root);
|
||||
};
|
||||
for (const name of protocolFields)
|
||||
fields[name].onchange = revalidateProtocolFields;
|
||||
for (const name of ['ftp_pasv_ports', 'log_path', 'log_max_size', 'log_max_backups', 'log_max_age',
|
||||
'log_compress', 'log_filter', 'log_filter_cidr', 'log_filter_path', 'log_filter_method'])
|
||||
fields[name].retain = true;
|
||||
|
||||
@@ -54,7 +54,7 @@ return view.extend({
|
||||
const clearButton = E('button', {
|
||||
'class': 'btn cbi-button-action',
|
||||
'type': 'button',
|
||||
'disabled': !L.hasViewPermission(),
|
||||
'disabled': !L.hasViewPermission() || null,
|
||||
'click': ui.createHandlerFn(this, 'handleCleanLogs')
|
||||
}, _('Clear current log'));
|
||||
|
||||
|
||||
Reference in new issue
Block a user