import * as plugins from './smartvpn.plugins.js'; import type { TVpnPlatform, IVpnServiceUnit } from './smartvpn.interfaces.js'; /** * Install the smartvpn daemon as a system service. */ export class VpnInstaller { /** * Detect the current platform. */ public static detectPlatform(): TVpnPlatform { switch (process.platform) { case 'linux': return 'linux'; case 'darwin': return 'macos'; case 'win32': return 'windows'; default: return 'unknown'; } } /** * Generate a systemd unit file for Linux. */ public static generateSystemdUnit(options: { binaryPath: string; socketPath: string; mode: 'client' | 'server'; configPath?: string; description?: string; }): IVpnServiceUnit { const desc = options.description || `SmartVPN ${options.mode} daemon`; const content = `[Unit] Description=${desc} After=network-online.target Wants=network-online.target [Service] Type=simple ExecStart=${options.binaryPath} --management-socket ${options.socketPath} --mode ${options.mode} Restart=always RestartSec=5 LimitNOFILE=65535 # Security hardening NoNewPrivileges=no ProtectSystem=strict ProtectHome=yes ReadWritePaths=/var/run /dev/net/tun PrivateTmp=yes [Install] WantedBy=multi-user.target `; return { platform: 'linux', content, installPath: `/etc/systemd/system/smartvpn-${options.mode}.service`, }; } /** * Generate a launchd plist for macOS. */ public static generateLaunchdPlist(options: { binaryPath: string; socketPath: string; mode: 'client' | 'server'; description?: string; }): IVpnServiceUnit { const label = `rocks.push.smartvpn.${options.mode}`; const content = ` Label ${label} ProgramArguments ${options.binaryPath} --management-socket ${options.socketPath} --mode ${options.mode} RunAtLoad KeepAlive StandardErrorPath /var/log/smartvpn-${options.mode}.err.log StandardOutPath /var/log/smartvpn-${options.mode}.out.log `; return { platform: 'macos', content, installPath: `/Library/LaunchDaemons/${label}.plist`, }; } /** * Generate the appropriate service unit for the current platform. */ public static generateServiceUnit(options: { binaryPath: string; socketPath: string; mode: 'client' | 'server'; }): IVpnServiceUnit { const platform = VpnInstaller.detectPlatform(); switch (platform) { case 'linux': return VpnInstaller.generateSystemdUnit(options); case 'macos': return VpnInstaller.generateLaunchdPlist(options); default: throw new Error(`VpnInstaller: unsupported platform: ${platform}`); } } }