initial
This commit is contained in:
107
ts/smartvpn.classes.vpnserver.ts
Normal file
107
ts/smartvpn.classes.vpnserver.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user