Spent hours on this yesterday to no avail. Could use some help or guiding questions
How to redirect back after confirming password with Fortify?
I am using Fortify for 2FA in my app and when displaying the recovery codes, Fortify's default behavior is to use the password.confirm middleware, which is fine. However, I'm having trouble naturally navigating to it without doing anything that feels too "hacky". And when I get something working, I can't figure out how to return back to the page I was on instead of the route that is set as home for Fortify.
My current function is this
async function loadRecoveryCodes() {
if (!props.twoFactorEnabled) {
recoveryCodes.value = [];
return;
}
loadingRecovery.value = true;
try {
const { data } = await axios.get(route('two-factor.recovery-codes'));
recoveryCodes.value = Array.isArray(data) ? data : [];
} catch (error: any) {
if (axios.isAxiosError(error)) {
// If Fortify requires a recent password confirmation, Laravel may
// respond with a 4xx/redirect. Navigate there via Inertia
const status = error?.response?.status;
// From checking browser logs, this is only ever a 423 status code
if (status === 423) {
console.log(error?.response);
router.visit(route('password.confirm'), { preserveScroll: true });
return;
}
console.error('Failed to load recovery codes:', error.response?.data?.message || error.message);
recoveryCodes.value = [];
}
} finally {
loadingRecovery.value = false;
}
}
This will work, but this is the scenario I described above. I am manually requesting the password.confirm View, but after confirming, it goes back to /dashboard per my config. Is there a way to have it go back to the settings page I was on where the user clicked the button to display their recovery codes?
Here's Fortify's GET/POST routes for password.confirm
Route::get(RoutePath::for('password.confirm', '/user/confirm-password'), [ConfirmablePasswordController::class, 'show'])
->middleware([config('fortify.auth_middleware', 'auth').':'.config('fortify.guard')])
->name('password.confirm');
Route::post(RoutePath::for('password.confirm', '/user/confirm-password'), [ConfirmablePasswordController::class, 'store'])
->middleware([config('fortify.auth_middleware', 'auth').':'.config('fortify.guard')])
->name('password.confirm.store');
Here's my features array from fortify.php
'features' => [
// Features::registration(),
// Features::resetPasswords(),
// Features::emailVerification(),
Features::updateProfileInformation(),
Features::updatePasswords(),
Features::twoFactorAuthentication([
'confirm' => true,
'confirmPassword' => true,
// 'window' => 0,
]),
],
];
And here's part of my FortifyServiceProvider.php showing that I'm setting the View for the GET route for this to be my Inertia View. I've commented out the GET route that is set by the Vue Starter Pack.
Fortify::confirmPasswordView(function () {
return Inertia::render('auth/ConfirmPassword');
});
How can I go back to my settings/security page and just immediately display the recovery codes? With this above, the user has to manually go back to their settings page and click the button again.
Using form.get instead of router.visit worked one time, but I cannot reproduce it again.
Please or to participate in this conversation.