eleven / ocho Public

Clone
git clone https://amadan.net/eleven/ocho

Plain git — no account needed to clone.

Download

Download this file

1package main
2
3import (
4 "path/filepath"
5 "testing"
6
7 "lchat/internal/bot"
8 "lchat/internal/e2ee"
9)
10
11// The zero-touch provisioning chain end-to-end against the real router:
12// mintAgentInvite (the Go port of agent/mint-invite.mjs, #856) mints an agent
13// invite via the admin API, and bot.EnsureSession (#806) redeems it and
14// persists a session — the exact pair add-bot and the activator co-spawn rely
15// on. If either side's HKDF walk drifted, the claim would fail here.
16func TestMintAgentInviteThenSelfProvision(t *testing.T) {
17 ts, s := newTestServer(t)
18
19 secret, err := mintAgentInvite(ts.URL, "admintok", "Eleven", "Your guide to the app.", "")
20 if err != nil {
21 t.Fatalf("mintAgentInvite: %v", err)
22 }
23 if secret == "" {
24 t.Fatal("mintAgentInvite returned an empty secret")
25 }
26 // The server must hold only the derived id, never the secret itself.
27 inv, err := e2ee.DeriveInvite(secret)
28 if err != nil {
29 t.Fatalf("derive: %v", err)
30 }
31 if _, found, err := s.db.getKeyInvite(inv.ID); err != nil || !found {
32 t.Fatalf("minted invite not on the server under its derived id: found=%v err=%v", found, err)
33 }
34
35 path := filepath.Join(t.TempDir(), "eleven-session.json")
36 sess, err := bot.EnsureSession(ts.URL, path, secret, "Eleven", t.Logf)
37 if err != nil {
38 t.Fatalf("EnsureSession: %v", err)
39 }
40 if sess == nil || sess.Token == "" || sess.UserPriv == "" {
41 t.Fatalf("self-provisioning did not yield a full session: %+v", sess)
42 }
43
44 // The invite is one-time: a second fresh boot against the same secret must
45 // fail loudly, not mint a second identity.
46 if _, err := bot.EnsureSession(ts.URL, filepath.Join(t.TempDir(), "again.json"), secret, "Eleven", nil); err == nil {
47 t.Fatal("re-redeeming a spent invite should fail")
48 }
49}
50
51// The admin API refuses agent invites when bots are off — the mint surfaces
52// that as an error instead of writing a half-staged env.
53func TestMintAgentInviteRespectsBotsGate(t *testing.T) {
54 ts, s := newTestServer(t)
55 if err := s.db.setBotsEnabled(false); err != nil {
56 t.Fatal(err)
57 }
58 if _, err := mintAgentInvite(ts.URL, "admintok", "Eleven", "", ""); err == nil {
59 t.Fatal("expected the bots-off gate to reject the mint")
60 }
61}
62