secubox-openwrt/luci-app-vhost-manager/htdocs/luci-static/resources/view/vhost-manager/logs.js
CyberMind-FR 77d40a1f89 feat: implement VHost Manager - nginx reverse proxy and SSL management
Implements a comprehensive virtual host management system for OpenWrt with
nginx reverse proxy and Let's Encrypt SSL certificate integration.

Features:
- Virtual host management with nginx reverse proxy configuration
- Backend connectivity testing before deployment
- SSL/TLS certificate provisioning via acme.sh and Let's Encrypt
- Certificate expiry monitoring with color-coded warnings
- HTTP Basic Authentication support
- WebSocket protocol support with upgrade headers
- Real-time nginx access log viewer per domain
- Automatic nginx configuration generation and reload

Components:
- RPCD backend (luci.vhost-manager): 11 ubus methods for vhost and cert management
  * status, list_vhosts, get_vhost, add_vhost, update_vhost, delete_vhost
  * test_backend, request_cert, list_certs, reload_nginx, get_access_logs
- 4 JavaScript views: overview, vhosts, certificates, logs
- ACL with read/write permissions for all ubus methods
- UCI config with global settings and vhost sections
- Comprehensive README with API docs, examples, and troubleshooting

Configuration:
- Nginx vhost configs generated in /etc/nginx/conf.d/vhosts/
- SSL certificates managed via ACME in /etc/acme/{domain}/
- Access logs per domain: /var/log/nginx/{domain}.access.log
- HTTP Basic Auth htpasswd files in /etc/nginx/htpasswd/

Architecture follows SecuBox standards:
- RPCD naming convention (luci. prefix)
- Menu paths match view file structure
- All JavaScript in strict mode
- Backend connectivity validation
- Comprehensive error handling

Dependencies: nginx-ssl, acme, curl

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 10:37:01 +01:00

72 lines
1.8 KiB
JavaScript

'use strict';
'require view';
'require form';
'require vhost-manager/api as API';
return L.view.extend({
load: function() {
return Promise.all([
API.listVHosts()
]);
},
render: function(data) {
var vhosts = data[0] || [];
var m = new form.Map('vhost_manager', _('Access Logs'),
_('View nginx access logs for virtual hosts'));
var s = m.section(form.NamedSection, '__logs', 'logs');
s.anonymous = true;
s.addremove = false;
var o;
o = s.option(form.ListValue, 'domain', _('Select Domain'));
o.rmempty = false;
vhosts.forEach(function(vhost) {
o.value(vhost.domain, vhost.domain);
});
if (vhosts.length === 0) {
o.value('', _('No virtual hosts configured'));
}
o = s.option(form.ListValue, 'lines', _('Number of Lines'));
o.value('50', '50');
o.value('100', '100');
o.value('200', '200');
o.value('500', '500');
o.default = '50';
s.render = L.bind(function(view, section_id) {
var domain = this.section.formvalue(section_id, 'domain');
var lines = parseInt(this.section.formvalue(section_id, 'lines')) || 50;
if (!domain || vhosts.length === 0) {
return E('div', { 'class': 'cbi-section' }, [
E('p', { 'style': 'font-style: italic' }, _('No virtual hosts to display logs for'))
]);
}
return API.getAccessLogs(domain, lines).then(L.bind(function(data) {
var logs = data.logs || [];
return E('div', { 'class': 'cbi-section' }, [
E('h3', {}, _('Access Logs for: ') + domain),
E('pre', {
'style': 'background: #000; color: #0f0; padding: 10px; overflow: auto; max-height: 500px; font-size: 11px; font-family: monospace'
}, logs.length > 0 ? logs.join('\n') : _('No logs available'))
]);
}, this));
}, this, this);
return m.render();
},
handleSaveApply: null,
handleSave: null,
handleReset: null
});