feat: the node itself requires an owner passkey (shared by agent and probe) and reports it; the panel derives the account and passkey it is bound to [CI]

This commit is contained in:
justme committed 2026-10-08 06:15:07 +08:00
1 parent 8c37db1577
commit 2ae63653c4
23 files changed
+328 -10

No files matched your search

@@ -250,6 +250,30 @@ public sealed class TrustTests
Assert.Equal(HttpStatusCode.Created, code.StatusCode);
}
[Fact]
public async Task APinnedAgent_ReportsItsOwner_AndThePanelFindsTheAccountAndPasskey()
{
// 宿主(属主)要求在节点这一侧:节点把安装时固定的属主报上来,面板顺着凭证 id 反查出它绑定在哪个账户的哪把 passkey 上
Operator op = await OperatorAsync();
(string code, _, _) = await CreateCodeAsync(role: "agent", controllers: [op.Passkey.Id]);
await using AgentHarness agent = await AgentHarness.StartAsync(_backend, pin: (code, op.Genesis, [op.Passkey.Id]));
JsonNode? owner = null;
await BackendFixture.EventuallyAsync(
async () =>
{
JsonNode info = await _backend.GetJsonAsync(_backend.Admin, "/api/admin/build-info");
owner = info["nodes"]!.AsArray().FirstOrDefault(n => n!["id"]!.GetValue<string>() == agent.Id)?["owners"]?.AsArray().FirstOrDefault();
return owner is not null;
},
TimeSpan.FromSeconds(30),
"the agent reports its owner in hello");
Assert.Equal(op.Passkey.Id, owner!["credential_id"]!.GetValue<string>());
Assert.False(string.IsNullOrEmpty(owner["passkey"]?.GetValue<string>()));
Assert.False(string.IsNullOrEmpty(owner["account"]?.GetValue<string>()));
}
[Fact]
public async Task TheProposal_ListsEveryNewPasskey_SoTheSignerSeesWhatTheyAreAuthorizing()
{