Add EditorWindow component with CodeMirror 6 using one-dark theme.
Detects language from file extension (js/ts/jsx/tsx, json, py, md)
via dynamic imports for code splitting. Features unsaved changes
indicator (yellow dot), Save button (TODO: SFTPService.WriteFile),
and Close button. Renders as an inline panel above the terminal.
File clicks in FileTree open the editor with mock content. Editor
re-creates when file path changes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add HostKeyDialog modal with two modes: new host (informational with
blue accent) and changed key (warning with red accent). Shows
hostname, key type, and fingerprint in monospace. ConnectionTree
now has @dblclick handler that calls sessionStore.connect(). Session
store gains a connect() method that looks up the connection, checks
for existing sessions, and creates a mock session tab. Pre-loaded
mock sessions removed — sessions start empty and are created on
double-click.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add useSftp composable with mock directory listings, path navigation,
and refresh. FileTree component shows path bar, toolbar (upload,
download, new folder, refresh, delete icons), file entries with
icons, humanized sizes, and dates. TransferProgress component shows
expandable transfer list with progress bars. SidebarToggle now
uses v-model to emit tab changes. MainLayout switches between
ConnectionTree and FileTree based on sidebar tab, and includes
TransferProgress panel. File double-click emits openFile event
for the editor integration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add useTerminal composable wrapping xterm.js with fit, search, and
web-links addons. TerminalView component mounts into a container div
and auto-fits on resize. SessionContainer now renders TerminalView
for SSH sessions using v-show to keep terminals alive across tab
switches. MobaXTerm Classic-inspired color theme. Data input and
resize events are placeholder TODOs for Wails SSHService bindings.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add SSHService, SFTPService, and CredentialService to the WraithApp
struct. SSH service uses a no-op output handler (Wails event emission
will be wired at runtime). CredentialService is created lazily after
vault unlock. Both SSH and SFTP services are registered with Wails
in main.go.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Gitea Actions workflow that builds wraith.exe for Windows amd64,
signs it with an Azure Key Vault certificate via jsign, and uploads
the signed binary with a version.json manifest.
Also adds a `version` var to main.go for -ldflags injection at build time.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three-panel layout with 240px sidebar, tabbed session area, and
status bar. Sidebar has Connections/SFTP toggle, search input, and
collapsible group tree with protocol-colored dots. Tab bar shows
active sessions with color-coded indicators and close buttons.
Status bar displays connection info, theme, encoding, and terminal
size. All backed by connection and session Pinia stores with mock
data until Wails bindings are connected.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add the unlock screen that gates entry to the main app. Includes
app store (unlocked state, firstRun flag), a centered dark-themed
unlock card with WRAITH branding, password validation for first-run
vault creation, and conditional rendering in App.vue.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Create WraithApp struct in internal/app that initializes SQLite,
runs migrations, seeds themes, and exposes vault management methods
(IsFirstRun, CreateVault, Unlock, IsUnlocked) to the frontend.
Register WraithApp, ConnectionService, ThemeService, and SettingsService
as Wails v3 bound services.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Claude Code integration as the first Wraith plugin: terminal I/O, SFTP
file access, CodeMirror handoff, and session context awareness. Proves
the plugin architecture and serves as the reference implementation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Keyboard events now check if focus is on an input, textarea, select, or
contenteditable element and let the browser handle them normally. Also
fixes connectRdp type (Awaited<>) and async onMounted in RdpCanvas.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Frontend sends verifyId with host-key-accept so backend can correlate the
verification response. Backend tracks pre-ready connections in pendingClients
map, destroys on error/disconnect, and guards against calling verify() after
the connection has already timed out or errored (_destruct crash fix).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
63 tests across 8 spec files, all passing. Removes 2 stale stub files from
backend/test/ that were incompatible with the current async EncryptionService
and 3-argument AuthService constructor. New suite lives in src/ co-located
with source files per NestJS convention.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
28 tests across 4 spec files. Vitest + happy-dom configured with Nuxt auto-import
shims ($$fetch, navigateTo, defineNuxtRouteMiddleware) so stores and composables
resolve cleanly outside the Nuxt runtime.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Default protocol color strips on all host cards (wraith-blue for SSH, purple for RDP)
- Deterministic tag colors from 8-color palette (teal, amber, violet, rose, emerald, sky, orange, indigo)
- Last-connected recency coloring (green=today, amber=this week, gray=older)
- Section header dots (wraith-400 for Recent, gray for All Hosts)
- Active nav link highlighting (wraith-400)
- Group headers get subtle wraith-500 left border accent
- Tree host dots default to protocol color instead of gray
- Fixed rogue modal using hardcoded #1a1a2e/#e94560 — now uses design system
- Fixed sky-600 save buttons → wraith-600 for brand consistency
- Credential type badges: SSH Key=wraith, Password=amber (was purple/blue)
- Colored tags in right sidebar detail panel
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
C-2: JWT moved from localStorage to httpOnly cookie (eliminates XSS token theft)
C-3: WebSocket auth via short-lived single-use tickets (JWT no longer in URLs)
H-1: JWT expiry reduced from 7 days to 4 hours
H-3: TOTP secrets encrypted at rest with vault EncryptionService (auto-migrates plaintext)
H-6: Rate limiting via @nestjs/throttler (60 req/min global, tighten on auth)
H-8: Constant-time login — Argon2id verify runs against dummy hash for non-existent users
H-9: Password hashing upgraded from bcrypt(10) to Argon2id (auto-upgrades on login)
H-10: Credential list API no longer returns encrypted blobs
H-16: Admin pages use Nuxt route middleware instead of client-side guard
Plus: auth bootstrap plugin, cookie-parser middleware, all frontend Authorization headers removed
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- H-5: Redact keystroke data from WS message logs — log type/sessionId/bytes only
- H-4: Remove private key content/length/passphrase logging, replace with safe single line
- H-14: Remove username@hostname from password auth log, use hostId only
- M-1: Enforce session ownership in data/resize/disconnect handlers via clientSessions map
- C-5: Real host key verification flow — MITM protection blocks changed keys immediately,
new hosts ask user via host-key-verify WS message with 30s timeout, pending map resolves on
host-key-accept/host-key-reject response
- H-13: Shell PROMPT_COMMAND/precmd injection is now opt-in via options.enableCwdTracking
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
BREAKING CHANGE (forward-only): New credentials/keys encrypted with v2
(Argon2id-derived AES-256-GCM). Existing v1 records decrypt transparently.
- Argon2id params: 64 MiB memory, 3 iterations, 4 parallelism (OWASP)
- Per-record 16-byte salt stored in ciphertext format
- v2 format: v2:<salt>:<iv>:<authTag>:<ciphertext>
- Backwards compatible: v1 records still decrypt with raw key
- Admin endpoint POST /api/credentials/migrate-v2 upgrades all v1→v2
- Added docs/FUTURE-FEATURES.md with remaining spec gaps
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Monaco can't mount in a popup window — it references document.activeElement
from the main window context, causing cross-window DOM errors.
Replaced with a fullscreen overlay teleported to <body>:
- Same dark theme toolbar with save/close/dirty indicator
- Ctrl+S to save, Esc to close
- Status bar shows language and keyboard shortcuts
- File tree stays visible underneath (overlay dismisses to it)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>