feat: add session max lifetime and fix refresh logic (#559)

* feat: allow any HTTP method for /api/auth/envoy and restrict methods for non-envoy proxies

* feat: add Allow header for invalid methods in proxyHandler

* feat: add session max lifetime and fix refresh logic

* fix: set default value for created_at column and improve session expiration logic

---------

Co-authored-by: Stavros <steveiliop56@gmail.com>
This commit is contained in:
Pushpinder Singh
2026-01-07 06:37:23 -05:00
committed by GitHub
parent 721f302c0b
commit e7bd64d7a3
16 changed files with 96 additions and 47 deletions

View File

@@ -26,14 +26,15 @@ type LoginAttempt struct {
}
type AuthServiceConfig struct {
Users []config.User
OauthWhitelist string
SessionExpiry int
SecureCookie bool
CookieDomain string
LoginTimeout int
LoginMaxRetries int
SessionCookieName string
Users []config.User
OauthWhitelist string
SessionExpiry int
SessionMaxLifetime int
SecureCookie bool
CookieDomain string
LoginTimeout int
LoginMaxRetries int
SessionCookieName string
}
type AuthService struct {
@@ -212,6 +213,7 @@ func (auth *AuthService) CreateSessionCookie(c *gin.Context, data *config.Sessio
TotpPending: data.TotpPending,
OAuthGroups: data.OAuthGroups,
Expiry: time.Now().Add(time.Duration(expiry) * time.Second).Unix(),
CreatedAt: time.Now().Unix(),
OAuthName: data.OAuthName,
OAuthSub: data.OAuthSub,
}
@@ -242,11 +244,19 @@ func (auth *AuthService) RefreshSessionCookie(c *gin.Context) error {
currentTime := time.Now().Unix()
if session.Expiry-currentTime > int64(time.Hour.Seconds()) {
var refreshThreshold int64
if auth.config.SessionExpiry <= int(time.Hour.Seconds()) {
refreshThreshold = int64(auth.config.SessionExpiry / 2)
} else {
refreshThreshold = int64(time.Hour.Seconds())
}
if session.Expiry-currentTime > refreshThreshold {
return nil
}
newExpiry := currentTime + int64(time.Hour.Seconds())
newExpiry := session.Expiry + refreshThreshold
_, err = auth.queries.UpdateSession(c, repository.UpdateSessionParams{
Username: session.Username,
@@ -265,7 +275,8 @@ func (auth *AuthService) RefreshSessionCookie(c *gin.Context) error {
return err
}
c.SetCookie(auth.config.SessionCookieName, cookie, int(time.Hour.Seconds()), "/", fmt.Sprintf(".%s", auth.config.CookieDomain), auth.config.SecureCookie, true)
c.SetCookie(auth.config.SessionCookieName, cookie, int(newExpiry-currentTime), "/", fmt.Sprintf(".%s", auth.config.CookieDomain), auth.config.SecureCookie, true)
log.Trace().Str("username", session.Username).Msg("Session cookie refreshed")
return nil
}
@@ -306,6 +317,16 @@ func (auth *AuthService) GetSessionCookie(c *gin.Context) (config.SessionCookie,
currentTime := time.Now().Unix()
if auth.config.SessionMaxLifetime != 0 && session.CreatedAt != 0 {
if currentTime-session.CreatedAt > int64(auth.config.SessionMaxLifetime) {
err = auth.queries.DeleteSession(c, cookie)
if err != nil {
log.Error().Err(err).Msg("Failed to delete session exceeding max lifetime")
}
return config.SessionCookie{}, fmt.Errorf("session expired due to max lifetime exceeded")
}
}
if currentTime > session.Expiry {
err = auth.queries.DeleteSession(c, cookie)
if err != nil {