mirror of
https://github.com/UNITRONIX/BetterDesk.git
synced 2026-09-10 09:35:39 +00:00
dd0889e3d6
Introduce a SessionManager for relay-based remote sessions in the Tauri MGMT client: new SessionCommand API, start/stop/session input routing, clipboard/recording/quality controls, and notification read/dismiss state. Wire AppState with new mutexes and show main window on startup. CI: add SBOM generation (anchore) and Trivy vulnerability scan steps. Misc: change console Docker DB path, large README/CHANGELOG updates (chat E2E, unattended access/WOL, i18n expansion, CDAP/SDK docs), and many web-nodejs assets/locales/routes/views/services and server-side changes.
5.9 KiB
5.9 KiB
CDAP Protocol Specification
Version 0.3.0 — Last updated with audio, clipboard, multi-monitor, codec negotiation
Transport
- WebSocket on port
21122, path/cdap - Subprotocol:
cdap-v1 - Text frames: JSON messages
- Binary frames: audio/video data with 1-byte type prefix
Authentication
{
"type": "auth",
"device_id": "CDAP-6A9A5452",
"auth_method": "api_key",
"credentials": "your-api-key-here",
"protocol_version": "0.3.0"
}
Server responds with:
{
"type": "auth_response",
"success": true,
"server_version": "3.0.0"
}
Auth Methods
| Method | Credentials field |
|---|---|
api_key |
API key string |
device_token |
Device-specific token |
user_password |
"username:password" |
Manifest Registration
After auth, agent sends its manifest:
{
"type": "manifest",
"device": {
"id": "CDAP-6A9A5452",
"name": "Office Sensor Hub",
"type": "os_agent",
"version": "1.0.0",
"platform": "linux/amd64"
},
"capabilities": ["telemetry", "commands", "terminal", "file_transfer", "clipboard"],
"widgets": [
{
"id": "sys_cpu",
"type": "gauge",
"label": "CPU Usage",
"group": "System",
"unit": "%",
"min": 0,
"max": 100,
"danger": 90,
"warning": 70
},
{
"id": "sys_memory",
"type": "gauge",
"label": "Memory Usage",
"group": "System",
"unit": "%",
"min": 0,
"max": 100
},
{
"id": "reboot_btn",
"type": "button",
"label": "Reboot",
"group": "Actions",
"command": "system_reboot",
"confirm": true
}
],
"heartbeat_interval": 15
}
Message Types
Agent → Server
| Type | Description | Payload |
|---|---|---|
auth |
Authentication request | device_id, auth_method, credentials |
manifest |
Device manifest + widgets | device, capabilities, widgets |
heartbeat |
Periodic health check | metrics: { cpu, memory, disk }, widget_values: {...} |
state_update |
Single widget value change | widget_id, value |
bulk_update |
Multiple widget values | values: { widget_id: value, ... } |
command_response |
Command execution result | command_id, success, result, error |
terminal_output |
Terminal PTY output | session_id, data (base64) |
terminal_end |
Terminal session ended | session_id, exit_code |
file_list_response |
Directory listing | request_id, entries: [{ name, size, is_dir, modified }] |
file_read_response |
File content chunk | request_id, data (base64), offset, total |
file_write_response |
Write confirmation | request_id, success, bytes_written |
file_delete_response |
Delete confirmation | request_id, success |
clipboard_update |
Clipboard content from device | format, data |
audio_frame |
Audio data | codec, data (base64), timestamp, sequence |
audio_end |
Audio session ended | session_id |
cursor_update |
Cursor image data | format, width, height, hotspot_x, hotspot_y, data |
codec_answer |
Codec negotiation response | codec, parameters |
monitor_list |
Available monitors | monitors: [{ id, name, width, height, primary }] |
key_exchange |
Encryption key relay | public_key, algorithm |
alert |
Device-initiated alert | severity, message, source |
pong |
Keepalive response | — |
Server → Agent
| Type | Description | Payload |
|---|---|---|
auth_response |
Auth result | success, error |
command |
Execute command | command_id, command, args |
terminal_start |
Start terminal session | session_id, shell, cols, rows |
terminal_input |
Terminal input data | session_id, data (base64) |
terminal_resize |
Resize terminal | session_id, cols, rows |
terminal_kill |
Kill terminal session | session_id |
file_list |
Request directory listing | request_id, path |
file_read |
Request file content | request_id, path, offset, length |
file_write |
Write file content | request_id, path, data (base64), offset |
file_delete |
Delete file/directory | request_id, path |
clipboard_set |
Set device clipboard | format, data |
screenshot_capture |
Request screenshot | request_id |
state_request |
Request current state | — |
config_update |
Push config changes | config: {...} |
alert_ack |
Acknowledge alert | alert_id |
codec_offer |
Codec negotiation offer | codecs: [...] |
monitor_select |
Select active monitor | monitor_id |
keyframe_request |
Request video keyframe | — |
quality_report |
Quality metrics from browser | bandwidth_kb, latency_ms, frame_loss, fps |
ping |
Keepalive request | — |
Widget Types
| Type | Fields | Description |
|---|---|---|
gauge |
min, max, unit, danger, warning |
Horizontal bar gauge |
toggle |
on_command, off_command |
On/off switch |
button |
command, confirm |
Action button |
led |
on_color, off_color |
Status LED indicator |
text |
— | Read-only text display |
slider |
min, max, step, command |
Adjustable slider |
select |
options, command |
Dropdown selector |
chart |
max_points |
Time-series bar chart |
Error Handling
Error messages use the error type:
{
"type": "error",
"code": "AUTH_FAILED",
"message": "Invalid API key"
}
| Code | Description |
|---|---|
AUTH_FAILED |
Authentication failure |
INVALID_MESSAGE |
Malformed message |
UNKNOWN_COMMAND |
Unrecognized command |
RATE_LIMITED |
Too many messages |
SESSION_EXPIRED |
Session timed out |
Keepalive
Server sends ping every 30 seconds. Agent must respond with pong within 10 seconds or connection is closed.