Files
felhom.eu/hub/internal/store/r954_revault_set_at_test.go
T
admin 8f97b8009b
gates / gates (push) Successful in 6m58s
hub v0.157.0: app_definition_refused (R-971), the vault time moves on a re-vault (R-954), the hub's own snapshot count (R-895 slice); uninstall knows felhom-thin-check
- hub: `app_definition_refused` in allowedEventTypes + operatorOnlyEvents (controller v0.328.0's catalog
  allow-list refusal); SaveHostRecoveryCredential moves set_at on a re-vault (found live: both rotated hosts
  kept their first vault's time); the daily key audit also lists the box's restic snapshots/ read-only over the
  login the hub already holds and logs count/newest/oldest (no alarm yet).
- installer (main only, rides the next tag): --uninstall removes /usr/local/sbin/felhom-thin-check (agent
  v0.159.0's bundle file); test_hostinstall.py knows it.
- runbook whole-guest-backup-orphan-thin.md: the human repair the agent's new orphan finding points to.

Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-17 16:27:51 +02:00

38 lines
1.5 KiB
Go

package store
import (
"testing"
"time"
)
// R-954 follow-up (hub v0.157.0): a re-vault (`--rotate-recovery`, the operator's own set-and-vault) MOVES set_at — the
// time the Console access card shows as „last vaulted". Found live 2026-10-17: demo-hp's and Tester 1's rotated
// passwords both still read set_at = their FIRST vault (2026-07-21, 2026-10-04). RED-PROOF
// (felhom.eu audits/agent-allowlist-rotation-2026-10-17/P3/redproof-set-at.txt): without `set_at = datetime('now')` in
// the upsert this test fails on both the meta and the credential read.
func TestHostRecovery_ReVaultMovesSetAt(t *testing.T) {
st := sealTestStore(t)
if err := st.SaveHostRecoveryCredential("h1", "root@pam", "first-Pw-1"); err != nil {
t.Fatal(err)
}
// Age the first vault by a year, as a real day-0 vault would be.
if _, err := st.db.Exec(`UPDATE host_recovery SET set_at = '2025-10-17 10:00:00' WHERE host_id = 'h1'`); err != nil {
t.Fatal(err)
}
before := time.Now().UTC().Add(-time.Minute)
if err := st.SaveHostRecoveryCredential("h1", "root@pam", "second-Pw-2"); err != nil {
t.Fatal(err)
}
c, err := st.GetHostRecoveryCredential("h1")
if err != nil || c == nil || c.Secret != "second-Pw-2" {
t.Fatalf("credential = %+v, %v", c, err)
}
if c.SetAt.Before(before) {
t.Fatalf("credential set_at = %v — the re-vault kept the first vault's time", c.SetAt)
}
m, err := st.GetHostRecoveryMeta("h1")
if err != nil || m == nil || m.SetAt.Before(before) {
t.Fatalf("meta set_at = %+v, %v — the card would show the first vault's time", m, err)
}
}