From b46c20b0d02a45882477ac710d76c180403f4da8 Mon Sep 17 00:00:00 2001 From: Vantz Stockwell Date: Tue, 17 Mar 2026 11:25:03 -0400 Subject: [PATCH] =?UTF-8?q?feat:=20wire=20all=20remaining=20stubs=20?= =?UTF-8?q?=E2=80=94=20settings,=20SFTP,=20RDP,=20credentials,=20FreeRDP?= =?UTF-8?q?=20callbacks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Four-agent parallel deployment: 1. Settings persistence — all 5 settings wired to SettingsService.Set/Get, theme picker persists, update check calls real UpdateService, external links use Browser.OpenURL, SFTP file open/save calls real service, Quick Connect creates real connection + session, exit uses Wails quit 2. SSH key management — credential dropdown in ConnectionEditDialog, collapsible "Add New Credential" panel with password/SSH key modes, CredentialService proxied through WraithApp (vault-locked guard), new CreateSSHKeyCredential method for atomic key+credential creation 3. RDP frontend wiring — useRdp.ts calls real RDPGetFrame/SendMouse/ SendKey/SendClipboard via Wails bindings, ConnectRDP on WraithApp resolves credentials and builds RDPConfig, session store handles RDP protocol, frame pipeline uses polling at 30fps 4. FreeRDP3 callback registration — PostConnect and BitmapUpdate callbacks via syscall.NewCallback, GDI mode for automatic frame decoding, freerdp_context_new() call added, settings/input/context pointers extracted from struct offsets, BGRA→RGBA channel swap in frame copy, event loop fixed to pass context not instance 11 files changed. Zero build errors. Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/screenshots/wraith-final.png | Bin 81409 -> 0 bytes .../src/components/common/SettingsModal.vue | 74 ++- .../src/components/common/ThemePicker.vue | 5 +- .../connections/ConnectionEditDialog.vue | 271 ++++++++++- .../src/components/editor/EditorWindow.vue | 17 +- frontend/src/composables/useRdp.ts | 119 ++--- frontend/src/layouts/MainLayout.vue | 87 ++-- frontend/src/stores/session.store.ts | 18 +- internal/app/app.go | 123 +++++ internal/credentials/service.go | 28 ++ internal/rdp/freerdp_windows.go | 458 +++++++++++++++++- 11 files changed, 1056 insertions(+), 144 deletions(-) delete mode 100644 docs/screenshots/wraith-final.png diff --git a/docs/screenshots/wraith-final.png b/docs/screenshots/wraith-final.png deleted file mode 100644 index 674a7d744c02687d03dc6ad353a5e50ce19f3a14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 81409 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 E2Wcicr~m)} diff --git a/frontend/src/components/common/SettingsModal.vue b/frontend/src/components/common/SettingsModal.vue index e309797..7a44ebe 100644 --- a/frontend/src/components/common/SettingsModal.vue +++ b/frontend/src/components/common/SettingsModal.vue @@ -268,8 +268,11 @@ diff --git a/frontend/src/composables/useRdp.ts b/frontend/src/composables/useRdp.ts index 17a2a74..4e8a47b 100644 --- a/frontend/src/composables/useRdp.ts +++ b/frontend/src/composables/useRdp.ts @@ -1,4 +1,7 @@ import { ref, onBeforeUnmount } from "vue"; +import { Call } from "@wailsio/runtime"; + +const APP = "github.com/vstockwell/wraith/internal/app.WraithApp"; /** * RDP mouse event flags — match the Go constants in internal/rdp/input.go @@ -199,71 +202,50 @@ export function useRdp(): UseRdpReturn { let frameCount = 0; /** - * Fetch the current frame from the backend. - * TODO: Replace with Wails binding — RDPService.GetFrame(sessionId) - * Mock: generates a gradient test pattern. + * Fetch the current frame from the Go RDP backend. + * + * Go's GetFrame returns []byte (raw RGBA, Width*Height*4 bytes). + * Wails serialises Go []byte as a base64-encoded string over the JSON bridge, + * so we decode it back to a Uint8ClampedArray and wrap it in an ImageData. */ async function fetchFrame( sessionId: string, width = 1920, height = 1080, ): Promise { - void sessionId; - - // Mock: generate a test frame with animated gradient - const imageData = new ImageData(width, height); - const data = imageData.data; - const t = Date.now() / 1000; - - for (let y = 0; y < height; y++) { - for (let x = 0; x < width; x++) { - const i = (y * width + x) * 4; - const nx = x / width; - const ny = y / height; - const diag = (nx + ny) / 2; - - data[i + 0] = Math.floor(20 + diag * 40); // R - data[i + 1] = Math.floor(25 + (1 - diag) * 30); // G - data[i + 2] = Math.floor(80 + diag * 100); // B - data[i + 3] = 255; // A - - // Grid lines every 100px - if (x % 100 === 0 || y % 100 === 0) { - data[i + 0] = Math.min(data[i + 0] + 20, 255); - data[i + 1] = Math.min(data[i + 1] + 20, 255); - data[i + 2] = Math.min(data[i + 2] + 20, 255); - } - } + let raw: string; + try { + raw = (await Call.ByName(`${APP}.RDPGetFrame`, sessionId)) as string; + } catch { + // Session may not be connected yet or backend returned an error — skip frame + return null; } - // Animated pulsing circle at center - const cx = width / 2; - const cy = height / 2; - const radius = 40 + 20 * Math.sin(t * 2); + if (!raw) return null; - for (let dy = -70; dy <= 70; dy++) { - for (let dx = -70; dx <= 70; dx++) { - const dist = Math.sqrt(dx * dx + dy * dy); - if (dist <= radius && dist >= radius - 4) { - const px = Math.floor(cx + dx); - const py = Math.floor(cy + dy); - if (px >= 0 && px < width && py >= 0 && py < height) { - const i = (py * width + px) * 4; - data[i + 0] = 88; - data[i + 1] = 166; - data[i + 2] = 255; - data[i + 3] = 255; - } - } - } + // Decode base64 → binary string → Uint8ClampedArray + const binaryStr = atob(raw); + const bytes = new Uint8ClampedArray(binaryStr.length); + for (let i = 0; i < binaryStr.length; i++) { + bytes[i] = binaryStr.charCodeAt(i); } - return imageData; + // Validate: RGBA requires exactly width * height * 4 bytes + const expected = width * height * 4; + if (bytes.length !== expected) { + console.warn( + `[useRdp] Frame size mismatch: got ${bytes.length}, expected ${expected}`, + ); + return null; + } + + return new ImageData(bytes, width, height); } /** - * Send a mouse event. - * TODO: Replace with Wails binding — RDPService.SendMouse(sessionId, x, y, flags) + * Send a mouse event to the remote session. + * Calls Go WraithApp.RDPSendMouse(sessionId, x, y, flags). + * Fire-and-forget — mouse events are best-effort. */ function sendMouse( sessionId: string, @@ -271,16 +253,17 @@ export function useRdp(): UseRdpReturn { y: number, flags: number, ): void { - void sessionId; - void x; - void y; - void flags; - // Mock: no-op — will call Wails binding when wired + Call.ByName(`${APP}.RDPSendMouse`, sessionId, x, y, flags).catch( + (err: unknown) => { + console.warn("[useRdp] sendMouse failed:", err); + }, + ); } /** - * Send a key event, mapping JS code to RDP scancode. - * TODO: Replace with Wails binding — RDPService.SendKey(sessionId, scancode, pressed) + * Send a key event, mapping the JS KeyboardEvent.code to an RDP scancode. + * Calls Go WraithApp.RDPSendKey(sessionId, scancode, pressed). + * Unmapped keys are silently dropped — not every JS key has an RDP scancode. */ function sendKey( sessionId: string, @@ -290,19 +273,23 @@ export function useRdp(): UseRdpReturn { const scancode = jsKeyToScancode(code); if (scancode === null) return; - void sessionId; - void pressed; - // Mock: no-op — will call Wails binding when wired + Call.ByName(`${APP}.RDPSendKey`, sessionId, scancode, pressed).catch( + (err: unknown) => { + console.warn("[useRdp] sendKey failed:", err); + }, + ); } /** - * Send clipboard text to the remote session. - * TODO: Replace with Wails binding — RDPService.SendClipboard(sessionId, text) + * Send clipboard text to the remote RDP session. + * Calls Go WraithApp.RDPSendClipboard(sessionId, text). */ function sendClipboard(sessionId: string, text: string): void { - void sessionId; - void text; - // Mock: no-op + Call.ByName(`${APP}.RDPSendClipboard`, sessionId, text).catch( + (err: unknown) => { + console.warn("[useRdp] sendClipboard failed:", err); + }, + ); } /** diff --git a/frontend/src/layouts/MainLayout.vue b/frontend/src/layouts/MainLayout.vue index 0b999a0..8d02373 100644 --- a/frontend/src/layouts/MainLayout.vue +++ b/frontend/src/layouts/MainLayout.vue @@ -212,6 +212,7 @@