SessionIssuer now owns 'grant access after authenticating', which LoginManager previously did internally. The passkey ceremony needs the same behaviour, and two implementations would inevitably drift — most likely in cookie attributes, where a difference stays invisible until it breaks in a browser. LoginManager keeps what is specific to code-based login: verifying the TOTP or backup code and enforcing the single-use nonce. Its 18 existing tests pass unchanged, which is the evidence that this is behaviour-preserving rather than a rewrite. Also folds the redundant early-return into a single guard in checkToken so the success path reads straight through.
30 lines
989 B
PHP
30 lines
989 B
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Service;
|
|
|
|
use App\Enum\Scope;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
/**
|
|
* Grants access after a successful authentication, regardless of method.
|
|
*
|
|
* Exists so the TOTP form and the passkey ceremony cannot drift apart: they must
|
|
* produce identical cookies, headers and redirects, and the only reliable way to
|
|
* guarantee that is for both to call the same code.
|
|
*/
|
|
interface SessionIssuerInterface
|
|
{
|
|
/**
|
|
* Record the authenticated identity according to the requested scope and
|
|
* build the response the caller should return.
|
|
*
|
|
* @param string $identity the session id, as typed by the user
|
|
* @param Scope $scope whether to set a cookie, an IP session, or neither
|
|
* @param bool $json JSON for an AJAX caller, HTML for a form post
|
|
*/
|
|
public function issue(string $identity, Scope $scope, Request $request, bool $json): Response;
|
|
}
|