Add app_version workflow_dispatch input for specifying custom version during manual builds. Implement version application step that validates input format and updates package.json, tauri.conf.json, and Cargo.toml with requested version string.
Add artifact name suffix based on provided version to distinguish versioned build outputs. Append version to NexaVPN-windows-installer and NexaVPN-windows
Add install-runtime command to tunnel-helper for automated WireGuard installation on Windows. Download and bundle official WireGuard MSI during build process with automatic version discovery from wireguard.com.
Add ensure_windows_runtime_installed checks before connect/disconnect operations. Implement install_windows_runtime with UAC elevation prompt and install_windows_runtime_direct for MS
Add statuspage package with service, handler, and types for exposing platform health. Implement GET /api/v1/status endpoint returning operational status, component health (API, database, gateway runtime), and control plane summary counts.
Add Service.Snapshot method querying database connectivity, user/device/gateway/service/policy counts, connected device count via handshake timestamps, and gateway runtime tel
Remove four-card stats grid section and consolidate key metrics into hero banner. Add Policies mini-stat showing active and service-based policy counts. Replace revoked device count with total traffic summary in Devices mini-stat.
Update hero grid layout from 3-column to 2-column metrics display. Add owner_username to traffic leaders and recent devices lists for better user context.
Remove dashboard
Add connection_status and owner_username fields to Device model. Join users table in ListByUser and ListAll queries to populate owner_username from username column.
Parse latest_handshake_at from gateway runtime snapshots and aggregate across peers. Add isPeerConnected helper with 3-minute handshake timeout threshold. Set connection_status to "connected" or "disconnected" based on handsh
Add traffic overview card to dashboard main grid showing total received, sent, and combined tunnel throughput. Display top 5 devices with horizontal bar chart visualization proportional to busiest device total.
Calculate busiestDeviceTotal from topDevices max combined rx/tx bytes. Add dashboard-traffic-summary grid with three stat cards, dashboard-traffic-list with device rows showing name
Replace placeholder dashboard with full operational overview including user/device/gateway summary hero, four-metric stats grid, top devices by traffic, recent audit events stream, service exposure posture, and gateway enforcement note.
Add formatBytes and formatRelativeDate utility functions for human-readable data display. Fetch users, devices, gateways, policies, services, and audit data with
Group navigation items into three sections with section titles. Add nav-sections and nav-section containers with gap spacing and uppercase section title styling.
Remove topbar icon wrapper and associated styling. Center sidebar brand logo with justify-content and add bottom padding. Adjust nav margin-top to 0 and move gap spacing to nav-sections level.
Move page-title-icon dimensions
Replace inline SVG brand glyph with NexaVPN_Logo.png image in sidebar. Simplify brand-block to sidebar-brand with logo image styling.
Update CSS color variables from green accent (#74e0b8) to cyan (#44e6e7) with violet (#8d5bff) and blue (#4a8cff) accents. Adjust background gradients to use new cyan-violet-blue palette with updated opacity values.
Update nav-link hover and active states with cyan-blue gradient background. Modify sidebar background
Add lucide-react dependency and create app-icons module with icon mappings for all admin sections. Replace logo images with inline SVG brand glyph component.
Update Layout component with icon-enhanced navigation links including chevron indicators and hover states. Add topbar icon wrapper with gradient background styling.
Redesign Page component header with icon, eyebrow text, and improved title block layout. Add page
Add dnsServersForProfile and dnsServersForPeer helpers with conditional DNS server selection based on service presence. Use NEXAVPN_CLIENT_DNS_SERVERS override when services are configured, otherwise fall back to DEFAULT_DNS_SERVERS or gateway base DNS servers.
Replace direct gateway DNS server usage in Enroll and applyCurrentPolicy with profileDNSServers variable. Update BuildSyncBundle to scan gateway DNS servers separately
Add DELETE /admin/devices/{id} endpoint with cascade deletion of device records, WireGuard peers, IP allocations, and device access profile settings. Update device status to 'deleted' and set deleted_at timestamp while preserving revoked_at if already set.
Add deleteDevice API method and delete button to devices page with query invalidation for both devices and device-profile lists. Record admin.device.deleted audit
Replace bufio.Reader.Peek calls with io.ReadFull for header and record body reading. Allocate header and full buffers explicitly and copy header into full buffer before reading remaining bytes. Remove redundant byte slice copy when returning full ClientHello data.
Extract NEXAVPN_VPN_DNS_ADDR environment variable to listenAddr with empty string validation and :53 fallback. Add bind directive to Corefile template using listenAddr variable. Keep zone definition as .:53 for all-domain matching while controlling bind address separately.
Add configDir, corefilePath, and overridesPath constants pointing to /tmp/nexavpn-vpn-dns directory. Update all file path references in writeCorefile and refreshOverrides to use new constants instead of hardcoded /etc/coredns paths.
Move default 172.16.10.0/24 destination assignment to after profile resolution and only apply when both selectedDestinations and services are empty. Extract selectedServices calculation before conditional check in applyCurrentPolicy.
Add nftables input chain to gateway with per-peer filtering. Accept established connections and non-WireGuard traffic. Allow DNS queries to configured
Add -L flag to cp commands to dereference symlinks and copy actual binaries instead of symlink references when bundling wg and wg-quick tools for aarch64-apple-darwin target.
Add wait_for_macos_tunnel_running helper with 6-second polling loop checking tunnel_service_is_active after wg-quick up command. Retry up to 12 times with 500ms intervals before returning error if interface not verified.
Add wg and wg-quick bundling to build-tunnel-helper.sh for aarch64-apple-darwin target. Check for wireguard-tools installation and copy binaries to output directory with execute permissions.
Implement find_wg_quick helper with bundled tool detection and standard path fallbacks. Add bundled_macos_tool to check for tools in current executable directory. Update connect_direct and disconnect_direct to use explicit
Add macos-desktop-client.yml workflow with manual dispatch trigger running on macos-arm64 runner. Install Node.js 22 and Rust toolchain with aarch64-apple-darwin target. Build bundled tunnel helper and Tauri application bundle, then upload .app, .dmg, and raw build artifacts.
Fix tunnel_metrics handler to clone app handle before spawn_blocking to prevent ownership issues when passing to tunnel
Add ServiceDNSRecord type and gateway API endpoint to expose active service domain-to-IP mappings. Implement ListServiceDNSRecords repository method querying services table with proxy_ip resolution using effectiveAccessProxyIP helper.
Add vpn-dns microservice built on CoreDNS with periodic sync from backend API. Generate Corefile with configurable upstream DNS servers and hosts plugin for service overrides.
Add ServiceCatalogItem type and services CRUD API endpoints (list, create, update, delete). Extend Policy type to include services array with domain, upstream_ip, proxy_ip, and ports metadata.
Add ServicesPage component with table view and create/edit modals for managing service definitions. Include service name, domain, proxy, and upstream columns with port parsing logic.
Integrate service selection
Move tunnel_manager::connect and disconnect calls into spawn_blocking tasks to prevent blocking async runtime. Clone app handle and profile path before spawning. Add map_err for task join failures.
Add tunnelActionPending state to track in-progress tunnel operations. Pass busy prop to AppHeader and disable sync/logout/connect buttons during tunnel actions. Update connect button text to show "
Add osslsigncode dependency and implement three-step signing workflow. Decode base64-encoded PFX certificate from secrets, sign bundled tunnel helper before build, then sign desktop executable and NSIS installer after build. Use configurable timestamp URL with DigiCert fallback. Clean up certificate file in always-run step to prevent secret leakage.
Add SelectOwnProfile handler to allow users to choose from available access profiles. Store selected profile ID per device in settings table with device_access_profile category. Implement GetSelectedProfileID and SetSelectedProfileID repository methods using JSONB storage.
Add ListSelectableProfiles to policy repository and service to query user/group/device-specific profiles ordered by priority. Filter gateway
Extract App.tsx logic into reusable components: AppHeader, ResourcePanel, StatusCard, StatTile, and ActionButton. Replace inline markup with component composition and props-based data flow.
Redesign visual system with enhanced gradients, refined color palette, and improved spacing. Update app-shell grid layout with 18px gaps and 1140px max width. Add radial gradient overlays and linear background
Replace direct cargo xwin execution with PATH traversal to locate actual cargo-xwin binary outside script's own directory. Add error handling with installation instructions when binary not found. Skip script's own directory and empty PATH entries during search.
Remove automatic push trigger on main/master branches and desktop-client path changes, keeping only manual workflow_dispatch. Remove self-hosted runner requirement to allow running on any Linux runner.
Add workflow to build Windows desktop client using cargo-xwin on Linux runners. Install Node.js 22, Rust with x86_64-pc-windows-msvc target, and required system dependencies including NSIS for installer creation. Build bundled Windows tunnel helper and desktop client installer, then upload both NSIS installer artifacts and raw executables.
Add align-items: start to body-grid and align-content: start to status-grid to prevent vertical stretching and maintain top alignment. Reduce responsive breakpoint from 960px to 760px to match new default window width.
Reduce padding, gaps, and font sizes across all components. Change html/body/root from min-height to fixed height with overflow hidden. Decrease app-frame padding from 18px to 12px and add grid-template-rows with overflow handling. Reduce brand lockup logo from 54px to 44px and adjust gaps throughout. Decrease button padding, surface padding, and card padding. Reduce body-grid sidebar from 290px to 250px.
Reduce default window dimensions from 1120x760 to 940x640 pixels and disable resizing. Remove TunnelMetrics and RawTunnelMetrics types, formatDataSize and normalizeTunnelMetrics helpers, and all transfer statistics tracking from App component. Replace refreshTunnelMetrics with simpler refreshTunnelStatus that only queries tunnel active state. Remove received/sent data display cards from status panel and eliminate metrics
Add png dependency and tauri image-png feature to support custom tray icon rendering. Load base disconnected icon from bundled PNG and generate connected variant with green circular badge containing white checkmark overlay. Implement draw_check_badge, draw_line, and blend_pixel helpers using Bresenham's line algorithm for badge rendering. Store both icon variants and TrayIcon reference in TrayState and update icon
Replace tauri::async_runtime::spawn with std::thread::spawn for periodic tray menu refresh background task and change async sleep to blocking thread sleep. Prefix unused state parameter with underscore in sync_profile command to suppress compiler warnings.
Add background task to refresh tray menu every 5 seconds to keep status display current. Add RawTunnelMetrics type and normalizeTunnelMetrics helper to handle both snake_case and camelCase field names from backend responses. Update refreshTunnelMetrics to normalize metrics before setting state and explicitly cast active status to boolean.
Add read_transfer_totals_from_show function to parse transfer statistics from wg show output as fallback when wg show dump command fails. Add parse_human_wireguard_bytes helper to convert human-readable byte values (B, KiB, MiB, GiB, TiB) to u64. Update read_transfer_totals to call fallback instead of returning error when dump command fails.
Replace metrics query in is_active with direct tunnel_backend status command call to avoid unnecessary metrics overhead when only checking tunnel state. Parse status command stdout and compare against "active" string case-insensitively. Add Windows CREATE_NO_WINDOW flag to status command execution.
Add fallback to tunnel_status when metrics query fails in current_metrics function, returning zero bytes with actual tunnel state. Update waitForTunnelStatus in frontend to use tunnel_status instead of tunnel_metrics for status polling and refresh metrics separately on success. Change CloseRequested window event handler to call app_handle().exit(0) instead of no-op. Replace "sc" with "sc.exe" in all Windows service command
Remove direct_windows_metrics, read_windows_metrics_from_show, parse_human_wireguard_bytes, and find_windows_wg functions from tunnel_manager.rs to rely on bundled backend for all metrics queries. Update find_wg_cli in tunnel-helper to return "wg.exe" as fallback when WireGuard installation paths don't exist, removing "wg" from candidate list.