Rewrote session code to be OOP.
This commit is contained in:
parent
58f22c9d74
commit
d2aa478c58
58 changed files with 753 additions and 414 deletions
database
misuzu.phppublic
auth
forum
manage
changelog
forum
general
news
users
settings
user-assets.phpsrc
templates
22
database/2020_05_25_152331_sessions_table_fixes.php
Normal file
22
database/2020_05_25_152331_sessions_table_fixes.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
namespace Misuzu\DatabaseMigrations\SessionsTableFixes;
|
||||
|
||||
use PDO;
|
||||
|
||||
function migrate_up(PDO $conn): void {
|
||||
$conn->exec("
|
||||
ALTER TABLE `msz_sessions`
|
||||
CHANGE COLUMN `session_key` `session_key` BINARY(64) NOT NULL AFTER `user_id`,
|
||||
CHANGE COLUMN `session_expires` `session_expires` TIMESTAMP NOT NULL DEFAULT DATE_ADD(NOW(), INTERVAL 1 MONTH) AFTER `session_country`,
|
||||
ADD INDEX `sessions_created_index` (`session_created`);
|
||||
");
|
||||
}
|
||||
|
||||
function migrate_down(PDO $conn): void {
|
||||
$conn->exec("
|
||||
ALTER TABLE `msz_sessions`
|
||||
CHANGE COLUMN `session_key` `session_key` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_bin' AFTER `user_id`,
|
||||
CHANGE COLUMN `session_expires` `session_expires` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP() AFTER `session_country`,
|
||||
DROP INDEX `sessions_created_index`;
|
||||
");
|
||||
}
|
100
misuzu.php
100
misuzu.php
|
@ -8,6 +8,8 @@ use Misuzu\Net\GeoIP;
|
|||
use Misuzu\Net\IPAddress;
|
||||
use Misuzu\Users\User;
|
||||
use Misuzu\Users\UserNotFoundException;
|
||||
use Misuzu\Users\UserSession;
|
||||
use Misuzu\Users\UserSessionNotFoundException;
|
||||
|
||||
define('MSZ_STARTUP', microtime(true));
|
||||
define('MSZ_ROOT', __DIR__);
|
||||
|
@ -418,19 +420,49 @@ MIG;
|
|||
exit;
|
||||
}
|
||||
|
||||
if(!empty($_COOKIE['msz_uid']) && !empty($_COOKIE['msz_sid'])
|
||||
&& ctype_digit($_COOKIE['msz_uid']) && ctype_xdigit($_COOKIE['msz_sid'])
|
||||
&& strlen($_COOKIE['msz_sid']) === 64) {
|
||||
$_COOKIE['msz_auth'] = Base64::decode(user_session_cookie_pack($_COOKIE['msz_uid'], $_COOKIE['msz_sid']), true);
|
||||
setcookie('msz_auth', $_COOKIE['msz_auth'], strtotime('1 year'), '/', '.' . $_SERVER['HTTP_HOST'], !empty($_SERVER['HTTPS']), true);
|
||||
if(isset($_COOKIE['msz_uid']) && isset($_COOKIE['msz_sid'])) {
|
||||
$authToken = (new AuthToken)
|
||||
->setUserId(filter_input(INPUT_COOKIE, 'msz_uid', FILTER_SANITIZE_NUMBER_INT) ?? 0)
|
||||
->setSessionToken(filter_input(INPUT_COOKIE, 'msz_sid', FILTER_SANITIZE_STRING) ?? '');
|
||||
|
||||
if($authToken->isValid())
|
||||
setcookie('msz_auth', $authToken->pack(), strtotime('1 year'), '/', '.' . $_SERVER['HTTP_HOST'], !empty($_SERVER['HTTPS']), true);
|
||||
|
||||
setcookie('msz_uid', '', -3600, '/', '', !empty($_SERVER['HTTPS']), true);
|
||||
setcookie('msz_sid', '', -3600, '/', '', !empty($_SERVER['HTTPS']), true);
|
||||
}
|
||||
|
||||
if(!empty($_COOKIE['msz_auth']) && is_string($_COOKIE['msz_auth'])) {
|
||||
$cookieData = user_session_cookie_unpack(Base64::decode($_COOKIE['msz_auth'], true));
|
||||
if(!isset($authToken))
|
||||
$authToken = AuthToken::unpack(filter_input(INPUT_COOKIE, 'msz_auth', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH) ?? '');
|
||||
if($authToken->isValid()) {
|
||||
try {
|
||||
$sessionInfo = $authToken->getSession();
|
||||
if($sessionInfo->hasExpired()) {
|
||||
$sessionInfo->delete();
|
||||
} elseif($sessionInfo->getUserId() === $authToken->getUserId()) {
|
||||
$userInfo = $sessionInfo->getUser();
|
||||
if(!$userInfo->isDeleted()) {
|
||||
$sessionInfo->setCurrent();
|
||||
$userInfo->setCurrent();
|
||||
|
||||
if(!empty($cookieData) && user_session_start($cookieData['user_id'], $cookieData['session_token'])) {
|
||||
$sessionInfo->bump();
|
||||
|
||||
if($sessionInfo->shouldBumpExpire())
|
||||
setcookie('msz_auth', $authToken->pack(), $sessionInfo->getExpiresTime(), '/', '.' . $_SERVER['HTTP_HOST'], !empty($_SERVER['HTTPS']), true);
|
||||
}
|
||||
}
|
||||
} catch(UserNotFoundException $ex) {
|
||||
UserSession::unsetCurrent();
|
||||
User::unsetCurrent();
|
||||
} catch(UserSessionNotFoundException $ex) {
|
||||
UserSession::unsetCurrent();
|
||||
User::unsetCurrent();
|
||||
}
|
||||
|
||||
if(!UserSession::hasCurrent()) {
|
||||
setcookie('msz_auth', '', -9001, '/', '.' . $_SERVER['HTTP_HOST'], !empty($_SERVER['HTTPS']), true);
|
||||
setcookie('msz_auth', '', -9001, '/', '', !empty($_SERVER['HTTPS']), true);
|
||||
} else {
|
||||
$userDisplayInfo = DB::prepare('
|
||||
SELECT
|
||||
u.`user_id`, u.`username`, u.`user_background_settings`, u.`user_deleted`,
|
||||
|
@ -439,38 +471,19 @@ MIG;
|
|||
LEFT JOIN `msz_roles` AS r
|
||||
ON u.`display_role` = r.`role_id`
|
||||
WHERE `user_id` = :user_id
|
||||
');
|
||||
$userDisplayInfo->bind('user_id', $cookieData['user_id']);
|
||||
$userDisplayInfo = $userDisplayInfo->fetch();
|
||||
') ->bind('user_id', $userInfo->getId())
|
||||
->fetch();
|
||||
|
||||
if($userDisplayInfo) {
|
||||
if(!is_null($userDisplayInfo['user_deleted'])) {
|
||||
setcookie('msz_auth', '', -9001, '/', '.' . $_SERVER['HTTP_HOST'], !empty($_SERVER['HTTPS']), true);
|
||||
setcookie('msz_auth', '', -9001, '/', '', !empty($_SERVER['HTTPS']), true);
|
||||
user_session_stop(true);
|
||||
$userDisplayInfo = [];
|
||||
} else {
|
||||
try {
|
||||
User::byId($cookieData['user_id'])->setCurrent();
|
||||
} catch(UserNotFoundException $ex) {}
|
||||
user_bump_last_active($userInfo->getId());
|
||||
|
||||
user_bump_last_active($cookieData['user_id']);
|
||||
user_session_bump_active(user_session_current('session_id'));
|
||||
|
||||
if(user_session_current('session_expires_bump')) {
|
||||
setcookie('msz_auth', $_COOKIE['msz_auth'], strtotime('1 month'), '/', '.' . $_SERVER['HTTP_HOST'], !empty($_SERVER['HTTPS']), true);
|
||||
}
|
||||
|
||||
$userDisplayInfo['perms'] = perms_get_user($userDisplayInfo['user_id']);
|
||||
$userDisplayInfo['ban_expiration'] = user_warning_check_expiration($userDisplayInfo['user_id'], MSZ_WARN_BAN);
|
||||
$userDisplayInfo['silence_expiration'] = $userDisplayInfo['ban_expiration'] > 0 ? 0 : user_warning_check_expiration($userDisplayInfo['user_id'], MSZ_WARN_SILENCE);
|
||||
}
|
||||
}
|
||||
$userDisplayInfo['perms'] = perms_get_user($userInfo->getId());
|
||||
$userDisplayInfo['ban_expiration'] = user_warning_check_expiration($userInfo->getId(), MSZ_WARN_BAN);
|
||||
$userDisplayInfo['silence_expiration'] = $userDisplayInfo['ban_expiration'] > 0 ? 0 : user_warning_check_expiration($userInfo->getId(), MSZ_WARN_SILENCE);
|
||||
}
|
||||
}
|
||||
|
||||
CSRF::setGlobalSecretKey(Config::get('csrf.secret', Config::TYPE_STR, 'soup'));
|
||||
CSRF::setGlobalIdentity(empty($userDisplayInfo) ? IPAddress::remote() : $cookieData['session_token']);
|
||||
CSRF::setGlobalIdentity(UserSession::hasCurrent() ? UserSession::getCurrent()->getToken() : IPAddress::remote());
|
||||
|
||||
if(Config::get('private.enabled', Config::TYPE_BOOL)) {
|
||||
$onLoginPage = $_SERVER['PHP_SELF'] === url('auth-login');
|
||||
|
@ -478,14 +491,16 @@ MIG;
|
|||
$misuzuBypassLockdown = !empty($misuzuBypassLockdown) || $onLoginPage;
|
||||
|
||||
if(!$misuzuBypassLockdown) {
|
||||
if(user_session_active()) {
|
||||
if(UserSession::hasCurrent()) {
|
||||
$privatePermCat = Config::get('private.perm.cat', Config::TYPE_STR);
|
||||
$privatePermVal = Config::get('private.perm.val', Config::TYPE_INT);
|
||||
|
||||
if(!empty($privatePermCat) && $privatePermVal > 0) {
|
||||
if(!perms_check_user($privatePermCat, $userDisplayInfo['user_id'], $privatePermVal)) {
|
||||
if(!perms_check_user($privatePermCat, User::getCurrent()->getId(), $privatePermVal)) {
|
||||
// au revoir
|
||||
unset($userDisplayInfo);
|
||||
user_session_stop(); // au revoir
|
||||
UserSession::unsetCurrent();
|
||||
User::unsetCurrent();
|
||||
}
|
||||
}
|
||||
} elseif(!$onLoginPage && !($onPasswordPage && Config::get('private.allow_password_reset', Config::TYPE_BOOL, true))) {
|
||||
|
@ -495,14 +510,13 @@ MIG;
|
|||
}
|
||||
}
|
||||
|
||||
if(!empty($userDisplayInfo)) {
|
||||
if(!empty($userDisplayInfo)) // delete this
|
||||
Template::set('current_user', $userDisplayInfo);
|
||||
}
|
||||
|
||||
$inManageMode = starts_with($_SERVER['REQUEST_URI'], '/manage');
|
||||
$hasManageAccess = !empty($userDisplayInfo['user_id'])
|
||||
&& !user_warning_check_restriction($userDisplayInfo['user_id'])
|
||||
&& perms_check_user(MSZ_PERMS_GENERAL, $userDisplayInfo['user_id'], MSZ_PERM_GENERAL_CAN_MANAGE);
|
||||
$hasManageAccess = User::hasCurrent()
|
||||
&& !user_warning_check_restriction(User::getCurrent()->getId())
|
||||
&& perms_check_user(MSZ_PERMS_GENERAL, User::getCurrent()->getId(), MSZ_PERM_GENERAL_CAN_MANAGE);
|
||||
Template::set('has_manage_access', $hasManageAccess);
|
||||
|
||||
if($inManageMode) {
|
||||
|
@ -511,6 +525,6 @@ MIG;
|
|||
exit;
|
||||
}
|
||||
|
||||
Template::set('manage_menu', manage_get_menu($userDisplayInfo['user_id'] ?? 0));
|
||||
Template::set('manage_menu', manage_get_menu(User::getCurrent()->getId()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Misuzu\AuthToken;
|
||||
use Misuzu\Net\IPAddress;
|
||||
use Misuzu\Users\User;
|
||||
use Misuzu\Users\UserNotFoundException;
|
||||
use Misuzu\Users\UserLoginAttempt;
|
||||
use Misuzu\Users\UserSession;
|
||||
use Misuzu\Users\UserSessionCreationFailedException;
|
||||
|
||||
require_once '../../misuzu.php';
|
||||
|
||||
if(user_session_active()) {
|
||||
if(UserSession::hasCurrent()) {
|
||||
url_redirect('index');
|
||||
return;
|
||||
}
|
||||
|
@ -23,7 +26,6 @@ $notices = [];
|
|||
$siteIsPrivate = Config::get('private.enable', Config::TYPE_BOOL);
|
||||
$loginPermCat = $siteIsPrivate ? Config::get('private.perm.cat', Config::TYPE_STR) : '';
|
||||
$loginPermVal = $siteIsPrivate ? Config::get('private.perm.val', Config::TYPE_INT) : 0;
|
||||
$ipAddress = IPAddress::remote();
|
||||
$remainingAttempts = UserLoginAttempt::remaining();
|
||||
|
||||
while(!empty($_POST['login']) && is_array($_POST['login'])) {
|
||||
|
@ -32,7 +34,6 @@ while(!empty($_POST['login']) && is_array($_POST['login'])) {
|
|||
break;
|
||||
}
|
||||
|
||||
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
|
||||
$loginRedirect = empty($_POST['login']['redirect']) || !is_string($_POST['login']['redirect']) ? '' : $_POST['login']['redirect'];
|
||||
|
||||
if(empty($_POST['login']['username']) || empty($_POST['login']['password'])
|
||||
|
@ -54,58 +55,56 @@ while(!empty($_POST['login']) && is_array($_POST['login'])) {
|
|||
$loginFailedError = "Invalid username or password, {$attemptsRemainingError}.";
|
||||
|
||||
try {
|
||||
$userData = User::findForLogin($_POST['login']['username']);
|
||||
$userInfo = User::findForLogin($_POST['login']['username']);
|
||||
} catch(UserNotFoundException $ex) {
|
||||
UserLoginAttempt::create(false);
|
||||
$notices[] = $loginFailedError;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!$userData->hasPassword()) {
|
||||
if(!$userInfo->hasPassword()) {
|
||||
$notices[] = 'Your password has been invalidated, please reset it.';
|
||||
break;
|
||||
}
|
||||
|
||||
if($userData->isDeleted() || !$userData->checkPassword($_POST['login']['password'])) {
|
||||
UserLoginAttempt::create(false, $userData);
|
||||
if($userInfo->isDeleted() || !$userInfo->checkPassword($_POST['login']['password'])) {
|
||||
UserLoginAttempt::create(false, $userInfo);
|
||||
$notices[] = $loginFailedError;
|
||||
break;
|
||||
}
|
||||
|
||||
if($userData->passwordNeedsRehash()) {
|
||||
$userData->setPassword($_POST['login']['password']);
|
||||
if($userInfo->passwordNeedsRehash()) {
|
||||
$userInfo->setPassword($_POST['login']['password']);
|
||||
}
|
||||
|
||||
if(!empty($loginPermCat) && $loginPermVal > 0 && !perms_check_user($loginPermCat, $userData->getId(), $loginPermVal)) {
|
||||
if(!empty($loginPermCat) && $loginPermVal > 0 && !perms_check_user($loginPermCat, $userInfo->getId(), $loginPermVal)) {
|
||||
$notices[] = "Login succeeded, but you're not allowed to browse the site right now.";
|
||||
UserLoginAttempt::create(true, $userData);
|
||||
UserLoginAttempt::create(true, $userInfo);
|
||||
break;
|
||||
}
|
||||
|
||||
if($userData->hasTOTP()) {
|
||||
if($userInfo->hasTOTP()) {
|
||||
url_redirect('auth-two-factor', [
|
||||
'token' => user_auth_tfa_token_create($userData->getId()),
|
||||
'token' => user_auth_tfa_token_create($userInfo->getId()),
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
UserLoginAttempt::create(true, $userData);
|
||||
$sessionKey = user_session_create($userData->getId(), $ipAddress, $userAgent);
|
||||
UserLoginAttempt::create(true, $userInfo);
|
||||
|
||||
if(empty($sessionKey)) {
|
||||
try {
|
||||
$sessionInfo = UserSession::create($userInfo);
|
||||
$sessionInfo->setCurrent();
|
||||
} catch(UserSessionCreationFailedException $ex) {
|
||||
$notices[] = "Something broke while creating a session for you, please tell an administrator or developer about this!";
|
||||
break;
|
||||
}
|
||||
|
||||
user_session_start($userData->getId(), $sessionKey);
|
||||
$authToken = AuthToken::create($userInfo, $sessionInfo);
|
||||
setcookie('msz_auth', $authToken->pack(), $sessionInfo->getExpiresTime(), '/', '.' . $_SERVER['HTTP_HOST'], !empty($_SERVER['HTTPS']), true);
|
||||
|
||||
$cookieLife = strtotime(user_session_current('session_expires'));
|
||||
$cookieValue = Base64::encode(user_session_cookie_pack($userData->getId(), $sessionKey), true);
|
||||
setcookie('msz_auth', $cookieValue, $cookieLife, '/', '.' . $_SERVER['HTTP_HOST'], !empty($_SERVER['HTTPS']), true);
|
||||
|
||||
if(!is_local_url($loginRedirect)) {
|
||||
if(!is_local_url($loginRedirect))
|
||||
$loginRedirect = url('index');
|
||||
}
|
||||
|
||||
redirect($loginRedirect);
|
||||
return;
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Users\User;
|
||||
use Misuzu\Users\UserSession;
|
||||
|
||||
require_once '../../misuzu.php';
|
||||
|
||||
if(!user_session_active()) {
|
||||
if(!UserSession::hasCurrent()) {
|
||||
url_redirect('index');
|
||||
return;
|
||||
}
|
||||
|
@ -11,7 +14,9 @@ if(!user_session_active()) {
|
|||
if(CSRF::validateRequest()) {
|
||||
setcookie('msz_auth', '', -9001, '/', '.' . $_SERVER['HTTP_HOST'], !empty($_SERVER['HTTPS']), true);
|
||||
setcookie('msz_auth', '', -9001, '/', '', !empty($_SERVER['HTTPS']), true);
|
||||
user_session_stop(true);
|
||||
UserSession::getCurrent()->delete();
|
||||
UserSession::unsetCurrent();
|
||||
User::unsetCurrent();
|
||||
url_redirect('index');
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -6,10 +6,11 @@ use Misuzu\AuditLog;
|
|||
use Misuzu\Net\IPAddress;
|
||||
use Misuzu\Users\User;
|
||||
use Misuzu\Users\UserLoginAttempt;
|
||||
use Misuzu\Users\UserSession;
|
||||
|
||||
require_once '../../misuzu.php';
|
||||
|
||||
if(user_session_active()) {
|
||||
if(UserSession::hasCurrent()) {
|
||||
url_redirect('settings-account');
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -5,10 +5,11 @@ use Misuzu\Net\IPAddress;
|
|||
use Misuzu\Net\IPAddressBlacklist;
|
||||
use Misuzu\Users\User;
|
||||
use Misuzu\Users\UserLoginAttempt;
|
||||
use Misuzu\Users\UserSession;
|
||||
|
||||
require_once '../../misuzu.php';
|
||||
|
||||
if(user_session_active()) {
|
||||
if(UserSession::hasCurrent()) {
|
||||
url_redirect('index');
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -4,10 +4,12 @@ namespace Misuzu;
|
|||
use Misuzu\Net\IPAddress;
|
||||
use Misuzu\Users\User;
|
||||
use Misuzu\Users\UserLoginAttempt;
|
||||
use Misuzu\Users\UserSession;
|
||||
use Misuzu\Users\UserSessionCreationFailedException;
|
||||
|
||||
require_once '../../misuzu.php';
|
||||
|
||||
if(user_session_active()) {
|
||||
if(UserSession::hasCurrent()) {
|
||||
url_redirect('index');
|
||||
return;
|
||||
}
|
||||
|
@ -22,11 +24,11 @@ $tokenInfo = user_auth_tfa_token_info(
|
|||
)
|
||||
);
|
||||
|
||||
$userData = User::byId($tokenInfo['user_id']);
|
||||
$userInfo = User::byId($tokenInfo['user_id']);
|
||||
|
||||
// checking user_totp_key specifically because there's a fringe chance that
|
||||
// there's a token present, but totp is actually disabled
|
||||
if(!$userData->hasTOTP()) {
|
||||
if(!$userInfo->hasTOTP()) {
|
||||
url_redirect('auth-login');
|
||||
return;
|
||||
}
|
||||
|
@ -50,30 +52,29 @@ while(!empty($twofactor)) {
|
|||
break;
|
||||
}
|
||||
|
||||
if(!in_array($twofactor['code'], $userData->getValidTOTPTokens())) {
|
||||
if(!in_array($twofactor['code'], $userInfo->getValidTOTPTokens())) {
|
||||
$notices[] = sprintf(
|
||||
"Invalid two factor code, %d attempt%s remaining",
|
||||
$remainingAttempts - 1,
|
||||
$remainingAttempts === 2 ? '' : 's'
|
||||
);
|
||||
UserLoginAttempt::create(false, $userData);
|
||||
UserLoginAttempt::create(false, $userInfo);
|
||||
break;
|
||||
}
|
||||
|
||||
UserLoginAttempt::create(true, $userData);
|
||||
$sessionKey = user_session_create($tokenInfo['user_id'], $ipAddress, $userAgent);
|
||||
UserLoginAttempt::create(true, $userInfo);
|
||||
user_auth_tfa_token_invalidate($tokenInfo['tfa_token']);
|
||||
|
||||
if(empty($sessionKey)) {
|
||||
try {
|
||||
$sessionInfo = UserSession::create($userInfo);
|
||||
$sessionInfo->setCurrent();
|
||||
} catch(UserSessionCreationFailedException $ex) {
|
||||
$notices[] = "Something broke while creating a session for you, please tell an administrator or developer about this!";
|
||||
break;
|
||||
}
|
||||
|
||||
user_auth_tfa_token_invalidate($tokenInfo['tfa_token']);
|
||||
user_session_start($tokenInfo['user_id'], $sessionKey);
|
||||
|
||||
$cookieLife = strtotime(user_session_current('session_expires'));
|
||||
$cookieValue = Base64::encode(user_session_cookie_pack($tokenInfo['user_id'], $sessionKey), true);
|
||||
setcookie('msz_auth', $cookieValue, $cookieLife, '/', '.' . $_SERVER['HTTP_HOST'], !empty($_SERVER['HTTPS']), true);
|
||||
$authToken = AuthToken::create($userInfo, $sessionInfo);
|
||||
setcookie('msz_auth', $authToken->pack(), $sessionInfo->getExpiresTime(), '/', '.' . $_SERVER['HTTP_HOST'], !empty($_SERVER['HTTPS']), true);
|
||||
|
||||
if(!is_local_url($redirect)) {
|
||||
$redirect = url('index');
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../misuzu.php';
|
||||
|
||||
$forumId = !empty($_GET['f']) && is_string($_GET['f']) ? (int)$_GET['f'] : 0;
|
||||
|
@ -12,7 +14,8 @@ if($forumId === 0) {
|
|||
}
|
||||
|
||||
$forum = forum_get($forumId);
|
||||
$forumUserId = user_session_current('user_id', 0);
|
||||
$forumUser = User::getCurrent();
|
||||
$forumUserId = $forumUser === null ? 0 : $forumUser->getId();
|
||||
|
||||
if(empty($forum) || ($forum['forum_type'] == MSZ_FORUM_TYPE_LINK && empty($forum['forum_link']))) {
|
||||
echo render_error(404);
|
||||
|
|
|
@ -1,25 +1,27 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../misuzu.php';
|
||||
|
||||
$indexMode = !empty($_GET['m']) && is_string($_GET['m']) ? (string)$_GET['m'] : '';
|
||||
$forumId = !empty($_GET['f']) && is_string($_GET['f']) ? (int)$_GET['f'] : 0;
|
||||
|
||||
$currentUser = User::getCurrent();
|
||||
$currentUserId = $currentUser === null ? 0 : $currentUser->getId();
|
||||
|
||||
switch($indexMode) {
|
||||
case 'mark':
|
||||
url_redirect($forumId < 1 ? 'forum-mark-global' : 'forum-mark-single', ['forum' => $forumId]);
|
||||
break;
|
||||
|
||||
default:
|
||||
$categories = forum_get_root_categories(user_session_current('user_id', 0));
|
||||
$categories = forum_get_root_categories($currentUserId);
|
||||
$blankForum = count($categories) < 1;
|
||||
|
||||
foreach($categories as $key => $category) {
|
||||
$categories[$key]['forum_subforums'] = forum_get_children(
|
||||
$category['forum_id'],
|
||||
user_session_current('user_id', 0)
|
||||
);
|
||||
$categories[$key]['forum_subforums'] = forum_get_children($category['forum_id'], $currentUserId);
|
||||
|
||||
foreach($categories[$key]['forum_subforums'] as $skey => $sub) {
|
||||
if(!forum_may_have_children($sub['forum_type'])) {
|
||||
|
@ -27,10 +29,7 @@ switch($indexMode) {
|
|||
}
|
||||
|
||||
$categories[$key]['forum_subforums'][$skey]['forum_subforums']
|
||||
= forum_get_children(
|
||||
$sub['forum_id'],
|
||||
user_session_current('user_id', 0)
|
||||
);
|
||||
= forum_get_children($sub['forum_id'], $currentUserId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../misuzu.php';
|
||||
|
||||
if(!perms_check_user(MSZ_PERMS_FORUM, user_session_current('user_id'), MSZ_PERM_FORUM_VIEW_LEADERBOARD)) {
|
||||
if(!User::hasCurrent() || !perms_check_user(MSZ_PERMS_FORUM, User::getCurrent()->getId(), MSZ_PERM_FORUM_VIEW_LEADERBOARD)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
@ -15,7 +17,7 @@ $leaderboardId = !empty($_GET['id']) && is_string($_GET['id'])
|
|||
: MSZ_FORUM_LEADERBOARD_CATEGORY_ALL;
|
||||
$leaderboardIdLength = strlen($leaderboardId);
|
||||
|
||||
$leaderboardYear = $leaderboardIdLength === 4 || $leaderboardIdLength === 6 ? substr($leaderboardId, 0, 4) : null;
|
||||
$leaderboardYear = $leaderboardIdLength === 4 || $leaderboardIdLength === 6 ? substr($leaderboardId, 0, 4) : null;
|
||||
$leaderboardMonth = $leaderboardIdLength === 6 ? substr($leaderboardId, 4, 2) : null;
|
||||
|
||||
$unrankedForums = !empty($_GET['allow_unranked']) ? [] : Config::get('forum_leader.unranked.forum', Config::TYPE_ARR);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../misuzu.php';
|
||||
|
||||
$redirect = !empty($_SERVER['HTTP_REFERER']) && empty($_SERVER['HTTP_X_MISUZU_XHR']) ? $_SERVER['HTTP_REFERER'] : '';
|
||||
|
@ -18,12 +20,14 @@ if(!CSRF::validateRequest()) {
|
|||
return;
|
||||
}
|
||||
|
||||
if(!user_session_active()) {
|
||||
$currentUser = User::getCurrent();
|
||||
|
||||
if($currentUser === null) {
|
||||
echo render_info_or_json($isXHR, 'You must be logged in to vote on polls.', 401);
|
||||
return;
|
||||
}
|
||||
|
||||
$currentUserId = user_session_current('user_id', 0);
|
||||
$currentUserId = $currentUser->getId();
|
||||
|
||||
if(user_warning_check_expiration($currentUserId, MSZ_WARN_BAN) > 0) {
|
||||
echo render_info_or_json($isXHR, 'You have been banned, check your profile for more information.', 403);
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
namespace Misuzu;
|
||||
|
||||
use Misuzu\AuditLog;
|
||||
use Misuzu\Users\User;
|
||||
use Misuzu\Users\UserSession;
|
||||
|
||||
require_once '../../misuzu.php';
|
||||
|
||||
|
@ -23,12 +25,13 @@ if($isXHR) {
|
|||
|
||||
$postRequestVerified = CSRF::validateRequest();
|
||||
|
||||
if(!empty($postMode) && !user_session_active()) {
|
||||
if(!empty($postMode) && !UserSession::hasCurrent()) {
|
||||
echo render_info_or_json($isXHR, 'You must be logged in to manage posts.', 401);
|
||||
return;
|
||||
}
|
||||
|
||||
$currentUserId = (int)user_session_current('user_id', 0);
|
||||
$currentUser = User::getCurrent():
|
||||
$currentUserId = $currentUser === null ? 0 : $currentUser->getId();
|
||||
|
||||
if(user_warning_check_expiration($currentUserId, MSZ_WARN_BAN) > 0) {
|
||||
echo render_info_or_json($isXHR, 'You have been banned, check your profile for more information.', 403);
|
||||
|
@ -251,7 +254,7 @@ switch($postMode) {
|
|||
break;
|
||||
}
|
||||
|
||||
$postFind = forum_post_find($postInfo['post_id'], user_session_current('user_id', 0));
|
||||
$postFind = forum_post_find($postInfo['post_id'], $currentUserId);
|
||||
|
||||
if(empty($postFind)) {
|
||||
echo render_error(404);
|
||||
|
|
|
@ -3,15 +3,20 @@ namespace Misuzu;
|
|||
|
||||
use Misuzu\Net\IPAddress;
|
||||
use Misuzu\Parsers\Parser;
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../misuzu.php';
|
||||
|
||||
if(!user_session_active()) {
|
||||
$currentUser = User::getCurrent();
|
||||
|
||||
if($currentUser === null) {
|
||||
echo render_error(401);
|
||||
return;
|
||||
}
|
||||
|
||||
if(user_warning_check_restriction(user_session_current('user_id', 0))) {
|
||||
$currentUserId = $currentUser->getId();
|
||||
|
||||
if(user_warning_check_restriction($currentUserId)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
@ -83,7 +88,7 @@ if(empty($forum)) {
|
|||
return;
|
||||
}
|
||||
|
||||
$perms = forum_perms_get_user($forum['forum_id'], user_session_current('user_id'))[MSZ_FORUM_PERMS_GENERAL];
|
||||
$perms = forum_perms_get_user($forum['forum_id'], $currentUserId)[MSZ_FORUM_PERMS_GENERAL];
|
||||
|
||||
if($forum['forum_archived']
|
||||
|| (!empty($topic['topic_locked']) && !perms_check($perms, MSZ_FORUM_PERM_LOCK_TOPIC))
|
||||
|
@ -121,7 +126,7 @@ if($mode === 'edit') {
|
|||
return;
|
||||
}
|
||||
|
||||
if(!perms_check($perms, $post['poster_id'] === user_session_current('user_id') ? MSZ_FORUM_PERM_EDIT_POST : MSZ_FORUM_PERM_EDIT_ANY_POST)) {
|
||||
if(!perms_check($perms, $post['poster_id'] === $currentUserId ? MSZ_FORUM_PERM_EDIT_POST : MSZ_FORUM_PERM_EDIT_ANY_POST)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
@ -142,7 +147,7 @@ if(!empty($_POST)) {
|
|||
$isEditingTopic = empty($topic) || ($mode === 'edit' && $post['is_opening_post']);
|
||||
|
||||
if($mode === 'create') {
|
||||
$timeoutCheck = max(1, forum_timeout($forumId, user_session_current('user_id')));
|
||||
$timeoutCheck = max(1, forum_timeout($forumId, $currentUserId));
|
||||
|
||||
if($timeoutCheck < 5) {
|
||||
$notices[] = sprintf("You're posting too quickly! Please wait %s seconds before posting again.", number_format($timeoutCheck));
|
||||
|
@ -195,7 +200,7 @@ if(!empty($_POST)) {
|
|||
} else {
|
||||
$topicId = forum_topic_create(
|
||||
$forum['forum_id'],
|
||||
user_session_current('user_id', 0),
|
||||
$currentUserId,
|
||||
$topicTitle,
|
||||
$topicType
|
||||
);
|
||||
|
@ -204,13 +209,13 @@ if(!empty($_POST)) {
|
|||
$postId = forum_post_create(
|
||||
$topicId,
|
||||
$forum['forum_id'],
|
||||
user_session_current('user_id', 0),
|
||||
$currentUserId,
|
||||
IPAddress::remote(),
|
||||
$postText,
|
||||
$postParser,
|
||||
$postSignature
|
||||
);
|
||||
forum_topic_mark_read(user_session_current('user_id', 0), $topicId, $forum['forum_id']);
|
||||
forum_topic_mark_read($currentUserId, $topicId, $forum['forum_id']);
|
||||
forum_count_increase($forum['forum_id'], empty($topic));
|
||||
break;
|
||||
|
||||
|
@ -248,7 +253,7 @@ if($mode === 'edit') { // $post is pretty much sure to be populated at this poin
|
|||
Template::set('posting_post', $post);
|
||||
}
|
||||
|
||||
$displayInfo = forum_posting_info(user_session_current('user_id'));
|
||||
$displayInfo = forum_posting_info($currentUserId);
|
||||
|
||||
Template::render('forum.posting', [
|
||||
'posting_breadcrumbs' => forum_get_breadcrumbs($forumId),
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../misuzu.php';
|
||||
|
||||
if(!MSZ_DEBUG) {
|
||||
if(!MSZ_DEBUG)
|
||||
return;
|
||||
}
|
||||
|
||||
$topicId = !empty($_GET['t']) && is_string($_GET['t']) ? (int)$_GET['t'] : 0;
|
||||
$topicUserId = user_session_current('user_id', 0);
|
||||
$topicUser = User::getCurrent();
|
||||
$topicUserId = $topicUser === null ? 0 : $topicUser->getId();
|
||||
|
||||
if($topicUserId < 1) {
|
||||
echo render_error(403);
|
||||
|
@ -48,6 +50,6 @@ if(!forum_has_priority_voting($topic['forum_type'])) {
|
|||
return;
|
||||
}
|
||||
|
||||
forum_topic_priority_increase($topicId, user_session_current('user_id', 0));
|
||||
forum_topic_priority_increase($topicId, $topicUserId);
|
||||
|
||||
url_redirect('forum-topic', ['topic' => $topicId]);
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
namespace Misuzu;
|
||||
|
||||
use Misuzu\AuditLog;
|
||||
use Misuzu\Users\User;
|
||||
use Misuzu\Users\UserSession;
|
||||
|
||||
require_once '../../misuzu.php';
|
||||
|
||||
|
@ -10,7 +12,8 @@ $topicId = !empty($_GET['t']) && is_string($_GET['t']) ? (int)$_GET['t'] : 0;
|
|||
$moderationMode = !empty($_GET['m']) && is_string($_GET['m']) ? (string)$_GET['m'] : '';
|
||||
$submissionConfirmed = !empty($_GET['confirm']) && is_string($_GET['confirm']) && $_GET['confirm'] === '1';
|
||||
|
||||
$topicUserId = user_session_current('user_id', 0);
|
||||
$topicUser = User::getCurrent();
|
||||
$topicUserId = $topicUser === null ? 0 : $this->getId();
|
||||
|
||||
if($topicId < 1 && $postId > 0) {
|
||||
$postInfo = forum_post_find($postId, $topicUserId);
|
||||
|
@ -91,7 +94,7 @@ if(in_array($moderationMode, $validModerationModes, true)) {
|
|||
|
||||
header(CSRF::header());
|
||||
|
||||
if(!user_session_active()) {
|
||||
if(!UserSession::hasCurrent()) {
|
||||
echo render_info_or_json($isXHR, 'You must be logged in to manage posts.', 401);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ use Misuzu\Users\UserNotFoundException;
|
|||
|
||||
require_once '../../../misuzu.php';
|
||||
|
||||
if(!perms_check_user(MSZ_PERMS_CHANGELOG, user_session_current('user_id'), MSZ_PERM_CHANGELOG_MANAGE_CHANGES)) {
|
||||
if(!User::hasCurrent() || !perms_check_user(MSZ_PERMS_CHANGELOG, User::getCurrent()->getId(), MSZ_PERM_CHANGELOG_MANAGE_CHANGES)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Changelog\ChangelogChange;
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../../misuzu.php';
|
||||
|
||||
if(!perms_check_user(MSZ_PERMS_CHANGELOG, user_session_current('user_id'), MSZ_PERM_CHANGELOG_MANAGE_CHANGES)) {
|
||||
if(!User::hasCurrent() || !perms_check_user(MSZ_PERMS_CHANGELOG, User::getCurrent()->getId(), MSZ_PERM_CHANGELOG_MANAGE_CHANGES)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use Misuzu\Users\User;
|
|||
|
||||
require_once '../../../misuzu.php';
|
||||
|
||||
if(!perms_check_user(MSZ_PERMS_CHANGELOG, user_session_current('user_id'), MSZ_PERM_CHANGELOG_MANAGE_TAGS)) {
|
||||
if(!User::hasCurrent() || !perms_check_user(MSZ_PERMS_CHANGELOG, User::getCurrent()->getId(), MSZ_PERM_CHANGELOG_MANAGE_TAGS)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Changelog\ChangelogTag;
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../../misuzu.php';
|
||||
|
||||
if(!perms_check_user(MSZ_PERMS_CHANGELOG, user_session_current('user_id'), MSZ_PERM_CHANGELOG_MANAGE_TAGS)) {
|
||||
if(!User::hasCurrent() || !perms_check_user(MSZ_PERMS_CHANGELOG, User::getCurrent()->getId(), MSZ_PERM_CHANGELOG_MANAGE_TAGS)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../../misuzu.php';
|
||||
|
||||
if(!perms_check_user(MSZ_PERMS_GENERAL, user_session_current('user_id'), MSZ_PERM_FORUM_MANAGE_FORUMS)) {
|
||||
if(!User::hasCurrent() || !perms_check_user(MSZ_PERMS_GENERAL, User::getCurrent()->getId(), MSZ_PERM_FORUM_MANAGE_FORUMS)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../../misuzu.php';
|
||||
|
||||
if(!perms_check_user(MSZ_PERMS_GENERAL, user_session_current('user_id'), MSZ_PERM_FORUM_MANAGE_FORUMS)) {
|
||||
if(!User::hasCurrent() || !perms_check_user(MSZ_PERMS_GENERAL, User::getCurrent()->getId(), MSZ_PERM_FORUM_MANAGE_FORUMS)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Net\IPAddressBlacklist;
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../../misuzu.php';
|
||||
|
||||
if(!perms_check_user(MSZ_PERMS_GENERAL, user_session_current('user_id'), MSZ_PERM_GENERAL_MANAGE_BLACKLIST)) {
|
||||
if(!User::hasCurrent() || !perms_check_user(MSZ_PERMS_GENERAL, User::getCurrent()->getId(), MSZ_PERM_GENERAL_MANAGE_BLACKLIST)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../../misuzu.php';
|
||||
|
||||
if(!perms_check_user(MSZ_PERMS_GENERAL, user_session_current('user_id'), MSZ_PERM_GENERAL_MANAGE_EMOTES)) {
|
||||
if(!User::hasCurrent() || !perms_check_user(MSZ_PERMS_GENERAL, User::getCurrent()->getId(), MSZ_PERM_GENERAL_MANAGE_EMOTES)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../../misuzu.php';
|
||||
|
||||
if(!perms_check_user(MSZ_PERMS_GENERAL, user_session_current('user_id'), MSZ_PERM_GENERAL_MANAGE_EMOTES)) {
|
||||
if(!User::hasCurrent() || !perms_check_user(MSZ_PERMS_GENERAL, User::getCurrent()->getId(), MSZ_PERM_GENERAL_MANAGE_EMOTES)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -144,11 +144,11 @@ $statistics = DB::query('
|
|||
FROM `msz_ip_blacklist`
|
||||
) AS `stat_blacklist`,
|
||||
(
|
||||
SELECT COUNT(`attempt_id`)
|
||||
SELECT COUNT(*)
|
||||
FROM `msz_login_attempts`
|
||||
) AS `stat_login_attempts_total`,
|
||||
(
|
||||
SELECT COUNT(`attempt_id`)
|
||||
SELECT COUNT(*)
|
||||
FROM `msz_login_attempts`
|
||||
WHERE `attempt_success` = 0
|
||||
) AS `stat_login_attempts_failed`,
|
||||
|
|
|
@ -3,10 +3,11 @@ namespace Misuzu;
|
|||
|
||||
use Misuzu\AuditLog;
|
||||
use Misuzu\Pagination;
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../../misuzu.php';
|
||||
|
||||
if(!perms_check_user(MSZ_PERMS_GENERAL, user_session_current('user_id'), MSZ_PERM_GENERAL_VIEW_LOGS)) {
|
||||
if(!User::hasCurrent() || !perms_check_user(MSZ_PERMS_GENERAL, User::getCurrent()->getId(), MSZ_PERM_GENERAL_VIEW_LOGS)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../../misuzu.php';
|
||||
|
||||
if(!perms_check_user(MSZ_PERMS_GENERAL, user_session_current('user_id'), MSZ_PERM_GENERAL_MANAGE_CONFIG)) {
|
||||
if(!User::hasCurrent() || !perms_check_user(MSZ_PERMS_GENERAL, User::getCurrent()->getId(), MSZ_PERM_GENERAL_MANAGE_CONFIG)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
namespace Misuzu;
|
||||
|
||||
use Misuzu\News\NewsCategory;
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../../misuzu.php';
|
||||
|
||||
if(!perms_check_user(MSZ_PERMS_NEWS, user_session_current('user_id'), MSZ_PERM_NEWS_MANAGE_CATEGORIES)) {
|
||||
if(!User::hasCurrent() || !perms_check_user(MSZ_PERMS_NEWS, User::getCurrent()->getId(), MSZ_PERM_NEWS_MANAGE_CATEGORIES)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -4,10 +4,11 @@ namespace Misuzu;
|
|||
use Misuzu\AuditLog;
|
||||
use Misuzu\News\NewsCategory;
|
||||
use Misuzu\News\NewsCategoryNotFoundException;
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../../misuzu.php';
|
||||
|
||||
if(!perms_check_user(MSZ_PERMS_NEWS, user_session_current('user_id'), MSZ_PERM_NEWS_MANAGE_CATEGORIES)) {
|
||||
if(!User::hasCurrent() || !perms_check_user(MSZ_PERMS_NEWS, User::getCurrent()->getId(), MSZ_PERM_NEWS_MANAGE_CATEGORIES)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -5,10 +5,11 @@ use Misuzu\AuditLog;
|
|||
use Misuzu\News\NewsCategory;
|
||||
use Misuzu\News\NewsPost;
|
||||
use Misuzu\News\NewsPostNotFoundException;
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../../misuzu.php';
|
||||
|
||||
if(!perms_check_user(MSZ_PERMS_NEWS, user_session_current('user_id'), MSZ_PERM_NEWS_MANAGE_POSTS)) {
|
||||
if(!User::hasCurrent() || !perms_check_user(MSZ_PERMS_NEWS, User::getCurrent()->getId(), MSZ_PERM_NEWS_MANAGE_POSTS)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
@ -31,7 +32,7 @@ if(!empty($_POST['post']) && CSRF::validateRequest()) {
|
|||
$isNew = true;
|
||||
}
|
||||
|
||||
$currentUserId = user_session_current('user_id');
|
||||
$currentUserId = User::getCurrent()->getId();
|
||||
$postInfo->setTitle( $_POST['post']['title'])
|
||||
->setText($_POST['post']['text'])
|
||||
->setCategoryId($_POST['post']['category'])
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
namespace Misuzu;
|
||||
|
||||
use Misuzu\News\NewsPost;
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../../misuzu.php';
|
||||
|
||||
if(!perms_check_user(MSZ_PERMS_NEWS, user_session_current('user_id'), MSZ_PERM_NEWS_MANAGE_POSTS)) {
|
||||
if(!User::hasCurrent() || !perms_check_user(MSZ_PERMS_NEWS, User::getCurrent()->getId(), MSZ_PERM_NEWS_MANAGE_POSTS)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../../misuzu.php';
|
||||
|
||||
if(!perms_check_user(MSZ_PERMS_USER, user_session_current('user_id'), MSZ_PERM_USER_MANAGE_USERS)) {
|
||||
if(!User::hasCurrent() || !perms_check_user(MSZ_PERMS_USER, User::getCurrent()->getId(), MSZ_PERM_USER_MANAGE_USERS)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
<?php
|
||||
// TODO: UNFUCK THIS FILE
|
||||
namespace Misuzu;
|
||||
|
||||
// TODO: UNFUCK THIS FILE
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../../misuzu.php';
|
||||
|
||||
if(!perms_check_user(MSZ_PERMS_USER, user_session_current('user_id'), MSZ_PERM_USER_MANAGE_ROLES)) {
|
||||
if(!User::hasCurrent() || !perms_check_user(MSZ_PERMS_USER, User::getCurrent()->getId(), MSZ_PERM_USER_MANAGE_ROLES)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
||||
$roleId = $_GET['r'] ?? null;
|
||||
$currentUserId = user_session_current('user_id');
|
||||
$currentUserId = User::getCurrent()->getId();
|
||||
/*$isSuperUser = user_check_super($currentUserId);
|
||||
$canEdit = $isSuperUser || user_check_authority($currentUserId, $userId);*/
|
||||
$canEditPerms = /*$canEdit && */perms_check_user(MSZ_PERMS_USER, $currentUserId, MSZ_PERM_USER_MANAGE_PERMS);
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../../misuzu.php';
|
||||
|
||||
if(!perms_check_user(MSZ_PERMS_USER, user_session_current('user_id'), MSZ_PERM_USER_MANAGE_ROLES)) {
|
||||
if(!User::hasCurrent() || !perms_check_user(MSZ_PERMS_USER, User::getCurrent()->getId(), MSZ_PERM_USER_MANAGE_ROLES)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../../misuzu.php';
|
||||
|
||||
if(!perms_check_user(MSZ_PERMS_USER, user_session_current('user_id'), MSZ_PERM_USER_MANAGE_USERS)) {
|
||||
if(!User::hasCurrent() || !perms_check_user(MSZ_PERMS_USER, User::getCurrent()->getId(), MSZ_PERM_USER_MANAGE_USERS)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
||||
$notices = [];
|
||||
$userId = (int)($_GET['u'] ?? 0);
|
||||
$currentUserId = user_session_current('user_id');
|
||||
$currentUserId = User::getCurrent()->getId();
|
||||
|
||||
if($userId < 1) {
|
||||
echo render_error(404);
|
||||
|
|
|
@ -2,16 +2,17 @@
|
|||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Net\IPAddress;
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../../../misuzu.php';
|
||||
|
||||
if(!perms_check_user(MSZ_PERMS_USER, user_session_current('user_id'), MSZ_PERM_USER_MANAGE_WARNINGS)) {
|
||||
if(!User::hasCurrent() || !perms_check_user(MSZ_PERMS_USER, User::getCurrent()->getId(), MSZ_PERM_USER_MANAGE_WARNINGS)) {
|
||||
echo render_error(403);
|
||||
return;
|
||||
}
|
||||
|
||||
$notices = [];
|
||||
$currentUserId = user_session_current('user_id');
|
||||
$currentUserId = User::getCurrent()->getId();
|
||||
|
||||
if(!empty($_POST['lookup']) && is_string($_POST['lookup'])) {
|
||||
url_redirect('manage-users-warnings', ['user' => user_id_from_username($_POST['lookup'])]);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../misuzu.php';
|
||||
|
||||
$roleId = !empty($_GET['r']) && is_string($_GET['r']) ? (int)$_GET['r'] : MSZ_ROLE_MAIN;
|
||||
|
@ -75,10 +77,7 @@ if(empty($orderDir)) {
|
|||
return;
|
||||
}
|
||||
|
||||
$canManageUsers = perms_check_user(
|
||||
MSZ_PERMS_USER, user_session_current('user_id', 0),
|
||||
MSZ_PERM_USER_MANAGE_USERS
|
||||
);
|
||||
$canManageUsers = perms_check_user(MSZ_PERMS_USER, User::hasCurrent() ? User::getCurrent()->getId() : 0, MSZ_PERM_USER_MANAGE_USERS);
|
||||
|
||||
$role = user_role_get($roleId);
|
||||
|
||||
|
@ -153,7 +152,7 @@ $getUsers = DB::prepare(sprintf(
|
|||
$usersPagination->getRange()
|
||||
));
|
||||
$getUsers->bind('role_id', $role['role_id']);
|
||||
$getUsers->bind('current_user_id', user_session_current('user_id', 0));
|
||||
$getUsers->bind('current_user_id', User::hasCurrent() ? User::getCurrent()->getId() : 0);
|
||||
$users = $getUsers->fetchAll();
|
||||
|
||||
if(empty($users)) {
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Misuzu;
|
|||
use Misuzu\Parsers\Parser;
|
||||
use Misuzu\Users\User;
|
||||
use Misuzu\Users\UserNotFoundException;
|
||||
use Misuzu\Users\UserSession;
|
||||
|
||||
require_once '../misuzu.php';
|
||||
|
||||
|
@ -21,15 +22,16 @@ try {
|
|||
|
||||
$notices = [];
|
||||
|
||||
$currentUserId = user_session_current('user_id', 0);
|
||||
$viewingAsGuest = $currentUserId === 0;
|
||||
$currentUser = User::getCurrent();
|
||||
$viewingAsGuest = $currentUser === null;
|
||||
$currentUserId = $viewingAsGuest ? 0 : $currentUser->getId();
|
||||
$viewingOwnProfile = $currentUserId === $profileUser->getId();
|
||||
|
||||
$isBanned = user_warning_check_restriction($profileUser->getId());
|
||||
$userPerms = perms_get_user($currentUserId)[MSZ_PERMS_USER];
|
||||
$canManageWarnings = perms_check($userPerms, MSZ_PERM_USER_MANAGE_WARNINGS);
|
||||
$canEdit = !$isBanned
|
||||
&& user_session_active()
|
||||
&& UserSession::hasCurrent()
|
||||
&& (
|
||||
$viewingOwnProfile
|
||||
|| user_check_super($currentUserId)
|
||||
|
@ -297,7 +299,7 @@ $profileStats = DB::prepare(sprintf('
|
|||
WHERE `user_id` = :user_id
|
||||
', MSZ_USER_RELATION_FOLLOW))->bind('user_id', $profileUser->getId())->fetch();
|
||||
|
||||
$relationInfo = user_session_active()
|
||||
$relationInfo = UserSession::hasCurrent()
|
||||
? user_relation_info($currentUserId, $profileUser->getId())
|
||||
: [];
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../misuzu.php';
|
||||
|
||||
// basing whether or not this is an xhr request on whether a referrer header is present
|
||||
|
@ -22,14 +24,14 @@ if(!CSRF::validateRequest()) {
|
|||
|
||||
header(CSRF::header());
|
||||
|
||||
if(!user_session_active()) {
|
||||
$currentUser = User::getCurrent();
|
||||
|
||||
if($currentUser === null) {
|
||||
echo render_info_or_json($isXHR, 'You must be logged in to manage relations.', 401);
|
||||
return;
|
||||
}
|
||||
|
||||
$userId = (int)user_session_current('user_id');
|
||||
|
||||
if(user_warning_check_expiration($userId, MSZ_WARN_BAN) > 0) {
|
||||
if(user_warning_check_expiration($currentUser->getId(), MSZ_WARN_BAN) > 0) {
|
||||
echo render_info_or_json($isXHR, 'You have been banned, check your profile for more information.', 403);
|
||||
return;
|
||||
}
|
||||
|
@ -42,12 +44,12 @@ if(!user_relation_is_valid_type($relationType)) {
|
|||
return;
|
||||
}
|
||||
|
||||
if($userId < 1 || $subjectId < 1) {
|
||||
if($currentUser->getId() < 1 || $subjectId < 1) {
|
||||
echo render_info_or_json($isXHR, "That user doesn't exist.", 400);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!user_relation_set($userId, $subjectId, $relationType)) {
|
||||
if(!user_relation_set($currentUser->getId(), $subjectId, $relationType)) {
|
||||
echo render_info_or_json($isXHR, "Failed to save relation.", 500);
|
||||
return;
|
||||
}
|
||||
|
@ -55,7 +57,7 @@ if(!user_relation_set($userId, $subjectId, $relationType)) {
|
|||
|
||||
if(($relationType === MSZ_USER_RELATION_NONE || $relationType === MSZ_USER_RELATION_FOLLOW)
|
||||
&& in_array($subjectId, Config::get('relations.replicate', Config::TYPE_ARR))) {
|
||||
user_relation_set($subjectId, $userId, $relationType);
|
||||
user_relation_set($subjectId, $currentUser->getId(), $relationType);
|
||||
}
|
||||
|
||||
if(!$isXHR) {
|
||||
|
@ -64,7 +66,7 @@ if(!$isXHR) {
|
|||
}
|
||||
|
||||
echo json_encode([
|
||||
'user_id' => $userId,
|
||||
'user_id' => $currentUser->getId(),
|
||||
'subject_id' => $subjectId,
|
||||
'relation_type' => $relationType,
|
||||
]);
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
namespace Misuzu;
|
||||
|
||||
use Misuzu\News\NewsPost;
|
||||
use Misuzu\Users\User;
|
||||
|
||||
require_once '../misuzu.php';
|
||||
|
||||
$searchQuery = !empty($_GET['q']) && is_string($_GET['q']) ? $_GET['q'] : '';
|
||||
|
||||
if(!empty($searchQuery)) {
|
||||
$forumTopics = forum_topic_listing_search($searchQuery, user_session_current('user_id', 0));
|
||||
$forumTopics = forum_topic_listing_search($searchQuery, User::hasCurrent() ? User::getCurrent()->getId() : 0);
|
||||
$forumPosts = forum_post_search($searchQuery);
|
||||
$newsPosts = NewsPost::bySearchQuery($searchQuery);
|
||||
|
||||
|
@ -67,7 +68,7 @@ if(!empty($searchQuery)) {
|
|||
MSZ_USER_RELATION_FOLLOW
|
||||
));
|
||||
$findUsers->bind('query', $searchQuery);
|
||||
$findUsers->bind('current_user_id', user_session_current('user_id', 0));
|
||||
$findUsers->bind('current_user_id', User::hasCurrent() ? User::getCurrent()->getId() : 0);
|
||||
$users = $findUsers->fetchAll();
|
||||
}
|
||||
|
||||
|
|
|
@ -3,12 +3,13 @@ namespace Misuzu;
|
|||
|
||||
use Misuzu\AuditLog;
|
||||
use Misuzu\Users\User;
|
||||
use Misuzu\Users\UserSession;
|
||||
use chillerlan\QRCode\QRCode;
|
||||
use chillerlan\QRCode\QROptions;
|
||||
|
||||
require_once '../../misuzu.php';
|
||||
|
||||
if(!user_session_active()) {
|
||||
if(!UserSession::hasCurrent()) {
|
||||
echo render_error(401);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -4,10 +4,11 @@ namespace Misuzu;
|
|||
use ZipArchive;
|
||||
use Misuzu\AuditLog;
|
||||
use Misuzu\Users\User;
|
||||
use Misuzu\Users\UserSession;
|
||||
|
||||
require_once '../../misuzu.php';
|
||||
|
||||
if(!user_session_active()) {
|
||||
if(!UserSession::hasCurrent()) {
|
||||
echo render_error(401);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Users\UserSession;
|
||||
|
||||
require_once '../../misuzu.php';
|
||||
|
||||
if(!user_session_active()) {
|
||||
if(!UserSession::hasCurrent()) {
|
||||
echo render_error(401);
|
||||
return;
|
||||
}
|
||||
|
||||
// do something with this page
|
||||
|
||||
url_redirect('settings-account');
|
||||
|
|
|
@ -2,17 +2,22 @@
|
|||
namespace Misuzu;
|
||||
|
||||
use Misuzu\AuditLog;
|
||||
use Misuzu\Users\User;
|
||||
use Misuzu\Users\UserSession;
|
||||
use Misuzu\Users\UserSessionNotFoundException;
|
||||
|
||||
require_once '../../misuzu.php';
|
||||
|
||||
if(!user_session_active()) {
|
||||
if(!User::hasCurrent()) {
|
||||
echo render_error(401);
|
||||
return;
|
||||
}
|
||||
|
||||
$errors = [];
|
||||
$currentUserId = user_session_current('user_id');
|
||||
$sessionActive = user_session_current('session_id');
|
||||
$currentUser = User::getCurrent();
|
||||
$currentSession = UserSession::getCurrent();
|
||||
$currentUserId = $currentUser->getId();
|
||||
$sessionActive = $currentSession->getId();;
|
||||
|
||||
if(!empty($_POST['session']) && CSRF::validateRequest()) {
|
||||
$currentSessionKilled = false;
|
||||
|
@ -20,23 +25,24 @@ if(!empty($_POST['session']) && CSRF::validateRequest()) {
|
|||
if(is_array($_POST['session'])) {
|
||||
foreach($_POST['session'] as $sessionId) {
|
||||
$sessionId = intval($sessionId);
|
||||
$session = user_session_find($sessionId);
|
||||
|
||||
if(!$session || (int)$session['user_id'] !== $currentUserId) {
|
||||
try {
|
||||
$sessionInfo = UserSession::byId($sessionId);
|
||||
} catch(UserSessionNotFoundException $ex) {}
|
||||
|
||||
if(empty($sessionInfo) || $sessionInfo->getUserId() !== $currentUser->getId()) {
|
||||
$errors[] = "Session #{$sessionId} does not exist.";
|
||||
continue;
|
||||
} elseif((int)$session['session_id'] === $sessionActive) {
|
||||
} elseif($sessionInfo->getId() === $sessionActive) {
|
||||
$currentSessionKilled = true;
|
||||
}
|
||||
|
||||
user_session_delete($session['session_id']);
|
||||
AuditLog::create(AuditLog::PERSONAL_SESSION_DESTROY, [
|
||||
$session['session_id'],
|
||||
]);
|
||||
$sessionInfo->delete();
|
||||
AuditLog::create(AuditLog::PERSONAL_SESSION_DESTROY, [$sessionInfo->getId()]);
|
||||
}
|
||||
} elseif($_POST['session'] === 'all') {
|
||||
$currentSessionKilled = true;
|
||||
user_session_purge_all($currentUserId);
|
||||
UserSession::purgeUser($currentUser);
|
||||
AuditLog::create(AuditLog::PERSONAL_SESSION_DESTROY_ALL);
|
||||
}
|
||||
|
||||
|
@ -46,17 +52,11 @@ if(!empty($_POST['session']) && CSRF::validateRequest()) {
|
|||
}
|
||||
}
|
||||
|
||||
$sessionPagination = new Pagination(user_session_count($currentUserId), 15);
|
||||
|
||||
$sessionList = user_session_list(
|
||||
$sessionPagination->getOffset(),
|
||||
$sessionPagination->getRange(),
|
||||
$currentUserId
|
||||
);
|
||||
$pagination = new Pagination(UserSession::countAll($currentUser), 15);
|
||||
|
||||
Template::render('settings.sessions', [
|
||||
'errors' => $errors,
|
||||
'session_list' => $sessionList,
|
||||
'session_active_id' => $sessionActive,
|
||||
'session_pagination' => $sessionPagination,
|
||||
'session_list' => UserSession::all($pagination, $currentUser),
|
||||
'session_current' => $currentSession,
|
||||
'session_pagination' => $pagination,
|
||||
]);
|
||||
|
|
|
@ -22,7 +22,7 @@ $canViewImages = !$userExists
|
|||
|| !user_warning_check_expiration($userId, MSZ_WARN_BAN)
|
||||
|| (
|
||||
parse_url($_SERVER['HTTP_REFERER'] ?? '', PHP_URL_PATH) === url('user-profile')
|
||||
&& perms_check_user(MSZ_PERMS_USER, user_session_current('user_id', 0), MSZ_PERM_USER_MANAGE_USERS)
|
||||
&& perms_check_user(MSZ_PERMS_USER, User::hasCurrent() ? User::getCurrent()->getId() : 0, MSZ_PERM_USER_MANAGE_USERS)
|
||||
);
|
||||
|
||||
switch($userAssetsMode) {
|
||||
|
|
90
src/AuthToken.php
Normal file
90
src/AuthToken.php
Normal file
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use Misuzu\Users\User;
|
||||
use Misuzu\Users\UserSession;
|
||||
|
||||
class AuthToken {
|
||||
public const VERSION = 1;
|
||||
public const WIDTH = 37;
|
||||
|
||||
private $userId = -1;
|
||||
private $sessionToken = '';
|
||||
|
||||
private $user = null;
|
||||
private $session = null;
|
||||
|
||||
public function isValid(): bool {
|
||||
return $this->getUserId() > 0
|
||||
&& !empty($this->getSessionToken());
|
||||
}
|
||||
|
||||
public function getUserId(): int {
|
||||
return $this->userId < 1 ? -1 : $this->userId;
|
||||
}
|
||||
public function setUserId(int $userId): self {
|
||||
$this->user = null;
|
||||
$this->userId = $userId;
|
||||
return $this;
|
||||
}
|
||||
public function getUser(): User {
|
||||
if($this->user === null)
|
||||
$this->user = User::byId($this->getUserId());
|
||||
return $this->user;
|
||||
}
|
||||
public function setUser(User $user): self {
|
||||
$this->user = $user;
|
||||
$this->userId = $user->getId();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSessionToken(): string {
|
||||
return $this->sessionToken ?? '';
|
||||
}
|
||||
public function setSessionToken(string $token): self {
|
||||
$this->session = null;
|
||||
$this->sessionToken = $token;
|
||||
return $this;
|
||||
}
|
||||
public function getSession(): UserSession {
|
||||
if($this->session === null)
|
||||
$this->session = UserSession::byToken($this->getSessionToken());
|
||||
return $this->session;
|
||||
}
|
||||
public function setSession(UserSession $session): self {
|
||||
$this->session = $session;
|
||||
$this->sessionToken = $session->getToken();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function pack(bool $base64 = true): string {
|
||||
$packed = pack('CNH*', self::VERSION, $this->getUserId(), $this->getSessionToken());
|
||||
if($base64)
|
||||
$packed = Base64::encode($packed, true);
|
||||
return $packed;
|
||||
}
|
||||
|
||||
public static function unpack(string $data, bool $base64 = true): self {
|
||||
$obj = new static;
|
||||
|
||||
if(empty($data))
|
||||
return $obj;
|
||||
if($base64)
|
||||
$data = Base64::decode($data, true);
|
||||
|
||||
$data = str_pad($data, self::WIDTH, "\x00");
|
||||
$data = unpack('Cversion/Nuser/H*token', $data);
|
||||
|
||||
if($data['version'] >= 1)
|
||||
$obj->setUserId($data['user'])
|
||||
->setSessionToken($data['token']);
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
public static function create(User $user, UserSession $session): self {
|
||||
return (new static)
|
||||
->setUser($user)
|
||||
->setSession($session);
|
||||
}
|
||||
}
|
|
@ -3,10 +3,12 @@ namespace Misuzu\Http\Filters;
|
|||
|
||||
use Misuzu\Http\HttpResponseMessage;
|
||||
use Misuzu\Http\HttpRequestMessage;
|
||||
use Misuzu\Users\User;
|
||||
use Misuzu\Users\UserSession;
|
||||
|
||||
class EnforceLogInFilter implements FilterInterface {
|
||||
public function process(HttpRequestMessage $request): ?HttpResponseMessage {
|
||||
if(!user_session_active())
|
||||
if(!UserSession::hasCurrent() || !User::hasCurrent())
|
||||
return new HttpResponseMessage(403);
|
||||
|
||||
return null;
|
||||
|
|
|
@ -3,10 +3,12 @@ namespace Misuzu\Http\Filters;
|
|||
|
||||
use Misuzu\Http\HttpResponseMessage;
|
||||
use Misuzu\Http\HttpRequestMessage;
|
||||
use Misuzu\Users\User;
|
||||
use Misuzu\Users\UserSession;
|
||||
|
||||
class EnforceLogOutFilter implements FilterInterface {
|
||||
public function process(HttpRequestMessage $request): ?HttpResponseMessage {
|
||||
if(user_session_active())
|
||||
if(UserSession::hasCurrent() || User::hasCurrent())
|
||||
return new HttpResponseMessage(404);
|
||||
|
||||
return null;
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Misuzu\Http\Handlers;
|
|||
use HttpResponse;
|
||||
use HttpRequest;
|
||||
use Misuzu\CSRF;
|
||||
use Misuzu\Users\User;
|
||||
|
||||
final class ForumHandler extends Handler {
|
||||
public function markAsReadGET(HttpResponse $response, HttpRequest $request): void {
|
||||
|
@ -20,7 +21,7 @@ final class ForumHandler extends Handler {
|
|||
|
||||
public function markAsReadPOST(HttpResponse $response, HttpRequest $request) {
|
||||
$forumId = (int)$request->getBodyParam('forum', FILTER_SANITIZE_NUMBER_INT);
|
||||
forum_mark_read($forumId, user_session_current('user_id'));
|
||||
forum_mark_read($forumId, User::getCurrent()->getId());
|
||||
|
||||
$response->redirect(
|
||||
url($forumId ? 'forum-category' : 'forum-index', ['forum' => $forumId]),
|
||||
|
|
|
@ -8,6 +8,7 @@ use Misuzu\DB;
|
|||
use Misuzu\Pagination;
|
||||
use Misuzu\Changelog\ChangelogChange;
|
||||
use Misuzu\News\NewsPost;
|
||||
use Misuzu\Users\UserSession;
|
||||
|
||||
final class HomeHandler extends Handler {
|
||||
public function index(HttpResponse $response, HttpRequest $request): void {
|
||||
|
@ -58,7 +59,7 @@ final class HomeHandler extends Handler {
|
|||
|
||||
$changelog = ChangelogChange::all(new Pagination(10));
|
||||
|
||||
$birthdays = user_session_active() ? user_get_birthdays() : [];
|
||||
$birthdays = UserSession::hasCurrent() ? user_get_birthdays() : [];
|
||||
|
||||
$latestUser = DB::query('
|
||||
SELECT
|
||||
|
|
|
@ -3,6 +3,7 @@ namespace Misuzu\Http\Handlers;
|
|||
|
||||
use HttpResponse;
|
||||
use HttpRequest;
|
||||
use Misuzu\AuthToken;
|
||||
use Misuzu\Base64;
|
||||
use Misuzu\Config;
|
||||
use Misuzu\DB;
|
||||
|
@ -13,6 +14,8 @@ use Misuzu\Users\UserNotFoundException;
|
|||
use Misuzu\Users\UserChatToken;
|
||||
use Misuzu\Users\UserChatTokenNotFoundException;
|
||||
use Misuzu\Users\UserChatTokenCreationFailedException;
|
||||
use Misuzu\Users\UserSession;
|
||||
use Misuzu\Users\UserSessionNotFoundException;
|
||||
|
||||
final class SockChatHandler extends Handler {
|
||||
private string $hashKey = 'woomy';
|
||||
|
@ -222,21 +225,27 @@ final class SockChatHandler extends Handler {
|
|||
// $userId = $authInfo->user_id;
|
||||
} elseif($authMethod === 'SESS:') {
|
||||
$sessionToken = mb_substr($authInfo->token, 5);
|
||||
$tokenData = user_session_cookie_unpack(
|
||||
Base64::decode($sessionToken, true),
|
||||
true
|
||||
);
|
||||
|
||||
if(isset($tokenData['session_token']))
|
||||
$sessionToken = $tokenData['session_token'];
|
||||
$authToken = AuthToken::unpack($sessionToken);
|
||||
if($authToken->isValid())
|
||||
$sessionToken = $authToken->getSessionToken();
|
||||
|
||||
user_session_start($authInfo->user_id, $sessionToken);
|
||||
try {
|
||||
$sessionInfo = UserSession::byToken($sessionToken);
|
||||
} catch(UserSessionNotFoundException $ex) {
|
||||
return ['success' => false, 'reason' => 'token'];
|
||||
}
|
||||
|
||||
if(user_session_active()) {
|
||||
$userId = user_session_current('user_id');
|
||||
user_bump_last_active($userId);
|
||||
user_session_bump_active(user_session_current('session_id'));
|
||||
} else return ['success' => false, 'reason' => 'expired'];
|
||||
if($sessionInfo->getUserId() !== $userInfo->getId())
|
||||
return ['success' => false, 'reason' => 'user'];
|
||||
|
||||
if($sessionInfo->hasExpired()) {
|
||||
$sessionInfo->delete();
|
||||
return ['success' => false, 'reason' => 'expired'];
|
||||
}
|
||||
|
||||
$sessionInfo->bump();
|
||||
user_bump_last_active($userInfo->getId());
|
||||
} else {
|
||||
try {
|
||||
$token = UserChatToken::byExact($userInfo, $authInfo->token);
|
||||
|
|
|
@ -173,16 +173,19 @@ class User {
|
|||
public static function unsetCurrent(): void {
|
||||
self::$localUser = null;
|
||||
}
|
||||
public static function getCurrent(): ?User {
|
||||
public static function getCurrent(): ?self {
|
||||
return self::$localUser;
|
||||
}
|
||||
public static function hasCurrent(): bool {
|
||||
return self::$localUser !== null;
|
||||
}
|
||||
|
||||
public static function create(
|
||||
string $username,
|
||||
string $password,
|
||||
string $email,
|
||||
string $ipAddress
|
||||
): ?User {
|
||||
): ?self {
|
||||
$createUser = DB::prepare('
|
||||
INSERT INTO `msz_users` (
|
||||
`username`, `password`, `email`, `register_ip`,
|
||||
|
@ -210,7 +213,7 @@ class User {
|
|||
return $memoizer;
|
||||
}
|
||||
|
||||
public static function byId(int $userId): ?User {
|
||||
public static function byId(int $userId): ?self {
|
||||
return self::getMemoizer()->find($userId, function() use ($userId) {
|
||||
$user = DB::prepare(self::USER_SELECT . 'WHERE `user_id` = :user_id')
|
||||
->bind('user_id', $userId)
|
||||
|
@ -220,7 +223,7 @@ class User {
|
|||
return $user;
|
||||
});
|
||||
}
|
||||
public static function findForLogin(string $usernameOrEmail): ?User {
|
||||
public static function findForLogin(string $usernameOrEmail): ?self {
|
||||
$usernameOrEmailLower = mb_strtolower($usernameOrEmail);
|
||||
return self::getMemoizer()->find(function($user) use ($usernameOrEmailLower) {
|
||||
return mb_strtolower($user->getUsername()) === $usernameOrEmailLower
|
||||
|
@ -235,7 +238,7 @@ class User {
|
|||
return $user;
|
||||
});
|
||||
}
|
||||
public static function findForProfile($userIdOrName): ?User {
|
||||
public static function findForProfile($userIdOrName): ?self {
|
||||
$userIdOrNameLower = mb_strtolower($userIdOrName);
|
||||
return self::getMemoizer()->find(function($user) use ($userIdOrNameLower) {
|
||||
return $user->getId() == $userIdOrNameLower || mb_strtolower($user->getUsername()) === $userIdOrNameLower;
|
||||
|
|
|
@ -67,7 +67,7 @@ class UserLoginAttempt {
|
|||
}
|
||||
|
||||
public static function remaining(?string $remoteAddr = null): int {
|
||||
$remoteAddr = $ipAddress ?? IPAddress::remote();
|
||||
$remoteAddr = $remoteAddr ?? IPAddress::remote();
|
||||
return (int)DB::prepare(
|
||||
'SELECT 5 - COUNT(*)'
|
||||
. ' FROM `' . DB::PREFIX . self::TABLE . '`'
|
||||
|
@ -79,7 +79,7 @@ class UserLoginAttempt {
|
|||
}
|
||||
|
||||
public static function create(bool $success, ?User $user = null, ?string $remoteAddr = null, string $userAgent = null): void {
|
||||
$remoteAddr = $ipAddress ?? IPAddress::remote();
|
||||
$remoteAddr = $remoteAddr ?? IPAddress::remote();
|
||||
$userAgent = $userAgent ?? filter_input(INPUT_SERVER, 'HTTP_USER_AGENT', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH) ?? '';
|
||||
$createLog = DB::prepare(
|
||||
'INSERT INTO `' . DB::PREFIX . self::TABLE . '` (`user_id`, `attempt_success`, `attempt_ip`, `attempt_country`, `attempt_user_agent`)'
|
||||
|
|
256
src/Users/UserSession.php
Normal file
256
src/Users/UserSession.php
Normal file
|
@ -0,0 +1,256 @@
|
|||
<?php
|
||||
namespace Misuzu\Users;
|
||||
|
||||
use Misuzu\DB;
|
||||
use Misuzu\Pagination;
|
||||
use Misuzu\Net\IPAddress;
|
||||
use WhichBrowser\Parser as UserAgentParser;
|
||||
|
||||
class UserSessionException extends UsersException {}
|
||||
class UserSessionCreationFailedException extends UserSessionException {}
|
||||
class UserSessionNotFoundException extends UserSessionException {}
|
||||
|
||||
class UserSession {
|
||||
public const TOKEN_SIZE = 64;
|
||||
public const LIFETIME = 60 * 60 * 24 * 31;
|
||||
|
||||
// Database fields
|
||||
private $session_id = -1;
|
||||
private $user_id = -1;
|
||||
private $session_key = '';
|
||||
private $session_ip = '::1';
|
||||
private $session_ip_last = null;
|
||||
private $session_user_agent = '';
|
||||
private $session_country = 'XX';
|
||||
private $session_expires = null;
|
||||
private $session_expires_bump = 1;
|
||||
private $session_created = null;
|
||||
private $session_active = null;
|
||||
|
||||
private $user = null;
|
||||
private $uaInfo = null;
|
||||
|
||||
private static $localSession = null;
|
||||
|
||||
public const TABLE = 'sessions';
|
||||
private const QUERY_SELECT = 'SELECT %1$s FROM `' . DB::PREFIX . self::TABLE . '` AS '. self::TABLE;
|
||||
private const SELECT = '%1$s.`session_id`, %1$s.`user_id`, %1$s.`session_key`, %1$s.`session_user_agent`, %1$s.`session_country`, %1$s.`session_expires_bump`'
|
||||
. ', INET6_NTOA(%1$s.`session_ip`) AS `session_ip`'
|
||||
. ', INET6_NTOA(%1$s.`session_ip_last`) AS `session_ip_last`'
|
||||
. ', UNIX_TIMESTAMP(%1$s.`session_created`) AS `session_created`'
|
||||
. ', UNIX_TIMESTAMP(%1$s.`session_active`) AS `session_active`'
|
||||
. ', UNIX_TIMESTAMP(%1$s.`session_expires`) AS `session_expires`';
|
||||
|
||||
public function getId(): int {
|
||||
return $this->session_id < 1 ? -1 : $this->session_id;
|
||||
}
|
||||
|
||||
public function getUserId(): int {
|
||||
return $this->user_id < 1 ? -1 : $this->user_id;
|
||||
}
|
||||
public function getUser(): User {
|
||||
if($this->user === null)
|
||||
$this->user = User::byId($this->getUserId());
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function getToken(): string {
|
||||
return $this->session_key;
|
||||
}
|
||||
|
||||
public function getInitialRemoteAddress(): string {
|
||||
return $this->session_ip;
|
||||
}
|
||||
|
||||
public function getLastRemoteAddress(): string {
|
||||
return $this->session_ip_last ?? '';
|
||||
}
|
||||
public function hasLastRemoteAddress(): bool {
|
||||
return !empty($this->session_ip_last);
|
||||
}
|
||||
public function setLastRemoteAddress(string $remoteAddr): self {
|
||||
$this->session_ip_last = $remoteAddr;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUserAgent(): string {
|
||||
return $this->session_user_agent;
|
||||
}
|
||||
public function getUserAgentInfo(): UserAgentParser {
|
||||
if($this->uaInfo === null)
|
||||
$this->uaInfo = new UserAgentParser($this->getUserAgent());
|
||||
return $this->uaInfo;
|
||||
}
|
||||
|
||||
public function getCountry(): string {
|
||||
return $this->session_country;
|
||||
}
|
||||
public function getCountryName(): string {
|
||||
return get_country_name($this->getCountry());
|
||||
}
|
||||
|
||||
public function getCreatedTime(): int {
|
||||
return $this->session_created === null ? -1 : $this->session_created;
|
||||
}
|
||||
|
||||
public function getActiveTime(): int {
|
||||
return $this->session_active === null ? -1 : $this->session_active;
|
||||
}
|
||||
public function hasActiveTime(): bool {
|
||||
return $this->session_active !== null;
|
||||
}
|
||||
public function setActiveTime(int $timestamp): self {
|
||||
if($timestamp > $this->session_active)
|
||||
$this->session_active = $timestamp;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getExpiresTime(): int {
|
||||
return $this->session_expires === null ? -1 : $this->session_expires;
|
||||
}
|
||||
public function setExpiresTime(int $timestamp): self {
|
||||
$this->session_expires = $timestamp;
|
||||
return $this;
|
||||
}
|
||||
public function hasExpired(): bool {
|
||||
return $this->getExpiresTime() <= time();
|
||||
}
|
||||
|
||||
public function shouldBumpExpire(): bool {
|
||||
return boolval($this->session_expires_bump);
|
||||
}
|
||||
|
||||
public function bump(bool $callUpdate = true, ?int $timestamp = null, ?string $remoteAddr = null): void {
|
||||
$timestamp = $timestamp ?? time();
|
||||
$remoteAddr = $remoteAddr ?? IPAddress::remote();
|
||||
|
||||
$this->setActiveTime($timestamp)
|
||||
->setLastRemoteAddress($remoteAddr);
|
||||
|
||||
if($this->shouldBumpExpire())
|
||||
$this->setExpiresTime($timestamp + self::LIFETIME);
|
||||
|
||||
if($callUpdate)
|
||||
$this->update();
|
||||
}
|
||||
|
||||
public function delete(): void {
|
||||
DB::prepare('DELETE FROM `' . DB::PREFIX . self::TABLE . '` WHERE `session_id` = :session')
|
||||
->bind('session', $this->getId())
|
||||
->execute();
|
||||
}
|
||||
|
||||
public static function purgeUser(User $user): void {
|
||||
DB::prepare('DELETE FROM `' . DB::PREFIX . self::TABLE . '` WHERE `user_id` = :user')
|
||||
->bind('user', $user->getId())
|
||||
->execute();
|
||||
}
|
||||
|
||||
public function setCurrent(): void {
|
||||
self::$localSession = $this;
|
||||
}
|
||||
public static function unsetCurrent(): void {
|
||||
self::$localSession = null;
|
||||
}
|
||||
public static function getCurrent(): ?self {
|
||||
return self::$localSession;
|
||||
}
|
||||
public static function hasCurrent(): bool {
|
||||
return self::$localSession !== null;
|
||||
}
|
||||
|
||||
public static function generateToken(): string {
|
||||
return bin2hex(random_bytes(self::TOKEN_SIZE / 2));
|
||||
}
|
||||
|
||||
public function update(): void {
|
||||
DB::prepare(
|
||||
'UPDATE `' . DB::PREFIX . self::TABLE . '`'
|
||||
. ' SET `session_active` = FROM_UNIXTIME(:active), `session_ip_last` = INET6_ATON(:remote_addr), `session_expires` = FROM_UNIXTIME(:expires)'
|
||||
. ' WHERE `session_id` = :session'
|
||||
) ->bind('active', $this->session_active)
|
||||
->bind('remote_addr', $this->session_ip_last)
|
||||
->bind('expires', $this->session_expires)
|
||||
->bind('session', $this->session_id)
|
||||
->execute();
|
||||
}
|
||||
|
||||
public static function create(User $user, ?string $remoteAddr = null, ?string $userAgent = null, ?string $token = null): self {
|
||||
$remoteAddr = $remoteAddr ?? IPAddress::remote();
|
||||
$userAgent = $userAgent ?? filter_input(INPUT_SERVER, 'HTTP_USER_AGENT', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH) ?? '';
|
||||
$token = $token ?? self::generateToken();
|
||||
|
||||
$sessionId = DB::prepare(
|
||||
'INSERT INTO `' . DB::PREFIX . self::TABLE . '`'
|
||||
. ' (`user_id`, `session_ip`, `session_country`, `session_user_agent`, `session_key`, `session_created`, `session_expires`)'
|
||||
. ' VALUES (:user, INET6_ATON(:remote_addr), :country, :user_agent, :token, NOW(), NOW() + INTERVAL :expires SECOND)'
|
||||
) ->bind('user', $user->getId())
|
||||
->bind('remote_addr', $remoteAddr)
|
||||
->bind('country', IPAddress::country($remoteAddr))
|
||||
->bind('user_agent', $userAgent)
|
||||
->bind('token', $token)
|
||||
->bind('expires', self::LIFETIME)
|
||||
->executeGetId();
|
||||
|
||||
if($sessionId < 1)
|
||||
throw new UserSessionCreationFailedException;
|
||||
|
||||
return self::byId($sessionId);
|
||||
}
|
||||
|
||||
private static function countQueryBase(): string {
|
||||
return sprintf(self::QUERY_SELECT, sprintf('COUNT(*)', self::TABLE));
|
||||
}
|
||||
public static function countAll(?User $user = null): int {
|
||||
$getCount = DB::prepare(
|
||||
self::countQueryBase()
|
||||
. ($user === null ? '' : ' WHERE `user_id` = :user')
|
||||
);
|
||||
if($user !== null)
|
||||
$getCount->bind('user', $user->getId());
|
||||
return (int)$getCount->fetchColumn();
|
||||
}
|
||||
|
||||
private static function byQueryBase(): string {
|
||||
return sprintf(self::QUERY_SELECT, sprintf(self::SELECT, self::TABLE));
|
||||
}
|
||||
public static function byId(int $sessionId): self {
|
||||
$session = DB::prepare(self::byQueryBase() . ' WHERE `session_id` = :session_id')
|
||||
->bind('session_id', $sessionId)
|
||||
->fetchObject(self::class);
|
||||
|
||||
if(!$session)
|
||||
throw new UserSessionNotFoundException;
|
||||
|
||||
return $session;
|
||||
}
|
||||
public static function byToken(string $token): self {
|
||||
$session = DB::prepare(self::byQueryBase() . ' WHERE `session_key` = :token')
|
||||
->bind('token', $token)
|
||||
->fetchObject(self::class);
|
||||
|
||||
if(!$session)
|
||||
throw new UserSessionNotFoundException;
|
||||
|
||||
return $session;
|
||||
}
|
||||
public static function all(?Pagination $pagination = null, ?User $user = null): array {
|
||||
$sessionsQuery = self::byQueryBase()
|
||||
. ($user === null ? '' : ' WHERE `user_id` = :user')
|
||||
. ' ORDER BY `session_created` DESC';
|
||||
|
||||
if($pagination !== null)
|
||||
$sessionsQuery .= ' LIMIT :range OFFSET :offset';
|
||||
|
||||
$getSessions = DB::prepare($sessionsQuery);
|
||||
|
||||
if($user !== null)
|
||||
$getSessions->bind('user', $user->getId());
|
||||
|
||||
if($pagination !== null)
|
||||
$getSessions->bind('range', $pagination->getRange())
|
||||
->bind('offset', $pagination->getOffset());
|
||||
|
||||
return $getSessions->fetchObjects(self::class);
|
||||
}
|
||||
}
|
|
@ -1,211 +1,90 @@
|
|||
<?php
|
||||
define('MSZ_SESSION_KEY_SIZE', 64);
|
||||
// These functions are used by external scripts that hook into Misuzu.
|
||||
// They will remain in a backwards compatible manner for the time being.
|
||||
|
||||
function user_session_create(
|
||||
int $userId,
|
||||
string $ipAddress,
|
||||
string $userAgent
|
||||
): string {
|
||||
$sessionKey = user_session_generate_key();
|
||||
|
||||
$createSession = \Misuzu\DB::prepare('
|
||||
INSERT INTO `msz_sessions`
|
||||
(
|
||||
`user_id`, `session_ip`, `session_country`,
|
||||
`session_user_agent`, `session_key`, `session_created`, `session_expires`
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
:user_id, INET6_ATON(:session_ip), :session_country,
|
||||
:session_user_agent, :session_key, NOW(), NOW() + INTERVAL 1 MONTH
|
||||
)
|
||||
');
|
||||
$createSession->bind('user_id', $userId);
|
||||
$createSession->bind('session_ip', $ipAddress);
|
||||
$createSession->bind('session_country', \Misuzu\Net\IPAddress::country($ipAddress));
|
||||
$createSession->bind('session_user_agent', $userAgent);
|
||||
$createSession->bind('session_key', $sessionKey);
|
||||
|
||||
return $createSession->execute() ? $sessionKey : '';
|
||||
}
|
||||
|
||||
function user_session_find($sessionId, bool $byKey = false): array {
|
||||
if(!$byKey && $sessionId < 1) {
|
||||
return [];
|
||||
function user_session_create(int $userId, string $ipAddress, string $userAgent): string {
|
||||
try {
|
||||
$userInfo = \Misuzu\Users\User::byId($userId);
|
||||
} catch(\Misuzu\Users\UserNotFoundException $ex) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$findSession = \Misuzu\DB::prepare(sprintf('
|
||||
SELECT
|
||||
`session_id`, `user_id`,
|
||||
INET6_NTOA(`session_ip`) as `session_ip`,
|
||||
INET6_NTOA(`session_ip_last`) as `session_ip_last`,
|
||||
`session_country`, `session_user_agent`, `session_key`, `session_created`,
|
||||
`session_expires`, `session_active`, `session_expires_bump`
|
||||
FROM `msz_sessions`
|
||||
WHERE `%s` = :session_id
|
||||
', $byKey ? 'session_key' : 'session_id'));
|
||||
$findSession->bind('session_id', $sessionId);
|
||||
return $findSession->fetch();
|
||||
}
|
||||
|
||||
function user_session_delete(int $sessionId): void {
|
||||
$deleteSession = \Misuzu\DB::prepare('
|
||||
DELETE FROM `msz_sessions`
|
||||
WHERE `session_id` = :session_id
|
||||
');
|
||||
$deleteSession->bind('session_id', $sessionId);
|
||||
$deleteSession->execute();
|
||||
}
|
||||
|
||||
function user_session_generate_key(): string {
|
||||
return bin2hex(random_bytes(MSZ_SESSION_KEY_SIZE / 2));
|
||||
}
|
||||
|
||||
function user_session_purge_all(int $userId): void {
|
||||
\Misuzu\DB::prepare('
|
||||
DELETE FROM `msz_sessions`
|
||||
WHERE `user_id` = :user_id
|
||||
')->execute([
|
||||
'user_id' => $userId,
|
||||
]);
|
||||
}
|
||||
|
||||
function user_session_count($userId = 0): int {
|
||||
$getCount = \Misuzu\DB::prepare(sprintf('
|
||||
SELECT COUNT(`session_id`)
|
||||
FROM `msz_sessions`
|
||||
%s
|
||||
', $userId < 1 ? '' : 'WHERE `user_id` = :user_id'));
|
||||
|
||||
if($userId >= 1) {
|
||||
$getCount->bind('user_id', $userId);
|
||||
try {
|
||||
$sessionInfo = \Misuzu\Users\UserSession::create($userInfo, $ipAddress, $userAgent);
|
||||
} catch(\Misuzu\Users\UserSessionCreationFailedException $ex) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return (int)$getCount->fetchColumn();
|
||||
return $sessionInfo->getToken();
|
||||
}
|
||||
|
||||
function user_session_list(int $offset, int $take, int $userId = 0): array {
|
||||
$offset = max(0, $offset);
|
||||
$take = max(1, $take);
|
||||
|
||||
$getSessions = \Misuzu\DB::prepare(sprintf('
|
||||
SELECT
|
||||
`session_id`, `session_country`, `session_user_agent`, `session_created`,
|
||||
`session_expires`, `session_active`, `session_expires_bump`,
|
||||
INET6_NTOA(`session_ip`) as `session_ip`,
|
||||
INET6_NTOA(`session_ip_last`) as `session_ip_last`
|
||||
FROM `msz_sessions`
|
||||
WHERE %s
|
||||
ORDER BY `session_id` DESC
|
||||
LIMIT :offset, :take
|
||||
', $userId < 1 ? '1' : '`user_id` = :user_id'));
|
||||
|
||||
if($userId > 0) {
|
||||
$getSessions->bind('user_id', $userId);
|
||||
}
|
||||
|
||||
$getSessions->bind('offset', $offset);
|
||||
$getSessions->bind('take', $take);
|
||||
|
||||
return $getSessions->fetchAll();
|
||||
}
|
||||
|
||||
function user_session_bump_active(int $sessionId, string $ipAddress = null): void {
|
||||
if($sessionId < 1) {
|
||||
function user_session_bump_active(int $sessionId, ?string $ipAddress = null): void {
|
||||
try {
|
||||
$sessionInfo = \Misuzu\Users\UserSession::byId($sessionId);
|
||||
} catch(\Misuzu\Users\UserSessionNotFoundException $ex) {
|
||||
return;
|
||||
}
|
||||
|
||||
$bump = \Misuzu\DB::prepare('
|
||||
UPDATE `msz_sessions`
|
||||
SET `session_active` = NOW(),
|
||||
`session_ip_last` = INET6_ATON(:last_ip),
|
||||
`session_expires` = IF(`session_expires_bump`, NOW() + INTERVAL 1 MONTH, `session_expires`)
|
||||
WHERE `session_id` = :session_id
|
||||
');
|
||||
$bump->bind('session_id', $sessionId);
|
||||
$bump->bind('last_ip', $ipAddress ?? \Misuzu\Net\IPAddress::remote());
|
||||
$bump->execute();
|
||||
}
|
||||
if($ipAddress !== null)
|
||||
$sessionInfo->setLastRemoteAddress($ipAddress);
|
||||
|
||||
// the functions below this line are imperative
|
||||
|
||||
function user_session_data(?array $newData = null): array {
|
||||
static $data = [];
|
||||
|
||||
if(!is_null($newData)) {
|
||||
$data = $newData;
|
||||
}
|
||||
|
||||
return $data;
|
||||
$sessionInfo->bump();
|
||||
}
|
||||
|
||||
function user_session_start(int $userId, string $sessionKey): bool {
|
||||
$session = user_session_find($sessionKey, true);
|
||||
$session = \Misuzu\Users\UserSession::getCurrent();
|
||||
|
||||
if(!$session || $session['user_id'] !== $userId) {
|
||||
if($session !== null
|
||||
&& $session->getToken() === $sessionKey
|
||||
&& $session->getUserId() === $userId)
|
||||
return true;
|
||||
|
||||
try {
|
||||
$session = \Misuzu\Users\UserSession::byToken($sessionKey);
|
||||
} catch(\Misuzu\Users\UserSessionNotFoundException $ex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(time() >= strtotime($session['session_expires'])) {
|
||||
user_session_delete($session['session_id']);
|
||||
if($session->getUserId() !== $userId)
|
||||
return false;
|
||||
|
||||
if($session->hasExpired()) {
|
||||
$session->delete();
|
||||
return false;
|
||||
}
|
||||
|
||||
user_session_data($session);
|
||||
$session->setCurrent();
|
||||
return true;
|
||||
}
|
||||
|
||||
function user_session_stop(bool $delete = false): void {
|
||||
if(empty(user_session_data())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if($delete) {
|
||||
user_session_delete(user_session_data()['session_id']);
|
||||
}
|
||||
|
||||
user_session_data([]);
|
||||
}
|
||||
|
||||
function user_session_current(?string $variable = null, $default = null) {
|
||||
if(empty($variable)) {
|
||||
return user_session_data() ?? [];
|
||||
}
|
||||
$getVar = !empty($variable);
|
||||
$session = \Misuzu\Users\UserSession::getCurrent();
|
||||
|
||||
return user_session_data()[$variable] ?? $default;
|
||||
if($session === null)
|
||||
return $getVar ? $default : [];
|
||||
|
||||
$data = [
|
||||
'session_id' => $session->getId(),
|
||||
'user_id' => $session->getUserId(),
|
||||
'session_ip' => $session->getInitialRemoteAddress(),
|
||||
'session_ip_last' => $session->getLastRemoteAddress(),
|
||||
'session_country' => $session->getCountry(),
|
||||
'session_user_agent' => $session->getUserAgent(),
|
||||
'session_key' => $session->getToken(),
|
||||
'session_created' => $session->getCreatedTime(),
|
||||
'session_expires' => $session->getExpiresTime(),
|
||||
'session_active' => ($date = $session->getActiveTime()) < 0 ? null : $date,
|
||||
'session_expires_bump' => $session->shouldBumpExpire() ? 1 : 0,
|
||||
];
|
||||
|
||||
if(!$getVar)
|
||||
return $data;
|
||||
|
||||
return $data[$variable] ?? $default;
|
||||
}
|
||||
|
||||
function user_session_active(): bool {
|
||||
return !empty(user_session_data())
|
||||
&& time() < strtotime(user_session_data()['session_expires']);
|
||||
}
|
||||
|
||||
define('MSZ_SESSION_COOKIE_VERSION', 1);
|
||||
// make sure to match this to the final fixed size of the cookie string
|
||||
// it'll pad older tokens out for backwards compatibility
|
||||
define('MSZ_SESSION_COOKIE_SIZE', 37);
|
||||
|
||||
function user_session_cookie_pack(int $userId, string $sessionToken): ?string {
|
||||
if(strlen($sessionToken) !== MSZ_SESSION_KEY_SIZE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return pack('CNH64', MSZ_SESSION_COOKIE_VERSION, $userId, $sessionToken);
|
||||
}
|
||||
|
||||
function user_session_cookie_unpack(string $packed): array {
|
||||
$packed = str_pad($packed, MSZ_SESSION_COOKIE_SIZE, "\x00");
|
||||
$unpacked = unpack('Cversion/Nuser/H64token', $packed);
|
||||
|
||||
if($unpacked['version'] < 1 || $unpacked['version'] > MSZ_SESSION_COOKIE_VERSION) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Make sure this contains all fields with a default for version > 1 exclusive stuff
|
||||
$data = [
|
||||
'user_id' => $unpacked['user'],
|
||||
'session_token' => $unpacked['token'],
|
||||
];
|
||||
|
||||
return $data;
|
||||
return \Misuzu\Users\UserSession::hasCurrent()
|
||||
&& !\Misuzu\Users\UserSession::getCurrent()->hasExpired();
|
||||
}
|
||||
|
|
|
@ -22,8 +22,8 @@ function manage_get_menu(int $userId): array {
|
|||
$menu['Users & Roles']['Users'] = url('manage-users');
|
||||
if(perms_check_user(MSZ_PERMS_USER, $userId, MSZ_PERM_USER_MANAGE_ROLES))
|
||||
$menu['Users & Roles']['Roles'] = url('manage-roles');
|
||||
if(perms_check_user(MSZ_PERMS_USER, $userId, MSZ_PERM_USER_MANAGE_REPORTS))
|
||||
$menu['Users & Roles']['Reports'] = url('manage-users-reports');
|
||||
//if(perms_check_user(MSZ_PERMS_USER, $userId, MSZ_PERM_USER_MANAGE_REPORTS))
|
||||
// $menu['Users & Roles']['Reports'] = url('manage-users-reports');
|
||||
if(perms_check_user(MSZ_PERMS_USER, $userId, MSZ_PERM_USER_MANAGE_WARNINGS))
|
||||
$menu['Users & Roles']['Warnings'] = url('manage-users-warnings');
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
<div class="settings__sessions__list">
|
||||
{% for session in session_list %}
|
||||
{{ user_session(session, session.session_id == session_active_id) }}
|
||||
{{ user_session(session, session_current.id == session.id) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
|
|
|
@ -123,18 +123,18 @@
|
|||
{% macro user_session(session, is_current_session) %}
|
||||
{% from '_layout/input.twig' import input_hidden, input_csrf, input_checkbox_raw %}
|
||||
|
||||
<div class="settings__session{% if is_current_session %} settings__session--current{% endif %}" id="session-{{ session.session_id }}">
|
||||
<div class="settings__session{% if is_current_session %} settings__session--current{% endif %}" id="session-{{ session.id }}">
|
||||
<div class="settings__session__container">
|
||||
<div class="settings__session__important">
|
||||
<div class="flag flag--{{ session.session_country|lower }} settings__session__flag" title="{{ session.session_country|country_name }}">{{ session.session_country }}</div>
|
||||
<div class="flag flag--{{ session.country|lower }} settings__session__flag" title="{{ session.countryName }}">{{ session.country }}</div>
|
||||
|
||||
<div class="settings__session__description">
|
||||
{{ session.session_user_agent|default('')|as_platform }}
|
||||
{{ session.userAgentInfo.toString }}
|
||||
</div>
|
||||
|
||||
<form class="settings__session__actions" method="post" action="{{ url('settings-sessions') }}">
|
||||
{{ input_csrf() }}
|
||||
{{ input_hidden('session[]', session.session_id) }}
|
||||
{{ input_hidden('session[]', session.id) }}
|
||||
|
||||
<button class="settings__session__action" title="{{ is_current_session ? 'Logout' : 'End Session' }}">
|
||||
{% if is_current_session %}
|
||||
|
@ -152,46 +152,46 @@
|
|||
Created from IP
|
||||
</div>
|
||||
<div class="settings__session__detail__value">
|
||||
{{ session.session_ip }}
|
||||
{{ session.initialRemoteAddress }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if session.session_ip_last is not null %}
|
||||
{% if session.hasLastRemoteAddress %}
|
||||
<div class="settings__session__detail">
|
||||
<div class="settings__session__detail__title">
|
||||
Last used from IP
|
||||
</div>
|
||||
<div class="settings__session__detail__value">
|
||||
{{ session.session_ip_last }}
|
||||
{{ session.lastRemoteAddress }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="settings__session__detail" title="{{ session.session_created|date('r') }}">
|
||||
<div class="settings__session__detail" title="{{ session.createdTime|date('r') }}">
|
||||
<div class="settings__session__detail__title">
|
||||
Created
|
||||
</div>
|
||||
<time class="settings__session__detail__value" datetime="{{ session.session_created|date('c') }}">
|
||||
{{ session.session_created|time_diff }}
|
||||
<time class="settings__session__detail__value" datetime="{{ session.createdTime|date('c') }}">
|
||||
{{ session.createdTime|time_diff }}
|
||||
</time>
|
||||
</div>
|
||||
|
||||
<div class="settings__session__detail" title="{{ session.session_expires|date('r') }}">
|
||||
<div class="settings__session__detail" title="{{ session.expiresTime|date('r') }}">
|
||||
<div class="settings__session__detail__title">
|
||||
Expires{% if not session.session_expires_bump %} (static){% endif %}
|
||||
Expires{% if not session.shouldBumpExpire %} (static){% endif %}
|
||||
</div>
|
||||
<time class="settings__session__detail__value" datetime="{{ session.session_expires|date('c') }}">
|
||||
{{ session.session_expires|time_diff }}
|
||||
<time class="settings__session__detail__value" datetime="{{ session.expiresTime|date('c') }}">
|
||||
{{ session.expiresTime|time_diff }}
|
||||
</time>
|
||||
</div>
|
||||
|
||||
{% if session.session_active is not null %}
|
||||
<div class="settings__session__detail" title="{{ session.session_active|date('r') }}">
|
||||
{% if session.hasActiveTime %}
|
||||
<div class="settings__session__detail" title="{{ session.activeTime|date('r') }}">
|
||||
<div class="settings__session__detail__title">
|
||||
Last Active
|
||||
</div>
|
||||
<time class="settings__session__detail__value" datetime="{{ session.session_active|date('c') }}">
|
||||
{{ session.session_active|time_diff }}
|
||||
<time class="settings__session__detail__value" datetime="{{ session.activeTime|date('c') }}">
|
||||
{{ session.activeTime|time_diff }}
|
||||
</time>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
@ -201,7 +201,7 @@
|
|||
User Agent
|
||||
</div>
|
||||
<div class="settings__session__detail__value">
|
||||
{{ session.session_user_agent|length > 0 ? session.session_user_agent : 'None' }}
|
||||
{{ session.userAgent is empty ? 'None' : session.userAgent }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue