security: fix data loss on container restart due to relative paths
Root cause: .env.example used relative paths (./data/...) which resolve to /app/data/ inside the container instead of the persistent volume at /data/. This caused the database to be recreated on every container restart, resetting the admin password to a new initial value. Fixes: - .env.example: comment out path settings with clear warning about relative paths; Dockerfile already provides correct absolute defaults - auth: add initial_setup_complete flag in settings table as defence-in-depth so EnsureAdmin never re-creates an admin after the initial setup, even if the users table is unexpectedly empty - main: add validateDataPaths() startup check that warns when relative container paths are detected (potential data-loss misconfiguration) - auth_test: extend TestEnsureAdmin to verify the flag prevents admin re-creation after user deletion
This commit is contained in:
@@ -236,7 +236,7 @@ func TestEnsureAdmin(t *testing.T) {
|
||||
t.Fatalf("Expected owner role, got %q", user.Role)
|
||||
}
|
||||
|
||||
// Second call should be no-op
|
||||
// Second call should be no-op (users exist)
|
||||
created2, _, err := svc.EnsureAdmin("admin2", "admin2@test.com")
|
||||
if err != nil {
|
||||
t.Fatalf("Second EnsureAdmin should not fail: %v", err)
|
||||
@@ -250,6 +250,25 @@ func TestEnsureAdmin(t *testing.T) {
|
||||
if err != ErrInvalidCredentials {
|
||||
t.Fatalf("admin2 should not have been created")
|
||||
}
|
||||
|
||||
// initial_setup_complete flag should be set
|
||||
if !svc.isInitialSetupComplete() {
|
||||
t.Fatal("Expected initial_setup_complete flag to be set after EnsureAdmin")
|
||||
}
|
||||
|
||||
// Even if all users are deleted, EnsureAdmin must NOT create a new admin
|
||||
// because the initial_setup_complete flag is set (defence-in-depth).
|
||||
_, err = db.Exec(`DELETE FROM users`)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to delete all users: %v", err)
|
||||
}
|
||||
created3, _, err := svc.EnsureAdmin("admin3", "admin3@test.com")
|
||||
if err != nil {
|
||||
t.Fatalf("Third EnsureAdmin should not fail: %v", err)
|
||||
}
|
||||
if created3 {
|
||||
t.Fatal("EnsureAdmin must not create a user when initial_setup_complete flag is set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAllUsers(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user