Commit Graph

398 Commits

Author SHA1 Message Date
Alex P b388bc3c62 fix: reduce observer promotion delay from ~40s to ~11s
1. Terminal access permission check:
   - Add Permission.TERMINAL_ACCESS check to Web Terminal button
   - Prevents observer sessions from accessing terminal

2. Immediate websocket cleanup:
   - Close peer connection immediately when websocket errors
   - Previously waited 24+ seconds for ICE to transition from disconnected to failed
   - Now triggers session cleanup immediately on tab close

3. Immediate grace period validation:
   - Trigger validateSinglePrimary() immediately when grace period expires
   - Previously waited up to 10 seconds for next periodic validation
   - Eliminates unnecessary delay in observer promotion

Timeline improvement:
Before: Tab close → 6s (ICE disconnect) → 24s (ICE fail) → RemoveSession → 10s grace → up to 10s validation = ~50s total
After: Tab close → immediate peerConnection.Close() → immediate RemoveSession → 10s grace → immediate validation = ~11s total
2025-10-09 11:39:00 +03:00
Alex P 7901677551 fix: increase RPC rate limit from 20 to 100 per second
The previous limit of 20 RPC/second per session was too aggressive for
multi-session scenarios. During normal operation with multiple sessions,
legitimate RPC calls would frequently hit the rate limit, especially
during page refreshes or reconnections when sessions make bursts of calls
like getSessions, getPermissions, getLocalVersion, and getVideoState.

Increased the limit to 100 RPC/second per session, which still provides
DoS protection while accommodating legitimate multi-session usage patterns.
2025-10-09 11:19:10 +03:00
Alex P ba8caf3448 debug: add detailed logging to trace session addition flow
Add comprehensive logging to identify why sessions fail to be added to
the session manager:
- Log entry/exit points in AddSession
- Track reconnection path execution
- Log max sessions limit checks
- Trace AddSession call and return in handleSessionRequest

This will help diagnose why sessions get stuck at ICE checking state
without being properly registered in the session manager.
2025-10-09 10:58:06 +03:00
Alex P 541d2bd77d fix: correct grace period protection during primary reconnection
- Remove broken bypass logic that caused immediate observer promotion on refresh
- Add session map debugging logs to validateSinglePrimary
- Ensure grace period properly blocks auto-promotion until expiration
2025-10-08 23:58:41 +03:00
Alex P f9ebd6ac2f feat: add strict observer-to-primary promotion controls and immediate logout promotion
Observer-to-primary promotion protections:
- Block auto-promotion during active primary grace periods
- Prevent creating multiple primary sessions simultaneously
- Validate transfer source is actual current primary
- Check for duplicate primaries before promotion

Immediate promotion on logout:
- Trigger validateSinglePrimary() immediately when primary disconnects
- Smart grace period bypass: allow promotion within 2 seconds of disconnect
- Provides instant promotion on logout while protecting against network blips

Enhanced validation and logging:
- Log session additions/removals with counts
- Display session IDs in validation logs for debugging
- Track grace period timing for smart bypass decisions
2025-10-08 23:44:10 +03:00
Alex P ffc4a2af21 fix: prevent getLocalVersion call for sessions without video permission
Sessions in pending mode do not have PermissionVideoView and should not
attempt to call getLocalVersion RPC method. Add permission check before
calling getLocalVersion to prevent unnecessary permission denied errors.
2025-10-08 21:42:59 +03:00
Alex P a1548fe5b1 feat: improve session approval workflow with re-request and rejection limits
Backend improvements:
- Keep denied sessions alive in pending mode instead of removing them
- Add requestSessionApproval RPC method for re-requesting access
- Fix security issue: preserve pending mode on reconnection for denied sessions
- Add MaxRejectionAttempts field to SessionSettings (default: 3, configurable 1-10)

Frontend improvements:
- Change "Try Again" button to "Request Access Again" that re-requests approval
- Add rejection counter with configurable maximum attempts
- Hide modal after max rejections; session stays pending in SessionPopover
- Add "Dismiss" button for primary to hide approval requests without deciding
- Add MaxRejectionAttempts control in multi-session settings page
- Reset rejection count when session is approved

This improves the user experience by allowing denied users to retry without
page reloads, while preventing spam with configurable rejection limits.
2025-10-08 21:37:02 +03:00
Alex P b0494e8eef security: prevent video access for pending/denied sessions
CRITICAL SECURITY FIX: Pending sessions (awaiting approval) were granted
video.view permission, allowing denied sessions to see video when they
reconnected.

**Vulnerability:**
1. Session requests access and enters pending mode
2. Primary session denies the request
3. Denied session clicks "Try Again" and reconnects
4. New session enters pending mode but has video.view permission
5. User can see video stream despite being denied

