diff --git a/chutney/ui/src/app/core/services/login.service.ts b/chutney/ui/src/app/core/services/login.service.ts index 83189e6fd..df299b60f 100644 --- a/chutney/ui/src/app/core/services/login.service.ts +++ b/chutney/ui/src/app/core/services/login.service.ts @@ -8,8 +8,8 @@ import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { ActivatedRouteSnapshot, Router } from '@angular/router'; -import { BehaviorSubject, firstValueFrom, Observable } from 'rxjs'; -import { catchError, delay, tap } from 'rxjs/operators'; +import { BehaviorSubject, firstValueFrom, Observable, timeout } from 'rxjs'; +import { catchError, delay, filter, first, tap } from 'rxjs/operators'; import { environment } from '@env/environment'; import { Authorization, User } from '@model'; @@ -41,12 +41,19 @@ export class LoginService { const unauthorizedMessage = this.translateService.instant('login.unauthorized') if (!this.isAuthenticated()) { if (this.oauth2Token) { - await firstValueFrom(this.initLoginObservable(requestURL, { - 'Authorization': 'Bearer ' + this.oauth2Token - })); + await this.initLoginWithToken(requestURL) } else { - await this.initLogin(requestURL); - return false; + await firstValueFrom(this.ssoService.tokenLoaded$.pipe( + timeout(1000), + filter(tokenLoaded => tokenLoaded === true), + first(), + catchError(async error => this.initLogin(requestURL)))); + if (this.oauth2Token) { + await this.initLoginWithToken(requestURL) + } else { + await this.initLogin(requestURL); + return false; + } } } const authorizations: Array = route.data['authorizations'] || []; @@ -59,6 +66,12 @@ export class LoginService { } } + private async initLoginWithToken(requestURL: string) { + await firstValueFrom(this.initLoginObservable(requestURL, { + Authorization: 'Bearer ' + this.oauth2Token, + })); + } + async initLogin(url?: string, headers: HttpHeaders | { [header: string]: string | string[]; } = {}) { diff --git a/chutney/ui/src/app/core/services/sso.service.ts b/chutney/ui/src/app/core/services/sso.service.ts index d69c5152c..11ac85914 100644 --- a/chutney/ui/src/app/core/services/sso.service.ts +++ b/chutney/ui/src/app/core/services/sso.service.ts @@ -8,8 +8,9 @@ import { HttpClient, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; import { AuthConfig, OAuthService } from 'angular-oauth2-oidc'; import { environment } from '@env/environment'; -import { map, Observable, tap } from 'rxjs'; +import { BehaviorSubject, map, Observable, tap } from 'rxjs'; import { Injectable } from '@angular/core'; +import { filter } from 'rxjs/operators'; interface SsoAuthConfig { issuer: string, @@ -34,8 +35,17 @@ export class SsoService { private ssoConfig: SsoAuthConfig + private tokenLoadedSubject = new BehaviorSubject(false); + public tokenLoaded$ = this.tokenLoadedSubject.asObservable(); - constructor(private oauthService: OAuthService, private http: HttpClient) {} + + constructor(private oauthService: OAuthService, private http: HttpClient) { + this.oauthService.events + .pipe(filter(e => e.type === 'token_received')) + .subscribe(() => { + this.tokenLoadedSubject.next(true); + }); + } fetchSsoConfig(): void { this.http.get(environment.backend + this.resourceUrl).pipe( @@ -62,6 +72,9 @@ export class SsoService { try { this.oauthService.configure(ssoConfig) await this.oauthService.loadDiscoveryDocumentAndTryLogin(); + if (this.oauthService.hasValidAccessToken()) { + this.tokenLoadedSubject.next(true); + } } catch (e) { console.error("SSO provider not available") }