/home/ivoiecob/email.hirewise-va.com/system/UserSession.php
<?php
/**
* This code is licensed under AGPLv3 license or Afterlogic Software License
* if commercial version of the product was purchased.
* For full statements of the licenses see LICENSE-AFTERLOGIC and LICENSE-AGPL3 files.
*/
namespace Aurora\System;
use Aurora\System\Models\AuthToken;
/**
* @license https://www.gnu.org/licenses/agpl-3.0.html AGPL-3.0
* @license https://afterlogic.com/products/common-licensing Afterlogic Software License
* @copyright Copyright (c) 2019, Afterlogic Corp.
*
* @package Api
*/
class UserSession
{
public const TOKEN_VERSION = '3.1';
public static $aTokensCache = [];
public static function getTokenData($oAccount, $bSignMe = true)
{
return [
'token' => 'auth',
'sign-me' => $bSignMe,
'id' => $oAccount->IdUser,
'account' => $oAccount->Id,
'account_type' => get_class($oAccount)
];
}
public function Set($aData, $iTime = 0, $iExpire = 0)
{
$aData['@time'] = $iTime;
$aData['@expire'] = $iExpire;
$aData['@ver'] = self::TOKEN_VERSION;
if ($iExpire > 0) {
$aData['@expire'] = $iExpire;
}
$sAuthToken = Api::EncodeKeyValues(
$aData
);
if (\Aurora\Api::GetSettings()->GetValue('StoreAuthTokenInDB', false)) {
$account = $aData['account'] ?? 0;
$account_type = $aData['account_type'] ?? '';
$this->SetToDB($aData['id'], $account, $account_type, $sAuthToken);
}
return $sAuthToken;
}
public function UpdateTimestamp($sAuthToken, $iTime = 0)
{
$aData = $this->Get($sAuthToken);
return $this->Set($aData, $iTime);
}
public function Get($sAuthToken)
{
$mAuthTokenData = false;
$mResult = true;
if (is_string($sAuthToken) && strlen($sAuthToken) !== 0) {
$bStoreAuthTokenInDB = \Aurora\Api::GetSettings()->GetValue('StoreAuthTokenInDB', false);
// check if the auth token is stored in the database
if ($bStoreAuthTokenInDB && !$this->GetFromDB($sAuthToken)) {
return false;
}
$mAuthTokenData = Api::DecodeKeyValues($sAuthToken);
// checking the validity of auth token data
if ($mAuthTokenData && isset($mAuthTokenData['id'])) {
$oUser = Api::getUserById((int) $mAuthTokenData['id']);
// check if user is disabled
if ($oUser && $oUser->IsDisabled) {
$mResult = false;
}
// check auth token version
if ($mResult) {
if ((isset($mAuthTokenData['@ver']) && $mAuthTokenData['@ver'] !== self::TOKEN_VERSION) || !isset($mAuthTokenData['@ver'])) {
$mResult = false;
}
}
// check auth token expiration date
if ($mResult) {
$iExpireTime = (int) isset($mAuthTokenData['@expire']) ? $mAuthTokenData['@expire'] : 0;
if ($iExpireTime > 0 && $iExpireTime < time()) {
$mResult = false;
}
}
// checking the token is valid from timestamp
if ($mResult && isset($mAuthTokenData['account'], $mAuthTokenData['account_type']) && class_exists($mAuthTokenData['account_type'])) {
$iTime = (int) $mAuthTokenData['@time']; // 0 means that signMe was true when user logged in, so there is no need to check it in that case
$oAccount = $mAuthTokenData['account_type']::where('Id', $mAuthTokenData['account'])->first();
if ($oAccount && $iTime !== 0 && (int) $oAccount->getExtendedProp('TokensValidFromTimestamp') > $iTime) {
$mResult = false;
}
}
// check user sessions that are considered expired
if ($mResult) {
if ((isset($mAuthTokenData['sign-me']) && !((bool) $mAuthTokenData['sign-me'])) || (!isset($mAuthTokenData['sign-me']))) {
$iTime = 0;
if (isset($mAuthTokenData['@time'])) {
$iTime = (int) $mAuthTokenData['@time'];
}
$iExpireUserSessionsBeforeTimestamp = \Aurora\System\Api::GetSettings()->GetValue("ExpireUserSessionsBeforeTimestamp", 0);
if ($iExpireUserSessionsBeforeTimestamp > $iTime && $iTime > 0) {
$mResult = false;
}
}
}
} else {
$mResult = false;
}
if (!$mResult) {
$this->Delete($sAuthToken);
$mAuthTokenData = $mResult;
\Aurora\System\Api::Log('User session expired: ');
\Aurora\System\Api::LogObject($mAuthTokenData);
}
}
return $mAuthTokenData;
}
public function Delete($sAuthToken)
{
if (is_string($sAuthToken) && \Aurora\Api::GetSettings()->GetValue('StoreAuthTokenInDB', false)) {
try {
$this->DeleteFromDB($sAuthToken);
} catch (\Aurora\System\Exceptions\DbException $oEx) {
// DB is not configured
}
}
}
public function DeleteAllUserSessions($iUserId)
{
return AuthToken::where('UserId', $iUserId)->delete();
}
public function DeleteAllAccountSessions($oAccount)
{
if ($oAccount instanceof \Aurora\System\Classes\Account) {
$iAccountId = $oAccount->Id;
$sAccountType = get_class($oAccount);
if (\Aurora\Api::GetSettings()->GetValue('StoreAuthTokenInDB', false)) {
try {
AuthToken::where('AccountId', $iAccountId)->where('AccountType', $sAccountType)->delete();
} catch (\Aurora\System\Exceptions\DbException $oEx) {
// DB is not configured
}
} else {
if (class_exists($sAccountType)) {
$oAccount = $sAccountType::where('Id', $iAccountId)->first();
if ($oAccount) {
$oAccount->setExtendedProp('TokensValidFromTimestamp', time());
$oAccount->save();
}
}
}
}
}
public function SetToDB($iUserId, $iAccountId, $sAccountType, $sAuthToken)
{
$oAuthToken = AuthToken::where('UserId', $iUserId)
->where('AccountId', $iAccountId)
->where('AccountType', $sAccountType)
->where('Token', $sAuthToken)
->first();
if (!$oAuthToken) {
$oAuthToken = new AuthToken();
}
$oAuthToken->UserId = $iUserId;
$oAuthToken->AccountId = $iAccountId;
$oAuthToken->AccountType = $sAccountType;
$oAuthToken->Token = $sAuthToken;
$oAuthToken->LastUsageDateTime = time();
try {
$oAuthToken->save();
} catch (\Aurora\System\Exceptions\DbException $oEx) {
// DB is not configured
}
}
public function GetFromDB($sAuthToken)
{
if (!isset(self::$aTokensCache[$sAuthToken])) {
try {
$oAuthToken = AuthToken::firstWhere('Token', $sAuthToken);
if ($oAuthToken) {
$oAuthToken->LastUsageDateTime = time();
$oAuthToken->save();
self::$aTokensCache[$sAuthToken] = $oAuthToken;
}
} catch (\Aurora\System\Exceptions\DbException $oEx) {
\Aurora\Api::LogException($oEx);
}
}
return isset(self::$aTokensCache[$sAuthToken]) ? self::$aTokensCache[$sAuthToken] : false;
}
public function DeleteFromDB($sAuthToken)
{
AuthToken::where('Token', $sAuthToken)->delete();
}
public function GetExpiredAuthTokens($iDays)
{
$iTime = $iDays * 86400;
return AuthToken::query()->whereRaw('(LastUsageDateTime + ' . $iTime . ') < UNIX_TIMESTAMP()')->get();
}
public function DeleteExpiredAuthTokens($iDays)
{
$iTime = $iDays * 86400;
return AuthToken::query()->whereRaw('(LastUsageDateTime + ' . $iTime . ') < UNIX_TIMESTAMP()')->delete();
}
public function GetUserSessionsFromDB($iUserId)
{
return AuthToken::where('UserId', $iUserId)->get();
}
}