auth0 / auth0-spa-js

Auth0 authentication for Single Page Applications (SPA) with PKCE
MIT License
917 stars 361 forks source link

handleRedirectCallback not working in Salesforce context #1051

Closed Bartheleway closed 1 year ago

Bartheleway commented 1 year ago

Describe the problem

Can't login as the handleRedirectCallback function is falling.

What was the expected behavior?

Able to log in.

Reproduction

I use the lib in Salesforce context. In this special context, even though we are in latest browser, AbortController is not available.

Environment

Possible fix

Changing createAbortController in https.ts to:

export const createAbortController = () => {
  let controller

  if (typeof AbortController === 'function') {
    controller = new AbortController();
  } else {
    controller = { 
      abort() {},
      signal: undefined 
    };
  }

  return controller
}

Do you think the possible fix is a good way to fix or do you see a better way to do it ? I tested it and it's fixing the issue. If it's okay, I can then make a PR. I'm just wondering how I should test that. Does doing AbortController = undefined before the test would be acceptable ?

frederikprijck commented 1 year ago

Hello,

v1 of this SDK shipped with a polyfill for AbortController. With v2, we have dropped this polyfill, see https://github.com/auth0/auth0-spa-js/blob/master/MIGRATION_GUIDE.md#polyfills-and-supported-browsers

If you need AbortController, you should be able to polyfill it yourself by including https://www.npmjs.com/package/abortcontroller-polyfill in your application.

Do you think the possible fix is a good way to fix or do you see a better way to do it ?

That doesn't introduce a working AbortController in your case, it's better to polyfill it.

Let me know if that would not work.

Bartheleway commented 1 year ago

Hi, thanks for your reply. I tested your approach with no success.

I agree, adding a polyfill rather than creating a dummy AbortController is a lot better. I think this cannot work as Salesforce intentionally made AbortController not available, thus recreating it is impossible.

According to Salesforce documentation, Locker Service is a tool that secure some API and prevent us from making breaking pattern code.

I'm thinking maybe adding the AbortController as an option like we have for cacheLocation would allow implementation like mine without having the piece of code inside the plugin itself as it's really an edge case and not really relevant in the code base.

frederikprijck commented 1 year ago

Looking at the Salesforce documentation, it mentions AbortController being an experimental feature:

You get this error because AbortController is an experimental interface in the DOM API and is not allowed by Locker Service.

Looking at the browser support on MDN, I wouldn't say AbortController is an experimental interface.

Same with caniuse, it shows AbortController is available to 96% of the global users.

I would reach out to Salesforce and see how you can get access to AbortController, or how you can provide a fallback that doesn't require to patch any library that relies on AbortController, including Auth0-SPA-JS.

Closing this for now, as I believe there is nothing to action.

Bartheleway commented 1 year ago

Well good luck with Salesforce understanding and fixing the situation ... And Locker Service is an old tool which I think they do not upgrade anymore but that we still have live ...

Reading you, it gave me an idea. Instead of doing my fix in the library call, I can do it right before loading it.

Which, for the record, looks like this:

async function loadStaticResource () {
  window.AbortController = class CustomAbortController {
    abort () {}
    signal = undefined
  }

  await loadScript(this, auth0ResourceUrl)
}

I know I'm loosing the abort feature which I guess is only impacting performance. And I would only have to remove that piece of code when Salesforce will allow us to generally migrate from Locker Service to Lightning Web Security (LWS Distortion).

Thanks for your help solving this !