feat(auth): add microsoft auto-remember policy with tenant override and configurable remember TTL

This commit is contained in:
2026-03-10 22:48:10 +01:00
parent f403a6704f
commit 964c07a9de
32 changed files with 1267 additions and 17 deletions

View File

@@ -13,6 +13,7 @@ use MintyPHP\Service\Settings\SettingsApiPolicyGateway;
use MintyPHP\Service\Settings\SettingsAppGateway;
use MintyPHP\Service\Settings\SettingsDefaultsGateway;
use MintyPHP\Service\Settings\SettingsFrontendTelemetryGateway;
use MintyPHP\Service\Settings\SettingsLoginPersistenceGateway;
use MintyPHP\Service\Settings\SettingsMetadataGateway;
use MintyPHP\Service\Settings\SettingsMicrosoftGateway;
use MintyPHP\Service\Settings\SettingsSessionGateway;
@@ -112,6 +113,74 @@ class AdminSettingsServiceSessionPolicyTest extends TestCase
$this->assertContains('session_absolute_timeout_invalid', $errorKeys);
}
// ---------------------------------------------------------------
// Login persistence settings
// ---------------------------------------------------------------
public function testBuildPageDataIncludesLoginPersistenceValues(): void
{
$loginPersistenceGateway = $this->createConfiguredMock(SettingsLoginPersistenceGateway::class, [
'isMicrosoftAutoRememberDefault' => true,
'getRememberTokenLifetimeDays' => 14,
]);
$service = $this->newService(loginPersistenceGateway: $loginPersistenceGateway);
$data = $service->buildPageData();
$values = is_array($data['values'] ?? null) ? $data['values'] : [];
$this->assertTrue((bool) ($values['microsoft_auto_remember_default'] ?? false));
$this->assertSame(14, (int) ($values['remember_token_lifetime_days'] ?? 0));
}
public function testUpdateFromAdminPersistsLoginPersistenceValues(): void
{
$loginPersistenceGateway = $this->createMock(SettingsLoginPersistenceGateway::class);
$loginPersistenceGateway->method('isMicrosoftAutoRememberDefault')->willReturn(false);
$loginPersistenceGateway->method('getRememberTokenLifetimeDays')->willReturn(30);
$loginPersistenceGateway->expects($this->once())
->method('setMicrosoftAutoRememberDefault')
->with(true);
$loginPersistenceGateway->expects($this->once())
->method('setRememberTokenLifetimeDays')
->with(14)
->willReturn(true);
$service = $this->newService(loginPersistenceGateway: $loginPersistenceGateway);
$result = $service->updateFromAdmin($this->validPostData([
'microsoft_auto_remember_default' => '1',
'remember_token_lifetime_days' => '14',
]));
$this->assertSame([], $result['errors'] ?? []);
}
public function testUpdateFromAdminReturnsErrorForInvalidRememberTtl(): void
{
$loginPersistenceGateway = $this->createMock(SettingsLoginPersistenceGateway::class);
$loginPersistenceGateway->method('isMicrosoftAutoRememberDefault')->willReturn(false);
$loginPersistenceGateway->method('getRememberTokenLifetimeDays')->willReturn(30);
$loginPersistenceGateway->method('setMicrosoftAutoRememberDefault');
$loginPersistenceGateway->expects($this->once())
->method('setRememberTokenLifetimeDays')
->with(500)
->willReturn(false);
$service = $this->newService(loginPersistenceGateway: $loginPersistenceGateway);
$result = $service->updateFromAdmin($this->validPostData([
'remember_token_lifetime_days' => '500',
]));
$errors = is_array($result['errors'] ?? null) ? $result['errors'] : [];
$errorKeys = [];
foreach ($errors as $error) {
if (is_array($error) && isset($error['key'])) {
$errorKeys[] = (string) $error['key'];
}
}
$this->assertContains('remember_token_lifetime_days_invalid', $errorKeys);
}
/**
* @param array<string, mixed> $overrides
* @return array<string, mixed>
@@ -157,7 +226,8 @@ class AdminSettingsServiceSessionPolicyTest extends TestCase
private function newService(
?SettingsSessionGateway $settingsSessionGateway = null,
?SettingsMetadataGateway $settingsMetadataGateway = null
?SettingsMetadataGateway $settingsMetadataGateway = null,
?SettingsLoginPersistenceGateway $loginPersistenceGateway = null
): AdminSettingsService {
$settingsDefaultsGateway = $this->createConfiguredMock(SettingsDefaultsGateway::class, [
'getDefaultTenantId' => null,
@@ -239,6 +309,13 @@ class AdminSettingsServiceSessionPolicyTest extends TestCase
'setSmtpFromName' => true,
]);
$loginPersistenceGateway = $loginPersistenceGateway ?? $this->createConfiguredMock(SettingsLoginPersistenceGateway::class, [
'isMicrosoftAutoRememberDefault' => false,
'getRememberTokenLifetimeDays' => 30,
'setMicrosoftAutoRememberDefault' => true,
'setRememberTokenLifetimeDays' => true,
]);
if ($settingsMetadataGateway === null) {
$settingsMetadataGateway = $this->createMock(SettingsMetadataGateway::class);
$settingsMetadataGateway->method('getValue')->willReturn(null);
@@ -281,6 +358,7 @@ class AdminSettingsServiceSessionPolicyTest extends TestCase
$settingsFrontendTelemetryGateway,
$settingsMicrosoftGateway,
$settingsSmtpGateway,
$loginPersistenceGateway,
$settingsMetadataGateway,
$settingCacheService,
$tenantService,