diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index a35aebd..e5e41f5 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -14,7 +14,8 @@ import {FocusNextDirective} from "@/directives/focus-next.directive";
`
})
export class AppComponent {
- constructor() {
+ constructor(tokenRefreshService: TokenRefreshService) {
registerLocaleData(localeRu);
+ tokenRefreshService.startTokenRefresh();
}
}
diff --git a/src/services/token-refresh.service.ts b/src/services/token-refresh.service.ts
new file mode 100644
index 0000000..b99996d
--- /dev/null
+++ b/src/services/token-refresh.service.ts
@@ -0,0 +1,72 @@
+import {BehaviorSubject, interval, Subscription, switchMap} from "rxjs";
+import {Injectable} from "@angular/core";
+import {AuthService} from "@service/auth.service";
+import {environment} from "@environment";
+
+@Injectable({
+ providedIn: 'root',
+})
+export class TokenRefreshService {
+ private tokenRefreshSubscription: Subscription | undefined;
+ private tokenRefreshing$ = new BehaviorSubject(false);
+ private refreshTokenExpireMs: number = environment.retryDelay;
+
+ constructor(private authService: AuthService) {
+ this.setRefreshTokenExpireMs(AuthService.tokenExpiresIn.getTime() - 1000 - Date.now());
+
+ authService.tokenChangeError.subscribe(_ => {
+ console.log('Token change error event received');
+ this.tokenRefreshing$.next(false);
+ this.stopTokenRefresh();
+ });
+ authService.expireTokenChange.subscribe(date => {
+ console.log('Expire token change event received:', date);
+ this.setRefreshTokenExpireMs(date.getTime() - 1000 - Date.now());
+ });
+ }
+
+ public startTokenRefresh(date: Date | null = null): void {
+ if (date)
+ this.refreshTokenExpireMs = new Date(date).getTime() - 1000 - Date.now();
+
+ if (!this.tokenRefreshSubscription || this.tokenRefreshSubscription.closed) {
+ this.tokenRefreshSubscription = interval(this.refreshTokenExpireMs).pipe(
+ switchMap(() => {
+ this.tokenRefreshing$.next(true);
+ return this.authService.refreshToken();
+ })
+ ).subscribe({
+ next: (_) => {
+ this.tokenRefreshing$.next(false);
+ },
+ error: error => {
+ console.error('Token refresh error:', error);
+ this.tokenRefreshing$.next(false);
+ }
+ });
+ }
+ }
+
+ public getTokenRefreshing$(): BehaviorSubject {
+ return this.tokenRefreshing$;
+ }
+
+ public stopTokenRefresh(): void {
+ if (this.tokenRefreshSubscription && !this.tokenRefreshSubscription.closed) {
+ this.tokenRefreshSubscription.unsubscribe();
+ this.tokenRefreshSubscription = undefined;
+ }
+ }
+
+ public setRefreshTokenExpireMs(expireMs: number): void {
+ if (expireMs < environment.retryDelay)
+ expireMs = 3000;
+
+ console.log(expireMs);
+ this.refreshTokenExpireMs = expireMs;
+
+ this.stopTokenRefresh();
+ this.startTokenRefresh();
+ }
+}
+