diff --git a/FAQ.md b/FAQ.md index 0a776baf2..0c12d72d1 100644 --- a/FAQ.md +++ b/FAQ.md @@ -62,3 +62,20 @@ With this change, an immediate refresh after login works as expected. Note that even though the workaround doesn't cause any weird side effects in browers, you should ideally remove it after the bug has been fixed in Firefox. For more context see this [issue](https://github.com/auth0-samples/auth0-react-samples/issues/145). + +## Why do I get `auth0-spa-js must run on a secure origin`? + +Internally, the SDK uses [Web Cryptography API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) to create [SHA-256 digest](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest). + +According to the spec ([via Github issues](https://github.com/w3c/webcrypto/issues/28)), Web Cryptography API requires a secure origin, so that accessing `Crypto.subtle` in a not secure context return undefined. + +In most browsers, secure origins are origins that match at least one of the following (scheme, host, port) patterns: + +``` +(https, *, *) +(wss, *, *) +(*, localhost, *) +(*, 127/8, *) +(*, ::1/128, *) +(file, *, —) +``` diff --git a/__tests__/index.test.ts b/__tests__/index.test.ts index 323e68e0e..dd416991b 100644 --- a/__tests__/index.test.ts +++ b/__tests__/index.test.ts @@ -86,6 +86,36 @@ describe('Auth0', () => { beforeEach(() => { jest.resetAllMocks(); window.location.assign = jest.fn(); + (global).crypto = { + subtle: { + digest: () => '' + } + }; + }); + describe('createAuth0Client()', () => { + it('should create an Auth0 client', async () => { + const auth0 = await createAuth0Client({ + domain: TEST_DOMAIN, + client_id: TEST_CLIENT_ID + }); + expect(auth0).toBeInstanceOf(Auth0Client); + }); + it('should return, logging a warning if crypto.digest is undefined', async () => { + (global).crypto = {}; + (window).console = { + error: jest.fn() + }; + const auth0 = await createAuth0Client({ + domain: TEST_DOMAIN, + client_id: TEST_CLIENT_ID + }); + expect(auth0).toBeUndefined(); + expect(window.console.error).toHaveBeenCalledWith(` + auth0-spa-js must run on a secure origin. + See https://github.com/auth0/auth0-spa-js/blob/master/FAQ.md#why-do-i-get-error-invalid-state-in-firefox-when-refreshing-the-page-immediately-after-a-login + for more information. + `); + }); }); describe('loginWithPopup()', () => { it('opens popup', async () => { diff --git a/src/index.ts b/src/index.ts index 19574e860..ec8fd202c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,6 +6,15 @@ import * as ClientStorage from './storage'; import './global'; export default async function createAuth0Client(options: Auth0ClientOptions) { + if (typeof window.crypto.subtle === 'undefined') { + console.error(` + auth0-spa-js must run on a secure origin. + See https://github.com/auth0/auth0-spa-js/blob/master/FAQ.md#why-do-i-get-error-invalid-state-in-firefox-when-refreshing-the-page-immediately-after-a-login + for more information. + `); + return; + } + const auth0 = new Auth0Client(options); if (!ClientStorage.get('auth0.is.authenticated')) {