mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-04-27 06:13:32 +09:00
Add option to invalidate other sessions on password change
Feature request in https://www.xetown.com/lakepark/345786
This commit is contained in:
parent
bdb10d57c5
commit
c7d8d84500
7 changed files with 99 additions and 12 deletions
|
|
@ -126,7 +126,7 @@ class Session
|
|||
// Hacked session! Destroy everything.
|
||||
$_SESSION = array();
|
||||
$must_create = true;
|
||||
self::setAutologinKeys(null, null);
|
||||
self::destroyAutologinKeys();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -154,7 +154,7 @@ class Session
|
|||
// Hacked session! Destroy everything.
|
||||
$_SESSION = array();
|
||||
$must_create = true;
|
||||
self::setAutologinKeys(null, null);
|
||||
self::destroyAutologinKeys();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -353,11 +353,12 @@ class Session
|
|||
if ($member_srl)
|
||||
{
|
||||
$_SESSION['RHYMIX']['login'] = $_SESSION['member_srl'] = intval($member_srl);
|
||||
$_SESSION['RHYMIX']['last_login'] = time();
|
||||
$_SESSION['is_logged'] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
self::setAutologinKeys(null, null);
|
||||
self::destroyAutologinKeys();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -440,7 +441,7 @@ class Session
|
|||
self::$_started = false;
|
||||
self::$_member_info = false;
|
||||
self::_setKeys();
|
||||
self::setAutologinKeys(null, null);
|
||||
self::destroyAutologinKeys();
|
||||
@session_destroy();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -851,7 +852,7 @@ class Session
|
|||
* @param string $security_key
|
||||
* @return bool
|
||||
*/
|
||||
public static function setAutologinKeys($autologin_key = null, $security_key = null)
|
||||
public static function setAutologinKeys($autologin_key, $security_key)
|
||||
{
|
||||
// Get session parameters.
|
||||
list($lifetime, $refresh_interval, $domain, $path) = self::_getParams();
|
||||
|
|
@ -862,18 +863,59 @@ class Session
|
|||
{
|
||||
setcookie('rx_autologin', $autologin_key . $security_key, $lifetime, $path, $domain, false, true);
|
||||
$_COOKIE['rx_autologin'] = $autologin_key . $security_key;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self::$_autologin_key)
|
||||
{
|
||||
executeQuery('member.deleteAutologin', (object)array('autologin_key' => substr(self::$_autologin_key, 0, 24)));
|
||||
self::$_autologin_key = false;
|
||||
}
|
||||
setcookie('rx_autologin', 'deleted', time() - 86400, $path, $domain, false, true);
|
||||
unset($_COOKIE['rx_autologin']);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy autologin keys.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function destroyAutologinKeys()
|
||||
{
|
||||
if (self::$_autologin_key)
|
||||
{
|
||||
executeQuery('member.deleteAutologin', (object)array('autologin_key' => substr(self::$_autologin_key, 0, 24)));
|
||||
self::$_autologin_key = false;
|
||||
$result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = false;
|
||||
}
|
||||
|
||||
setcookie('rx_autologin', 'deleted', time() - 86400, $path, $domain, false, true);
|
||||
unset($_COOKIE['rx_autologin']);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy all other autologin keys (except the current session).
|
||||
*
|
||||
* @param int $member_srl
|
||||
* @return bool
|
||||
*/
|
||||
public static function destroyOtherAutologinKeys($member_srl)
|
||||
{
|
||||
$member_srl = intval($member_srl);
|
||||
if (!$member_srl)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (self::$_autologin_key)
|
||||
{
|
||||
executeQuery('member.deleteAutologin', (object)array('member_srl' => $member_srl, 'not_autologin_key' => substr(self::$_autologin_key, 0, 24)));
|
||||
}
|
||||
else
|
||||
{
|
||||
executeQuery('member.deleteAutologin', (object)array('member_srl' => $member_srl));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,6 +161,7 @@ $lang->cmd_config_password_strength = 'password strength';
|
|||
$lang->cmd_password_hashing_algorithm = 'Password Hashing Algorithm';
|
||||
$lang->cmd_password_hashing_work_factor = 'Password Hashing Work Factor';
|
||||
$lang->cmd_password_hashing_auto_upgrade = 'Auto-upgrade Hashing Algorithm';
|
||||
$lang->cmd_password_change_invalidate_other_sessions = 'Log out other devices on password change';
|
||||
$lang->password_strength_low = 'low';
|
||||
$lang->password_strength_normal = 'normal';
|
||||
$lang->password_strength_high = 'high';
|
||||
|
|
@ -168,6 +169,7 @@ $lang->about_password_strength_config = 'When members register or change the pas
|
|||
$lang->about_password_hashing_algorithm = 'You can choose how to encrypt (hash) members\' passwords stored in the database.';
|
||||
$lang->about_password_hashing_work_factor = 'Higher work factors are more secure, but logins may take a long time. This only applies to bcrypt and pbkdf2.';
|
||||
$lang->about_password_hashing_auto_upgrade = 'Passwords encrypted using different algorithms will be automatically converted to the configured algorithm at next login.';
|
||||
$lang->about_password_change_invalidate_other_sessions = 'Log out all other devices (browsers) when a member changes the password.';
|
||||
$lang->about_password_strength['low'] = 'the password must be at least 4';
|
||||
$lang->about_password_strength['normal'] = 'the password must be at least 6, and must have at least one alpha character and numeric characters';
|
||||
$lang->about_password_strength['high'] = 'the password must be at least 8, and must have at least one alpha character, numeric character and special character ';
|
||||
|
|
|
|||
|
|
@ -170,6 +170,7 @@ $lang->cmd_config_password_strength = '비밀번호 보안수준';
|
|||
$lang->cmd_password_hashing_algorithm = '비밀번호 암호화 알고리듬';
|
||||
$lang->cmd_password_hashing_work_factor = '비밀번호 암호화 소요시간';
|
||||
$lang->cmd_password_hashing_auto_upgrade = '알고리듬 자동 업그레이드';
|
||||
$lang->cmd_password_change_invalidate_other_sessions = '비번 변경시 다른 기기 로그아웃';
|
||||
$lang->password_strength_low = '낮음';
|
||||
$lang->password_strength_normal = '보통';
|
||||
$lang->password_strength_high = '높음';
|
||||
|
|
@ -177,6 +178,7 @@ $lang->about_password_strength_config = '회원들이 비밀번호를 등록/변
|
|||
$lang->about_password_hashing_algorithm = '회원들의 비밀번호를 DB에 저장할 때 암호화(해싱)하는 방식을 지정할 수 있습니다.';
|
||||
$lang->about_password_hashing_work_factor = '시간이 오래 걸리는 알고리듬일수록 보안이 강하지만, 로그인이 오래 걸릴 수 있습니다. bcrypt 및 pbkdf2 알고리듬에만 적용됩니다.';
|
||||
$lang->about_password_hashing_auto_upgrade = '설정된 알고리듬과 다른 방법으로 암호화된 비밀번호가 있으면 다음 로그인시 설정된 알고리듬으로 자동 변환합니다.';
|
||||
$lang->about_password_change_invalidate_other_sessions = '비밀번호를 변경하면 현재 기기(브라우저)를 제외한 모든 로그인이 풀리도록 합니다.';
|
||||
$lang->about_password_strength['low'] = '비밀번호는 4자 이상이어야 합니다.';
|
||||
$lang->about_password_strength['normal'] = '비밀번호는 6자리 이상이어야 하며 영문과 숫자를 반드시 포함해야 합니다.';
|
||||
$lang->about_password_strength['high'] = '비밀번호는 8자리 이상이어야 하며 영문과 숫자, 특수문자를 반드시 포함해야 합니다.';
|
||||
|
|
|
|||
|
|
@ -171,6 +171,7 @@ class memberAdminController extends member
|
|||
'password_hashing_algorithm',
|
||||
'password_hashing_work_factor',
|
||||
'password_hashing_auto_upgrade',
|
||||
'password_change_invalidate_other_sessions',
|
||||
'update_nickname_log',
|
||||
'member_allow_fileupload'
|
||||
);
|
||||
|
|
|
|||
|
|
@ -735,6 +735,21 @@ class memberController extends member
|
|||
$args->password = $password;
|
||||
$output = $this->updateMemberPassword($args);
|
||||
if(!$output->toBool()) return $output;
|
||||
|
||||
// Log out all other sessions.
|
||||
$oModuleModel = getModel('module');
|
||||
$member_config = $oModuleModel->getModuleConfig('member');
|
||||
if ($member_config->password_change_invalidate_other_sessions === 'Y')
|
||||
{
|
||||
$invalid_before = time();
|
||||
$filename = RX_BASEDIR . sprintf('files/member_extra_info/invalid_before/%s%d.txt', getNumberingPath($member_srl), $member_srl);
|
||||
Rhymix\Framework\Storage::write($filename, $invalid_before);
|
||||
Rhymix\Framework\Session::destroyOtherAutologinKeys($member_srl);
|
||||
if ($_SESSION['RHYMIX'] && $_SESSION['RHYMIX']['last_login'])
|
||||
{
|
||||
$_SESSION['RHYMIX']['last_login'] = $invalid_before;
|
||||
}
|
||||
}
|
||||
|
||||
$this->add('member_srl', $args->member_srl);
|
||||
$this->setMessage('success_updated');
|
||||
|
|
@ -771,6 +786,7 @@ class memberController extends member
|
|||
$output = $this->deleteMember($member_srl);
|
||||
if(!$output->toBool()) return $output;
|
||||
// Destroy all session information
|
||||
executeQuery('member.deleteAutologin', (object)array('member_srl' => $member_srl));
|
||||
Rhymix\Framework\Session::logout();
|
||||
// Return success message
|
||||
$this->setMessage('success_leaved');
|
||||
|
|
@ -1922,6 +1938,21 @@ class memberController extends member
|
|||
$this->destroySessionInfo();
|
||||
return;
|
||||
}
|
||||
|
||||
// Invalidate the session if the member's password has changed
|
||||
$oModuleModel = getModel('module');
|
||||
$member_config = $oModuleModel->getModuleConfig('member');
|
||||
if ($member_config->password_change_invalidate_other_sessions === 'Y')
|
||||
{
|
||||
$filename = RX_BASEDIR . sprintf('files/member_extra_info/invalid_before/%s%d.txt', getNumberingPath($member_srl), $member_srl);
|
||||
$invalid_before = Rhymix\Framework\Storage::read($filename);
|
||||
if ($invalid_before && $_SESSION['RHYMIX'] && $_SESSION['RHYMIX']['last_login'] && $_SESSION['RHYMIX']['last_login'] < $invalid_before)
|
||||
{
|
||||
$this->destroySessionInfo();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Log in for treatment sessions set
|
||||
/*
|
||||
$_SESSION['is_logged'] = true;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
</tables>
|
||||
<conditions>
|
||||
<condition operation="equal" column="autologin_key" var="autologin_key" />
|
||||
<condition operation="notequal" column="autologin_key" var="not_autologin_key" pipe="and" />
|
||||
<condition operation="equal" column="member_srl" var="member_srl" pipe="and" />
|
||||
</conditions>
|
||||
</query>
|
||||
|
|
|
|||
|
|
@ -71,6 +71,14 @@
|
|||
<p class="x_help-block">{$lang->about_password_hashing_auto_upgrade}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="x_control-group">
|
||||
<label class="x_control-label">{$lang->cmd_password_change_invalidate_other_sessions}</label>
|
||||
<div class="x_controls">
|
||||
<label for="password_change_invalidate_other_sessions_y" class="x_inline"><input type="radio" name="password_change_invalidate_other_sessions" id="password_change_invalidate_other_sessions_y" value="Y" checked="checked"|cond="$config->password_change_invalidate_other_sessions == 'Y'" /> {$lang->cmd_yes}</label>
|
||||
<label for="password_change_invalidate_other_sessions_n" class="x_inline"><input type="radio" name="password_change_invalidate_other_sessions" id="password_change_invalidate_other_sessions_n" value="N" checked="checked"|cond="$config->password_change_invalidate_other_sessions != 'Y'" /> {$lang->cmd_no}</label>
|
||||
<p class="x_help-block">{$lang->about_password_change_invalidate_other_sessions}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="x_control-group">
|
||||
<label class="x_control-label" for="webmaster_name">{$lang->webmaster_name}</label>
|
||||
<div class="x_controls">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue