Fix the login flashing sometimes

Race condition between being able to login via OIDC in the background,
and making first requests
This commit is contained in:
Amelia 2025-07-01 20:22:17 +02:00
parent a122ae07a9
commit 08914f7546
No known key found for this signature in database
GPG key ID: D6D0ECE365407EAA
3 changed files with 29 additions and 4 deletions

View file

@ -0,0 +1,16 @@
import {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} from '@angular/router';
import {Injectable} from "@angular/core";
import {Observable, take} from "rxjs";
import {OidcService} from "../_services/oidc.service";
@Injectable({
providedIn: 'root'
})
export class OidcResolver implements Resolve<any> {
constructor(private oidcService: OidcService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> {
return this.oidcService.loaded$.pipe(take(1));
}
}

View file

@ -1,6 +1,6 @@
import {DestroyRef, effect, inject, Injectable, signal} from '@angular/core';
import {OAuthErrorEvent, OAuthService} from "angular-oauth2-oidc";
import {BehaviorSubject, from} from "rxjs";
import {BehaviorSubject, from, Observable} from "rxjs";
import {HttpClient} from "@angular/common/http";
import {environment} from "../../environments/environment";
import {OidcPublicConfig} from "../admin/_models/oidc-config";
@ -23,6 +23,8 @@ export class OidcService {
baseUrl = environment.apiUrl;
private readonly loaded = new BehaviorSubject<boolean>(false);
public readonly loaded$: Observable<boolean> = this.loaded.asObservable();
private readonly _ready = signal(false);
public readonly ready = this._ready.asReadonly();
private readonly _settings = signal<OidcPublicConfig | undefined>(undefined);
@ -42,6 +44,7 @@ export class OidcService {
this.config().subscribe(oidcSetting => {
if (!oidcSetting.authority) {
this.loaded.next(true);
return
}
@ -72,9 +75,8 @@ export class OidcService {
});
from(this.oauth2.loadDiscoveryDocumentAndTryLogin()).subscribe({
next: success => {
if (!success) return;
next: _ => {
this.loaded.next(true);
this._ready.set(true);
},
error: error => {

View file

@ -2,12 +2,19 @@ import {NgModule} from '@angular/core';
import {PreloadAllModules, RouterModule, Routes} from '@angular/router';
import {AuthGuard} from './_guards/auth.guard';
import {LibraryAccessGuard} from './_guards/library-access.guard';
import {OidcResolver} from "./_resolvers/oidc.resolver";
const routes: Routes = [
{
path: '',
canActivate: [AuthGuard],
runGuardsAndResolvers: 'always',
resolve: {
// Require OIDC discovery to be loaded before launching the app
// making sure we don't flash the login screen because we've made request before we could auto login
// If no OIDC is set up, this will resolve after one request to the backend
_: OidcResolver,
},
children: [
{
path: 'settings',