From 3dcdca18a3582bd13b990b4d5b0d15da5b207937 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Thu, 30 Oct 2025 14:33:21 -0600 Subject: [PATCH] endpoint for getting config --- .../app/routes/home/routes/devices/index.ts | 60 ++++++++++--------- .../src/app/services/api/api.service.ts | 25 ++++---- .../src/app/services/api/live-api.service.ts | 16 +++-- .../src/app/services/api/mock-api.service.ts | 24 ++++++++ 4 files changed, 79 insertions(+), 46 deletions(-) diff --git a/web/projects/start-tunnel/src/app/routes/home/routes/devices/index.ts b/web/projects/start-tunnel/src/app/routes/home/routes/devices/index.ts index f7a385a86..d348f793f 100644 --- a/web/projects/start-tunnel/src/app/routes/home/routes/devices/index.ts +++ b/web/projects/start-tunnel/src/app/routes/home/routes/devices/index.ts @@ -90,7 +90,7 @@ import { TunnelData, WgServer } from 'src/app/services/patch-db/data-model' tuiOption iconStart="@tui.settings" new - (click)="config.set(true)" + (click)="onConfig(device)" > View Config @@ -163,7 +163,7 @@ import { TunnelData, WgServer } from 'src/app/services/patch-db/data-model' - +

Device Config

