okta / okta-oidc-js

okta-oidc-js
https://github.com/okta/okta-oidc-js
Other
395 stars 232 forks source link

Angular apps are never stable when using OktaAuthService. #423

Open jraadt opened 5 years ago

jraadt commented 5 years ago

I'm submitting this issue for the package(s):

I'm submitting a:

Current behavior

Using the OktaAuthService causes Angular apps to never become stable if you access the app after you're logged in. Apps need to get to a stable state in order to use service workers and to be used as a PWA. I believe this is problem with the line this.oktaAuth = new OktaAuth(buildConfigObject(auth)); in the constructor of OktaAuthService.

There's more information on what causes apps to be stable or not stable at the Angular service worker page at https://angular.io/guide/service-worker-communications. Excerpt from there:

In order to avoid negatively affecting the initial rendering, ServiceWorkerModule will by default wait for the app to stabilize, before registering the ServiceWorker script. Constantly polling for updates, e.g. with interval(), will prevent the app from stabilizing and the ServiceWorker script will never be registered with the browser.

You can avoid that by waiting for the app to stabilize first, before starting to poll for updates (as shown in the example above).

Note that this is true for any kind of polling done by your application. Check the isStable documentation for more information.

Expected behavior

The app should become stable before Okta does its thing.

Minimal reproduction of the problem with instructions

Using the sample Angular app, import ApplicationRef and add this to your app.component.ts constructor: appRef.isStable.subscribe(isStable => console.log(isStable));

Once you log into the Angular app, click refresh and you'll see it never gets stable.

Extra information about the use case/user story you are trying to implement

Service workers and PWAs are not doable using this Okta library.

Environment

jraadt commented 5 years ago

After some experimenting I think I have code that fixes okta.service.ts. I turned oktaAuth into a Promise:

private oktaAuth: Promise<OktaAuth>;

And replaced the two this.oktaAuth lines in the constructor with:

this.oktaAuth = new Promise((resolve, reject) => {
  this.applicationRef.isStable.pipe(first(stable => stable)).subscribe(_ => {
    var oktaAuthInstance = new OktaAuth(buildConfigObject(auth));
    oktaAuthInstance.userAgent = `${packageInfo.name}/${packageInfo.version} ${oktaAuthInstance.userAgent}`;
    resolve(oktaAuthInstance);
  });
});

Then I replaced instances of this.oktaAuth with (await this.oktaAuth).

swiftone commented 5 years ago

@jraadt - Thanks for your investigations, particularly the code snippets. We look into issues as priorities allow, so your efforts are helpful and appreciated.

jraadt commented 5 years ago

You may also want to look at how Angular allows users to determine when to register the service worker. They now have an option to register when stable. Might be some code you could use there to also prevent this from registering until the app is stable. https://github.com/angular/angular/pull/21842

jraadt commented 4 years ago

With the new okta-angular 3.0 the app doesn't always get to a stable state, but now that you can define your registration strategy for Angular service workers it's less important that the app becomes stable if you needed it just for service workers.