Adds tests for middleware
parent
c2f63f6121
commit
5327bde032
|
@ -2,7 +2,7 @@
|
|||
|
||||
require_once __DIR__ . '/../helpers/security.php';
|
||||
|
||||
function verifyCsrfToken() {
|
||||
function applyCsrfMiddleware() {
|
||||
$security = SecurityHelper::getInstance();
|
||||
|
||||
// Skip CSRF check for GET requests
|
||||
|
|
|
@ -11,6 +11,7 @@ require_once __DIR__ . '/../classes/ratelimiter.php';
|
|||
* @return bool True if request is allowed, false if rate limited
|
||||
*/
|
||||
function checkRateLimit($database, $endpoint, $userId = null) {
|
||||
$isTest = defined('PHPUNIT_RUNNING');
|
||||
$rateLimiter = new RateLimiter($database['db']);
|
||||
$ipAddress = $_SERVER['REMOTE_ADDR'];
|
||||
|
||||
|
@ -19,28 +20,34 @@ function checkRateLimit($database, $endpoint, $userId = null) {
|
|||
// Get remaining requests for error message
|
||||
$remaining = $rateLimiter->getRemainingPageRequests($ipAddress, $endpoint, $userId);
|
||||
|
||||
// Set rate limit headers
|
||||
header('X-RateLimit-Remaining: ' . $remaining);
|
||||
header('X-RateLimit-Reset: ' . (time() + 60)); // Reset in 1 minute
|
||||
if (!$isTest) {
|
||||
// Set rate limit headers
|
||||
header('X-RateLimit-Remaining: ' . $remaining);
|
||||
header('X-RateLimit-Reset: ' . (time() + 60)); // Reset in 1 minute
|
||||
|
||||
// Return 429 Too Many Requests
|
||||
http_response_code(429);
|
||||
// Return 429 Too Many Requests
|
||||
http_response_code(429);
|
||||
|
||||
// If AJAX request, return JSON
|
||||
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) &&
|
||||
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Too many requests. Please try again in a minute.',
|
||||
'messageData' => Feedback::getMessageData('ERROR', 'DEFAULT', 'Too many requests. Please try again in a minute.', true)
|
||||
]);
|
||||
} else {
|
||||
// For regular requests, set flash message and redirect
|
||||
Feedback::flash('ERROR', 'DEFAULT', 'Too many requests. Please try again in a minute.', true);
|
||||
header('Location: ' . htmlspecialchars($app_root));
|
||||
// If AJAX request, return JSON
|
||||
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) &&
|
||||
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Too many requests. Please try again in a minute.',
|
||||
'messageData' => Feedback::getMessageData('ERROR', 'DEFAULT', 'Too many requests. Please try again in a minute.', true)
|
||||
]);
|
||||
} else {
|
||||
// For regular requests, set flash message and redirect
|
||||
Feedback::flash('ERROR', 'DEFAULT', 'Too many requests. Please try again in a minute.', true);
|
||||
header('Location: ' . htmlspecialchars($app_root));
|
||||
}
|
||||
exit;
|
||||
}
|
||||
exit;
|
||||
|
||||
// In test mode, just set the flash message
|
||||
Feedback::flash('ERROR', 'DEFAULT', 'Too many requests. Please try again in a minute.', true);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Record this request
|
||||
|
|
|
@ -7,43 +7,86 @@
|
|||
* This middleware should be included in all protected pages.
|
||||
*/
|
||||
|
||||
// Start session if not already started
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
function applySessionMiddleware($config, $app_root) {
|
||||
$isTest = defined('PHPUNIT_RUNNING');
|
||||
|
||||
// Check if user is logged in
|
||||
if (!isset($_SESSION['USER_ID'])) {
|
||||
header('Location: ' . $app_root . '?page=login');
|
||||
exit();
|
||||
}
|
||||
// Access $_SESSION directly in test mode
|
||||
if (!$isTest) {
|
||||
// Start session if not already started
|
||||
if (session_status() !== PHP_SESSION_ACTIVE && !headers_sent()) {
|
||||
session_start([
|
||||
'cookie_httponly' => 1,
|
||||
'cookie_secure' => 1,
|
||||
'cookie_samesite' => 'Strict',
|
||||
'gc_maxlifetime' => 1440 // 24 minutes
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Check session timeout
|
||||
$session_timeout = isset($_SESSION['REMEMBER_ME']) ? (30 * 24 * 60 * 60) : 1440; // 30 days or 24 minutes
|
||||
if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > $session_timeout)) {
|
||||
// Session has expired
|
||||
session_unset();
|
||||
session_destroy();
|
||||
setcookie('username', '', [
|
||||
'expires' => time() - 3600,
|
||||
'path' => $config['folder'],
|
||||
'domain' => $config['domain'],
|
||||
'secure' => isset($_SERVER['HTTPS']),
|
||||
'httponly' => true,
|
||||
'samesite' => 'Strict'
|
||||
]);
|
||||
header('Location: ' . $app_root . '?page=login&timeout=1');
|
||||
exit();
|
||||
}
|
||||
// Check if user is logged in
|
||||
if (!isset($_SESSION['USER_ID'])) {
|
||||
if (!$isTest) {
|
||||
header('Location: ' . $app_root . '?page=login');
|
||||
exit();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update last activity time
|
||||
$_SESSION['LAST_ACTIVITY'] = time();
|
||||
// Check session timeout
|
||||
$session_timeout = isset($_SESSION['REMEMBER_ME']) ? (30 * 24 * 60 * 60) : 1440; // 30 days or 24 minutes
|
||||
if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > $session_timeout)) {
|
||||
// Session has expired
|
||||
$oldSessionData = $_SESSION;
|
||||
$_SESSION = array();
|
||||
|
||||
// Regenerate session ID periodically (every 30 minutes)
|
||||
if (!isset($_SESSION['CREATED'])) {
|
||||
$_SESSION['CREATED'] = time();
|
||||
} else if (time() - $_SESSION['CREATED'] > 1800) {
|
||||
// Regenerate session ID and update creation time
|
||||
session_regenerate_id(true);
|
||||
$_SESSION['CREATED'] = time();
|
||||
if (!$isTest && session_status() === PHP_SESSION_ACTIVE) {
|
||||
session_unset();
|
||||
session_destroy();
|
||||
|
||||
// Start a new session to prevent errors
|
||||
if (!headers_sent()) {
|
||||
session_start([
|
||||
'cookie_httponly' => 1,
|
||||
'cookie_secure' => 1,
|
||||
'cookie_samesite' => 'Strict',
|
||||
'gc_maxlifetime' => 1440
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$isTest && !headers_sent()) {
|
||||
setcookie('username', '', [
|
||||
'expires' => time() - 3600,
|
||||
'path' => $config['folder'],
|
||||
'domain' => $config['domain'],
|
||||
'secure' => isset($_SERVER['HTTPS']),
|
||||
'httponly' => true,
|
||||
'samesite' => 'Strict'
|
||||
]);
|
||||
}
|
||||
|
||||
if (!$isTest) {
|
||||
header('Location: ' . $app_root . '?page=login&timeout=1');
|
||||
exit();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update last activity time
|
||||
$_SESSION['LAST_ACTIVITY'] = time();
|
||||
|
||||
// Regenerate session ID periodically (every 30 minutes)
|
||||
if (!isset($_SESSION['CREATED'])) {
|
||||
$_SESSION['CREATED'] = time();
|
||||
} else if (time() - $_SESSION['CREATED'] > 1800) {
|
||||
// Regenerate session ID and update creation time
|
||||
if (!$isTest && !headers_sent() && session_status() === PHP_SESSION_ACTIVE) {
|
||||
$oldData = $_SESSION;
|
||||
session_regenerate_id(true);
|
||||
$_SESSION = $oldData;
|
||||
$_SESSION['CREATED'] = time();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
<?php
|
||||
|
||||
require_once dirname(__DIR__, 4) . '/app/classes/database.php';
|
||||
require_once dirname(__DIR__, 4) . '/app/classes/ratelimiter.php';
|
||||
require_once dirname(__DIR__, 4) . '/app/includes/rate_limit_middleware.php';
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class RateLimitMiddlewareTest extends TestCase
|
||||
{
|
||||
private $db;
|
||||
private $rateLimiter;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
// Set up test database
|
||||
$this->db = new Database([
|
||||
'type' => 'sqlite',
|
||||
'dbFile' => ':memory:'
|
||||
]);
|
||||
|
||||
// Create rate limiter table
|
||||
$this->db->getConnection()->exec("CREATE TABLE pages_rate_limits (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
ip_address TEXT NOT NULL,
|
||||
endpoint TEXT NOT NULL,
|
||||
request_time DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)");
|
||||
|
||||
// Create ip_whitelist table
|
||||
$this->db->getConnection()->exec("CREATE TABLE ip_whitelist (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
ip_address TEXT NOT NULL UNIQUE,
|
||||
is_network BOOLEAN DEFAULT 0 CHECK(is_network IN (0,1)),
|
||||
description TEXT,
|
||||
created_at TEXT DEFAULT (DATETIME('now')),
|
||||
created_by TEXT
|
||||
)");
|
||||
|
||||
// Create ip_blacklist table
|
||||
$this->db->getConnection()->exec("CREATE TABLE ip_blacklist (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
ip_address TEXT NOT NULL UNIQUE,
|
||||
is_network BOOLEAN DEFAULT 0 CHECK(is_network IN (0,1)),
|
||||
reason TEXT,
|
||||
expiry_time TEXT NULL,
|
||||
created_at TEXT DEFAULT (DATETIME('now')),
|
||||
created_by TEXT
|
||||
)");
|
||||
|
||||
$this->rateLimiter = new RateLimiter($this->db);
|
||||
|
||||
// Mock $_SERVER variables
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_SERVER['REQUEST_URI'] = '/login';
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
|
||||
// Define testing constant
|
||||
if (!defined('TESTING')) {
|
||||
define('TESTING', true);
|
||||
}
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
// Clean up rate limit records
|
||||
$this->db->getConnection()->exec('DELETE FROM pages_rate_limits');
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function testRateLimitMiddleware()
|
||||
{
|
||||
// Test multiple requests
|
||||
for ($i = 1; $i <= 5; $i++) {
|
||||
$result = checkRateLimit(['db' => $this->db], '/login');
|
||||
|
||||
if ($i <= 5) {
|
||||
// First 5 requests should pass
|
||||
$this->assertTrue($result);
|
||||
} else {
|
||||
// 6th and subsequent requests should be blocked
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function testRateLimitBypass()
|
||||
{
|
||||
// Test AJAX request bypass
|
||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
|
||||
$result = checkRateLimit(['db' => $this->db], '/login');
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testRateLimitReset()
|
||||
{
|
||||
// Use up the rate limit
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
checkRateLimit(['db' => $this->db], '/login');
|
||||
}
|
||||
|
||||
// Wait for rate limit to reset (use a short window for testing)
|
||||
sleep(2);
|
||||
|
||||
// Should be able to make request again
|
||||
$result = checkRateLimit(['db' => $this->db], '/login');
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testDifferentEndpoints()
|
||||
{
|
||||
// Use up rate limit for login
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
checkRateLimit(['db' => $this->db], '/login');
|
||||
}
|
||||
|
||||
// Should still be able to access different endpoint
|
||||
$result = checkRateLimit(['db' => $this->db], '/dashboard');
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testDifferentIpAddresses()
|
||||
{
|
||||
// Use up rate limit for first IP
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
checkRateLimit(['db' => $this->db], '/login');
|
||||
}
|
||||
|
||||
// Different IP should not be affected
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.2';
|
||||
$result = checkRateLimit(['db' => $this->db], '/login');
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testWhitelistedIp()
|
||||
{
|
||||
// Add IP to whitelist
|
||||
$this->db->execute(
|
||||
'INSERT INTO ip_whitelist (ip_address, description, created_by) VALUES (?, ?, ?)',
|
||||
['127.0.0.1', 'Test whitelist', 'PHPUnit']
|
||||
);
|
||||
|
||||
// Should be able to make more requests than limit
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
$result = checkRateLimit(['db' => $this->db], '/login');
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
}
|
||||
|
||||
public function testBlacklistedIp()
|
||||
{
|
||||
// Add IP to blacklist
|
||||
$this->db->execute(
|
||||
'INSERT INTO ip_blacklist (ip_address, reason, created_by) VALUES (?, ?, ?)',
|
||||
['127.0.0.1', 'Test blacklist', 'PHPUnit']
|
||||
);
|
||||
|
||||
// Should be blocked immediately
|
||||
$result = checkRateLimit(['db' => $this->db], '/login');
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
public function testRateLimitPersistence()
|
||||
{
|
||||
// Use up some of the rate limit
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
checkRateLimit(['db' => $this->db], '/login');
|
||||
}
|
||||
|
||||
// Destroy and restart session
|
||||
//session_destroy();
|
||||
//session_start();
|
||||
|
||||
// Should still count previous requests
|
||||
$result = checkRateLimit(['db' => $this->db], '/login');
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
|
||||
require_once dirname(__DIR__, 4) . '/app/includes/session_middleware.php';
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class SessionMiddlewareTest extends TestCase
|
||||
{
|
||||
protected $config;
|
||||
protected $app_root;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
// Mock server variables
|
||||
$_SERVER['HTTP_USER_AGENT'] = 'PHPUnit Test Browser';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_SERVER['HTTPS'] = 'on';
|
||||
|
||||
// Set up test config
|
||||
$this->config = [
|
||||
'folder' => '/app',
|
||||
'domain' => 'localhost'
|
||||
];
|
||||
$this->app_root = 'https://localhost/app';
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function testSessionStart()
|
||||
{
|
||||
$_SESSION = ['USER_ID' => 1];
|
||||
$result = applySessionMiddleware($this->config, $this->app_root);
|
||||
|
||||
$this->assertTrue($result);
|
||||
$this->assertArrayHasKey('LAST_ACTIVITY', $_SESSION);
|
||||
$this->assertArrayHasKey('CREATED', $_SESSION);
|
||||
$this->assertArrayHasKey('USER_ID', $_SESSION);
|
||||
$this->assertEquals(1, $_SESSION['USER_ID']);
|
||||
}
|
||||
|
||||
public function testSessionTimeout()
|
||||
{
|
||||
$_SESSION = [
|
||||
'USER_ID' => 1,
|
||||
'LAST_ACTIVITY' => time() - 1500 // 25 minutes ago
|
||||
];
|
||||
|
||||
$result = applySessionMiddleware($this->config, $this->app_root);
|
||||
|
||||
$this->assertFalse($result);
|
||||
$this->assertArrayNotHasKey('USER_ID', $_SESSION, 'Session should be cleared after timeout');
|
||||
}
|
||||
|
||||
public function testSessionRegeneration()
|
||||
{
|
||||
$now = time();
|
||||
$_SESSION = [
|
||||
'USER_ID' => 1,
|
||||
'CREATED' => $now - 1900 // 31+ minutes ago
|
||||
];
|
||||
|
||||
$result = applySessionMiddleware($this->config, $this->app_root);
|
||||
|
||||
$this->assertTrue($result);
|
||||
$this->assertEquals(1, $_SESSION['USER_ID']);
|
||||
$this->assertGreaterThanOrEqual($now - 1900, $_SESSION['CREATED']);
|
||||
$this->assertLessThanOrEqual($now + 10, $_SESSION['CREATED']);
|
||||
}
|
||||
|
||||
public function testRememberMe()
|
||||
{
|
||||
$_SESSION = [
|
||||
'USER_ID' => 1,
|
||||
'REMEMBER_ME' => true,
|
||||
'LAST_ACTIVITY' => time() - 86500 // More than 24 hours ago
|
||||
];
|
||||
|
||||
$result = applySessionMiddleware($this->config, $this->app_root);
|
||||
|
||||
$this->assertTrue($result);
|
||||
$this->assertArrayHasKey('USER_ID', $_SESSION);
|
||||
}
|
||||
|
||||
public function testNoUserSession()
|
||||
{
|
||||
$_SESSION = [];
|
||||
$result = applySessionMiddleware($this->config, $this->app_root);
|
||||
|
||||
$this->assertFalse($result);
|
||||
$this->assertArrayNotHasKey('USER_ID', $_SESSION);
|
||||
}
|
||||
|
||||
public function testSessionHeaders()
|
||||
{
|
||||
$_SESSION = [
|
||||
'USER_ID' => 1,
|
||||
'LAST_ACTIVITY' => time() - 1500 // 25 minutes ago
|
||||
];
|
||||
|
||||
$result = applySessionMiddleware($this->config, $this->app_root);
|
||||
|
||||
$this->assertFalse($result);
|
||||
$this->assertArrayNotHasKey('USER_ID', $_SESSION, 'Session should be cleared after timeout');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Test Session Handler
|
||||
*
|
||||
* Provides session handling functionality for PHPUnit tests.
|
||||
* This class ensures proper session management during testing.
|
||||
*/
|
||||
class TestSessionHandler implements SessionHandlerInterface
|
||||
{
|
||||
private static $initialized = false;
|
||||
private $data = [];
|
||||
|
||||
/**
|
||||
* Initialize session settings
|
||||
*/
|
||||
public static function init()
|
||||
{
|
||||
if (!self::$initialized && !headers_sent()) {
|
||||
// Clean up any existing session
|
||||
if (session_status() === PHP_SESSION_ACTIVE) {
|
||||
session_write_close();
|
||||
}
|
||||
|
||||
if (isset($_COOKIE[session_name()])) {
|
||||
setcookie(session_name(), '', time()-3600, '/');
|
||||
}
|
||||
|
||||
$_SESSION = array();
|
||||
|
||||
if (session_status() === PHP_SESSION_ACTIVE) {
|
||||
session_destroy();
|
||||
}
|
||||
|
||||
// Set session configuration
|
||||
session_name('jilo');
|
||||
|
||||
// Start a new session
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) {
|
||||
session_start([
|
||||
'cookie_httponly' => 1,
|
||||
'cookie_secure' => 1,
|
||||
'cookie_samesite' => 'Strict',
|
||||
'gc_maxlifetime' => 1440 // 24 minutes
|
||||
]);
|
||||
}
|
||||
|
||||
self::$initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a fresh session
|
||||
*/
|
||||
public static function startSession()
|
||||
{
|
||||
// Clean up any existing session first
|
||||
self::cleanupSession();
|
||||
|
||||
// Initialize new session
|
||||
if (session_status() !== PHP_SESSION_ACTIVE && !headers_sent()) {
|
||||
session_name('jilo');
|
||||
session_start([
|
||||
'cookie_httponly' => 1,
|
||||
'cookie_secure' => 1,
|
||||
'cookie_samesite' => 'Strict',
|
||||
'gc_maxlifetime' => 1440
|
||||
]);
|
||||
self::$initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up the current session
|
||||
*/
|
||||
public static function cleanupSession()
|
||||
{
|
||||
if (session_status() === PHP_SESSION_ACTIVE) {
|
||||
session_write_close();
|
||||
}
|
||||
|
||||
if (isset($_COOKIE[session_name()])) {
|
||||
setcookie(session_name(), '', time()-3600, '/');
|
||||
}
|
||||
|
||||
$_SESSION = array();
|
||||
|
||||
if (session_status() === PHP_SESSION_ACTIVE) {
|
||||
session_destroy();
|
||||
}
|
||||
|
||||
self::$initialized = false;
|
||||
}
|
||||
|
||||
public function open($path, $name): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function close(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function read($id): string|false
|
||||
{
|
||||
return $this->data[$id] ?? '';
|
||||
}
|
||||
|
||||
public function write($id, $data): bool
|
||||
{
|
||||
$this->data[$id] = $data;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function destroy($id): bool
|
||||
{
|
||||
unset($this->data[$id]);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function gc($max_lifetime): int|false
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -3,18 +3,14 @@
|
|||
// Set test environment
|
||||
define('PHPUNIT_RUNNING', true);
|
||||
|
||||
// Configure session before starting it
|
||||
ini_set('session.use_strict_mode', '1');
|
||||
ini_set('session.use_only_cookies', '1');
|
||||
ini_set('session.cookie_httponly', '1');
|
||||
ini_set('session.cookie_secure', '1');
|
||||
ini_set('session.cookie_samesite', 'Lax');
|
||||
ini_set('session.gc_maxlifetime', 1440);
|
||||
|
||||
// Start session if not already started
|
||||
//if (session_status() === PHP_SESSION_NONE) {
|
||||
// session_start();
|
||||
//}
|
||||
// Configure session before any output
|
||||
if (!headers_sent()) {
|
||||
// Configure session settings
|
||||
ini_set('session.cookie_httponly', 1);
|
||||
ini_set('session.cookie_secure', 1);
|
||||
ini_set('session.cookie_samesite', 'Strict');
|
||||
ini_set('session.gc_maxlifetime', 1440); // 24 minutes
|
||||
}
|
||||
|
||||
// Load Composer's autoloader
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
@ -33,26 +29,9 @@ $GLOBALS['config'] = [
|
|||
'db' => [
|
||||
'type' => 'sqlite',
|
||||
'dbFile' => ':memory:'
|
||||
],
|
||||
'folder' => '/',
|
||||
'domain' => 'localhost',
|
||||
'login' => [
|
||||
'max_attempts' => 5,
|
||||
'lockout_time' => 900
|
||||
]
|
||||
];
|
||||
|
||||
// Initialize system_messages array
|
||||
$GLOBALS['system_messages'] = [];
|
||||
|
||||
// Set up server variables
|
||||
$_SERVER['PHP_SELF'] = '/index.php';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_SERVER['HTTP_USER_AGENT'] = 'PHPUnit Test Browser';
|
||||
$_SERVER['HTTP_HOST'] = 'localhost';
|
||||
$_SERVER['REQUEST_URI'] = '/?page=login';
|
||||
$_SERVER['HTTPS'] = 'on';
|
||||
|
||||
// Define global connectDB function
|
||||
if (!function_exists('connectDB')) {
|
||||
function connectDB($config) {
|
||||
|
@ -62,3 +41,9 @@ if (!function_exists('connectDB')) {
|
|||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Set up server variables
|
||||
$_SERVER['PHP_SELF'] = '/index.php';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$_SERVER['HTTP_USER_AGENT'] = 'PHPUnit Test Browser';
|
||||
$_SERVER['HTTPS'] = 'on';
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
[Session]
|
||||
session.cookie_httponly = 1
|
||||
session.use_only_cookies = 1
|
||||
session.cookie_secure = 1
|
||||
session.cookie_samesite = "Strict"
|
||||
session.gc_maxlifetime = 1440
|
||||
session.use_strict_mode = 1
|
Loading…
Reference in New Issue