feat(security): add session timeout + transaction wrapping (B1)

Session timeout: configurable idle (default 30min) and absolute (default 8h)
timeouts via DB settings, enforced in web/index.php on every request.
Timestamps set at login in action layer; graceful fallback for pre-existing
sessions.

Transaction wrapping: UserAccountService.createFromAdmin/register, roles
create/edit, and permissions edit now wrap multi-step DB operations in
transactions to guarantee atomicity.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-09 19:16:26 +01:00
parent 8d6cfa2fbc
commit 11ca546eae
17 changed files with 415 additions and 103 deletions

View File

@@ -2,6 +2,7 @@
namespace MintyPHP\Tests\Service\User;
use MintyPHP\Repository\Support\DatabaseSessionRepository;
use MintyPHP\Repository\User\UserListQueryRepositoryInterface;
use MintyPHP\Repository\User\UserReadRepositoryInterface;
use MintyPHP\Repository\User\UserWriteRepositoryInterface;
@@ -418,7 +419,8 @@ class UserAccountServiceTest extends TestCase
?UserSettingsGateway $settingsGateway = null,
?UserScopeGateway $scopeGateway = null,
?UserDirectoryGateway $directoryGateway = null,
?SystemAuditService $auditService = null
?SystemAuditService $auditService = null,
?DatabaseSessionRepository $databaseSessionRepository = null
): UserAccountService {
$readRepository = $readRepository ?? $this->createMock(UserReadRepositoryInterface::class);
$writeRepository = $writeRepository ?? $this->createMock(UserWriteRepositoryInterface::class);
@@ -463,6 +465,7 @@ class UserAccountServiceTest extends TestCase
}
$auditService = $auditService ?? $this->createMock(SystemAuditService::class);
$databaseSessionRepository = $databaseSessionRepository ?? $this->createMock(DatabaseSessionRepository::class);
return new UserAccountService(
$readRepository,
@@ -473,7 +476,8 @@ class UserAccountServiceTest extends TestCase
$settingsGateway,
$scopeGateway,
$directoryGateway,
$auditService
$auditService,
$databaseSessionRepository
);
}
}