diff --git a/__tests__/utils.test.ts b/__tests__/utils.test.ts index 0cb30b16a..72bf678bd 100644 --- a/__tests__/utils.test.ts +++ b/__tests__/utils.test.ts @@ -151,6 +151,25 @@ describe('utils', () => { const result = await sha256('test'); expect(result).toBe(true); }); + it('handles ie11 digest.result scenario', async () => { + (global).crypto = { + subtle: { + digest: jest.fn((alg, encoded) => { + expect(alg).toMatchObject({ name: 'SHA-256' }); + expect(Array.from(encoded)).toMatchObject([116, 101, 115, 116]); + return { result: true }; + }) + } + }; + const result = await sha256('test'); + expect(result).toBe(true); + }); + }); + describe('bufferToBase64UrlEncoded ', () => { + it('generates correct base64 encoded value from a buffer', async () => { + const result = await bufferToBase64UrlEncoded([116, 101, 115, 116]); + expect(result).toBe('dGVzdA'); + }); }); describe('openPopup', () => { it('opens the popup', () => { diff --git a/src/utils.ts b/src/utils.ts index 348764a6a..6c0d5a4fb 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -108,8 +108,22 @@ export const createQueryParams = (params: any) => { .join('&'); }; -export const sha256 = (s: string) => - window.crypto.subtle.digest({ name: 'SHA-256' }, new TextEncoder().encode(s)); +export const sha256 = async (s: string) => { + const response = await Promise.resolve( + window.crypto.subtle.digest( + { name: 'SHA-256' }, + new TextEncoder().encode(s) + ) + ); + // msCrypto (IE11) uses the old spec, which is not Promise based + // https://msdn.microsoft.com/en-us/expression/dn904640(v=vs.71) + // Instead of returning a promise, it returns a CryptoOperation + // with a `result` property in it + if ((response).result) { + return (response).result; + } + return response; +}; const urlEncodeB64 = (input: string) => { const b64Chars = { '+': '-', '/': '_', '=': '' }; @@ -131,7 +145,7 @@ export const urlDecodeB64 = (input: string) => decodeB64(input.replace(/_/g, '/').replace(/-/g, '+')); export const bufferToBase64UrlEncoded = input => { - const ie11SafeInput = new Uint8Array(Array.from(input)); + const ie11SafeInput = new Uint8Array(input); return urlEncodeB64( window.btoa(String.fromCharCode(...Array.from(ie11SafeInput))) );