feat: 配对管理端点与中继侧设备注册上报
- agent --pair:临时监听 :3001 仅开放 /provision 与 /destroy,以节点密码为共享秘密; 窗口由三个独立条件关闭(首次成功配对 / 失败尝试 10 次 / 10 分钟超时),配对成功后 管理监听即关(设计 §7 第 4 步) - agent 为每台配对手机生成中继 bearer(config.Save 0600 原子写;启动时为手写条目补发) - transport.PushDevices:握手成功后全量上报本节点受信设备集;空集是吊销声明而非无操作 - relay /v1/agent/devices:agent 会话后鉴权的设备注册;全量替换本节点条目; 操作员 MSA_DEVICES 为 static 不可被覆盖;跨节点 id 不可抢占 - 中继设备注册替代了 §11 第 6 项的一部分:节点 destroy + 重握手即可在路由层吊销 - 配置:provisionSecret 字段(无密码保护节点需显式设置才可配对);Validate(pairMode) - 测试:pair 流程 8 项、设备注册 6 项、transport 1 项;文档 §7 实现修订注记与 README 状态
This commit is contained in:
@@ -205,6 +205,43 @@ func TestResultPostsTheEnvelopeVerbatim(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// The device registration posts the node's authoritative paired set under the session, which is
|
||||
// what lets the relay learn about freshly paired phones. Empty is posted too: "nobody" is a
|
||||
// revocation claim, not a no-op.
|
||||
func TestPushDevicesPostsTheFullSetUnderTheSession(t *testing.T) {
|
||||
var got map[string]any
|
||||
client, _ := newClient(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != PathDevices {
|
||||
t.Fatalf("posted to %q", r.URL.Path)
|
||||
}
|
||||
if r.Header.Get("X-MSA-Session") == "" {
|
||||
t.Error("the device push must carry the session")
|
||||
}
|
||||
json.NewDecoder(r.Body).Decode(&got)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}), "t")
|
||||
err := client.PushDevices(context.Background(), []DeviceRegistration{
|
||||
{App: "ap_5b1d0000", Token: "tok-a"},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got["node"] != "nd_test0001" {
|
||||
t.Fatalf("node is %v", got["node"])
|
||||
}
|
||||
devices, _ := got["devices"].([]any)
|
||||
if len(devices) != 1 {
|
||||
t.Fatalf("devices: %v", got["devices"])
|
||||
}
|
||||
// An empty list is a real claim, not a skipped call.
|
||||
client2, _ := newClient(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}), "t")
|
||||
if err := client2.PushDevices(context.Background(), []DeviceRegistration{}); err != nil {
|
||||
t.Fatalf("empty push: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRetryAfterHasASaneDefault(t *testing.T) {
|
||||
client, _ := newClient(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
Reference in New Issue
Block a user