securityCode = $this->sessionTenant->configuration()->security()->code(); } /** * Authenticate a request and return the user if valid * * @param Request $request The HTTP request to authenticate * @return User|null The authenticated user, or null if not authenticated */ public function authenticate(Request $request): ?User { $authorization = $request->headers->get('Authorization'); $cookieToken = $request->cookies->get('accessToken'); // Cookie token takes precedence if ($cookieToken) { return $this->authenticateJWT($cookieToken); } if ($authorization) { if (str_starts_with($authorization, 'Bearer ')) { $token = substr($authorization, 7); return $this->authenticateBearer($token); } if (str_starts_with($authorization, 'Basic ')) { $decoded = base64_decode(substr($authorization, 6) ?: '', true); if ($decoded !== false) { [$identity, $secret] = array_pad(explode(':', $decoded, 2), 2, null); if ($identity !== null && $secret !== null) { return $this->authenticateBasicHeader($identity, $secret); } } } } return null; } /** * Authenticate JWT token from cookie or header */ public function authenticateJWT(string $token): ?User { $payload = $this->tokenService->validateToken($token, $this->securityCode); if (!$payload) { return null; } // Verify user still exists if ($this->userService->fetchByIdentifier($payload['identifier']) === null) { return null; } $user = new User(); $user->populate($payload, 'jwt'); return $user; } /** * Authenticate Bearer token */ public function authenticateBearer(string $token): ?User { return $this->authenticateJWT($token); } /** * Authenticate HTTP Basic header (for API access) * Note: This is for request authentication, not login */ private function authenticateBasicHeader(string $identity, string $credentials): ?User { // For Basic auth headers, we need to validate against the provider // This is a simplified flow for API access $provider = $this->providerRegistry->resolve('default'); if ($provider === null) { return null; } $result = $provider->authenticate($identity, $credentials); if (!$result->isSuccess()) { return null; } return $this->getUserByIdentity($identity); } // ========================================================================= // Token Operations (delegated to AuthenticationManager for new flows) // These are kept for backwards compatibility during transition // ========================================================================= /** * @deprecated Use AuthenticationManager::createTokens() instead */ public function createAccessToken(array $payload): string { return $this->tokenService->createToken($payload, $this->securityCode, 900); } /** * @deprecated Use AuthenticationManager::createTokens() instead */ public function createRefreshToken(array $payload): string { $refreshPayload = [ 'tenant' => $payload['tenant'] ?? null, 'identifier' => $payload['identifier'], 'identity' => $payload['identity'], 'type' => 'refresh' ]; return $this->tokenService->createToken($refreshPayload, $this->securityCode, 604800); } /** * @deprecated Use AuthenticationManager::refreshAccessToken() instead */ public function validateRefreshToken(string $refreshToken): ?User { $payload = $this->tokenService->validateToken($refreshToken, $this->securityCode); if (!$payload) { return null; } if (!isset($payload['type']) || $payload['type'] !== 'refresh') { return null; } $identifier = $payload['identifier'] ?? null; if (!$identifier || $this->providerRegistry->validateUser($identifier) === false) { return null; } $user = new User(); $user->populate([ 'identifier' => $payload['identifier'], 'identity' => $payload['identity'], 'tenant' => $payload['tenant'] ?? null, ], 'jwt'); return $user; } /** * @deprecated Use AuthenticationManager::logout() instead */ public function logout(?string $jti = null, ?int $exp = null): void { if ($jti !== null) { $expiresAt = $exp ?? (time() + 86400); $this->tokenService->blacklist($jti, $expiresAt); } } /** * @deprecated Use AuthenticationManager::logoutAll() instead */ public function logoutAllDevices(string $identity): void { $this->tokenService->blacklistUserTokensBefore($identity, time()); } /** * Extract token claims (for logout to get jti/exp) */ public function extractTokenClaims(string $token): ?array { return $this->tokenService->validateToken($token, $this->securityCode, checkBlacklist: false); } }