Fix onboarding return after bank auth errors (#361)
## Summary - Keep non-onboarded users on the accounts step after bank authorization errors - Add feature and browser coverage for the callback error path ## Tests - vendor/bin/pint --dirty --format agent - php artisan test --compact tests/Browser/OnboardingFlowTest.php --filter='returns to the accounts step' - php artisan test --compact tests/Feature/OpenBanking/AuthorizationControllerTest.php --filter='callback with error'
This commit is contained in:
parent
6cd465bb78
commit
0f1ce81b4e
|
|
@ -103,7 +103,8 @@ class AuthorizationController extends Controller
|
|||
public function callback(Request $request, BankingProviderInterface $provider): RedirectResponse
|
||||
{
|
||||
$user = auth()->user();
|
||||
$errorRedirect = $user->isOnboarded() ? 'settings.connections.index' : 'onboarding';
|
||||
$errorRedirectRoute = $user->isOnboarded() ? 'settings.connections.index' : 'onboarding';
|
||||
$errorRedirectParams = $user->isOnboarded() ? [] : ['step' => 'create-account'];
|
||||
|
||||
if ($request->has('error')) {
|
||||
Log::warning('EnableBanking authorization error', [
|
||||
|
|
@ -117,14 +118,14 @@ class AuthorizationController extends Controller
|
|||
->first()
|
||||
?->delete();
|
||||
|
||||
return redirect()->route($errorRedirect)
|
||||
return redirect()->route($errorRedirectRoute, $errorRedirectParams)
|
||||
->with('error', $request->query('error_description', 'Authorization was denied or cancelled.'));
|
||||
}
|
||||
|
||||
$code = $request->query('code');
|
||||
|
||||
if (! $code) {
|
||||
return redirect()->route($errorRedirect)
|
||||
return redirect()->route($errorRedirectRoute, $errorRedirectParams)
|
||||
->with('error', 'No authorization code received.');
|
||||
}
|
||||
|
||||
|
|
@ -133,7 +134,7 @@ class AuthorizationController extends Controller
|
|||
} catch (\Throwable $e) {
|
||||
Log::error('EnableBanking session creation failed', ['error' => $e->getMessage()]);
|
||||
|
||||
return redirect()->route($errorRedirect)
|
||||
return redirect()->route($errorRedirectRoute, $errorRedirectParams)
|
||||
->with('error', 'Failed to connect to your bank. Please try again.');
|
||||
}
|
||||
|
||||
|
|
@ -143,7 +144,7 @@ class AuthorizationController extends Controller
|
|||
->first();
|
||||
|
||||
if (! $connection) {
|
||||
return redirect()->route($errorRedirect)
|
||||
return redirect()->route($errorRedirectRoute, $errorRedirectParams)
|
||||
->with('error', 'No pending connection found.');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use App\Models\Account;
|
||||
use App\Models\Bank;
|
||||
use App\Models\BankingConnection;
|
||||
use App\Models\User;
|
||||
|
||||
// =============================================================================
|
||||
|
|
@ -168,6 +169,40 @@ it('allows continuing with existing accounts', function () {
|
|||
->assertNoJavascriptErrors();
|
||||
});
|
||||
|
||||
it('returns to the accounts step when bank authorization fails during onboarding', function () {
|
||||
$user = User::factory()->create([
|
||||
'onboarded_at' => null,
|
||||
]);
|
||||
|
||||
$bank = Bank::factory()->create(['name' => 'Connected Bank']);
|
||||
Account::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'bank_id' => $bank->id,
|
||||
'type' => 'checking',
|
||||
'currency_code' => 'EUR',
|
||||
]);
|
||||
$connection = BankingConnection::factory()->pending()->create([
|
||||
'user_id' => $user->id,
|
||||
'aspsp_name' => 'Failing Bank',
|
||||
'aspsp_country' => 'ES',
|
||||
]);
|
||||
|
||||
$this->actingAs($user);
|
||||
|
||||
$page = visit('/open-banking/callback?error=access_denied&error_description=Authentication+failed');
|
||||
|
||||
$page->wait(1)
|
||||
->assertPathIs('/onboarding')
|
||||
->assertQueryStringHas('step', 'create-account')
|
||||
->assertSee('Your Accounts')
|
||||
->assertSee('Connected Bank')
|
||||
->assertDontSee('Welcome to')
|
||||
->assertNoJavascriptErrors();
|
||||
|
||||
$connection->refresh();
|
||||
expect($connection->trashed())->toBeTrue();
|
||||
});
|
||||
|
||||
// =============================================================================
|
||||
// More Accounts Flow Tests
|
||||
// =============================================================================
|
||||
|
|
|
|||
|
|
@ -146,6 +146,23 @@ test('callback with error redirects with error message and deletes pending conne
|
|||
expect($connection->trashed())->toBeTrue();
|
||||
});
|
||||
|
||||
test('callback with error during onboarding redirects to the accounts step', function () {
|
||||
$user = User::factory()->notOnboarded()->create();
|
||||
Account::factory()->create(['user_id' => $user->id]);
|
||||
$connection = BankingConnection::factory()->pending()->create([
|
||||
'user_id' => $user->id,
|
||||
]);
|
||||
|
||||
$response = $this->actingAs($user)
|
||||
->get('/open-banking/callback?error=access_denied&error_description=User+denied+access');
|
||||
|
||||
$response->assertRedirect(route('onboarding', ['step' => 'create-account']));
|
||||
$response->assertSessionHas('error', 'User denied access');
|
||||
|
||||
$connection->refresh();
|
||||
expect($connection->trashed())->toBeTrue();
|
||||
});
|
||||
|
||||
test('callback without code redirects with error', function () {
|
||||
$user = User::factory()->onboarded()->create();
|
||||
$response = $this->actingAs($user)->get('/open-banking/callback');
|
||||
|
|
|
|||
Loading…
Reference in New Issue