From 516fd29da423432ef6dfded21a984f1d15dcab1a Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Mon, 5 Oct 2026 17:31:50 -0400 Subject: fix: slop casino and economy fixes --- internal/admin/correct_audit_fixes_test.go | 31 +++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'internal/admin/correct_audit_fixes_test.go') diff --git a/internal/admin/correct_audit_fixes_test.go b/internal/admin/correct_audit_fixes_test.go index 381fb5c..60073f7 100644 --- a/internal/admin/correct_audit_fixes_test.go +++ b/internal/admin/correct_audit_fixes_test.go @@ -1,6 +1,11 @@ package admin -import "testing" +import ( + "os" + "path/filepath" + "strings" + "testing" +) // Regression: the raw file API must canonicalize repeated "/" and "data/" // prefixes, or "//players/..." reaches the real file while the classifiers @@ -20,3 +25,27 @@ func TestCanonicalDataRelPathStripsRepeatedPrefixes(t *testing.T) { } } } + +// Regression: a valid-but-non-mapping body used to pass through unchanged and +// blank password_hash. It must now be refused, and a mapping body must keep +// the on-disk hash. +func TestRestoreAccountSecretRefusesNonMappingBody(t *testing.T) { + dir := t.TempDir() + full := filepath.Join(dir, "players", "accounts", "alice.yaml") + if err := os.MkdirAll(filepath.Dir(full), 0755); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(full, []byte("name: alice\npassword_hash: secret\n"), 0600); err != nil { + t.Fatal(err) + } + if _, err := restoreAccountSecret("players/accounts/alice.yaml", full, []byte("# comment only\n")); err == nil { + t.Fatal("non-mapping body accepted; the password hash would be blanked") + } + out, err := restoreAccountSecret("players/accounts/alice.yaml", full, []byte("name: alice\npassword_hash: \"[redacted]\"\n")) + if err != nil { + t.Fatal(err) + } + if !strings.Contains(string(out), "secret") { + t.Fatalf("password hash not preserved: %s", out) + } +} -- cgit v1.2.3