@brggroup/share-lib 0.0.30 → 0.0.31
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.
- package/fesm2022/brggroup-share-lib.mjs +79 -17
- package/fesm2022/brggroup-share-lib.mjs.map +1 -1
- package/lib/auth/auth.interceptor.d.ts.map +1 -1
- package/lib/auth/auth.service.d.ts +1 -0
- package/lib/auth/auth.service.d.ts.map +1 -1
- package/lib/auth/token.storage.d.ts +2 -0
- package/lib/auth/token.storage.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -5,7 +5,7 @@ import { Router, ActivatedRoute, NavigationEnd } from '@angular/router';
|
|
|
5
5
|
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
|
|
6
6
|
import * as i3 from '@ngx-translate/core';
|
|
7
7
|
import { TranslateService, TranslateModule } from '@ngx-translate/core';
|
|
8
|
-
import { firstValueFrom, BehaviorSubject, of, catchError,
|
|
8
|
+
import { firstValueFrom, BehaviorSubject, of, catchError, throwError, finalize, from, switchMap as switchMap$1, EMPTY, filter, take, fromEvent } from 'rxjs';
|
|
9
9
|
import { NzNotificationService } from 'ng-zorro-antd/notification';
|
|
10
10
|
import * as i1 from 'ng-zorro-antd/modal';
|
|
11
11
|
import { NzModalService } from 'ng-zorro-antd/modal';
|
|
@@ -419,7 +419,14 @@ class TokenStorage {
|
|
|
419
419
|
static saveToken(tokenRes) {
|
|
420
420
|
AppStorage.tokenStorage.setItem(this.JWT_TOKEN, tokenRes.Data.Token);
|
|
421
421
|
AppStorage.tokenStorage.setItem(this.JWT_RFT_TOKEN, tokenRes.Data.RefreshToken);
|
|
422
|
-
|
|
422
|
+
TokenStorage.saveTokenInfo(tokenRes.Data.Token);
|
|
423
|
+
}
|
|
424
|
+
static saveTokenRft(token) {
|
|
425
|
+
AppStorage.tokenStorage.setItem(this.JWT_TOKEN, token);
|
|
426
|
+
TokenStorage.saveTokenInfo(token);
|
|
427
|
+
}
|
|
428
|
+
static saveTokenInfo(token) {
|
|
429
|
+
const userInfo = jwtDecode(token);
|
|
423
430
|
AppStorage.tokenStorage.setItem(this.USER_NAME, userInfo[this.USER_NAME]);
|
|
424
431
|
AppStorage.tokenStorage.setItem(this.FULL_NAME, userInfo[this.FULL_NAME]);
|
|
425
432
|
AppStorage.tokenStorage.setItem(this.ORG_ID, userInfo[this.ORG_ID]);
|
|
@@ -479,6 +486,21 @@ class AuthService extends HTTPService {
|
|
|
479
486
|
commonService = inject(CommonService);
|
|
480
487
|
router = inject(Router);
|
|
481
488
|
translate = inject(TranslateService);
|
|
489
|
+
async refreshToken() {
|
|
490
|
+
const refreshToken = TokenStorage.getRftToken();
|
|
491
|
+
if (!refreshToken)
|
|
492
|
+
return null;
|
|
493
|
+
const body = { rft: refreshToken };
|
|
494
|
+
try {
|
|
495
|
+
const result = (await firstValueFrom(this.httpClient.post(AppGlobals.apiEndpoint + '/api/Auth/RefreshToken', body)));
|
|
496
|
+
if (result?.IsSuccess) {
|
|
497
|
+
TokenStorage.saveTokenRft(result.Data);
|
|
498
|
+
return result;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
catch { }
|
|
502
|
+
return null;
|
|
503
|
+
}
|
|
482
504
|
async pingAuth() {
|
|
483
505
|
try {
|
|
484
506
|
const res = await this.post(AppGlobals.apiEndpoint + URLs.pingAuth);
|
|
@@ -621,23 +643,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", ngImpor
|
|
|
621
643
|
}] });
|
|
622
644
|
|
|
623
645
|
let initialReturnUrl = null;
|
|
646
|
+
let isRefreshing = false;
|
|
647
|
+
const refreshTokenSubject = new BehaviorSubject(null);
|
|
624
648
|
function authInterceptor(req, next) {
|
|
625
649
|
const router = inject(Router);
|
|
626
650
|
const loadingService = inject(LoadingService);
|
|
627
|
-
const
|
|
628
|
-
const notiService = inject(NotiService);
|
|
629
|
-
const translate = inject(TranslateService);
|
|
651
|
+
const authService = inject(AuthService);
|
|
630
652
|
const authToken = TokenStorage.getToken();
|
|
631
653
|
const noLoadingMark = req.headers.get('No-Loading-Mark');
|
|
632
|
-
if (noLoadingMark
|
|
654
|
+
if (noLoadingMark !== '1')
|
|
633
655
|
loadingService.loadingUp();
|
|
634
|
-
|
|
656
|
+
// Convert dates
|
|
635
657
|
if (!(req.body instanceof FormData)) {
|
|
636
658
|
const newBody = convertDatesInBody(req.body);
|
|
637
659
|
if (req.body !== newBody) {
|
|
638
660
|
req = req.clone({ body: newBody });
|
|
639
661
|
}
|
|
640
662
|
}
|
|
663
|
+
// Add token
|
|
641
664
|
if (authToken) {
|
|
642
665
|
req = req.clone({
|
|
643
666
|
setHeaders: { Authorization: `Bearer ${authToken}` },
|
|
@@ -645,8 +668,46 @@ function authInterceptor(req, next) {
|
|
|
645
668
|
}
|
|
646
669
|
return next(req).pipe(catchError((error) => {
|
|
647
670
|
if (error.status === 401) {
|
|
648
|
-
|
|
649
|
-
|
|
671
|
+
return handle401(req, next, router, authService);
|
|
672
|
+
}
|
|
673
|
+
return throwError(() => error);
|
|
674
|
+
}), finalize(() => {
|
|
675
|
+
if (noLoadingMark !== '1')
|
|
676
|
+
loadingService.loadingDown();
|
|
677
|
+
}));
|
|
678
|
+
}
|
|
679
|
+
//
|
|
680
|
+
// ⭐ REFRESH TOKEN HANDLER
|
|
681
|
+
//
|
|
682
|
+
function handle401(req, next, router, authService) {
|
|
683
|
+
if (!isRefreshing) {
|
|
684
|
+
isRefreshing = true;
|
|
685
|
+
refreshTokenSubject.next(null);
|
|
686
|
+
return from(authService.refreshToken()).pipe(switchMap$1((resAny) => {
|
|
687
|
+
const res = resAny;
|
|
688
|
+
isRefreshing = false;
|
|
689
|
+
if (!res?.IsSuccess) {
|
|
690
|
+
TokenStorage.clearToken();
|
|
691
|
+
const currentUrl = router.routerState.snapshot.url;
|
|
692
|
+
if (!initialReturnUrl && !currentUrl.startsWith('/login')) {
|
|
693
|
+
initialReturnUrl = currentUrl;
|
|
694
|
+
}
|
|
695
|
+
router.navigate(['/login'], {
|
|
696
|
+
queryParams: { returnUrl: initialReturnUrl || '/' },
|
|
697
|
+
});
|
|
698
|
+
return EMPTY;
|
|
699
|
+
}
|
|
700
|
+
// Lưu token mới
|
|
701
|
+
TokenStorage.saveToken(res);
|
|
702
|
+
// Phát token mới cho các request đang chờ
|
|
703
|
+
refreshTokenSubject.next(TokenStorage.getToken());
|
|
704
|
+
// Retry request
|
|
705
|
+
return next(req.clone({
|
|
706
|
+
setHeaders: { Authorization: `Bearer ${TokenStorage.getToken()}` },
|
|
707
|
+
}));
|
|
708
|
+
}), catchError((err) => {
|
|
709
|
+
isRefreshing = false;
|
|
710
|
+
TokenStorage.clearToken();
|
|
650
711
|
const currentUrl = router.routerState.snapshot.url;
|
|
651
712
|
if (!initialReturnUrl && !currentUrl.startsWith('/login')) {
|
|
652
713
|
initialReturnUrl = currentUrl;
|
|
@@ -654,14 +715,15 @@ function authInterceptor(req, next) {
|
|
|
654
715
|
router.navigate(['/login'], {
|
|
655
716
|
queryParams: { returnUrl: initialReturnUrl || '/' },
|
|
656
717
|
});
|
|
657
|
-
return
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
718
|
+
return throwError(() => err);
|
|
719
|
+
}));
|
|
720
|
+
}
|
|
721
|
+
else {
|
|
722
|
+
// Nếu đang refresh → chờ token mới rồi retry
|
|
723
|
+
return refreshTokenSubject.pipe(filter((token) => token != null), take(1), switchMap$1((token) => next(req.clone({
|
|
724
|
+
setHeaders: { Authorization: `Bearer ${token}` },
|
|
725
|
+
}))));
|
|
726
|
+
}
|
|
665
727
|
}
|
|
666
728
|
function convertDatesInBody(obj) {
|
|
667
729
|
if (obj instanceof Date) {
|