Skip to content

Commit a062848

Browse files
committed
fix: cancel and session-expiry now correctly return to the password screen
Root cause was two-layered: 1. resetToPasswordFlow() reset authFlow to FLOW.PASSWORD but also cleared user_name/user_pic/user_fullname/user_verified in the same setState call. isPasswordFlow's render condition requires user_verified === true, so wiping it forced the render logic to showDefaultFlow (the email screen) regardless of authFlow being correct. 2. That alone wasn't sufficient: since the password step now submits as a native form POST (see the earlier native-submit fix), the mfa_required transition is a full page reload, not a client-side setState - the React app remounts from scratch and only recovers state the backend flashed to session. issueChallenge() (EmailOTPMFAChallengeStrategy/AbstractMFA ChallengeStrategy) only returns otp_length/otp_lifetime, so challengeRequired()'s session flash never carried username/user_fullname/ user_pic/user_verified in the first place - user_verified was already false the moment the 2FA screen first rendered, before Cancel was ever clicked. Fix #1 alone had nothing to preserve. Fix: postLogin()'s mfa_required branch now merges the same identity fields into the challengeRequired() payload that the AuthenticationException errorLogin() branch already flashes (same fields, same getters: username, user_fullname, user_pic, user_verified, user_is_active) - restoring the identity chip on the 2FA screen and giving resetToPasswordFlow() correct state to preserve. resetToPasswordFlow() no longer clears user_name/user_pic/ user_fullname/user_verified. Verified live: 2FA screen now shows the identity chip from first render: Cancel from the 2FA screen now returns directly to the password screen with the same user still identified, instead of resetting to the email-entry screen. tests/TwoFactorLoginFlowTest.php passes in full (31 tests, 120 assertions) - unaffected, since no test asserted the previously-missing identity fields.
1 parent f67f5b1 commit a062848

2 files changed

Lines changed: 15 additions & 4 deletions

File tree

app/Http/Controllers/UserController.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,21 @@ public function postLogin()
531531
Session::put('flow', IAuthService::AuthenticationFlowMFA);
532532
Session::put('mfa_method', $method);
533533

534+
// The password step now submits as a native form POST, so this
535+
// response is a fresh page load, not a client-side transition -
536+
// without these, the React app remounts with no identity state
537+
// at all (no chip, and Cancel/session-expiry can't return to the
538+
// password screen because it looks like the user was never
539+
// verified). Same fields/getters as the AuthenticationException
540+
// errorLogin() branch below.
541+
$payload = array_merge($payload, [
542+
'username' => $username,
543+
'user_fullname' => $user->getFullName(),
544+
'user_pic' => $user->getPic(),
545+
'user_verified' => true,
546+
'user_is_active' => $user->isActive() ? 1 : 0,
547+
]);
548+
534549
return $this->login_strategy->challengeRequired($payload);
535550
}
536551

resources/js/login/login.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -295,11 +295,7 @@ class LoginPage extends React.Component {
295295
authFlow: FLOW.PASSWORD,
296296
disableInput: false,
297297
twoFactorCode: "",
298-
user_name: "",
299298
user_password: "",
300-
user_pic: "",
301-
user_fullname: "",
302-
user_verified: false,
303299
recoveryCode: "",
304300
trustDevice: false,
305301
errors: {

0 commit comments

Comments
 (0)