@brggroup/share-lib 0.0.84 → 0.0.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, Injectable, NgZone, Component, HostListener, ViewContainerRef, Input, ViewChild, EventEmitter, Output, Directive, Optional, Self, HostBinding, forwardRef, Pipe } from '@angular/core';
2
+ import { inject, Injectable, Component, HostListener, ViewContainerRef, Input, ViewChild, EventEmitter, Output, Directive, Optional, Self, HostBinding, forwardRef, Pipe } from '@angular/core';
3
3
  import * as i1$4 from '@angular/router';
4
4
  import { Router, ActivatedRoute, NavigationEnd, RouterLink, RouterOutlet } from '@angular/router';
5
5
  import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
@@ -544,7 +544,11 @@ class TokenStorage {
544
544
  }
545
545
 
546
546
  class SessionManagerService {
547
- zone = inject(NgZone);
547
+ zone;
548
+ constructor(zone) {
549
+ this.zone = zone;
550
+ }
551
+ handlers;
548
552
  idleTimer;
549
553
  refreshTimer;
550
554
  heartbeatTimer;
@@ -553,30 +557,38 @@ class SessionManagerService {
553
557
  get IDLE_TIME() {
554
558
  return (SessionManagerService.IDLE_MIN || 0) * 60 * 1000;
555
559
  }
556
- LEADER_KEY = 'APP_LEADER';
557
- HEARTBEAT_KEY = 'APP_LEADER_HEARTBEAT';
558
- channel = new BroadcastChannel('APP_SESSION');
560
+ LEADER_KEY = 'APP_SESSION_LEADER';
561
+ HEARTBEAT_KEY = 'APP_SESSION_HEARTBEAT';
562
+ ACTIVITY_KEY = 'APP_LAST_ACTIVITY';
559
563
  tabId = crypto.randomUUID();
560
564
  isLeader = false;
561
- handlers;
562
- /* ---------------- START ---------------- */
565
+ isRunning = false;
566
+ refreshLock = false;
567
+ channel = null;
568
+ /* -------------------------------- START -------------------------------- */
563
569
  start(handlers) {
564
- if (this.IDLE_TIME <= 0)
570
+ if (this.IDLE_TIME <= 0 || this.isRunning)
565
571
  return;
572
+ this.isRunning = true;
566
573
  this.handlers = handlers;
574
+ if ('BroadcastChannel' in window) {
575
+ this.channel = new BroadcastChannel('APP_SESSION');
576
+ this.listenChannel();
577
+ }
567
578
  this.listenActivity();
568
- this.listenChannel();
569
579
  this.updateActivity();
570
580
  this.resetIdle();
571
581
  this.electLeader();
572
582
  }
573
583
  stop() {
584
+ this.isRunning = false;
574
585
  clearTimeout(this.idleTimer);
575
586
  clearTimeout(this.refreshTimer);
576
587
  clearInterval(this.heartbeatTimer);
577
- this.channel.close();
588
+ this.channel?.close();
589
+ this.channel = null;
578
590
  }
579
- /* ---------------- ACTIVITY ---------------- */
591
+ /* -------------------------------- ACTIVITY -------------------------------- */
580
592
  listenActivity() {
581
593
  const events = ['mousemove', 'keydown', 'click', 'scroll'];
582
594
  events.forEach((e) => {
@@ -584,17 +596,21 @@ class SessionManagerService {
584
596
  });
585
597
  }
586
598
  onActivity = this.debounce(() => {
599
+ if (!this.isRunning)
600
+ return;
587
601
  this.updateActivity();
588
602
  this.resetIdle();
589
- this.channel.postMessage({ type: 'activity' });
603
+ this.broadcast('activity');
590
604
  }, 1000);
591
605
  updateActivity() {
592
- localStorage.setItem('APP_LAST_ACTIVITY', Date.now().toString());
606
+ localStorage.setItem(this.ACTIVITY_KEY, Date.now().toString());
593
607
  }
594
- /* ---------------- IDLE ---------------- */
608
+ /* -------------------------------- IDLE -------------------------------- */
595
609
  resetIdle() {
610
+ if (!this.isRunning)
611
+ return;
596
612
  clearTimeout(this.idleTimer);
597
- const last = Number(localStorage.getItem('APP_LAST_ACTIVITY') || Date.now());
613
+ const last = Number(localStorage.getItem(this.ACTIVITY_KEY) || Date.now());
598
614
  const remain = this.IDLE_TIME - (Date.now() - last);
599
615
  if (remain <= 0) {
600
616
  this.logout();
@@ -606,7 +622,7 @@ class SessionManagerService {
606
622
  }, remain);
607
623
  });
608
624
  }
609
- /* ---------------- LEADER ---------------- */
625
+ /* -------------------------------- LEADER -------------------------------- */
610
626
  electLeader() {
611
627
  const leader = localStorage.getItem(this.LEADER_KEY);
612
628
  if (!leader) {
@@ -616,7 +632,6 @@ class SessionManagerService {
616
632
  this.checkLeaderHeartbeat();
617
633
  }
618
634
  becomeLeader() {
619
- console.log('Become leader', this.tabId);
620
635
  this.isLeader = true;
621
636
  localStorage.setItem(this.LEADER_KEY, this.tabId);
622
637
  this.startHeartbeat();
@@ -635,12 +650,12 @@ class SessionManagerService {
635
650
  }
636
651
  }, 3000);
637
652
  }
638
- /* ---------------- REFRESH ---------------- */
653
+ /* -------------------------------- REFRESH TOKEN -------------------------------- */
639
654
  scheduleRefresh() {
640
- if (!this.isLeader)
655
+ if (!this.isLeader || !this.isRunning)
641
656
  return;
642
657
  clearTimeout(this.refreshTimer);
643
- const token = TokenStorage.getToken();
658
+ const token = this.handlers.getToken();
644
659
  if (!token)
645
660
  return;
646
661
  const exp = this.parseJwt(token).exp * 1000;
@@ -654,12 +669,13 @@ class SessionManagerService {
654
669
  }, delay);
655
670
  }
