fix: IDEAS.md quickfixes — idle-timeout app config, id_token out of Claims, FormEvent import
session.idle_timeout (minutes, default 15) joins the app-config registry and drives the onboarding Garmin session eviction, distinct from session.duration (the login cookie lifetime in hours). The raw Keycloak ID token no longer rides in auth.Claims through every request context: it's minted into the session cookie separately and read back only by the logout handler via IDTokenFromSessionCookie. OnboardingWizard uses the type-imported FormEvent<HTMLFormElement> instead of the React.FormEvent namespace alias. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -17,7 +17,16 @@ type AppKey struct {
|
||||
}
|
||||
|
||||
// KeySessionDuration is the session cookie lifetime, in integer hours.
|
||||
const KeySessionDuration = "session.duration"
|
||||
const (
|
||||
KeySessionDuration = "session.duration"
|
||||
// KeySessionIdleTimeout bounds an *onboarding Garmin session* (the
|
||||
// ephemeral, pre-account login attempt), not the login cookie --
|
||||
// session.duration is how long a signed-in user stays signed in
|
||||
// (hours); session.idle_timeout is how long an unfinished setup
|
||||
// attempt survives untouched before its subprocess is torn down
|
||||
// (minutes).
|
||||
KeySessionIdleTimeout = "session.idle_timeout"
|
||||
)
|
||||
|
||||
var appRegistry = []AppKey{
|
||||
{
|
||||
@@ -26,6 +35,12 @@ var appRegistry = []AppKey{
|
||||
Description: "Session cookie lifetime in hours",
|
||||
Validate: validatePositiveInt,
|
||||
},
|
||||
{
|
||||
Key: KeySessionIdleTimeout,
|
||||
Default: "15",
|
||||
Description: "Idle timeout in minutes for an unfinished onboarding Garmin session",
|
||||
Validate: validatePositiveInt,
|
||||
},
|
||||
}
|
||||
|
||||
// AppRegistry returns every known application-configuration key, in
|
||||
@@ -57,7 +72,8 @@ func ValidateAppValue(key, value string) error {
|
||||
// AppConfig is the typed result of merging DB overrides over registry
|
||||
// defaults.
|
||||
type AppConfig struct {
|
||||
SessionDuration time.Duration
|
||||
SessionDuration time.Duration
|
||||
SetupSessionIdleTimeout time.Duration
|
||||
}
|
||||
|
||||
// LoadApp merges overrides (store.ConfigValues' map) over defaults. Pure
|
||||
@@ -76,5 +92,9 @@ func LoadApp(overrides map[string]string) (AppConfig, error) {
|
||||
merged[key] = value
|
||||
}
|
||||
hours, _ := strconv.Atoi(merged[KeySessionDuration])
|
||||
return AppConfig{SessionDuration: time.Duration(hours) * time.Hour}, nil
|
||||
idleMinutes, _ := strconv.Atoi(merged[KeySessionIdleTimeout])
|
||||
return AppConfig{
|
||||
SessionDuration: time.Duration(hours) * time.Hour,
|
||||
SetupSessionIdleTimeout: time.Duration(idleMinutes) * time.Minute,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -11,11 +11,14 @@ func TestLoadApp(t *testing.T) {
|
||||
name string
|
||||
overrides map[string]string
|
||||
want time.Duration
|
||||
wantIdle time.Duration
|
||||
wantErr string
|
||||
}{
|
||||
{name: "defaults when no overrides", overrides: nil, want: 720 * time.Hour},
|
||||
{name: "override applied", overrides: map[string]string{"session.duration": "168"}, want: 168 * time.Hour},
|
||||
{name: "defaults when no overrides", overrides: nil, want: 720 * time.Hour, wantIdle: 15 * time.Minute},
|
||||
{name: "override applied", overrides: map[string]string{"session.duration": "168"}, want: 168 * time.Hour, wantIdle: 15 * time.Minute},
|
||||
{name: "idle timeout override applied", overrides: map[string]string{"session.idle_timeout": "30"}, want: 720 * time.Hour, wantIdle: 30 * time.Minute},
|
||||
{name: "invalid stored value", overrides: map[string]string{"session.duration": "zero"}, wantErr: "session.duration"},
|
||||
{name: "invalid idle timeout", overrides: map[string]string{"session.idle_timeout": "0"}, wantErr: "session.idle_timeout"},
|
||||
{name: "unknown stored key", overrides: map[string]string{"bogus.key": "1"}, wantErr: "unknown configuration key"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
@@ -33,6 +36,9 @@ func TestLoadApp(t *testing.T) {
|
||||
if got.SessionDuration != tt.want {
|
||||
t.Fatalf("SessionDuration = %v, want %v", got.SessionDuration, tt.want)
|
||||
}
|
||||
if got.SetupSessionIdleTimeout != tt.wantIdle {
|
||||
t.Fatalf("SetupSessionIdleTimeout = %v, want %v", got.SetupSessionIdleTimeout, tt.wantIdle)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user