@@ -27,10 +27,12 @@ const events = [
2727  'discarded' , 
2828  'disconnected' , 
2929  'loginAttempt' , 
30+   'logoutAttempt' , 
3031  'networkError' , 
3132  'offlineQueuePush' , 
3233  'offlineQueuePop' , 
3334  'queryError' , 
35+   'reAuthenticated' , 
3436  'reconnected' , 
3537  'reconnectionError' , 
3638  'tokenExpired' 
@@ -98,6 +100,8 @@ export class Kuzzle extends KuzzleEventEmitter {
98100  private  _tokenExpiredInterval : any ; 
99101  private  _lastTokenExpired : any ; 
100102  private  _cookieAuthentication : boolean ; 
103+   private  _reconnectInProgress : boolean ; 
104+   private  _loggedIn : boolean ; 
101105
102106  private  __proxy__ : any ; 
103107
@@ -323,6 +327,48 @@ export class Kuzzle extends KuzzleEventEmitter {
323327
324328    this . _lastTokenExpired  =  null ; 
325329
330+     this . _reconnectInProgress  =  false ; 
331+ 
332+     this . _loggedIn  =  false ; 
333+ 
334+     this . on ( 'loginAttempt' ,  async  status  =>  { 
335+       if  ( status . success )  { 
336+         this . _loggedIn  =  true ; 
337+         return ; 
338+       } 
339+       
340+       /** 
341+        * In case of login failure we need to be sure that the stored token is still valid 
342+        */ 
343+       try  { 
344+         const  response  =  await  this . auth . checkToken ( ) ; 
345+         this . _loggedIn  =  response . valid ; 
346+       }  catch  { 
347+         this . _loggedIn  =  false ; 
348+       } 
349+     } ) ; 
350+ 
351+     /** 
352+      * When successfuly logged out 
353+      */ 
354+     this . on ( 'logoutAttempt' ,  status  =>  { 
355+       if  ( status . success )  { 
356+         this . _loggedIn  =  false ; 
357+       } 
358+     } ) ; 
359+ 
360+     /** 
361+      * On connection we need to verify if the token is still valid to know if we are still "logged in" 
362+      */ 
363+     this . on ( 'connected' ,  async  ( )  =>  { 
364+       try  { 
365+         const  {  valid }  =  await  this . auth . checkToken ( ) ; 
366+         this . _loggedIn  =  valid ; 
367+       }  catch  { 
368+         this . _loggedIn  =  false ; 
369+       } 
370+     } ) ; 
371+ 
326372    return  proxify ( this ,  { 
327373      seal : true , 
328374      name : 'kuzzle' , 
@@ -531,31 +577,44 @@ export class Kuzzle extends KuzzleEventEmitter {
531577      this . emit ( 'disconnected' ,  context ) ; 
532578    } ) ; 
533579
534-     this . protocol . addListener ( 'reconnect' ,  async  ( )  =>  { 
535-       if  ( this . autoQueue )  { 
536-         this . stopQueuing ( ) ; 
537-       } 
538- 
539-       // If an authenticator was set, check if the token is still valid and try 
540-       // to re-authenticate if needed. Otherwise the SDK is in disconnected state. 
541-       if  ( this . authenticator  &&  !  await  this . tryReAuthenticate ( ) )  { 
542-         this . disconnect ( ) ; 
543- 
544-         return ; 
545-       } 
546- 
547-       if  ( this . autoReplay )  { 
548-         this . playQueue ( ) ; 
549-       } 
550- 
551-       this . emit ( 'reconnected' ) ; 
552-     } ) ; 
580+     this . protocol . addListener ( 'reconnect' ,  this . _reconnect . bind ( this ) ) ; 
553581
554582    this . protocol . addListener ( 'discarded' ,  data  =>  this . emit ( 'discarded' ,  data ) ) ; 
555583
584+     this . protocol . addListener ( 'websocketRenewalStart' ,  ( )  =>  {  this . _reconnectInProgress  =  true ;  } ) ; 
585+     this . protocol . addListener ( 'websocketRenewalDone' ,  ( )  =>  {  this . _reconnectInProgress  =  false ;  } ) ; 
586+ 
556587    return  this . protocol . connect ( ) ; 
557588  } 
558589
590+   async  _reconnect ( )  { 
591+     if  ( this . _reconnectInProgress )  { 
592+       return ; 
593+     } 
594+     
595+     if  ( this . autoQueue )  { 
596+       this . stopQueuing ( ) ; 
597+     } 
598+   
599+     // If an authenticator was set, check if a user was logged in and  if the token is still valid and try 
600+     // to re-authenticate if needed. Otherwise the SDK is in disconnected state. 
601+     if  (  this . _loggedIn 
602+       &&  this . authenticator  
603+       &&  !  await  this . tryReAuthenticate ( ) 
604+     )  { 
605+       this . _loggedIn  =  false ; 
606+       this . disconnect ( ) ; 
607+       
608+       return ; 
609+     } 
610+     
611+     if  ( this . autoReplay )  { 
612+       this . playQueue ( ) ; 
613+     } 
614+     
615+     this . emit ( 'reconnected' ) ; 
616+   } 
617+ 
559618  /** 
560619   * Try to re-authenticate the SDK if the current token is invalid. 
561620   * 
@@ -567,6 +626,7 @@ export class Kuzzle extends KuzzleEventEmitter {
567626   * This method never returns a rejected promise. 
568627   */ 
569628  private  async  tryReAuthenticate  ( ) : Promise < boolean >  { 
629+     this . _reconnectInProgress  =  true ; 
570630    try  { 
571631      const  {  valid }  =  await  this . auth . checkToken ( ) ; 
572632
@@ -584,6 +644,8 @@ export class Kuzzle extends KuzzleEventEmitter {
584644      } ) ; 
585645
586646      return  false ; 
647+     }  finally  { 
648+       this . _reconnectInProgress  =  false ; 
587649    } 
588650  } 
589651
@@ -601,6 +663,8 @@ export class Kuzzle extends KuzzleEventEmitter {
601663
602664    const  {  valid }  =  await  this . auth . checkToken ( ) ; 
603665
666+     this . _loggedIn  =  valid ; 
667+ 
604668    if  ( !  valid )  { 
605669      throw  new  Error ( 'The "authenticator" function failed to authenticate the SDK.' ) ; 
606670    } 
@@ -639,6 +703,7 @@ export class Kuzzle extends KuzzleEventEmitter {
639703   * Disconnects from Kuzzle and invalidate this instance. 
640704   */ 
641705  disconnect  ( )  { 
706+     this . _loggedIn  =  false ; 
642707    this . protocol . close ( ) ; 
643708  } 
644709
@@ -769,7 +834,17 @@ Discarded request: ${JSON.stringify(request)}`));
769834   * On token expiration, reset jwt and unsubscribe all rooms. 
770835   * Throttles to avoid duplicate event triggers. 
771836   */ 
772-   tokenExpired ( )  { 
837+   async  tokenExpired  ( )  { 
838+     if  ( this . _reconnectInProgress )  { 
839+       return ; 
840+     } 
841+ 
842+     if  ( this . _loggedIn  &&  this . authenticator  &&  await  this . tryReAuthenticate ( ) )  { 
843+       this . emit ( 'reAuthenticated' ) ; 
844+ 
845+       return ; 
846+     } 
847+ 
773848    const  now  =  Date . now ( ) ; 
774849
775850    if  ( ( now  -  this . _lastTokenExpired )  <  this . tokenExpiredInterval )  { 
0 commit comments