@brggroup/share-lib 0.0.85 → 0.0.87
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,
|
|
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,8 +544,11 @@ class TokenStorage {
|
|
|
544
544
|
}
|
|
545
545
|
|
|
546
546
|
class SessionManagerService {
|
|
547
|
-
zone
|
|
548
|
-
|
|
547
|
+
zone;
|
|
548
|
+
constructor(zone) {
|
|
549
|
+
this.zone = zone;
|
|
550
|
+
}
|
|
551
|
+
handlers;
|
|
549
552
|
idleTimer;
|
|
550
553
|
refreshTimer;
|
|
551
554
|
heartbeatTimer;
|
|
@@ -554,33 +557,48 @@ class SessionManagerService {
|
|
|
554
557
|
get IDLE_TIME() {
|
|
555
558
|
return (SessionManagerService.IDLE_MIN || 0) * 60 * 1000;
|
|
556
559
|
}
|
|
557
|
-
LEADER_KEY = '
|
|
558
|
-
HEARTBEAT_KEY = '
|
|
559
|
-
|
|
560
|
+
LEADER_KEY = 'APP_SESSION_LEADER';
|
|
561
|
+
HEARTBEAT_KEY = 'APP_SESSION_HEARTBEAT';
|
|
562
|
+
ACTIVITY_KEY = 'APP_LAST_ACTIVITY';
|
|
563
|
+
SESSION_EVENT = 'APP_SESSION_EVENT';
|
|
564
|
+
LOGIN_EVENT = 'APP_LOGIN_EVENT';
|
|
565
|
+
LOGOUT_EVENT = 'APP_LOGOUT_EVENT';
|
|
566
|
+
ACTIVITY_EVENT = 'APP_ACTIVITY_EVENT';
|
|
567
|
+
TOKEN_REFRESH_EVENT = 'APP_TOKEN_REFRESH_EVENT';
|
|
560
568
|
tabId = crypto.randomUUID();
|
|
561
569
|
isLeader = false;
|
|
562
|
-
|
|
563
|
-
|
|
570
|
+
isRunning = false;
|
|
571
|
+
refreshLock = false;
|
|
572
|
+
channel = null;
|
|
573
|
+
/* -------------------------------- START -------------------------------- */
|
|
564
574
|
start(handlers) {
|
|
565
575
|
if (this.IDLE_TIME <= 0 || this.isRunning)
|
|
566
576
|
return;
|
|
577
|
+
this.isRunning = true;
|
|
567
578
|
this.handlers = handlers;
|
|
579
|
+
if ('BroadcastChannel' in window) {
|
|
580
|
+
this.channel = new BroadcastChannel('APP_SESSION');
|
|
581
|
+
this.listenChannel();
|
|
582
|
+
}
|
|
568
583
|
this.listenActivity();
|
|
569
|
-
this.listenChannel();
|
|
570
584
|
this.updateActivity();
|
|
571
585
|
this.resetIdle();
|
|
572
586
|
this.electLeader();
|
|
587
|
+
window.addEventListener('storage', (event) => {
|
|
588
|
+
if (event.key === this.LOGIN_EVENT) {
|
|
589
|
+
location.reload();
|
|
590
|
+
}
|
|
591
|
+
});
|
|
573
592
|
}
|
|
574
593
|
stop() {
|
|
575
594
|
this.isRunning = false;
|
|
576
595
|
clearTimeout(this.idleTimer);
|
|
577
596
|
clearTimeout(this.refreshTimer);
|
|
578
597
|
clearInterval(this.heartbeatTimer);
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
}
|
|
598
|
+
this.channel?.close();
|
|
599
|
+
this.channel = null;
|
|
582
600
|
}
|
|
583
|
-
/*
|
|
601
|
+
/* -------------------------------- ACTIVITY -------------------------------- */
|
|
584
602
|
listenActivity() {
|
|
585
603
|
const events = ['mousemove', 'keydown', 'click', 'scroll'];
|
|
586
604
|
events.forEach((e) => {
|
|
@@ -588,22 +606,21 @@ class SessionManagerService {
|
|
|
588
606
|
});
|
|
589
607
|
}
|
|
590
608
|
onActivity = this.debounce(() => {
|
|
609
|
+
if (!this.isRunning)
|
|
610
|
+
return;
|
|
591
611
|
this.updateActivity();
|
|
592
612
|
this.resetIdle();
|
|
593
|
-
this.broadcast(
|
|
613
|
+
this.broadcast(this.ACTIVITY_EVENT);
|
|
594
614
|
}, 1000);
|
|
595
615
|
updateActivity() {
|
|
596
|
-
localStorage.setItem(
|
|
616
|
+
localStorage.setItem(this.ACTIVITY_KEY, Date.now().toString());
|
|
597
617
|
}
|
|
598
|
-
|
|
618
|
+
/* -------------------------------- IDLE -------------------------------- */
|
|
619
|
+
resetIdle() {
|
|
599
620
|
if (!this.isRunning)
|
|
600
621
|
return;
|
|
601
|
-
this.channel?.postMessage({ type });
|
|
602
|
-
}
|
|
603
|
-
/* ---------------- IDLE ---------------- */
|
|
604
|
-
resetIdle() {
|
|
605
622
|
clearTimeout(this.idleTimer);
|
|
606
|
-
const last = Number(localStorage.getItem(
|
|
623
|
+
const last = Number(localStorage.getItem(this.ACTIVITY_KEY) || Date.now());
|
|
607
624
|
const remain = this.IDLE_TIME - (Date.now() - last);
|
|
608
625
|
if (remain <= 0) {
|
|
609
626
|
this.logout();
|
|
@@ -615,7 +632,7 @@ class SessionManagerService {
|
|
|
615
632
|
}, remain);
|
|
616
633
|
});
|
|
617
634
|
}
|
|
618
|
-
/*
|
|
635
|
+
/* -------------------------------- LEADER -------------------------------- */
|
|
619
636
|
electLeader() {
|
|
620
637
|
const leader = localStorage.getItem(this.LEADER_KEY);
|
|
621
638
|
if (!leader) {
|
|
@@ -625,7 +642,6 @@ class SessionManagerService {
|
|
|
625
642
|
this.checkLeaderHeartbeat();
|
|
626
643
|
}
|
|
627
644
|
becomeLeader() {
|
|
628
|
-
console.log('Become leader', this.tabId);
|
|
629
645
|
this.isLeader = true;
|
|
630
646
|
localStorage.setItem(this.LEADER_KEY, this.tabId);
|
|
631
647
|
this.startHeartbeat();
|
|
@@ -644,12 +660,12 @@ class SessionManagerService {
|
|
|
644
660
|
}
|
|
645
661
|
}, 3000);
|
|
646
662
|
}
|
|
647
|
-
/*
|
|
663
|
+
/* -------------------------------- REFRESH TOKEN -------------------------------- */
|
|
648
664
|
scheduleRefresh() {
|
|
649
|
-
if (!this.isLeader)
|
|
665
|
+
if (!this.isLeader || !this.isRunning)
|
|
650
666
|
return;
|
|
651
667
|
clearTimeout(this.refreshTimer);
|
|
652
|
-
const token =
|
|
668
|
+
const token = this.handlers.getToken();
|
|
653
669
|
if (!token)
|
|
654
670
|
return;
|
|
655
671
|
const exp = this.parseJwt(token).exp * 1000;
|
|
@@ -663,12 +679,13 @@ class SessionManagerService {
|
|
|
663
679
|
}, delay);
|
|
664
680
|
}
|
|
665
681
|
async refreshToken() {
|
|
666
|
-
if (!this.isLeader)
|
|
682
|
+
if (!this.isLeader || this.refreshLock || !this.isRunning)
|
|
667
683
|
return;
|
|
684
|
+
this.refreshLock = true;
|
|
668
685
|
try {
|
|
669
686
|
const res = await this.handlers.refreshToken();
|
|
670
687
|
if (res?.IsSuccess) {
|
|
671
|
-
this.broadcast(
|
|
688
|
+
this.broadcast(this.TOKEN_REFRESH_EVENT);
|
|
672
689
|
this.scheduleRefresh();
|
|
673
690
|
}
|
|
674
691
|
else {
|
|
@@ -678,28 +695,56 @@ class SessionManagerService {
|
|
|
678
695
|
catch {
|
|
679
696
|
this.logout();
|
|
680
697
|
}
|
|
698
|
+
finally {
|
|
699
|
+
this.refreshLock = false;
|
|
700
|
+
}
|
|
681
701
|
}
|
|
682
|
-
/*
|
|
702
|
+
/* -------------------------------- CHANNEL -------------------------------- */
|
|
683
703
|
listenChannel() {
|
|
704
|
+
if (!this.channel)
|
|
705
|
+
return;
|
|
684
706
|
this.channel.onmessage = (msg) => {
|
|
707
|
+
if (!this.isRunning)
|
|
708
|
+
return;
|
|
685
709
|
const type = msg.data?.type;
|
|
686
|
-
if (type ===
|
|
710
|
+
if (type === this.ACTIVITY_EVENT) {
|
|
687
711
|
this.resetIdle();
|
|
688
712
|
}
|
|
689
|
-
if (type ===
|
|
713
|
+
if (type === this.LOGOUT_EVENT) {
|
|
690
714
|
this.handlers.logout();
|
|
691
715
|
}
|
|
692
|
-
if (type ===
|
|
716
|
+
if (type === this.LOGIN_EVENT) {
|
|
717
|
+
location.reload();
|
|
718
|
+
}
|
|
719
|
+
if (type === this.TOKEN_REFRESH_EVENT) {
|
|
693
720
|
this.scheduleRefresh();
|
|
694
721
|
}
|
|
695
722
|
};
|
|
696
723
|
}
|
|
697
|
-
|
|
724
|
+
broadcast(type) {
|
|
725
|
+
if (!this.isRunning)
|
|
726
|
+
return;
|
|
727
|
+
if (this.channel) {
|
|
728
|
+
this.channel.postMessage({ type });
|
|
729
|
+
}
|
|
730
|
+
else {
|
|
731
|
+
localStorage.setItem(this.SESSION_EVENT, JSON.stringify({ type, t: Date.now() }));
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
broadcastLogin() {
|
|
735
|
+
this.broadcast(this.LOGIN_EVENT);
|
|
736
|
+
}
|
|
737
|
+
broadcastLogout() {
|
|
738
|
+
this.broadcast(this.LOGOUT_EVENT);
|
|
739
|
+
}
|
|
740
|
+
/* -------------------------------- LOGOUT -------------------------------- */
|
|
698
741
|
logout() {
|
|
699
|
-
this.
|
|
742
|
+
if (!this.isRunning)
|
|
743
|
+
return;
|
|
700
744
|
this.handlers.logout();
|
|
745
|
+
this.broadcast(this.LOGOUT_EVENT);
|
|
701
746
|
}
|
|
702
|
-
/*
|
|
747
|
+
/* -------------------------------- UTILS -------------------------------- */
|
|
703
748
|
debounce(fn, delay) {
|
|
704
749
|
let timer;
|
|
705
750
|
return () => {
|
|
@@ -711,7 +756,7 @@ class SessionManagerService {
|
|
|
711
756
|
const payload = token.split('.')[1];
|
|
712
757
|
return JSON.parse(atob(payload));
|
|
713
758
|
}
|
|
714
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: SessionManagerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
759
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: SessionManagerService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
715
760
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: SessionManagerService, providedIn: 'root' });
|
|
716
761
|
}
|
|
717
762
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImport: i0, type: SessionManagerService, decorators: [{
|
|
@@ -719,7 +764,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImpor
|
|
|
719
764
|
args: [{
|
|
720
765
|
providedIn: 'root',
|
|
721
766
|
}]
|
|
722
|
-
}] });
|
|
767
|
+
}], ctorParameters: () => [{ type: i0.NgZone }] });
|
|
723
768
|
|
|
724
769
|
const URLs$4 = {
|
|
725
770
|
login: '/api/Auth/Login',
|
|
@@ -784,7 +829,9 @@ class AuthService extends HTTPService {
|
|
|
784
829
|
this.sessionManager.start({
|
|
785
830
|
refreshToken: () => this.refreshToken(),
|
|
786
831
|
logout: () => this.signOut(),
|
|
832
|
+
getToken: () => this.getToken(),
|
|
787
833
|
});
|
|
834
|
+
this.sessionManager.broadcastLogin();
|
|
788
835
|
if (returnUrl) {
|
|
789
836
|
this.router.navigateByUrl(returnUrl);
|
|
790
837
|
}
|
|
@@ -806,7 +853,11 @@ class AuthService extends HTTPService {
|
|
|
806
853
|
initSession() {
|
|
807
854
|
const token = TokenStorage.getToken();
|
|
808
855
|
if (token) {
|
|
809
|
-
this.sessionManager.start({
|
|
856
|
+
this.sessionManager.start({
|
|
857
|
+
refreshToken: () => this.refreshToken(),
|
|
858
|
+
logout: () => this.signOut(),
|
|
859
|
+
getToken: () => this.getToken(),
|
|
860
|
+
});
|
|
810
861
|
}
|
|
811
862
|
}
|
|
812
863
|
/* ----------------------------------------
|
|
@@ -814,6 +865,7 @@ class AuthService extends HTTPService {
|
|
|
814
865
|
---------------------------------------- */
|
|
815
866
|
signOut() {
|
|
816
867
|
TokenStorage.clearToken();
|
|
868
|
+
this.sessionManager.broadcastLogout();
|
|
817
869
|
this.sessionManager.stop();
|
|
818
870
|
const currentUrl = this.router.routerState.snapshot.url;
|
|
819
871
|
this.router.navigate(['/login'], {
|