fix(console): remove redundant user api requests, show discovery document loading errors (#6683)

* optimize user observable

* fix observable guard

* lint

* lint

---------

Co-authored-by: Elio Bischof <elio@zitadel.com>
This commit is contained in:
Max Peintner 2023-10-11 09:02:20 +02:00 committed by GitHub
parent f2d1cd2045
commit 412cd144ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 27 additions and 34 deletions

View File

@ -1,5 +1,5 @@
<div class="main-container">
<ng-container *ngIf="(authService.user | async) || {} as user">
<ng-container *ngIf="(authService.userSubject | async) || {} as user">
<cnsl-header
*ngIf="user && user !== {}"
[org]="org"

View File

@ -225,9 +225,11 @@ export class AppComponent implements OnDestroy {
});
this.isDarkTheme = this.themeService.isDarkTheme;
this.isDarkTheme.subscribe((dark) => this.onSetTheme(dark ? 'dark-theme' : 'light-theme'));
this.isDarkTheme
.pipe(takeUntil(this.destroy$))
.subscribe((dark) => this.onSetTheme(dark ? 'dark-theme' : 'light-theme'));
this.translate.onLangChange.subscribe((language: LangChangeEvent) => {
this.translate.onLangChange.pipe(takeUntil(this.destroy$)).subscribe((language: LangChangeEvent) => {
this.document.documentElement.lang = language.lang;
this.language = language.lang;
});
@ -271,7 +273,7 @@ export class AppComponent implements OnDestroy {
this.translate.addLangs(supportedLanguages);
this.translate.setDefaultLang(fallbackLanguage);
this.authService.user.subscribe((userprofile) => {
this.authService.userSubject.pipe(takeUntil(this.destroy$)).subscribe((userprofile) => {
if (userprofile) {
const cropped = navigator.language.split('-')[0] ?? fallbackLanguage;
const fallbackLang = cropped.match(supportedLanguagesRegexp) ? cropped : fallbackLanguage;

View File

@ -1,7 +1,6 @@
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { map, Observable, take } from 'rxjs';
import { GrpcAuthService } from '../services/grpc-auth.service';
@ -19,11 +18,13 @@ export class UserGuard {
state: RouterStateSnapshot,
): Observable<boolean> | Promise<boolean> | boolean {
return this.authService.user.pipe(
map((user) => user?.id !== route.params['id']),
tap((isNotMe) => {
if (!isNotMe) {
take(1),
map((user) => {
const isMe = user?.id === route.params['id'];
if (isMe) {
this.router.navigate(['/users', 'me']);
}
return !isMe;
}),
);
}

View File

@ -3,6 +3,7 @@ import { AuthConfig, OAuthService } from 'angular-oauth2-oidc';
import { BehaviorSubject, from, lastValueFrom, Observable } from 'rxjs';
import { StatehandlerService } from './statehandler/statehandler.service';
import { ToastService } from './toast.service';
@Injectable({
providedIn: 'root',
@ -15,6 +16,7 @@ export class AuthenticationService {
constructor(
private oauthService: OAuthService,
private statehandler: StatehandlerService,
private toast: ToastService,
) {}
public initConfig(data: AuthConfig): void {
@ -39,7 +41,10 @@ export class AuthenticationService {
}
this.oauthService.configure(this.authConfig);
this.oauthService.strictDiscoveryDocumentValidation = false;
await this.oauthService.loadDiscoveryDocumentAndTryLogin();
await this.oauthService.loadDiscoveryDocumentAndTryLogin().catch((error) => {
this.toast.showError(error, false, false);
});
this._authenticated = this.oauthService.hasValidAccessToken();
if (!this.oauthService.hasValidIdToken() || !this.authenticated || partialConfig || force) {
const newState = await lastValueFrom(this.statehandler.createState());

View File

@ -1,19 +1,8 @@
import { Injectable } from '@angular/core';
import { SortDirection } from '@angular/material/sort';
import { OAuthService } from 'angular-oauth2-oidc';
import { BehaviorSubject, from, merge, Observable, of, Subject } from 'rxjs';
import {
catchError,
distinctUntilChanged,
filter,
finalize,
map,
mergeMap,
switchMap,
take,
timeout,
withLatestFrom,
} from 'rxjs/operators';
import { BehaviorSubject, forkJoin, from, Observable, of, Subject } from 'rxjs';
import { catchError, distinctUntilChanged, filter, finalize, map, switchMap, timeout, withLatestFrom } from 'rxjs/operators';
import {
AddMyAuthFactorOTPEmailRequest,
@ -184,25 +173,21 @@ export class GrpcAuthService {
},
});
this.user = merge(
of(this.oauthService.getAccessToken()).pipe(filter((token) => (token ? true : false))),
this.user = forkJoin([
of(this.oauthService.getAccessToken()),
this.oauthService.events.pipe(
filter((e) => e.type === 'token_received'),
timeout(this.oauthService.waitForTokenInMsec || 0),
catchError((_) => of(null)), // timeout is not an error
map((_) => this.oauthService.getAccessToken()),
),
).pipe(
take(1),
mergeMap(() => {
]).pipe(
filter((token) => (token ? true : false)),
distinctUntilChanged(),
switchMap(() => {
return from(
this.getMyUser().then((resp) => {
const user = resp.user;
if (user) {
return user;
} else {
return undefined;
}
return resp.user;
}),
);
}),