feat(auth): add microsoft auto-remember policy with tenant override and configurable remember TTL
This commit is contained in:
@@ -10,6 +10,7 @@ use MintyPHP\Repository\User\UserReadRepositoryInterface;
|
||||
use MintyPHP\Repository\User\UserWriteRepositoryInterface;
|
||||
use MintyPHP\Service\Auth\AuthPermissionGateway;
|
||||
use MintyPHP\Service\Auth\AuthSessionTenantContextService;
|
||||
use MintyPHP\Service\Auth\AuthSettingsGateway;
|
||||
use MintyPHP\Service\Auth\RememberMeService;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
@@ -427,6 +428,81 @@ class RememberMeServiceTest extends TestCase
|
||||
$this->assertSame(15, $service->expireAllTokensByAdmin());
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Dynamic TTL via AuthSettingsGateway
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
public function testRememberUserUsesConfiguredTtlFromGateway(): void
|
||||
{
|
||||
$settingsGateway = $this->createMock(AuthSettingsGateway::class);
|
||||
$settingsGateway->method('getRememberTokenLifetimeDays')->willReturn(7);
|
||||
|
||||
$capturedExpiresAt = '';
|
||||
$tokenRepo = $this->createMock(RememberTokenRepositoryInterface::class);
|
||||
$tokenRepo->expects($this->once())
|
||||
->method('create')
|
||||
->with(
|
||||
42,
|
||||
$this->anything(),
|
||||
$this->anything(),
|
||||
$this->callback(function (string $e) use (&$capturedExpiresAt): bool {
|
||||
$capturedExpiresAt = $e;
|
||||
return strtotime($e . ' UTC') > time();
|
||||
})
|
||||
)
|
||||
->willReturn(1);
|
||||
|
||||
$cookieStore = $this->createMock(CookieStoreInterface::class);
|
||||
$cookieStore->expects($this->once())
|
||||
->method('set')
|
||||
->with(
|
||||
'remember',
|
||||
$this->anything(),
|
||||
$this->callback(fn (array $opts): bool => $opts['expires'] > time()
|
||||
&& $opts['expires'] <= time() + (7 * 86400) + 10)
|
||||
);
|
||||
|
||||
$service = $this->newService(
|
||||
tokenRepository: $tokenRepo,
|
||||
cookieStore: $cookieStore,
|
||||
authSettingsGateway: $settingsGateway
|
||||
);
|
||||
$service->rememberUser(42);
|
||||
|
||||
// Verify expiration is ~7 days from now (not 30)
|
||||
$expiresTimestamp = strtotime($capturedExpiresAt . ' UTC');
|
||||
$this->assertGreaterThan(time() + (6 * 86400), $expiresTimestamp);
|
||||
$this->assertLessThanOrEqual(time() + (7 * 86400) + 10, $expiresTimestamp);
|
||||
}
|
||||
|
||||
public function testRememberUserFallsBackTo30DaysWhenNoGateway(): void
|
||||
{
|
||||
$capturedExpiresAt = '';
|
||||
$tokenRepo = $this->createMock(RememberTokenRepositoryInterface::class);
|
||||
$tokenRepo->expects($this->once())
|
||||
->method('create')
|
||||
->with(
|
||||
42,
|
||||
$this->anything(),
|
||||
$this->anything(),
|
||||
$this->callback(function (string $e) use (&$capturedExpiresAt): bool {
|
||||
$capturedExpiresAt = $e;
|
||||
return true;
|
||||
})
|
||||
)
|
||||
->willReturn(1);
|
||||
|
||||
$cookieStore = $this->createMock(CookieStoreInterface::class);
|
||||
$cookieStore->method('set');
|
||||
|
||||
$service = $this->newService(tokenRepository: $tokenRepo, cookieStore: $cookieStore);
|
||||
$service->rememberUser(42);
|
||||
|
||||
$expiresTimestamp = strtotime($capturedExpiresAt . ' UTC');
|
||||
$this->assertGreaterThan(time() + (29 * 86400), $expiresTimestamp);
|
||||
$this->assertLessThanOrEqual(time() + (30 * 86400) + 10, $expiresTimestamp);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Helper
|
||||
// ---------------------------------------------------------------
|
||||
@@ -439,7 +515,8 @@ class RememberMeServiceTest extends TestCase
|
||||
?AuthSessionTenantContextService $authSessionTenantContextService = null,
|
||||
?SessionStoreInterface $sessionStore = null,
|
||||
?CookieStoreInterface $cookieStore = null,
|
||||
?RequestRuntimeInterface $requestRuntime = null
|
||||
?RequestRuntimeInterface $requestRuntime = null,
|
||||
?AuthSettingsGateway $authSettingsGateway = null
|
||||
): RememberMeService {
|
||||
// RequestRuntimeInterface has a method named "method()" which PHPUnit 12
|
||||
// cannot mock (reserved name). Use a simple anonymous-class stub instead.
|
||||
@@ -483,7 +560,8 @@ class RememberMeServiceTest extends TestCase
|
||||
$authSessionTenantContextService ?? $this->createMock(AuthSessionTenantContextService::class),
|
||||
$sessionStore ?? $this->createMock(SessionStoreInterface::class),
|
||||
$cookieStore ?? $this->createMock(CookieStoreInterface::class),
|
||||
$requestRuntime
|
||||
$requestRuntime,
|
||||
$authSettingsGateway
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user