diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-10-15 02:06:35 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-10-15 02:06:35 +0200 |
| commit | 419af660eeb8a4403e37a63c54a15586d04d5a8e (patch) | |
| tree | b0c0cdd831a5fb2864d5bedf581681aa0ec86023 /packages/meshbay-hub/tests/test_account_pinning.py | |
| parent | 47583c5e405f3011a526df73cc9485c46598f214 (diff) | |
| download | meshbay-419af660eeb8a4403e37a63c54a15586d04d5a8e.tar.gz | |
feat(cli): chat — Tier 2 check on the signing device, interactive room
Each message's signing device is checked against the group's roster as the
page checks it (a port of transport-roster.js, held to it by the parity
test): chains of countersignatures walked from each account's roots, the
keys accepted per account and node kept in the store, the roster read again
once before a key is called changed. Only "changed" is said, under the
message; --json carries every verdict.
chat with no group opens the interactive chat: the groups, then one group's
conversation IRC-style with pushed messages arriving live and a line to
write in; Esc or /part goes back to the groups, /quit or Ctrl+Q quits. Like
the bare command, it opens on the sign-in screen when nothing is stored.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-hub/tests/test_account_pinning.py')
| -rw-r--r-- | packages/meshbay-hub/tests/test_account_pinning.py | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/packages/meshbay-hub/tests/test_account_pinning.py b/packages/meshbay-hub/tests/test_account_pinning.py index ebd29bd..87853fb 100644 --- a/packages/meshbay-hub/tests/test_account_pinning.py +++ b/packages/meshbay-hub/tests/test_account_pinning.py @@ -228,3 +228,35 @@ def test_a_device_pinned_before_the_evidence_existed_reads_as_a_root(): out = _verify([_entry("alice", pk_a), _entry("alice", pk_b, added_by=pk_a)]) assert pk_b in out["alice"]["unevidenced"] + + +def test_the_command_line_client_walks_the_same_chains(): + """`meshbay_cli/client/roster.py` is a port of `_verifyRoster`: held to it on + one roster holding every case — a root, a real chain two deep, a device + claiming a countersigner with no proof, one hanging off it, and a signature + over the wrong transcript.""" + cli_roster = pytest.importorskip("meshbay_cli.client.roster") + sk_a, pk_a = _device() + sk_b, pk_b = _device() + _, pk_c = _device() + _, pk_d = _device() + _, pk_e = _device() + sk_f, pk_f = _device() + unproved = _entry("alice", pk_d, added_by=pk_a) # names A, proves nothing + wrong = _entry("alice", pk_e, added_by=pk_a, sk_signer=sk_a) + wrong["add_ts"] += 1 # signed another transcript + devices = [ + _entry("alice", pk_a), + _entry("alice", pk_b, added_by=pk_a, sk_signer=sk_a), + _entry("alice", pk_c, added_by=pk_b, sk_signer=sk_b), + unproved, + _entry("alice", pk_f, added_by=pk_d, sk_signer=sk_f), # hangs off the unproved + wrong, + _entry("bob", pk_f), + ] + js = _verify(devices) + py = cli_roster.verify_roster({"devices": devices, "node_pk": NODE_PK}, NODE_PK) + for user in ("alice", "bob"): + assert sorted(py[user].verified) == sorted(js[user]["verified"]), user + assert sorted(py[user].unevidenced) == sorted(js[user]["unevidenced"]), user + assert sorted(js["alice"]["verified"]) == sorted([pk_a, pk_b, pk_c]) |