@@ -35,14 +35,17 @@ class Session implements AuthenticatorInterface
3535 */
3636 public const ID_TYPE_USERNAME = 'username ' ;
3737
38+ // Identity types
3839 public const ID_TYPE_EMAIL_PASSWORD = 'email_password ' ;
3940 public const ID_TYPE_MAGIC_LINK = 'magic-link ' ;
4041 public const ID_TYPE_EMAIL_2FA = 'email_2fa ' ;
4142 public const ID_TYPE_EMAIL_ACTIVATE = 'email_activate ' ;
42- private const STATE_UNKNOWN = 0 ;
43- private const STATE_ANONYMOUS = 1 ;
44- private const STATE_PENDING = 2 ;
45- private const STATE_LOGGED_IN = 3 ;
43+
44+ // User states
45+ private const STATE_UNKNOWN = 0 ; // Not checked yet.
46+ private const STATE_ANONYMOUS = 1 ;
47+ private const STATE_PENDING = 2 ; // 2FA or Activation required.
48+ private const STATE_LOGGED_IN = 3 ;
4649
4750 /**
4851 * The persistence engine
@@ -149,6 +152,9 @@ public function attempt(array $credentials): Result
149152 // Update the user's last used date on their password identity.
150153 $ user ->touchIdentity ($ user ->getEmailIdentity ());
151154
155+ // Check ID_TYPE_EMAIL_ACTIVATE identity
156+ $ hasEmailActivate = $ this ->setAuthActionEmailActivate ();
157+
152158 // If an action has been defined for login, start it up.
153159 $ hasAction = $ this ->startUpAction ('login ' , $ user );
154160
@@ -158,7 +164,7 @@ public function attempt(array $credentials): Result
158164
159165 $ this ->issueRememberMeToken ();
160166
161- if (! $ hasAction ) {
167+ if (! $ hasAction && ! $ hasEmailActivate ) {
162168 $ this ->completeLogin ($ user );
163169 }
164170
@@ -405,16 +411,52 @@ private function checkUserState(): void
405411 $ this ->userState = self ::STATE_ANONYMOUS ;
406412 }
407413
414+ /**
415+ * Has Auth Action?
416+ */
417+ public function hasAction (): bool
418+ {
419+ // Check the Session
420+ if ($ this ->getSessionKey ('auth_action ' )) {
421+ return true ;
422+ }
423+
424+ // Check the database
425+ return $ this ->setAuthAction ();
426+ }
427+
408428 /**
409429 * Gets identities for action from database, and set session.
430+ *
431+ * @return bool true if the action is set in the session.
410432 */
411- private function setAuthAction (): void
433+ private function setAuthAction (): bool
412434 {
413- // Get identities for action
414- $ identities = $ this ->getIdentitiesForAction ();
435+ if ($ this ->user === null ) {
436+ return false ;
437+ }
438+
439+ // First, check ID_TYPE_EMAIL_ACTIVATE identity
440+ $ hasAction = $ this ->setAuthActionEmailActivate ();
441+ if ($ hasAction ) {
442+ return true ;
443+ }
444+
445+ // Next, check ID_TYPE_EMAIL_2FA identity
446+ return $ this ->setAuthActionEmail2FA ();
447+ }
415448
416- // Having an action?
417- foreach ($ identities as $ identity ) {
449+ /**
450+ * @return bool true if the action is set in the session.
451+ */
452+ private function setAuthActionEmailActivate (): bool
453+ {
454+ $ identity = $ this ->userIdentityModel ->getIdentityByType (
455+ $ this ->user ,
456+ self ::ID_TYPE_EMAIL_ACTIVATE
457+ );
458+
459+ if ($ identity ) {
418460 $ actionClass = setting ('Auth.actions ' )[$ identity ->name ];
419461
420462 if ($ actionClass ) {
@@ -423,9 +465,37 @@ private function setAuthAction(): void
423465 $ this ->setSessionKey ('auth_action ' , $ actionClass );
424466 $ this ->setSessionKey ('auth_action_message ' , $ identity ->extra );
425467
426- return ;
468+ return true ;
469+ }
470+ }
471+
472+ return false ;
473+ }
474+
475+ /**
476+ * @return bool true if the action is set in the session.
477+ */
478+ private function setAuthActionEmail2FA (): bool
479+ {
480+ $ identity = $ this ->userIdentityModel ->getIdentityByType (
481+ $ this ->user ,
482+ self ::ID_TYPE_EMAIL_2FA
483+ );
484+
485+ if ($ identity ) {
486+ $ actionClass = setting ('Auth.actions ' )[$ identity ->name ];
487+
488+ if ($ actionClass ) {
489+ $ this ->userState = self ::STATE_PENDING ;
490+
491+ $ this ->setSessionKey ('auth_action ' , $ actionClass );
492+ $ this ->setSessionKey ('auth_action_message ' , $ identity ->extra );
493+
494+ return true ;
427495 }
428496 }
497+
498+ return false ;
429499 }
430500
431501 /**
0 commit comments