refactor(open-banking): extract the callback authorization error branch
The error-param cleanup and the two isOnboarded ternaries picking the failure destination were the bulk of callback()'s complexity. Pull them into handleAuthorizationError() and failureRedirect(), which also collapses the four repeated (route, params, 'error', message) argument lists into one call each. No behaviour change.
This commit is contained in:
parent
091457c747
commit
baacd24839
|
|
@ -165,44 +165,14 @@ class AuthorizationController extends Controller
|
|||
->with('error', __('Please log back in to finish connecting your bank account.'));
|
||||
}
|
||||
|
||||
$errorRedirectRoute = $user->isOnboarded() ? 'settings.connections.index' : 'onboarding';
|
||||
$errorRedirectParams = $user->isOnboarded() ? [] : ['step' => 'create-account'];
|
||||
|
||||
if ($request->has('error')) {
|
||||
$errorDescription = $request->query('error_description');
|
||||
$errorMessage = is_string($errorDescription) && $errorDescription !== ''
|
||||
? $errorDescription
|
||||
: 'Authorization was denied or cancelled.';
|
||||
|
||||
Log::warning('EnableBanking authorization error', [
|
||||
'error' => $request->query('error'),
|
||||
'description' => $errorDescription,
|
||||
]);
|
||||
|
||||
$pendingConnection = $connection ?? $user->bankingConnections()
|
||||
->where('status', BankingConnectionStatus::Pending)
|
||||
->latest()
|
||||
->first();
|
||||
|
||||
if ($pendingConnection) {
|
||||
if ($pendingConnection->accounts()->exists()) {
|
||||
$pendingConnection->update([
|
||||
'status' => BankingConnectionStatus::Error,
|
||||
'error_message' => $errorMessage,
|
||||
'state_token' => null,
|
||||
]);
|
||||
} else {
|
||||
$pendingConnection->delete();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->finishRedirect($errorRedirectRoute, $errorRedirectParams, 'error', $errorMessage);
|
||||
return $this->handleAuthorizationError($request, $user, $connection);
|
||||
}
|
||||
|
||||
$code = $request->query('code');
|
||||
|
||||
if (! $code) {
|
||||
return $this->finishRedirect($errorRedirectRoute, $errorRedirectParams, 'error', 'No authorization code received.');
|
||||
return $this->failureRedirect($user, 'No authorization code received.');
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
@ -214,13 +184,13 @@ class AuthorizationController extends Controller
|
|||
$connection->update(['state_token' => null]);
|
||||
}
|
||||
|
||||
return $this->finishRedirect($errorRedirectRoute, $errorRedirectParams, 'error', 'Failed to connect to your bank. Please try again.');
|
||||
return $this->failureRedirect($user, 'Failed to connect to your bank. Please try again.');
|
||||
}
|
||||
|
||||
$connection ??= $this->findPendingConnectionForSession($user, $sessionData);
|
||||
|
||||
if (! $connection) {
|
||||
return $this->finishRedirect($errorRedirectRoute, $errorRedirectParams, 'error', 'No pending connection found.');
|
||||
return $this->failureRedirect($user, 'No pending connection found.');
|
||||
}
|
||||
|
||||
$isReconnect = $connection->accounts()->exists();
|
||||
|
|
@ -264,6 +234,56 @@ class AuthorizationController extends Controller
|
|||
return $this->finishRedirect('open-banking.map-accounts', ['connection' => $connection]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up after a bank that denied or cancelled the authorization.
|
||||
*
|
||||
* A pending connection that already has accounts is a reconnect, so it is kept
|
||||
* and marked as failing. A brand new one has nothing worth keeping.
|
||||
*/
|
||||
private function handleAuthorizationError(Request $request, User $user, ?BankingConnection $connection): RedirectResponse|Response
|
||||
{
|
||||
$errorDescription = $request->query('error_description');
|
||||
$errorMessage = is_string($errorDescription) && $errorDescription !== ''
|
||||
? $errorDescription
|
||||
: 'Authorization was denied or cancelled.';
|
||||
|
||||
Log::warning('EnableBanking authorization error', [
|
||||
'error' => $request->query('error'),
|
||||
'description' => $errorDescription,
|
||||
]);
|
||||
|
||||
$pendingConnection = $connection ?? $user->bankingConnections()
|
||||
->where('status', BankingConnectionStatus::Pending)
|
||||
->latest()
|
||||
->first();
|
||||
|
||||
if ($pendingConnection) {
|
||||
if ($pendingConnection->accounts()->exists()) {
|
||||
$pendingConnection->update([
|
||||
'status' => BankingConnectionStatus::Error,
|
||||
'error_message' => $errorMessage,
|
||||
'state_token' => null,
|
||||
]);
|
||||
} else {
|
||||
$pendingConnection->delete();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->failureRedirect($user, $errorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Abandon the callback with a message, sending the user wherever they came from.
|
||||
*
|
||||
* A user still onboarding has no connections screen to land on yet.
|
||||
*/
|
||||
private function failureRedirect(User $user, string $message): RedirectResponse|Response
|
||||
{
|
||||
return $user->isOnboarded()
|
||||
? $this->finishRedirect('settings.connections.index', [], 'error', $message)
|
||||
: $this->finishRedirect('onboarding', ['step' => 'create-account'], 'error', $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the connection a callback belongs to from the state token EnableBanking
|
||||
* echoes back. This works without a logged-in session.
|
||||
|
|
|
|||
Loading…
Reference in New Issue