node-engine client: the adoption handing's two ends (HandAccounts, OpenHanded, HandedAccount, KeyFingerprint, IsBcrypt) over the seat's AccountsHanded (B5f; ADR 0634 §4; issue 1966)

Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
2026-11-05 15:54:21 +01:00
parent bb2140c236
commit d8d319e3ff
2 changed files with 123 additions and 0 deletions
@@ -0,0 +1,47 @@
package nodeengineclient
import (
"strings"
"testing"
"time"
"git.novox.be/novox/mesh-sdk/go/seal"
)
// A handing is sealed to the vault's key and opened with it alone; another key, a wrong count and a plain value are refused.
func TestAHandingOpensWithTheVaultsKeyAlone(t *testing.T) {
vault, err := seal.GenerateKeyPair()
if err != nil {
t.Fatal(err)
}
other, err := seal.GenerateKeyPair()
if err != nil {
t.Fatal(err)
}
hash := "$2a$10$" + strings.Repeat("a", 53)
accounts := []HandedAccount{{User: "a", Hash: hash}, {User: "b", Hash: hash}}
h, err := HandAccounts(accounts, vault.PublicKey, "sha256:list", time.Date(2026, 11, 5, 10, 0, 0, 0, time.FixedZone("x", 3600)))
if err != nil {
t.Fatal(err)
}
if h.Users != 2 || h.To != KeyFingerprint(vault.PublicKey) || h.At.Location() != time.UTC {
t.Errorf("handing = %+v", h)
}
got, err := OpenHanded(h, vault.PublicKey, vault.PrivateKey)
if err != nil || len(got) != 2 || got[1].User != "b" {
t.Errorf("opened %v, %v", got, err)
}
if _, err := OpenHanded(h, other.PublicKey, other.PrivateKey); err == nil {
t.Error("a handing sealed to the vault opened for another key")
}
h.Users = 3
if _, err := OpenHanded(h, vault.PublicKey, vault.PrivateKey); err == nil {
t.Error("a handing that says 3 users and holds 2 was opened")
}
if !IsBcrypt(hash) || IsBcrypt("plain") {
t.Error("IsBcrypt")
}
if _, err := HandAccounts(accounts, " ", "x", time.Now()); err == nil {
t.Error("sealed to no key")
}
}