83 lines
2.4 KiB
TypeScript
83 lines
2.4 KiB
TypeScript
import {BehaviorSubject, catchError, of, Subject} from "rxjs";
|
|
import {Injectable} from "@angular/core";
|
|
import {AuthService} from "@service/auth.service";
|
|
import {environment} from "@environment";
|
|
import ApiService from "@api/api.service";
|
|
|
|
@Injectable({
|
|
providedIn: 'root',
|
|
})
|
|
export class TokenRefreshService {
|
|
private tokenRefreshing$ = new BehaviorSubject<boolean>(false);
|
|
private refreshTokenTimeout: any;
|
|
private refreshTokenExpireMs: number = environment.retryDelay;
|
|
|
|
constructor(private authService: AuthService) {
|
|
this.setRefreshTokenExpireMs(AuthService.tokenExpiresIn);
|
|
}
|
|
|
|
private startTokenRefresh(): void {
|
|
this.refreshTokenTimeout = setTimeout(() => {
|
|
this.refreshToken();
|
|
}, this.refreshTokenExpireMs);
|
|
}
|
|
|
|
private refreshToken(): void {
|
|
if (this.tokenRefreshing$.value)
|
|
return;
|
|
|
|
this.tokenRefreshing$.next(true);
|
|
|
|
this.authService.refreshToken()
|
|
.pipe(
|
|
catchError(error => {
|
|
if (error.status === 403 || error.status === 401 || !localStorage.getItem(ApiService.tokenKey)) {
|
|
localStorage.removeItem(ApiService.tokenKey);
|
|
return of(undefined);
|
|
}
|
|
|
|
let retryTime = this.refreshTokenExpireMs;
|
|
|
|
if (retryTime < environment.retryDelay)
|
|
retryTime = environment.retryDelay;
|
|
|
|
// 15 minutes
|
|
if (retryTime * 2 <= 900_000)
|
|
retryTime *= 2;
|
|
else
|
|
retryTime = 900_000;
|
|
|
|
return of(retryTime);
|
|
}))
|
|
.subscribe(data => {
|
|
if (data)
|
|
this.setRefreshTokenExpireMs(data);
|
|
|
|
this.tokenRefreshing$.next(false);
|
|
});
|
|
}
|
|
|
|
public getTokenRefreshing$(): Subject<boolean> {
|
|
return this.tokenRefreshing$;
|
|
}
|
|
|
|
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;
|
|
|
|
if (expireMsNumber < environment.retryDelay)
|
|
expireMsNumber = environment.retryDelay;
|
|
|
|
this.refreshTokenExpireMs = expireMsNumber;
|
|
console.log('New refresh token interval:', this.refreshTokenExpireMs);
|
|
|
|
clearTimeout(this.refreshTokenTimeout);
|
|
this.startTokenRefresh();
|
|
}
|
|
}
|