[Bug]: EventService does not fire events anymore
What Version of the library are you using? 14.1.1
Describe the bug In V13 in your AuthenticationModule code you could run something like this:
eventService
.registerForEvents()
.pipe(filter((notification) => {
return notification.type == EventTypes.ConfigLoaded || notification.type == EventTypes.ConfigLoadingFailed;
}))
.subscribe(() => {
userService.Init();
});
The pipe/filter never runs nor subscribe ever fires in V14 anymore.
To Reproduce Take any of the examples that uses this code, and upgrade to v14 and run it. It doesn't break into the code.
Expected behavior Should still fire properly.
Desktop (please complete the following information):
- OS: Windows 11
- Browser Chrome
- Version Latest
Have you tried it without the filter operator? So does it not fire at all or only when fitering those Events?
It never fires at all.
Here's the module that does the loading:
@NgModule({
imports: [CommonModule, AuthModule.forRoot({
config: {
authority: apiUrl(),
configId: AUTH_CONFIG_ID,
startCheckSession: true,
redirectUrl: `${location.protocol}//${location.host}`,
postLogoutRedirectUri: LOGOUT_PATH,
postLoginRoute: DEFAULT_LOGIN_REDIRECT_PATH,
clientId: CLIENT_ID,
scope: 'openid profile email',
responseType: 'code',
silentRenew: true,
silentRenewUrl: `${location.protocol}//${location.host}/silent-renew.html`,
logLevel: environment.production ? LogLevel.Error : LogLevel.Debug,
autoUserInfo: true,
forbiddenRoute: FORBIDDEN_PATH,
autoCleanStateAfterAuthentication: true,
triggerAuthorizationResultEvent: true,
maxIdTokenIatOffsetAllowedInSeconds: 600,
unauthorizedRoute: UNAUTHORIZED_PATH,
renewTimeBeforeTokenExpiresInSeconds: 20,
ngswBypass: true,
renewUserInfoAfterTokenRenew: true,
}
})],
providers: [
{
provide: AbstractSecurityStorage,
useClass: DefaultLocalStorage,
},
{
provide: BaseUserService,
useExisting: UserService,
},
{
provide: HTTP_INTERCEPTORS,
useClass: AuthenticationInterceptor,
multi: true,
},
],
})
export class AuthenticationModule {
constructor(eventService: PublicEventsService, userService: UserService) {
// userService.Init();
eventService
.registerForEvents()
// .pipe(filter((notification) => {
// return notification.type == EventTypes.ConfigLoaded || notification.type == EventTypes.ConfigLoadingFailed;
// }))
.subscribe(() => {
userService.Init();
});
}
}
Hey, I just tried to reproduce the issue, but I could not reproduce the issue.
export class AppComponent implements OnInit {
constructor(public oidcSecurityService: OidcSecurityService, private eventService: PublicEventsService) {}
ngOnInit() {
this.oidcSecurityService.checkAuth().subscribe(({ isAuthenticated }) => console.log('app authenticated', isAuthenticated));
this.eventService
.registerForEvents()
.subscribe((value) => {
console.log('@@@@', value);
});
}
}
The sample was run with npm run start-sample-code-flow-auth0, the modification was to register the events in the app.component with the code above.
In the app.module of the sample is the event service used as well, but saw that after I modified the sample in the way seeing above. However, I see the events being fired.
Can you provide a sample app, you can use a configuration from our samples, to reproduce the issue?
Thanks
I think the confusion is this and maybe we're just doing it the wrong way and it just happened to work before:
Our app requires that we know the authentication status before anything displays no matter what page.
As a result in the past we waited for the ConfigLoaded event to fire, then setup then called this.oidcSecurityService.checkAuth() and then from there, once we got a value back, we would display the UI accordingly.
Now when we do this, no matter where we put it, the event are not fired and the configuration is not loaded at all.
But if we put the checkAuth function in then our code for handling redirects for login gets called before anything is ready to call which I think causes the error. (i.e. the checkauth seems to return before the configuration is ready and thus it can't get any information like where to redirect to for login)
Then everything blows up.
I tried the sample apps and they don't seem to block while waiting for the configuration and offline authentication status all of the way through is ready as I would assume would be the default most people would want. I.e. I can't think of any app that would want to render anything at all until the authentication status is done and ready with everything for that loaded.
So how do we get angular to force load the oidc configuration and all of the authentication stuff to a status of ready, and then continue rendering the first page in a blocking fashion?
If you have a sample repo to reproduce, this would be fine.
As a result in the past we waited for the ConfigLoaded event to fire, then setup then called this.oidcSecurityService.checkAuth() and then from there, once we got a value back, we would display the UI accordingly.
What you can do is a callback route which does do the checkAuth() and then redirects to your app or redirects to a unauthenticated route. You have to register this component as a route and let your IDP redirect to this route then.
Ok, so I have a repro case:
If you take the sample-code-flow-refresh-tokens and put this in the app.module.ts constructor:
constructor(private readonly eventService: PublicEventsService, private readonly oidcSecurityService: OidcSecurityService) {
this.eventService
.registerForEvents()
.pipe(filter((notification) => notification.type === EventTypes.ConfigLoaded))
.subscribe((config) => {
console.log('ConfigLoaded', config);
});
this.oidcSecurityService.preloadAuthWellKnownDocument().subscribe((authWellKnown) => {
console.log(`Auth Well Known: ${authWellKnown}`);
})
}
And then set a break point on the console.log('ConfigLoaded') it's never called until after you click the login button. Even with the forced preloadAuthWellKnownDocument() call it still never gets called.
If you go to the V13 branch you'll see that this is called immediately.
Ideally I'd put an await into an APP_INITIALIZER that blocks until the config is loaded before allowing my app to load any further, but I just need a work around for now so that I can make it work like V13 did.
Thanks for providing such useful information. I could reproduce it. With the PR above the bug should be fixed.
Great! Thanks! Any ETA when this will be released? We're a little blocked ATM on this one.
@damienbod any plans to test and release this one?
Will release this weekend 4.1.3
Released.