fix 401 loop hell
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { BehaviorSubject, Observable, of } from 'rxjs';
|
||||
import { catchError, map, tap } from 'rxjs/operators';
|
||||
import { catchError, filter, finalize, map, shareReplay, take, tap } from 'rxjs/operators';
|
||||
import { ApiConfigService } from '../../core/services/api-config.service';
|
||||
|
||||
// ── Public interfaces ─────────────────────────────────────────────────────────
|
||||
@@ -69,6 +69,8 @@ export class AuthService {
|
||||
/** Observable stream of the current user (null = not authenticated). */
|
||||
public currentUser = this.currentUser$.asObservable();
|
||||
|
||||
private readonly sessionReady$ = new BehaviorSubject(false);
|
||||
private refreshInFlight$: Observable<boolean> | null = null;
|
||||
private redirectUrl = '/dashboard';
|
||||
|
||||
constructor(
|
||||
@@ -118,18 +120,25 @@ export class AuthService {
|
||||
* Never throws.
|
||||
*/
|
||||
refresh(): Observable<boolean> {
|
||||
return this.http.post<ApiLoginResponse>(
|
||||
`${this.apiConfig.authUrl}/refresh`,
|
||||
{},
|
||||
{ withCredentials: true }
|
||||
).pipe(
|
||||
tap(response => {
|
||||
this.accessToken$.next(response.accessToken);
|
||||
this.currentUser$.next(response.user);
|
||||
}),
|
||||
map(() => true),
|
||||
catchError(() => of(false))
|
||||
);
|
||||
if (!this.refreshInFlight$) {
|
||||
this.refreshInFlight$ = this.http.post<ApiLoginResponse>(
|
||||
`${this.apiConfig.authUrl}/refresh`,
|
||||
{},
|
||||
{ withCredentials: true }
|
||||
).pipe(
|
||||
tap(response => {
|
||||
this.accessToken$.next(response.accessToken);
|
||||
this.currentUser$.next(response.user);
|
||||
}),
|
||||
map(() => true),
|
||||
catchError(() => of(false)),
|
||||
finalize(() => {
|
||||
this.refreshInFlight$ = null;
|
||||
}),
|
||||
shareReplay(1)
|
||||
);
|
||||
}
|
||||
return this.refreshInFlight$;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,10 +164,23 @@ export class AuthService {
|
||||
*/
|
||||
initializeFromRefreshToken(): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
this.refresh().subscribe(() => resolve());
|
||||
this.refresh().pipe(
|
||||
finalize(() => {
|
||||
this.sessionReady$.next(true);
|
||||
resolve();
|
||||
})
|
||||
).subscribe();
|
||||
});
|
||||
}
|
||||
|
||||
/** Resolves once startup session restore has finished (success or failure). */
|
||||
whenSessionReady(): Observable<boolean> {
|
||||
if (this.sessionReady$.value) {
|
||||
return of(true);
|
||||
}
|
||||
return this.sessionReady$.pipe(filter(Boolean), take(1));
|
||||
}
|
||||
|
||||
// ── State accessors ─────────────────────────────────────────────────────
|
||||
|
||||
getToken(): string | null {
|
||||
@@ -166,7 +188,7 @@ export class AuthService {
|
||||
}
|
||||
|
||||
isAuthenticated(): boolean {
|
||||
return this.currentUser$.value !== null;
|
||||
return this.currentUser$.value !== null && this.getToken() !== null;
|
||||
}
|
||||
|
||||
getCurrentUser(): UserInfo | null {
|
||||
|
||||
Reference in New Issue
Block a user