<?php declare(strict_types=1); namespace Xentral\Modules\SystemMailer\Transport; use Xentral\Components\Mailer\Exception\OAuthCredentialsException; use Xentral\Components\Mailer\Transport\PhpMailerOAuthAuthentificationInterface; use Xentral\Modules\GoogleApi\Data\GoogleAccountData; use Xentral\Modules\GoogleApi\Exception\AuthorizationExpiredException; use Xentral\Modules\GoogleApi\Exception\NoAccessTokenException; use Xentral\Modules\GoogleApi\Exception\NoRefreshTokenException; use Xentral\Modules\GoogleApi\Service\GoogleAccountGateway; use Xentral\Modules\GoogleApi\Service\GoogleAuthorizationService; final class PhpMailerGoogleAuthentification implements PhpMailerOAuthAuthentificationInterface { /** @var GoogleAccountGateway */ private $gateway; /** @var GoogleAuthorizationService */ private $authorizationService; /** @var GoogleAccountData */ private $googleAccount; /** * @param GoogleAccountGateway $gateway * @param GoogleAuthorizationService $authorizationService * @param GoogleAccountData $googleAccount */ public function __construct( GoogleAccountGateway $gateway, GoogleAuthorizationService $authorizationService, GoogleAccountData $googleAccount ) { $this->gateway = $gateway; $this->authorizationService = $authorizationService; $this->googleAccount = $googleAccount; } /** * GetOauth64 * * encode the user email related to this request along with the token in base64 * this is used for authentication, in the phpmailer smtp class * * @throws OAuthCredentialsException * @throws NoAccessTokenException * @throws NoRefreshTokenException * @throws AuthorizationExpiredException * * @return string */ public function getOauth64():string { $gmailAddress = $this->gateway->getAccountProperties($this->googleAccount->getId()) ->get('gmail_address'); if ($this->googleAccount === null || $gmailAddress === null) { throw new OAuthCredentialsException('SMTP Google OAuth - missing credentials'); } $token = $this->gateway->getAccessToken($this->googleAccount->getId()); if ($token->getTimeToLive() < 30) { $token = $this->authorizationService->refreshAccessToken($this->googleAccount); } $offlineToken = $token->getToken(); return base64_encode( sprintf( "user=%s\001auth=Bearer %s\001\001", $gmailAddress, $offlineToken ) ); } }