Repository: authelia/authelia (go)

Issue:
Version 4.34.4 : I can not disable "Remember Me" although the remember_me_duration value is set to -1
It would seem that the WebUI is still showing the "Remember Me" checkbox and I can not disable "Remember Me" although the remember_me_duration value is set to -1 in the "session" section of the configuration.yml file.

I'm on version 4.34.4.

I have tried it on more that one computer in case it was a cache issue but it is not.

_Originally posted by @ToqQrrl in https://github.com/authelia/authelia/issues/2985#issuecomment-1065915355_

Pull request:
fix(configuration): remember me duration disabled impossible
This fixes an issue not properly resolved by db6dd32151a8161e8348f32d19a687f0faa16ddf.

Fixes #2996

Patch:
diff --git a/internal/configuration/schema/const.go b/internal/configuration/schema/const.go
index 1c483b61a..94d72dd50 100644
--- a/internal/configuration/schema/const.go
+++ b/internal/configuration/schema/const.go
@@ -9,20 +9,24 @@ const argon2id = "argon2id"
 // ProfileRefreshDisabled represents a value for refresh_interval that disables the check entirely.
 const ProfileRefreshDisabled = "disable"
 
-// ProfileRefreshAlways represents a value for refresh_interval that's the same as 0ms.
-const ProfileRefreshAlways = "always"
+const (
+	// ProfileRefreshAlways represents a value for refresh_interval that's the same as 0ms.
+	ProfileRefreshAlways = "always"
 
-// RefreshIntervalDefault represents the default value of refresh_interval.
-const RefreshIntervalDefault = "5m"
+	// RefreshIntervalDefault represents the default value of refresh_interval.
+	RefreshIntervalDefault = "5m"
 
-// RefreshIntervalAlways represents the duration value refresh interval should have if set to always.
-const RefreshIntervalAlways = 0 * time.Millisecond
+	// RefreshIntervalAlways represents the duration value refresh interval should have if set to always.
+	RefreshIntervalAlways = 0 * time.Millisecond
+)
 