**Fix:**
Remove PermissionVideoView from SessionModePending. Pending sessions now
have NO permissions until explicitly approved by the primary session.

This ensures:
- Denied sessions cannot access video on reconnection
- Only approved sessions (observer/queued/primary) can view video
- CanReceiveVideo() properly blocks video frames for pending sessions
2025-10-08 20:26:18 +03:00
Alex P b322255684 fix: resolve all Go and TypeScript linting issues
Address all linting warnings and errors in both backend and frontend code:

**Go (golangci-lint):**
- Add error checking for ignored return values (errcheck)
- Remove unused RPC functions (unused)
- Fix import formatting (goimports)

**TypeScript/React (eslint):**
- Replace all 'any' and 'Function' types with proper type definitions
- Add RpcSendFunction type for consistent JSON-RPC callback signatures
- Fix React Hook exhaustive-deps warnings by adding missing dependencies
- Wrap functions in useCallback where needed to stabilize dependencies
- Remove unused variables and imports
- Remove empty code blocks
- Suppress exhaustive-deps warnings where intentional (with comments)

All linting now passes with 0 errors and 0 warnings.
2025-10-08 20:15:45 +03:00
Alex P cd70efb83f feat: multi-session support with role-based permissions
Implements concurrent WebRTC session management with granular permission control, enabling multiple users to connect simultaneously with different access levels.

Features:
- Session modes: Primary (full control), Observer (view-only), Queued, Pending
- Role-based permissions (31 permissions across video, input, settings, system)
- Session approval workflow with configurable access control
- Primary control transfer, request, and approval mechanisms
- Grace period reconnection (prevents interruption on network issues)
- Automatic session timeout and cleanup
- Nickname system with browser-based auto-generation
- Trust-based emergency promotion (deadlock prevention)
- Session blacklisting (prevents transfer abuse)

Technical Implementation:
- Centralized permission system (internal/session package)
- Broadcast throttling (100ms global, 50ms per-session) for DoS protection
- Defense-in-depth permission validation
- Pre-allocated event maps for hot-path performance
- Lock-free session iteration with snapshot pattern
- Comprehensive session management UI with real-time updates

New Files:
- session_manager.go (1628 lines) - Core session lifecycle
- internal/session/permissions.go (306 lines) - Permission rules
- session_permissions.go (77 lines) - Package integration
- datachannel_helpers.go (11 lines) - Permission denied handler
- errors.go (10 lines) - Error definitions
- 14 new UI components (session management, approval dialogs, overlays)

