mirror of
https://github.com/projectsend/projectsend.git
synced 2026-09-17 00:55:07 +00:00
ff26fac9c5
#1739 put the nightly OAuth refresh under the same lock a send holds, which is right -- but standing aside for the lock holder still printed "Refreshed <provider> (<account>)". No token request was made, so the line describes something that did not happen, and scheduler output is read precisely by somebody trying to work out what did.
refreshSerially() now answers whether it refreshed, and the command says which of the two happened. Standing aside is a healthy outcome: somebody else is refreshing this very connection, which slides the token window just as well as doing it again would. It is just not a refresh, and it should not claim to be one.
The existing test for the stand-aside now asserts the output too, and it fails against the old message.
Same reasoning as d8ef21b, which said when the worker check was skipped rather than skipping it quietly.
61 lines
2.2 KiB
PHP
61 lines
2.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Modules\Platform\Mail;
|
|
|
|
/**
|
|
* One OAuth mail provider's token machinery: building the consent URL,
|
|
* turning the returned code into tokens, and keeping those tokens fresh.
|
|
*
|
|
* Deliberately not Socialite: a mail connection needs raw tokens with a
|
|
* send scope, not a user identity, and Socialite's user() call would
|
|
* drag in a userinfo permission (User.Read on Graph) that sending mail
|
|
* does not need. Implementations write their results straight onto the
|
|
* MailOAuthConnection row and save it.
|
|
*/
|
|
interface MailOAuthBroker
|
|
{
|
|
/** The provider consent URL the admin's browser is sent to. */
|
|
public function authorizeUrl(MailOAuthConnection $connection, string $state, string $redirectUri): string;
|
|
|
|
/**
|
|
* Exchange the callback's authorization code for tokens and record
|
|
* them, along with the connected mailbox's address, on the connection.
|
|
*
|
|
* @throws MailOAuthException
|
|
*/
|
|
public function exchange(MailOAuthConnection $connection, string $code, string $redirectUri): void;
|
|
|
|
/**
|
|
* Refresh the access token (rotating the refresh token when the
|
|
* provider hands back a new one) and record the outcome — including
|
|
* `last_error` on failure, so the settings page and the scheduled
|
|
* health check read one source of truth.
|
|
*
|
|
* @throws MailOAuthException
|
|
*/
|
|
public function refresh(MailOAuthConnection $connection): void;
|
|
|
|
/**
|
|
* A refresh that is not racing a send: the scheduled health check's
|
|
* way in, serialised against freshAccessToken() on the same
|
|
* connection.
|
|
*
|
|
* False when it stood aside because somebody else holds the lock, so
|
|
* a caller reporting to a human can say that rather than claim a
|
|
* refresh it did not do.
|
|
*
|
|
* @throws MailOAuthException
|
|
*/
|
|
public function refreshSerially(MailOAuthConnection $connection): bool;
|
|
|
|
/**
|
|
* An access token currently valid for at least a small safety margin,
|
|
* refreshing first when needed — what transports call at send time.
|
|
*
|
|
* @throws MailOAuthException
|
|
*/
|
|
public function freshAccessToken(MailOAuthConnection $connection): string;
|
|
}
|