108 lines
2.6 KiB
TypeScript
108 lines
2.6 KiB
TypeScript
import * as plugins from './smartvpn.plugins.js';
|
|
import { VpnBridge } from './smartvpn.classes.vpnbridge.js';
|
|
import type {
|
|
IVpnServerOptions,
|
|
IVpnServerConfig,
|
|
IVpnStatus,
|
|
IVpnServerStatistics,
|
|
IVpnClientInfo,
|
|
IVpnKeypair,
|
|
TVpnServerCommands,
|
|
} from './smartvpn.interfaces.js';
|
|
|
|
/**
|
|
* VPN Server — manages a smartvpn daemon in server mode.
|
|
*/
|
|
export class VpnServer extends plugins.events.EventEmitter {
|
|
private bridge: VpnBridge<TVpnServerCommands>;
|
|
private options: IVpnServerOptions;
|
|
|
|
constructor(options: IVpnServerOptions) {
|
|
super();
|
|
this.options = options;
|
|
this.bridge = new VpnBridge<TVpnServerCommands>({
|
|
transport: options.transport,
|
|
mode: 'server',
|
|
});
|
|
|
|
// Forward bridge events
|
|
this.bridge.on('exit', (code: number | null, signal: string | null) => {
|
|
this.emit('exit', { code, signal });
|
|
});
|
|
this.bridge.on('reconnected', () => {
|
|
this.emit('reconnected');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Start the daemon bridge (spawn or connect).
|
|
*/
|
|
public async start(config?: IVpnServerConfig): Promise<void> {
|
|
const started = await this.bridge.start();
|
|
if (!started) {
|
|
throw new Error('VpnServer: failed to start daemon bridge');
|
|
}
|
|
const cfg = config || this.options.config;
|
|
if (cfg) {
|
|
await this.bridge.sendCommand('start', { config: cfg });
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Stop the VPN server.
|
|
*/
|
|
public async stopServer(): Promise<void> {
|
|
await this.bridge.sendCommand('stop', {} as Record<string, never>);
|
|
}
|
|
|
|
/**
|
|
* Get server status.
|
|
*/
|
|
public async getStatus(): Promise<IVpnStatus> {
|
|
return this.bridge.sendCommand('getStatus', {} as Record<string, never>);
|
|
}
|
|
|
|
/**
|
|
* Get server statistics.
|
|
*/
|
|
public async getStatistics(): Promise<IVpnServerStatistics> {
|
|
return this.bridge.sendCommand('getStatistics', {} as Record<string, never>);
|
|
}
|
|
|
|
/**
|
|
* List connected clients.
|
|
*/
|
|
public async listClients(): Promise<IVpnClientInfo[]> {
|
|
const result = await this.bridge.sendCommand('listClients', {} as Record<string, never>);
|
|
return result.clients;
|
|
}
|
|
|
|
/**
|
|
* Disconnect a specific client.
|
|
*/
|
|
public async disconnectClient(clientId: string): Promise<void> {
|
|
await this.bridge.sendCommand('disconnectClient', { clientId });
|
|
}
|
|
|
|
/**
|
|
* Generate a new Noise keypair.
|
|
*/
|
|
public async generateKeypair(): Promise<IVpnKeypair> {
|
|
return this.bridge.sendCommand('generateKeypair', {} as Record<string, never>);
|
|
}
|
|
|
|
/**
|
|
* Stop the daemon bridge.
|
|
*/
|
|
public stop(): void {
|
|
this.bridge.stop();
|
|
}
|
|
|
|
/**
|
|
* Whether the bridge is running.
|
|
*/
|
|
public get running(): boolean {
|
|
return this.bridge.running;
|
|
}
|
|
}
|