50 files changed, 5836 insertions(+), 442 deletions(-)
2025-10-08 18:52:45 +03:00
Marc Brooks b144d9926f
Remove the temporary directory after extracting buildkit (#874) 2025-10-07 11:57:26 +02:00
Aylen e755a6e1b1
Update openSUSE image reference to Leap 16.0 (#865) 2025-10-07 11:57:10 +02:00
Marc Brooks 99a8c2711c
Add podman support (#875)
Reimplement #141 since we've changed everything since
2025-10-07 11:43:25 +02:00
Marc Brooks 317218a682
docs: debugging UI builds because of ui symlink (#873)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-04 12:05:14 +02:00
Aveline 62b8dee170
chore: downgrade gin to v1.10.1 (#869) 2025-10-03 08:48:51 +02:00
Alex bdd6f4247b
fix: segfault in cGo 2025-10-02 19:15:03 +02:00
dependabot[bot] 63aa940f42
build(deps): bump github.com/prometheus/client_golang (#851)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-01 21:44:24 +02:00
dependabot[bot] 043ef9ddfc
build(deps): bump github.com/gin-gonic/gin from 1.10.1 to 1.11.0 (#852)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-01 21:44:08 +02:00
Marc Brooks 437f0b854a
upgrade ui packages (#861) 2025-10-01 21:43:46 +02:00
dependabot[bot] a45d55123c
build(deps): bump github.com/prometheus/common from 0.66.0 to 0.66.1 (#855)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-01 21:42:08 +02:00
dependabot[bot] 213e750e04
build(deps): bump github.com/coder/websocket from 1.8.13 to 1.8.14 (#854)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-01 21:41:48 +02:00
dependabot[bot] 6dcb0286e3
build(deps): bump golang.org/x/net from 0.43.0 to 0.44.0 (#856)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-01 21:40:57 +02:00
dependabot[bot] 74ccca0b1a
build(deps): bump golang.org/x/crypto from 0.41.0 to 0.42.0 (#849)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-01 21:39:31 +02:00
dependabot[bot] 0ad435475b
build(deps): bump github.com/go-co-op/gocron/v2 from 2.16.5 to 2.16.6 (#859)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-01 21:39:15 +02:00
dependabot[bot] 23bf3978fa
build(deps): bump actions/setup-go from 5 to 6 (#848)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-01 21:35:35 +02:00
Marc Brooks 9438ab7778
Fix the lazy loading for the settings page. (#837)
Move SettingsItem into it's own page

Packages upgraded
@headlessui/react 2.2.8 -> 2.2.9
framer-motion 12.23.18 -> 12/23/22
react-router 7.9.1 -> 7.9.3
@tailwindcss/typography 0.6.18 -> 0.5.19
@types/react 19.1.13 -> 19.1.14
eslint-plugin-react-refresh 0.4.21 -> 0.4.22
2025-10-01 11:43:15 +02:00
Alexander 12d31a3d8e
Add da_DK keyboard Layout (#839) 2025-09-30 14:27:17 +02:00
Aveline 657a177462
feat: jetkvm native in cGo 2025-09-29 14:09:30 +02:00
Marc Brooks 8f4081a5b1
Cleaning up action versions (#828) 2025-09-26 11:22:17 +02:00
Aveline 359778967f
chore: remove msgpack from gin dependency (#833) 2025-09-26 08:52:07 +02:00
Adam Shiervani 703625d59a
fix: faster paste speed (#824)
* fix: update delay handling in PasteModal component

- Changed default delay value to 20 and adjusted validation to allow values between 0 and 65534.
- Cleaned up code formatting for better readability.

* fix: formatting
2025-09-25 10:26:11 +02:00
Marc Brooks cb24ef6d4f
Update UI dependencies (#819) 2025-09-24 12:16:02 +02:00
Siyuan Miao fe77acd5f0 chore: bump to 0.4.8 2025-09-22 12:51:19 +02:00
Aveline 83caa8f82d
feat: get local version only (#813) 2025-09-19 13:45:59 +02:00
Adam Shiervani 27750b9cc2
feat: re-add keyboard and keypress report handlers to RPC (#811) 2025-09-18 17:33:08 +02:00
Adam Shiervani 5112bef19c
fix: remove unnecessary grow-0 utility from in keyboard (#810) 2025-09-18 17:02:08 +02:00
Siyuan Miao 1ffdca4fd6 build: use immediate assignment for VERSION_DEV and other vars 2025-09-18 15:41:39 +02:00
Siyuan Miao c6dba4d59f chore: bump to 0.4.7 2025-09-18 13:53:08 +02:00
Aveline afb146d78c
feat: release keyPress automatically (#796)
* feat: release keyPress automatically

* send keepalive when pressing the key

* remove logging

* clean up logging

* chore: use unreliable channel to send keepalive events

* chore: use ordered unreliable channel for pointer events

* chore: adjust auto release key interval

* chore: update logging for kbdAutoReleaseLock

* chore: update comment for KEEPALIVE_INTERVAL

* fix: should cancelAutorelease when pressed is true

* fix: handshake won't happen if webrtc reconnects

* chore: add trace log for writeWithTimeout

* chore: add timeout for KeypressReport

* chore: use the proper key to send release command

* refactor: simplify HID RPC keyboard input handling and improve key state management

- Updated `handleHidRPCKeyboardInput` to return errors directly instead of keys down state.
- Refactored `rpcKeyboardReport` and `rpcKeypressReport` to return errors instead of states.
- Introduced a queue for managing key down state updates in the `Session` struct to prevent input handling stalls.
- Adjusted the `UpdateKeysDown` method to handle state changes more efficiently.
- Removed unnecessary logging and commented-out code for clarity.

* refactor: enhance keyboard auto-release functionality and key state management

* fix: correct Windows default auto-repeat delay comment from 1ms to 1s

* refactor: send keypress as early as possible

* refactor: replace console.warn with console.info for HID RPC channel events

* refactor: remove unused NewKeypressKeepAliveMessage function from HID RPC

* fix: handle error in key release process and log warnings

* fix: log warning on keypress report failure

* fix: update auto-release keyboard interval to 225

* refactor: enhance keep-alive handling and jitter compensation in HID RPC

- Implemented staleness guard to ignore outdated keep-alive packets.
- Added jitter compensation logic to adjust timer extensions based on packet arrival times.
- Introduced new methods for managing keep-alive state and reset functionality in the Session struct.
- Updated auto-release delay mechanism to use dynamic durations based on keep-alive timing.
- Adjusted keep-alive interval in the UI to improve responsiveness.

* gofmt

* clean up code

* chore: use dynamic duration for scheduleAutoRelease

* Use harcoded timer reset value for now

* fix: prevent nil pointer dereference when stopping timers in Close method

* refactor: remove nil check for kbdAutoReleaseTimers in DelayAutoReleaseWithDuration

* refactor: optimize dependencies in useHidRpc hooks

* refactor: streamline keep-alive timer management in useKeyboard hook

* refactor: clarify comments in useKeyboard hook for resetKeyboardState function

* refactor: reduce keysDownStateQueueSize

* refactor: close and reset keysDownStateQueue in newSession function

* chore: resolve conflicts

* resolve conflicts

---------

Co-authored-by: Adam Shiervani <adam.shiervani@gmail.com>
2025-09-18 13:35:47 +02:00
Aveline 72e3013337
feat: send all paste keystrokes to backend (#789)
* feat: send all paste keystrokes to backend

* feat: cancel paste mode

* wip: send macro using hidRPC channel

* add delay

* feat: allow paste progress to be cancelled

* allow user to override delay

* chore: clear keysDownState

* fix: use currentSession.reportHidRPCKeyboardMacroState

* fix: jsonrpc.go:1142:21: Error return value is not checked (errcheck)

* fix: performance issue of Uint8Array concat

* chore: hide delay option when debugMode isn't enabled

* feat: use clientSide macro if backend doesn't support macros

* fix: update keysDownState handling

* minor issues

* refactor

* fix: send duplicated keyDownState

* chore: add max length for paste text

---------

Co-authored-by: Adam Shiervani <adam.shiervani@gmail.com>
2025-09-18 13:00:57 +02:00
Marc 25b102ac34
fix: ensure that security-key backed SSH keys are supported (#807) 2025-09-17 12:14:45 +02:00
Aveline 5c94c6c87f
chore: upgrade jetkvm native and fix the params of fadeIn / fadeOut (#808) 2025-09-17 01:38:23 +02:00
Marc Brooks cf679978be
fix(timesync): ensure that auto-update waits for time sync (#609)
- Added check to not attempt auto update if time sync is needed and not yet successful (delays 30 second to recheck).
- Added resync of time when DHCP or link state changes if online
- Added conditional* fallback from configured* NTP servers to the IP-named NTP servers, and then to the DNS named ones if that fails
- Added conditional* fallback from the configured* HTTP servers to the default DNS named ones.
- Uses the configuration* option for how many queries to run in parallel
- Added known static IPs for time servers (in case DNS resolution isn't up yet)
- Added time.cloudflare.com to fall-back NTP servers
- Added fallback to NTP via hostnames
- Logs the resultant time (and mode)
2025-09-16 15:37:02 +02:00
Marc Brooks 80a8b9e9e3
feat: Adds IPv6 disabling feature (#803)
* Allow disabling IPv6

Simply ignores any IPv6 addresses in the lease and doesn't offer them to the RPC
Also fixed display issue for IPv6 link local address.
Fixes https://github.com/orgs/jetkvm/projects/7/views/1?pane=issue&itemId=122761546&issue=jetkvm%7Ckvm%7C685

* Don't listen on disabled addresses in mDNS or web server.

* We have to set the IPv4 and IPv6 modes on the server.
2025-09-16 12:44:56 +02:00
Aveline 1717549578
fix: goroutine leak issue of cloudBlink (#801)
* fix: goroutine leak issue of cloudBlink

* chore: add lock and allow context to be cancelled earlier
2025-09-12 18:30:35 +02:00
Aveline 37b1a8bf34
docs: update pprof section of DEVELOPMENT.md (#802) 2025-09-12 11:11:28 +02:00
Marc Brooks ca8b06f4cf
chore: enhance the gzip and cacheable handling of static files
Add SVG and ICO to cacheable files.
Emit robots.txt directly.
Recognize WOFF2 (font) files as assets (so the get the immutable treatment)
Pre-gzip the entire /static/ directory (not just /static/assets/) and include SVG, ICO, and HTML files
Ensure fonts.css is processed by vite/rollup so that the preload and css reference the same immutable files (which get long-cached with hashes)
Add CircularXXWeb-Black to the preload list as it is used in the hot-path.
Handle system-driven color-scheme changes from dark to light correctly.
2025-09-12 08:41:41 +02:00
Aveline 33e099f258
update netboot.xyz-multiarch.iso to 2.0.88 (#799)
* chore: update netboot.xyz-multiarch.iso to 2.0.88

* feat: add script to update netboot.xyz iso
2025-09-12 08:41:17 +02:00
Aveline ea068414dc
feat: validate ssh public key before saving (#794)
* feat: validate ssh public key before saving

* fix: TestValidSSHKeyTypes
2025-09-11 23:32:40 +02:00
Adam Shiervani 8d1a66806c
refactor(ui): Don't fetch KeybardAndMouse Icon on every re-render (#795) 2025-09-11 19:57:35 +02:00