fix deployment db issue and widthrawal administration page
This commit is contained in:
@@ -1,15 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers\View;
|
||||
use App\Controllers\BaseController;
|
||||
use Config\SessionTimeout;
|
||||
use CodeIgniter\Controller;
|
||||
use CodeIgniter\API\ResponseTrait;
|
||||
|
||||
class SessionTimeoutController extends BaseController
|
||||
use CodeIgniter\API\ResponseTrait;
|
||||
use CodeIgniter\Controller;
|
||||
use CodeIgniter\HTTP\RequestInterface;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
use Config\SessionTimeout;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Lightweight session heartbeat endpoints.
|
||||
* Intentionally does not extend BaseController to avoid school-year / API priming.
|
||||
*/
|
||||
class SessionTimeoutController extends Controller
|
||||
{
|
||||
use ResponseTrait;
|
||||
|
||||
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
|
||||
{
|
||||
parent::initController($request, $response, $logger);
|
||||
session();
|
||||
}
|
||||
|
||||
public function getTimeoutConfig()
|
||||
{
|
||||
return $this->response->setJSON([
|
||||
@@ -17,77 +31,121 @@ class SessionTimeoutController extends BaseController
|
||||
'timeout' => SessionTimeout::TIMEOUT_DURATION,
|
||||
'warning_time' => SessionTimeout::TIMEOUT_DURATION - SessionTimeout::WARNING_THRESHOLD,
|
||||
'check_interval' => SessionTimeout::CLIENT_CHECK_INTERVAL,
|
||||
'ping_interval' => SessionTimeout::CLIENT_PING_INTERVAL,
|
||||
'logout_url' => site_url('logout'),
|
||||
'keep_alive_url' => site_url('session/ping-activity'),
|
||||
'check_url' => site_url('session/check-timeout')
|
||||
'check_url' => site_url('session/check-timeout'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function checkTimeout()
|
||||
{
|
||||
$session = session();
|
||||
try {
|
||||
$session = session();
|
||||
|
||||
// Verify session exists and has last_activity
|
||||
if (!$session->has('last_activity')) {
|
||||
return $this->expireSession();
|
||||
}
|
||||
if (! $session->has('last_activity')) {
|
||||
return $this->expireSession();
|
||||
}
|
||||
|
||||
$lastActivity = $session->get('last_activity');
|
||||
$elapsed = time() - $lastActivity;
|
||||
$lastActivity = (int) $session->get('last_activity');
|
||||
$elapsed = time() - $lastActivity;
|
||||
|
||||
if ($elapsed >= SessionTimeout::TIMEOUT_DURATION) {
|
||||
return $this->expireSession();
|
||||
}
|
||||
|
||||
if ($elapsed >= SessionTimeout::WARNING_THRESHOLD) {
|
||||
return $this->response->setJSON([
|
||||
'status' => 'warning',
|
||||
'time_remaining' => SessionTimeout::TIMEOUT_DURATION - $elapsed,
|
||||
]);
|
||||
}
|
||||
|
||||
if ($elapsed >= SessionTimeout::TIMEOUT_DURATION) {
|
||||
return $this->expireSession();
|
||||
} elseif ($elapsed >= SessionTimeout::WARNING_THRESHOLD) {
|
||||
return $this->response->setJSON([
|
||||
'status' => 'warning',
|
||||
'time_remaining' => SessionTimeout::TIMEOUT_DURATION - $elapsed
|
||||
'status' => 'active',
|
||||
'time_remaining' => SessionTimeout::TIMEOUT_DURATION - $elapsed,
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
$this->logDbFailureOnce('session/check-timeout', $e);
|
||||
|
||||
return $this->response
|
||||
->setStatusCode(503)
|
||||
->setJSON([
|
||||
'status' => 'error',
|
||||
'message' => 'Session check temporarily unavailable.',
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => 'active',
|
||||
'time_remaining' => SessionTimeout::TIMEOUT_DURATION - $elapsed
|
||||
]);
|
||||
}
|
||||
|
||||
public function pingActivity()
|
||||
{
|
||||
$session = session();
|
||||
|
||||
// Only update if session is still valid
|
||||
if (!$session->has('last_activity') ||
|
||||
(time() - $session->get('last_activity') >= SessionTimeout::TIMEOUT_DURATION)) {
|
||||
return $this->expireSession();
|
||||
try {
|
||||
$session = session();
|
||||
|
||||
if (! $session->has('last_activity')
|
||||
|| (time() - (int) $session->get('last_activity') >= SessionTimeout::TIMEOUT_DURATION)
|
||||
) {
|
||||
return $this->expireSession();
|
||||
}
|
||||
|
||||
$session->set('last_activity', time());
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => 'active',
|
||||
'time_remaining' => SessionTimeout::TIMEOUT_DURATION,
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
$this->logDbFailureOnce('session/ping-activity', $e);
|
||||
|
||||
return $this->response
|
||||
->setStatusCode(503)
|
||||
->setJSON([
|
||||
'status' => 'error',
|
||||
'message' => 'Activity ping temporarily unavailable.',
|
||||
]);
|
||||
}
|
||||
|
||||
$session->set('last_activity', time());
|
||||
return $this->response->setJSON([
|
||||
'status' => 'active',
|
||||
'time_remaining' => SessionTimeout::TIMEOUT_DURATION
|
||||
]);
|
||||
}
|
||||
|
||||
private function expireSession()
|
||||
{
|
||||
$this->destroySession();
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => 'expired',
|
||||
'redirect' => site_url('login'),
|
||||
'message' => 'Your session has expired due to inactivity.'
|
||||
'message' => 'Your session has expired due to inactivity.',
|
||||
]);
|
||||
}
|
||||
|
||||
private function destroySession()
|
||||
private function destroySession(): void
|
||||
{
|
||||
$session = session();
|
||||
$session->setFlashdata('error', 'Your session has expired due to inactivity.');
|
||||
|
||||
// Clear session data
|
||||
$session->remove('last_activity');
|
||||
$session->destroy();
|
||||
|
||||
if (session_status() === PHP_SESSION_ACTIVE) {
|
||||
session_regenerate_id(true);
|
||||
try {
|
||||
$session = session();
|
||||
$session->setFlashdata('error', 'Your session has expired due to inactivity.');
|
||||
$session->remove('last_activity');
|
||||
$session->destroy();
|
||||
|
||||
if (session_status() === PHP_SESSION_ACTIVE) {
|
||||
session_regenerate_id(true);
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
$this->logDbFailureOnce('session/destroy', $e);
|
||||
}
|
||||
}
|
||||
|
||||
private function logDbFailureOnce(string $endpoint, Throwable $e): void
|
||||
{
|
||||
static $logged = [];
|
||||
|
||||
$key = $endpoint . '|' . get_class($e);
|
||||
if (isset($logged[$key])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$logged[$key] = true;
|
||||
log_message('error', 'Session endpoint failure on {endpoint}: {message}', [
|
||||
'endpoint' => $endpoint,
|
||||
'message' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user