Without JWT_SECRET, or with one of the published placeholders, the server generates 32 random bytes once and keeps them in the data directory (jwt.secret, mode 0600), so tokens cannot be forged and logins survive restarts. Instances that ran on the old default log in once more. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
84 lines
2.4 KiB
Go
84 lines
2.4 KiB
Go
package config
|
|
|
|
import (
|
|
"log/slog"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func TestConfigLogLevelAndDebug(t *testing.T) {
|
|
// Load writes the generated JWT secret into the data directory; keep it out of the repository
|
|
t.Setenv("DATA_DIR", t.TempDir())
|
|
os.Setenv("PORT", "9090")
|
|
defer os.Unsetenv("PORT")
|
|
|
|
// 1. Default info
|
|
os.Unsetenv("LOG_LEVEL")
|
|
os.Unsetenv("DEBUG")
|
|
cfg := Load()
|
|
if cfg.SlogLevel() != slog.LevelInfo {
|
|
t.Fatalf("expected LevelInfo, got %v", cfg.SlogLevel())
|
|
}
|
|
|
|
// 2. LOG_LEVEL=debug
|
|
os.Setenv("LOG_LEVEL", "debug")
|
|
cfg = Load()
|
|
if cfg.SlogLevel() != slog.LevelDebug {
|
|
t.Fatalf("expected LevelDebug, got %v", cfg.SlogLevel())
|
|
}
|
|
|
|
// 3. LOG_LEVEL=warn
|
|
os.Setenv("LOG_LEVEL", "warn")
|
|
cfg = Load()
|
|
if cfg.SlogLevel() != slog.LevelWarn {
|
|
t.Fatalf("expected LevelWarn, got %v", cfg.SlogLevel())
|
|
}
|
|
|
|
// 4. LOG_LEVEL=error
|
|
os.Setenv("LOG_LEVEL", "error")
|
|
cfg = Load()
|
|
if cfg.SlogLevel() != slog.LevelError {
|
|
t.Fatalf("expected LevelError, got %v", cfg.SlogLevel())
|
|
}
|
|
|
|
// 5. DEBUG=true overrides LOG_LEVEL
|
|
os.Setenv("LOG_LEVEL", "error")
|
|
os.Setenv("DEBUG", "true")
|
|
cfg = Load()
|
|
if cfg.SlogLevel() != slog.LevelDebug {
|
|
t.Fatalf("expected LevelDebug when DEBUG=true, got %v", cfg.SlogLevel())
|
|
}
|
|
|
|
// 6. DEBUG=1 overrides LOG_LEVEL
|
|
os.Setenv("DEBUG", "1")
|
|
cfg = Load()
|
|
if cfg.SlogLevel() != slog.LevelDebug {
|
|
t.Fatalf("expected LevelDebug when DEBUG=1, got %v", cfg.SlogLevel())
|
|
}
|
|
os.Unsetenv("DEBUG")
|
|
os.Unsetenv("LOG_LEVEL")
|
|
}
|
|
|
|
func TestJWTSecretNeverUsesAKnownDefault(t *testing.T) {
|
|
dir := t.TempDir()
|
|
for _, env := range []string{"", "mindsift-default-selfhosted-jwt-secret-key-2026", "change_this_to_a_secure_random_key_min_32_chars"} {
|
|
got := resolveJWTSecret(env, dir)
|
|
if got == env || len(got) < 32 {
|
|
t.Fatalf("env %q: insecure secret %q", env, got)
|
|
}
|
|
}
|
|
// The generated secret is stable across restarts
|
|
first := resolveJWTSecret("", dir)
|
|
if again := resolveJWTSecret("", dir); again != first {
|
|
t.Fatalf("generated secret must persist, got %q then %q", first, again)
|
|
}
|
|
info, err := os.Stat(filepath.Join(dir, jwtSecretFile))
|
|
if err != nil || info.Mode().Perm() != 0o600 {
|
|
t.Fatalf("secret file must exist with mode 0600: %v %v", info, err)
|
|
}
|
|
if got := resolveJWTSecret("ein-eigener-sehr-langer-zufaelliger-wert-123456", dir); got != "ein-eigener-sehr-langer-zufaelliger-wert-123456" {
|
|
t.Fatalf("a real JWT_SECRET must win, got %q", got)
|
|
}
|
|
}
|