-// LDAPImplementationCustom is the string for the custom LDAP implementation.
-const LDAPImplementationCustom = "custom"
+const (
+	// LDAPImplementationCustom is the string for the custom LDAP implementation.
+	LDAPImplementationCustom = "custom"
 
-// LDAPImplementationActiveDirectory is the string for the Active Directory LDAP implementation.
-const LDAPImplementationActiveDirectory = "activedirectory"
+	// LDAPImplementationActiveDirectory is the string for the Active Directory LDAP implementation.
+	LDAPImplementationActiveDirectory = "activedirectory"
+)
 
 // TOTP Algorithm.
 const (
@@ -31,6 +35,11 @@ const (
 	TOTPAlgorithmSHA512 = "SHA512"
 )
 
+const (
+	// RememberMeDisabled represents the duration for a disabled remember me session configuration.
+	RememberMeDisabled = time.Second * -1
+)
+
 var (
 	// TOTPPossibleAlgorithms is a list of valid TOTP Algorithms.
 	TOTPPossibleAlgorithms = []string{TOTPAlgorithmSHA1, TOTPAlgorithmSHA256, TOTPAlgorithmSHA512}
diff --git a/internal/configuration/validator/session.go b/internal/configuration/validator/session.go
index ddc076891..67517089f 100644
--- a/internal/configuration/validator/session.go
+++ b/internal/configuration/validator/session.go
@@ -35,7 +35,7 @@ func validateSession(config *schema.SessionConfiguration, validator *schema.Stru
 		config.Inactivity = schema.DefaultSessionConfiguration.Inactivity // 5 min.
 	}
 
-	if config.RememberMeDuration <= 0 && config.RememberMeDuration != -1 {
+	if config.RememberMeDuration <= 0 && config.RememberMeDuration != schema.RememberMeDisabled {
 		config.RememberMeDuration = schema.DefaultSessionConfiguration.RememberMeDuration // 1 month.
 	}
 
diff --git a/internal/handlers/handler_firstfactor.go b/internal/handlers/handler_firstfactor.go
index 7073a60ff..1a48b8cb3 100644
--- a/internal/handlers/handler_firstfactor.go
+++ b/internal/handlers/handler_firstfactor.go
@@ -4,6 +4,7 @@ import (
 	"errors"
 	"time"
 
+	"github.com/authelia/authelia/v4/internal/configuration/schema"
 	"github.com/authelia/authelia/v4/internal/middlewares"
 	"github.com/authelia/authelia/v4/internal/regulation"
 	"github.com/authelia/authelia/v4/internal/session"
@@ -92,7 +93,7 @@ func FirstFactorPost(delayFunc middlewares.TimingAttackDelayFunc) middlewares.Re
 		}
 
 		// Check if bodyJSON.KeepMeLoggedIn can be deref'd and derive the value based on the configuration and JSON data.
-		keepMeLoggedIn := ctx.Providers.SessionProvider.RememberMe != -1 && bodyJSON.KeepMeLoggedIn != nil && *bodyJSON.KeepMeLoggedIn
+		keepMeLoggedIn := ctx.Providers.SessionProvider.RememberMe != schema.RememberMeDisabled && bodyJSON.KeepMeLoggedIn != nil && *bodyJSON.KeepMeLoggedIn
 
 		// Set the cookie to expire if remember me is enabled and the user has asked us to.
 		if keepMeLoggedIn {
diff --git a/internal/server/server.go b/internal/server/server.go
index d0dc79b95..d27f0e803 100644
--- a/internal/server/server.go
+++ b/internal/server/server.go
@@ -28,7 +28,7 @@ var assets embed.FS
 
 func registerRoutes(configuration schema.Configuration, providers middlewares.Providers) fasthttp.RequestHandler {
 	autheliaMiddleware := middlewares.AutheliaMiddleware(configuration, providers)
-	rememberMe := strconv.FormatBool(configuration.Session.RememberMeDuration != -1)
+	rememberMe := strconv.FormatBool(configuration.Session.RememberMeDuration != schema.RememberMeDisabled)
 	resetPassword := strconv.FormatBool(!configuration.AuthenticationBackend.DisableResetPassword)
 
 	duoSelfEnrollment := f


Test patch:
diff --git a/internal/configuration/provider_test.go b/internal/configuration/provider_test.go
index 2325d92f3..b770000f3 100644
--- a/internal/configuration/provider_test.go
+++ b/internal/configuration/provider_test.go
@@ -295,6 +295,7 @@ func TestShouldDecodeSMTPSenderWithName(t *testing.T) {
 
 	assert.Equal(t, "Admin", config.Notifier.SMTP.Sender.Name)
 	assert.Equal(t, "admin@example.com", config.Notifier.SMTP.Sender.Address)
+	assert.Equal(t, schema.RememberMeDisabled, config.Session.RememberMeDuration)
 }
 
 func TestShouldNotReadConfigurationOnFSAccessDenied(t *testing.T) {
diff --git a/internal/configuration/test_resources/config_alt.yml b/internal/configuration/test_resources/config_alt.yml
index 72776ab6d..95c8fb89c 100644
--- a/internal/configuration/test_resources/config_alt.yml
+++ b/internal/configuration/test_resources/config_alt.yml
@@ -97,6 +97,7 @@ session:
   name: authelia_session
   expiration: 3600000  # 1 hour
   inactivity: 300000  # 5 minutes
+  remember_me_duration: -1
   domain: example.com
   redis:
     host: 127.0.0.1
diff --git a/internal/configuration/validator/session_test.go b/internal/configuration/validator/session_test.go
index b09f155a3..605a65fa9 100644
--- a/internal/configuration/validator/session_test.go
+++ b/internal/configuration/validator/session_test.go
@@ -3,7 +3,6 @@ package validator
 import (
 	"fmt"
 	"testing"
-	"time"
 
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
@@ -412,7 +411,7 @@ func TestShouldSetDefaultWhenNegativeAndNotOverrideDisabledRememberMe(t *testing
 	config := newDefaultSessionConfig()
 	config.Inactivity = -1
 	config.Expiration = -1
-	config.RememberMeDuration = -1
+	config.RememberMeDuration = schema.RememberMeDisabled
 
 	ValidateSession(&config, validator)
 
@@ -421,7 +420,7 @@ func TestShouldSetDefaultWhenNegativeAndNotOverrideDisabledRememberMe(t *testing
 
 	assert.Equal(t, schema.DefaultSessionConfiguration.Inactivity, config.Inactivity)
 	assert.Equal(t, schema.DefaultSessionConfiguration.Expiration, config.Expiration)
-	assert.Equal(t, time.Duration(-1), config.RememberMeDuration)
+	assert.Equal(t, schema.RememberMeDisabled, config.RememberMeDuration)
 }
 
 func TestShouldSetDefaultRememberMeDuration(t *testing.T) {