@if (segmented?.activeItemIndex) { - + } @else { Download @@ -234,10 +234,14 @@ export default class Devices { private readonly loading = inject(LoadingService) private readonly patch = inject>(PatchDB) - protected readonly mock = MOCK - protected readonly href = `data:text/plain;charset=utf-8,${encodeURIComponent(MOCK)}` protected readonly dialog = signal(false) - protected readonly config = signal(false) + + protected readonly showConfig = signal(false) + protected readonly config = signal('') + protected readonly href = computed( + () => `data:text/plain;charset=utf-8,${encodeURIComponent(this.config())}`, + ) + protected readonly editing = signal(false) protected readonly subnets = toSignal( @@ -279,18 +283,36 @@ export default class Devices { ip: ['', Validators.required], }) - protected onAdd(): void { + protected onAdd() { this.editing.set(false) this.form.reset() this.dialog.set(true) } - protected onEdit(device: MappedDevice): void { + protected onEdit(device: MappedDevice) { this.editing.set(true) this.form.reset(device) this.dialog.set(true) } + async onConfig(device: MappedDevice) { + const loader = this.loading.open().subscribe() + try { + const config = await this.api.showDeviceConfig({ + subnet: device.subnet.range, + ip: device.ip, + }) + + this.config.set(config) + this.showConfig.set(true) + } catch (e) { + console.log(e) + } finally { + loader.unsubscribe() + this.dialog.set(false) + } + } + protected async onSave() { if (this.form.invalid) { tuiMarkControlAsTouchedAndValidate(this.form) @@ -353,21 +375,3 @@ type MappedDevice = { ip: string name: string } - -const MOCK = `[Interface] -# Server's private IP address for the WireGuard VPN subnet -Address = 10.20.10.1/24 -# UDP port WireGuard listens on -ListenPort = 33333 -# Server private key (generated) -PrivateKey = 4K68mdpQWdEz/FpdVuRoZYgWpQgpW63J9GFzn+iOulQ= - -# Commands to run after starting/stopping WireGuard tunnel to enable forwarding and NAT (example) -PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE -PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE - -# Add client peers below with their public keys and allowed IPs -[Peer] -# Client public key -PublicKey = MQBiYHxAj7u8paj3L4w4uav3P/9YBPbaN4gkWn90SSs= -# Allowed client IP address within VPN subnet` diff --git a/web/projects/start-tunnel/src/app/services/api/api.service.ts b/web/projects/start-tunnel/src/app/services/api/api.service.ts index 4ffa4ec7d..b65a59d75 100644 --- a/web/projects/start-tunnel/src/app/services/api/api.service.ts +++ b/web/projects/start-tunnel/src/app/services/api/api.service.ts @@ -8,22 +8,23 @@ import { Observable } from 'rxjs' }) export abstract class ApiService { abstract openWebsocket$(guid: string): Observable - abstract subscribe(): Promise + abstract subscribe(): Promise // db.subscribe // auth - abstract login(params: LoginReq): Promise - abstract logout(): Promise - abstract setPassword(params: LoginReq): Promise + abstract login(params: LoginReq): Promise // auth.login + abstract logout(): Promise // auth.logout + abstract setPassword(params: LoginReq): Promise // auth.set-password // subnets - abstract addSubnet(params: UpsertSubnetReq): Promise - abstract editSubnet(params: UpsertSubnetReq): Promise - abstract deleteSubnet(params: DeleteSubnetReq): Promise + abstract addSubnet(params: UpsertSubnetReq): Promise // subnet.add + abstract editSubnet(params: UpsertSubnetReq): Promise // subnet.add + abstract deleteSubnet(params: DeleteSubnetReq): Promise // subnet.remove // devices - abstract addDevice(params: UpsertDeviceReq): Promise - abstract editDevice(params: UpsertDeviceReq): Promise - abstract deleteDevice(params: DeleteDeviceReq): Promise + abstract addDevice(params: UpsertDeviceReq): Promise // device.add + abstract editDevice(params: UpsertDeviceReq): Promise // device.add + abstract deleteDevice(params: DeleteDeviceReq): Promise // device.remove + abstract showDeviceConfig(params: DeleteDeviceReq): Promise // device.show-config // forwards - abstract addForward(params: AddForwardReq): Promise - abstract deleteForward(params: DeleteForwardReq): Promise + abstract addForward(params: AddForwardReq): Promise // forward.add + abstract deleteForward(params: DeleteForwardReq): Promise // forward.remove } export type SubscribeRes = { diff --git a/web/projects/start-tunnel/src/app/services/api/live-api.service.ts b/web/projects/start-tunnel/src/app/services/api/live-api.service.ts index 50dfec710..45c224ffa 100644 --- a/web/projects/start-tunnel/src/app/services/api/live-api.service.ts +++ b/web/projects/start-tunnel/src/app/services/api/live-api.service.ts @@ -70,7 +70,7 @@ export class LiveApiService extends ApiService { } async deleteSubnet(params: DeleteSubnetReq): Promise { - return this.rpcRequest({ method: 'subnet.delete', params }) + return this.rpcRequest({ method: 'subnet.remove', params }) } // devices @@ -84,27 +84,31 @@ export class LiveApiService extends ApiService { } async deleteDevice(params: DeleteDeviceReq): Promise { - return this.rpcRequest({ method: 'device.delete', params }) + return this.rpcRequest({ method: 'device.remove', params }) + } + + async showDeviceConfig(params: DeleteDeviceReq): Promise { + return this.rpcRequest({ method: 'device.show-config', params }) } // forwards async addForward(params: AddForwardReq): Promise { - return this.rpcRequest({ method: 'forward.create', params }) + return this.rpcRequest({ method: 'forward.add', params }) } async deleteForward(params: DeleteForwardReq): Promise { - return this.rpcRequest({ method: 'forward.delete', params }) + return this.rpcRequest({ method: 'forward.remove', params }) } // private private async upsertSubnet(params: UpsertSubnetReq): Promise { - return this.rpcRequest({ method: 'subnet.upsert', params }) + return this.rpcRequest({ method: 'subnet.add', params }) } private async upsertDevice(params: UpsertDeviceReq): Promise { - return this.rpcRequest({ method: 'device.upsert', params }) + return this.rpcRequest({ method: 'device.add', params }) } private async rpcRequest( diff --git a/web/projects/start-tunnel/src/app/services/api/mock-api.service.ts b/web/projects/start-tunnel/src/app/services/api/mock-api.service.ts index a7d84eae7..1111a1b77 100644 --- a/web/projects/start-tunnel/src/app/services/api/mock-api.service.ts +++ b/web/projects/start-tunnel/src/app/services/api/mock-api.service.ts @@ -161,6 +161,12 @@ export class MockApiService extends ApiService { return null } + async showDeviceConfig(params: DeleteDeviceReq): Promise { + await pauseFor(1000) + + return MOCK_CONFIG + } + async addForward(params: AddForwardReq): Promise { await pauseFor(1000) @@ -202,3 +208,21 @@ export class MockApiService extends ApiService { function replaceSlashes(val: string) { return val.replace(new RegExp('/', 'g'), '~1') } + +const MOCK_CONFIG = `[Interface] +# Server's private IP address for the WireGuard VPN subnet +Address = 10.20.10.1/24 +# UDP port WireGuard listens on +ListenPort = 33333 +# Server private key (generated) +PrivateKey = 4K68mdpQWdEz/FpdVuRoZYgWpQgpW63J9GFzn+iOulQ= + +# Commands to run after starting/stopping WireGuard tunnel to enable forwarding and NAT (example) +PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE + +# Add client peers below with their public keys and allowed IPs +[Peer] +# Client public key +PublicKey = MQBiYHxAj7u8paj3L4w4uav3P/9YBPbaN4gkWn90SSs= +# Allowed client IP address within VPN subnet`