Auth0-spa-js: LoginWithPopup event on cancel

Created on 15 Oct 2020  路  5Comments  路  Source: auth0/auth0-spa-js

Describe the problem you'd like to have solved

We have an overlay on our page when using the login with Popup function. This works fine if the user actually logs in, but if they cancel the popup with the X at the top, we have to wait until the timeout before we can identify this has happened.

Describe the ideal solution

When the popup is cancelled, an event is thrown, or the promise is rejected with 'user closed'.

Alternatives and current work-arounds

JavaScript doesn't give you an easy way to capture window close events, especially if they are not within the same domain, A workaround using setInterval may work.

Something like:

export const runPopup = (authorizeUrl: string, config: PopupConfigOptions) => {
  let popup = config.popup;

  if (popup) {
    popup.location.href = authorizeUrl;
  } else {
    popup = openPopup(authorizeUrl);
    var timer = setInterval(function () {
      if (popup.closed) {
          clearInterval(timer);
          window.dispatchEvent(new Event("auth0.popupclose"));
      }
    }, 1000);
  }

or (presuming a PopupCancelledError class exists)

export const runPopup = (authorizeUrl: string, config: PopupConfigOptions) => {
  let popup = config.popup;

  if (popup) {
    popup.location.href = authorizeUrl;
  } else {
    popup = openPopup(authorizeUrl);
  }

  if (!popup) {
    throw new Error('Could not open popup');
  }

  return new Promise<AuthenticationResult>((resolve, reject) => {
    const timeoutId = setTimeout(() => {
      reject(new PopupTimeoutError(popup));
    }, (config.timeoutInSeconds || DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS) * 1000);
    const intervalId = setInterval(function () {
      if (popup.closed) {
          clearInterval(intervalId);
          reject(new PopupCancelledError(popup));
      }
    }, 1000);
    window.addEventListener('message', e => {
      if (!e.data || e.data.type !== 'authorization_response') {
        return;
      }
      clearTimeout(timeoutId);
      clearInterval(intervalId);
      popup.close();
      if (e.data.response.error) {
        return reject(GenericError.fromPayload(e.data.response));
      }
      resolve(e.data.response);
    });
  });
};
feature request

Most helpful comment

Hi @GMaiolo @ongas @Benjathing - just to let you know we're looking at this now, will post an update to this issue shortly

We also have a, somewhat convoluted, workaround here https://github.com/auth0/auth0-spa-js/compare/pop-cancel-example

All 5 comments

Thanks for raising @Benjathing, and apologies for the radio silence. Let me take this to the team to see what we can do here.

@stevehobbsdev any news on this? I could give it a shot if a hand is needed

Could we get this looked at as a priority please? It's caused issues with a number of public applications.

Hi @GMaiolo @ongas @Benjathing - just to let you know we're looking at this now, will post an update to this issue shortly

We also have a, somewhat convoluted, workaround here https://github.com/auth0/auth0-spa-js/compare/pop-cancel-example

Hi @Benjathing we're glad to support this feature now in version v1.15.0 馃嵕 thank you for reporting

Was this page helpful?
0 / 5 - 0 ratings