refactor: refresh token
The service did not update tokens well, so it was rewritten
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
import {BehaviorSubject, filter, interval, Subscription, switchMap} from "rxjs";
|
||||
import {BehaviorSubject, catchError, of, Subject, Subscription} from "rxjs";
|
||||
import {Injectable} from "@angular/core";
|
||||
import {AuthService} from "@service/auth.service";
|
||||
import {environment} from "@environment";
|
||||
@ -8,64 +8,70 @@ import ApiService from "@api/api.service";
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class TokenRefreshService {
|
||||
private tokenRefreshSubscription: Subscription | undefined;
|
||||
private tokenRefreshing$ = new BehaviorSubject<boolean>(false);
|
||||
private refreshTokenTimeout: any;
|
||||
private refreshTokenExpireMs: number = environment.retryDelay;
|
||||
|
||||
constructor(private authService: AuthService) {
|
||||
this.setRefreshTokenExpireMs(AuthService.tokenExpiresIn.getTime() - 1000 - Date.now());
|
||||
|
||||
authService.expireTokenChange.subscribe(date => {
|
||||
console.debug('Expire token change event received:', date);
|
||||
this.setRefreshTokenExpireMs(date.getTime() - 1000 - Date.now());
|
||||
});
|
||||
this.setRefreshTokenExpireMs(AuthService.tokenExpiresIn);
|
||||
}
|
||||
|
||||
public startTokenRefresh(date: Date | null = null): void {
|
||||
if (date)
|
||||
this.refreshTokenExpireMs = new Date(date).getTime() - 1000 - Date.now();
|
||||
private startTokenRefresh(): void {
|
||||
this.refreshTokenTimeout = setTimeout(() => {
|
||||
this.refreshToken();
|
||||
|
||||
console.debug(this.tokenRefreshSubscription);
|
||||
if (this.tokenRefreshSubscription && !this.tokenRefreshSubscription.closed)
|
||||
if (this.refreshTokenExpireMs > 0)
|
||||
this.startTokenRefresh();
|
||||
}, this.refreshTokenExpireMs);
|
||||
}
|
||||
|
||||
private refreshToken(): void {
|
||||
if (this.tokenRefreshing$.value) {
|
||||
console.warn('Refreshing token was started...');
|
||||
return;
|
||||
}
|
||||
|
||||
this.tokenRefreshSubscription = interval(this.refreshTokenExpireMs).pipe(
|
||||
filter(isRefreshing => !isRefreshing),
|
||||
switchMap(() => {
|
||||
this.tokenRefreshing$.next(true);
|
||||
console.debug('Send query to refresh token');
|
||||
return this.authService.refreshToken();
|
||||
})
|
||||
).subscribe({
|
||||
next: (_) => {
|
||||
console.log('Start Refreshing token...');
|
||||
this.tokenRefreshing$.next(true);
|
||||
|
||||
this.authService.refreshToken()
|
||||
.pipe(
|
||||
catchError(error => {
|
||||
console.warn('Error refreshing token', error);
|
||||
localStorage.removeItem(ApiService.tokenKey);
|
||||
this.refreshTokenExpireMs = -1;
|
||||
return of(undefined);
|
||||
}))
|
||||
.subscribe(data => {
|
||||
if (data) {
|
||||
console.log('Token refreshed');
|
||||
this.setRefreshTokenExpireMs(data);
|
||||
}
|
||||
this.tokenRefreshing$.next(false);
|
||||
},
|
||||
error: error => {
|
||||
this.tokenRefreshing$.next(false);
|
||||
localStorage.removeItem(ApiService.tokenKey);
|
||||
}
|
||||
});
|
||||
console.log('Token refresh process completed');
|
||||
});
|
||||
}
|
||||
|
||||
public getTokenRefreshing$(): BehaviorSubject<boolean> {
|
||||
public getTokenRefreshing$(): Subject<boolean> {
|
||||
return this.tokenRefreshing$;
|
||||
}
|
||||
|
||||
public stopTokenRefresh(): void {
|
||||
if (this.tokenRefreshSubscription && !this.tokenRefreshSubscription.closed) {
|
||||
this.tokenRefreshSubscription.unsubscribe();
|
||||
this.tokenRefreshSubscription = undefined;
|
||||
}
|
||||
}
|
||||
public setRefreshTokenExpireMs(expireMs: number | string | Date | null = null): void {
|
||||
let expireMsNumber: number;
|
||||
if (expireMs === null)
|
||||
expireMsNumber = -1;
|
||||
else if (expireMs instanceof Date || typeof expireMs === 'string')
|
||||
expireMsNumber = new Date(expireMs).getTime() - 1000 - Date.now();
|
||||
else
|
||||
expireMsNumber = expireMs;
|
||||
|
||||
public setRefreshTokenExpireMs(expireMs: number): void {
|
||||
if (expireMs < environment.retryDelay)
|
||||
expireMs = environment.retryDelay;
|
||||
if (expireMsNumber < environment.retryDelay)
|
||||
expireMsNumber = environment.retryDelay;
|
||||
|
||||
this.refreshTokenExpireMs = expireMs;
|
||||
this.refreshTokenExpireMs = expireMsNumber;
|
||||
console.log('New refresh token interval:', this.refreshTokenExpireMs);
|
||||
|
||||
console.log(expireMs);
|
||||
this.stopTokenRefresh();
|
||||
clearTimeout(this.refreshTokenTimeout);
|
||||
this.startTokenRefresh();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user