feat: make Remember Me a tri-state option (None/Yes/No)

Change ZM_OPT_USE_REMEMBER_ME from a boolean to a tri-state string:
- None: checkbox hidden, sessions persist for ZM_COOKIE_LIFETIME (old disabled)
- Yes: checkbox shown and pre-checked by default
- No: checkbox shown and unchecked by default (old enabled behavior)

Update ConfigData.pm.in with new type definition, login.php to honor the
checked state, and session/action handlers to recognize the new values.
Migration in zm_update-1.39.4.sql maps old '1' to 'No' and '0' to 'None'.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
pull/4707/merge
Isaac Connor 2026-03-12 16:35:41 -04:00
parent 8f29a06ca7
commit 8044c80f9d
5 changed files with 35 additions and 12 deletions

19
db/zm_update-1.39.4.sql Normal file
View File

@ -0,0 +1,19 @@
--
-- Convert ZM_OPT_USE_REMEMBER_ME from boolean to tri-state (None/Yes/No)
--
UPDATE Config SET
Value = CASE WHEN Value = '1' THEN 'No' ELSE 'None' END,
Type = 'string',
DefaultValue = 'None',
Hint = 'None|Yes|No',
Pattern = '(?^i:^([YyNn]))',
Format = ' $1 ',
Prompt = 'Show a "Remember Me" option on the login page',
Help = '
Controls whether a "Remember Me" checkbox appears on the login page.
None: No checkbox is shown. Sessions always persist for ZM_COOKIE_LIFETIME.
Yes: Checkbox is shown and checked by default. Users may uncheck it for a session-only cookie.
No: Checkbox is shown and unchecked by default. Users may check it to persist the session.
'
WHERE Name = 'ZM_OPT_USE_REMEMBER_ME';

View File

@ -537,18 +537,21 @@ our @options = (
},
{
name => 'ZM_OPT_USE_REMEMBER_ME',
default => 'no',
default => 'None',
description => 'Show a "Remember Me" option on the login page',
help => q`
When enabled, a "Remember Me" checkbox will appear on the login
page. If the user does not check "Remember Me", the session
cookie will expire when the browser is closed. If checked, the
session will persist for the duration configured by
ZM_COOKIE_LIFETIME. When this option is disabled, sessions
always persist for ZM_COOKIE_LIFETIME as before.
Controls whether a "Remember Me" checkbox appears on the login page.
None: No checkbox is shown. Sessions always persist for ZM_COOKIE_LIFETIME.
Yes: Checkbox is shown and checked by default. Users may uncheck it for a session-only cookie.
No: Checkbox is shown and unchecked by default. Users may check it to persist the session.
`,
requires => [ { name=>'ZM_OPT_USE_AUTH', value=>'yes' } ],
type => $types{boolean},
type => {
db_type => 'string',
hint => 'None|Yes|No',
pattern => qr|^([YyNn])|i,
format => q( $1 )
},
category => 'auth',
},
# Google reCaptcha settings

View File

@ -26,7 +26,7 @@ if ( ('login' == $action) && isset($_REQUEST['username']) && ( ZM_AUTH_TYPE == '
// if captcha existed, it was passed
if (defined('ZM_OPT_USE_REMEMBER_ME') && ZM_OPT_USE_REMEMBER_ME) {
if (defined('ZM_OPT_USE_REMEMBER_ME') && ZM_OPT_USE_REMEMBER_ME != 'None' && ZM_OPT_USE_REMEMBER_ME != '' && ZM_OPT_USE_REMEMBER_ME != '0') {
if (!empty($_REQUEST['remember_me'])) {
zm_setcookie('ZM_REMEMBER_ME', '1', array('expires' => time() + ZM_COOKIE_LIFETIME));
$_COOKIE['ZM_REMEMBER_ME'] = '1';

View File

@ -27,7 +27,7 @@ function zm_session_start() {
ini_set('session.use_strict_mode', 1);
$currentCookieParams = session_get_cookie_params();
if (defined('ZM_OPT_USE_REMEMBER_ME') && ZM_OPT_USE_REMEMBER_ME && empty($_COOKIE['ZM_REMEMBER_ME'])) {
if (defined('ZM_OPT_USE_REMEMBER_ME') && ZM_OPT_USE_REMEMBER_ME != 'None' && ZM_OPT_USE_REMEMBER_ME != '' && ZM_OPT_USE_REMEMBER_ME != '0' && empty($_COOKIE['ZM_REMEMBER_ME'])) {
$currentCookieParams['lifetime'] = 0;
} else {
$currentCookieParams['lifetime'] = ZM_COOKIE_LIFETIME;

View File

@ -33,10 +33,11 @@ if ( defined('ZM_OPT_USE_AUTH') and ZM_OPT_USE_AUTH ) {
<label for="inputPassword" class="sr-only"><?php echo translate('Password') ?></label>
<input type="password" id="inputPassword" name="password" class="form-control" placeholder="Password" required autocomplete="current-password"/>
<?php
if (defined('ZM_OPT_USE_REMEMBER_ME') && ZM_OPT_USE_REMEMBER_ME) {
if (defined('ZM_OPT_USE_REMEMBER_ME') && ZM_OPT_USE_REMEMBER_ME != 'None' && ZM_OPT_USE_REMEMBER_ME != '' && ZM_OPT_USE_REMEMBER_ME != '0') {
$checked = (ZM_OPT_USE_REMEMBER_ME == 'Yes') ? ' checked="checked"' : '';
?>
<div class="form-check mt-2 mb-2">
<input type="checkbox" class="form-check-input" id="inputRememberMe" name="remember_me" value="1"/>
<input type="checkbox" class="form-check-input" id="inputRememberMe" name="remember_me" value="1"<?php echo $checked ?>/>
<label class="form-check-label" for="inputRememberMe"><?php echo translate('RememberMe') ?></label>
</div>
<?php