Feat v0.6.9 cookie fix roadmap (#44)
Co-authored-by: Jeffrey Smith <jasafpro@gmail.com> Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
This commit was merged in pull request #44.
This commit is contained in:
103
server/handlers/session_config.go
Normal file
103
server/handlers/session_config.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"armature/store"
|
||||
)
|
||||
|
||||
// SessionConfig holds parsed, clamped session TTL settings.
|
||||
type SessionConfig struct {
|
||||
AccessTokenTTL time.Duration
|
||||
RefreshTokenTTL time.Duration
|
||||
IdleTimeout time.Duration // 0 = disabled
|
||||
}
|
||||
|
||||
// Defaults & clamp bounds
|
||||
const (
|
||||
defaultAccessTTL = 15 * time.Minute
|
||||
defaultRefreshTTL = 7 * 24 * time.Hour // 7d
|
||||
defaultIdleTimeout = 0 // disabled
|
||||
|
||||
minAccessTTL = 5 * time.Minute
|
||||
maxAccessTTL = 60 * time.Minute
|
||||
minRefreshTTL = 1 * time.Hour
|
||||
maxRefreshTTL = 90 * 24 * time.Hour // 90d
|
||||
minIdleTTL = 5 * time.Minute
|
||||
maxIdleTTL = 24 * time.Hour
|
||||
)
|
||||
|
||||
// LoadSessionConfig reads session settings from the global_settings table.
|
||||
// Returns defaults if the key is missing or values are unparseable.
|
||||
func LoadSessionConfig(ctx context.Context, gc store.GlobalConfigStore) SessionConfig {
|
||||
sc := SessionConfig{
|
||||
AccessTokenTTL: defaultAccessTTL,
|
||||
RefreshTokenTTL: defaultRefreshTTL,
|
||||
IdleTimeout: defaultIdleTimeout,
|
||||
}
|
||||
|
||||
raw, err := gc.Get(ctx, "session")
|
||||
if err != nil || raw == nil {
|
||||
return sc
|
||||
}
|
||||
|
||||
if v, ok := raw["access_token_ttl"].(string); ok && v != "" {
|
||||
if d, err := parseDurationString(v); err == nil {
|
||||
sc.AccessTokenTTL = clamp(d, minAccessTTL, maxAccessTTL)
|
||||
}
|
||||
}
|
||||
|
||||
if v, ok := raw["refresh_token_ttl"].(string); ok && v != "" {
|
||||
if d, err := parseDurationString(v); err == nil {
|
||||
sc.RefreshTokenTTL = clamp(d, minRefreshTTL, maxRefreshTTL)
|
||||
}
|
||||
}
|
||||
|
||||
if v, ok := raw["idle_timeout"].(string); ok && v != "" {
|
||||
if d, err := parseDurationString(v); err == nil {
|
||||
sc.IdleTimeout = clamp(d, minIdleTTL, maxIdleTTL)
|
||||
}
|
||||
}
|
||||
|
||||
return sc
|
||||
}
|
||||
|
||||
// parseDurationString parses strings like "15m", "2h", "7d", "30d".
|
||||
// Supports suffixes: s (seconds), m (minutes), h (hours), d (days).
|
||||
func parseDurationString(s string) (time.Duration, error) {
|
||||
s = strings.TrimSpace(s)
|
||||
if s == "" {
|
||||
return 0, fmt.Errorf("empty duration")
|
||||
}
|
||||
|
||||
// Try Go's standard parser first (handles "15m", "2h30m", etc.)
|
||||
if d, err := time.ParseDuration(s); err == nil {
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// Handle "Xd" suffix (days)
|
||||
if strings.HasSuffix(s, "d") {
|
||||
numStr := strings.TrimSuffix(s, "d")
|
||||
n, err := strconv.ParseFloat(numStr, 64)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("invalid duration: %s", s)
|
||||
}
|
||||
return time.Duration(n * float64(24*time.Hour)), nil
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf("invalid duration: %s", s)
|
||||
}
|
||||
|
||||
func clamp(d, min, max time.Duration) time.Duration {
|
||||
if d < min {
|
||||
return min
|
||||
}
|
||||
if d > max {
|
||||
return max
|
||||
}
|
||||
return d
|
||||
}
|
||||
Reference in New Issue
Block a user