Files
HomeAgent/internal/devicebridge/client/protocol.go
JianFeeeee ba5785036a feat: 设备鉴权迁移至客户端 + 插件卸载保护
安全修复(客户端鉴权):
- remotedevice 服务端移除授权状态存储(authorized map/SetAuthorized/handleDeviceAuth)
- DeviceMeta.Authorized 改为设备 hello 自报,服务端仅透传展示
- device_ctl_* 工具移除服务端授权检查,无条件转发,设备端自行决定是否执行
- 共享设备桥库 Bridge 新增本地 authorized 状态,未授权收到 cmd 直接拒绝
- waiter: --device-authorized / device_authorized 配置控制本地授权
- GUI: 授权存 gui-prefs 本地文件;设备页仅本机可切换开关
- webui /device/auth 旧路径返回 410 Gone
- 根因:agent 可经 config_set 篡改服务端授权配置自行授权设备

插件管理强化:
- 内置插件禁止卸载(IsBuiltinPlugin + 409),外部插件卸载即时生效
- 卸载不存在插件返回 404;移除误导性 reload_required 提示
- webui 插件路由:名称白名单校验防路径穿越、保留字路径保护
2026-08-24 19:26:11 +08:00

107 lines
2.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Package client 提供设备桥客户端共享库,实现与 remotedevice 插件通信的完整协议。
// 编译为 C 共享库后GUI (Electron) 可通过 FFI 调用CLI (waiter) 可直接导入 Go 包。
package client
import "encoding/json"
// ===== 消息类型(与 remotedevice plugin 协议对齐) =====
// HelloMsg 设备登记消息
type HelloMsg struct {
Op string `json:"op"`
Device DeviceMeta `json:"device"`
}
// DeviceMeta 设备元信息
type DeviceMeta struct {
DeviceID string `json:"device_id"`
Name string `json:"name"`
Kind string `json:"kind"`
Caps []string `json:"caps"`
Info map[string]interface{} `json:"info,omitempty"`
}
// BindMsg 设备绑定消息
type BindMsg struct {
Op string `json:"op"`
DeviceID string `json:"device_id"`
Token string `json:"token"`
}
// CmdMsg 服务端下发的命令消息
type CmdMsg struct {
Op string `json:"op"`
ReqID string `json:"req_id"`
Command string `json:"command"`
CmdType string `json:"cmd_type"`
}
// CmdResult 命令执行结果
type CmdResult struct {
Op string `json:"op"`
ReqID string `json:"req_id"`
Status string `json:"status"`
Output string `json:"output,omitempty"`
Error string `json:"error,omitempty"`
DeviceID string `json:"device_id,omitempty"`
}
// DataStart 二进制数据传输开始(设备→网关)
type DataStart struct {
Op string `json:"op"`
ReqID string `json:"req_id"`
Kind string `json:"kind"`
MIME string `json:"mime"`
Total int `json:"total"`
ChunkSize int `json:"chunk_size,omitempty"`
}
// DataEnd 二进制数据传输结束
type DataEnd struct {
Op string `json:"op"`
ReqID string `json:"req_id"`
Status string `json:"status"`
Total int `json:"total,omitempty"`
Error string `json:"error,omitempty"`
}
// SpeechStart TTS 音频数据开始(网关→设备)
type SpeechStart struct {
Op string `json:"op"`
ReqID string `json:"req_id"`
Kind string `json:"kind"`
MIME string `json:"mime"`
Total int `json:"total"`
}
// SpeechEnd TTS 音频数据结束
type SpeechEnd struct {
Op string `json:"op"`
ReqID string `json:"req_id"`
}
// StatusMsg 设备状态上报
type StatusMsg struct {
Op string `json:"op"`
DeviceID string `json:"device_id"`
Status string `json:"status"`
}
// EventMsg 设备主动上报事件
type EventMsg struct {
Op string `json:"op"`
DeviceID string `json:"device_id,omitempty"`
Type string `json:"type"`
Payload interface{} `json:"payload,omitempty"`
}
// ===== 序列化辅助 =====
func mustJSON(v interface{}) []byte {
b, err := json.Marshal(v)
if err != nil {
return []byte("{}")
}
return b
}