656
671
  async refreshToken() {
657
- if (!this.isLeader)
672
+ if (!this.isLeader || this.refreshLock || !this.isRunning)
658
673
  return;
674
+ this.refreshLock = true;
659
675
  try {
660
676
  const res = await this.handlers.refreshToken();
661
677
  if (res?.IsSuccess) {
662
- this.channel.postMessage({ type: 'token-refresh' });
678
+ this.broadcast('token-refresh');
663
679
  this.scheduleRefresh();
664
680
  }
665
681
  else {
@@ -669,10 +685,17 @@ class SessionManagerService {
669
685
  catch {
670
686
  this.logout();
671
687
  }
688
+ finally {
689
+ this.refreshLock = false;
690
+ }
672
691
  }
673
- /* ---------------- CHANNEL ---------------- */
692
+ /* -------------------------------- CHANNEL -------------------------------- */
674
693
  listenChannel() {
694
+ if (!this.channel)
695
+ return;
675
696
  this.channel.onmessage = (msg) => {
697
+ if (!this.isRunning)
698
+ return;
676
699
  const type = msg.data?.type;
677
700
  if (type === 'activity') {
678
701
  this.resetIdle();
@@ -685,12 +708,24 @@ class SessionManagerService {
685
708
  }
686
709
  };
687
710
  }
688
- /* ---------------- LOGOUT ---------------- */
711
+ broadcast(type) {
712
+ if (!this.isRunning)
713
+ return;
714
+ if (this.channel) {
715
+ this.channel.postMessage({ type });
716
+ }
717
+ else {
718
+ localStorage.setItem('APP_SESSION_EVENT', JSON.stringify({ type, t: Date.now() }));
719
+ }
720
+ }
721
+ /* -------------------------------- LOGOUT -------------------------------- */
689
722
  logout() {
690
- this.channel.postMessage({ type: 'logout' });
723
+ if (!this.isRunning)
724
+ return;
725
+ this.broadcast('logout');
691
726
  this.handlers.logout();
692
727
  }
693
- /* ---------------- UTILS ---------------- */
728
+ /* -------------------------------- UTILS -------------------------------- */
694
729
  debounce(fn, delay) {
695
730
  let timer;
696
731
  return () => {
@@ -702,7 +737,7 @@ class SessionManagerService {
702
737
  const payload = token.split('.')[1];
703
738
  return JSON.parse(atob(payload));
704
739
  }
705
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: SessionManagerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
740
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: SessionManagerService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
706
741
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: SessionManagerService, providedIn: 'root' });
707
742
  }
708
743
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: SessionManagerService, decorators: [{
@@ -710,7 +745,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImpor
710
745
  args: [{
711
746
  providedIn: 'root',
712
747
  }]
713
- }] });
748
+ }], ctorParameters: () => [{ type: i0.NgZone }] });
714
749
 
715
750
  const URLs$4 = {
716
751
  login: '/api/Auth/Login',
@@ -775,6 +810,7 @@ class AuthService extends HTTPService {
775
810
  this.sessionManager.start({
776
811
  refreshToken: () => this.refreshToken(),
777
812
  logout: () => this.signOut(),
813
+ getToken: () => this.getToken(),
778
814
  });
779
815
  if (returnUrl) {
780
816
  this.router.navigateByUrl(returnUrl);
@@ -797,7 +833,11 @@ class AuthService extends HTTPService {
797
833
  initSession() {
798
834
  const token = TokenStorage.getToken();
799
835
  if (token) {
800
- this.sessionManager.start({ refreshToken: () => this.refreshToken(), logout: () => this.signOut() });
836
+ this.sessionManager.start({
837
+ refreshToken: () => this.refreshToken(),
838
+ logout: () => this.signOut(),
839
+ getToken: () => this.getToken(),
840
+ });
801
841
  }
802
842
  }
803
843
  /* ----------------------------------------