Add web server, certificates and Samba/AD management tabs, a web server config generator, toggleable feature menus and an animated start page background

- Web server tab (nginx, Apache, Caddy, PHP-FPM): service control with autostart, config test and live logs, sites list with enable/disable/edit/delete, new site wizard (static, reverse proxy, PHP) and a code editor for all config files; every change is checked (nginx -t, apachectl configtest, caddy validate, php-fpm -t) before reloading and rolled back if the check fails
- Config generator: all options grouped and searchable (reverse proxy with load balancing and WebSockets, HTTPS/TLS, HSTS, security headers, IP allow list, basic auth, rate limit, gzip, caching, upload size, PHP, redirects, logs, custom directives), presets, live preview for nginx/Apache/Caddy; save as a site (needed Apache modules are enabled) or open in the editor first
- Certificates tab: Let's Encrypt via certbot (request with nginx/Apache/webroot/standalone/DNS challenge, renew, dry run, delete) in a terminal tab, acme.sh certificates, expiry of all found certificate files, auto-renew timer, self-signed certificates and a TLS endpoint check from this computer
- Samba/AD tab: shares (smb.conf edited section by section, checked with testparm), Samba users, services and connected clients; create a new AD domain (samba-tool domain provision), join or leave a domain (realmd/sssd) and manage domain users, groups, members and computers; passwords are passed via stdin
- Settings: feature menus (Docker, firewall, network, web server, certificates, Samba/AD) can be enabled or disabled for the host menu, terminal toolbar and quick search
- Start page: slowly drifting, blurred colour glows in the theme colours behind the vault (can be turned off in the design settings, respects reduced motion)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-16 15:58:18 +02:00
co-authored by Claude Opus 5.5
parent 29d3747859
commit fd155fe2db
13 changed files with 2585 additions and 14 deletions
+19 -1
View File
@@ -15,6 +15,9 @@ const { VpnManager } = require('./vpn');
const { DockerManager } = require('./docker');
const { FirewallManager } = require('./firewall');
const { NetworkConfigManager } = require('./network');
const { WebServerManager } = require('./webserver');
const { CertManager, probe: probeTls } = require('./certs');
const { SambaManager } = require('./samba');
const { SyncService } = require('./sync');
const backup = require('../core/backup');
const composeTemplates = require('./compose-templates');
@@ -89,6 +92,8 @@ const vpn = new VpnManager(store, app.getPath('userData'));
const docker = new DockerManager(ssh);
const firewall = new FirewallManager(ssh);
const network = new NetworkConfigManager(ssh);
// Verwaltungs-Tabs mit gemeinsamen Kanälen <prefix>:open/read/op/close (siehe admin.js)
const admins = { web: new WebServerManager(ssh), certs: new CertManager(ssh), samba: new SambaManager(ssh) };
const ai = new AiAssistant(store, send);
// LAN-Synchronisation; Vergleichscode beim Koppeln bestätigt der Nutzer in der Oberfläche
@@ -153,7 +158,7 @@ function openTabWindow(data, pos) {
for (const [id, o] of sessionOwner) {
if (o !== w) continue;
sessionOwner.delete(id);
for (const m of [ssh, docker, firewall, network]) { try { m.close(id); } catch {} }
for (const m of [ssh, docker, firewall, network, ...Object.values(admins)]) { try { m.close(id); } catch {} }
}
});
}
@@ -321,6 +326,19 @@ handle('network:readFile', (id, path) => network.readFile(id, path));
handle('network:writeFile', (id, path, content, verify) => network.writeFile(id, path, content, verify));
handle('network:close', (id) => network.close(id));
// ---------- Webserver / Zertifikate / Samba-AD ----------
for (const [p, m] of Object.entries(admins)) {
handle(`${p}:open`, async (id, hostRef) => {
const host = hostWithOverrides(hostRef);
if (await vpn.ensureForHost(host)) send('vpn:changed');
return m.open(id, host, () => send(`${p}:closed`, id));
});
handle(`${p}:read`, (id) => m.read(id));
handle(`${p}:op`, (id, op, ...args) => m.op(id, op, ...args));
handle(`${p}:close`, (id) => m.close(id));
}
handle('certs:probe', (host, port) => probeTls(host, port));
// ---------- Synchronisation ----------
handle('sync:status', () => sync.status());
handle('sync:enable', (on, name) => sync.setEnabled(on, name));