refactor: refresh token

The service did not update tokens well, so it was rewritten
This commit is contained in:
2024-08-24 04:27:13 +03:00
parent 48a74ecbf5
commit 1f03c2a9c3
3 changed files with 57 additions and 53 deletions

View File

@ -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();
}
}