From f5fe9e34348666e86fb2db13b2b6c04fbeb79b7f Mon Sep 17 00:00:00 2001 From: Jared Perreault <90656038+jaredperreault-okta@users.noreply.github.com> Date: Thu, 30 May 2024 10:17:56 -0400 Subject: [PATCH] fix: awaits restoreOriginalUri Promise (#284) OKTA-733912 fix: awaits restoreOriginalUri Promise --- CHANGELOG.md | 6 +++ package.json | 2 +- src/Security.tsx | 2 +- test/jest/security.test.tsx | 82 +++++++++++++++++++++++++------------ yarn.lock | 51 ++++++++++++++++++++++- 5 files changed, 113 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dc35fae..02d92e3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 6.9.0 + +### Bug Fixes + +-[#284](https://github.com/okta/okta-react/pull/284) fix: passes the return value of `restoreOriginalUri()`, so promises will be awaited + # 6.8.0 ### Bug Fixes diff --git a/package.json b/package.json index 977a2c39..574c94b6 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "@babel/plugin-transform-runtime": "^7.19.1", "@babel/preset-env": "^7.19.3", "@babel/preset-react": "^7.18.6", - "@okta/okta-auth-js": "^7.0.0", + "@okta/okta-auth-js": "^7.7.0", "@rollup/plugin-babel": "^5.2.1", "@rollup/plugin-replace": "^2.3.4", "@testing-library/jest-dom": "^5.16.2", diff --git a/src/Security.tsx b/src/Security.tsx index b9a1bd3d..4cead8f7 100644 --- a/src/Security.tsx +++ b/src/Security.tsx @@ -57,7 +57,7 @@ const Security: React.FC<{ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore oktaAuth.options.restoreOriginalUri = (async (oktaAuth: unknown, originalUri: string) => { - restoreOriginalUri(oktaAuth as OktaAuth, originalUri); + return restoreOriginalUri(oktaAuth as OktaAuth, originalUri); }) as ((oktaAuth: OktaAuth, originalUri?: string) => Promise); }, []); // empty array, only check on component mount diff --git a/test/jest/security.test.tsx b/test/jest/security.test.tsx index a916113a..64489f91 100644 --- a/test/jest/security.test.tsx +++ b/test/jest/security.test.tsx @@ -27,8 +27,10 @@ console.warn = jest.fn(); describe('', () => { let oktaAuth: OktaAuth; let initialAuthState: AuthState | null; + // eslint-disable-next-line @typescript-eslint/no-unused-vars const restoreOriginalUri = async (_: OktaAuth, url: string) => { - location.href = url; + // leaving empty, doesn't affect tests, was causing jsdom error (location.href is not supported) + // location.href = url; }; beforeEach(() => { jest.clearAllMocks(); @@ -136,14 +138,58 @@ describe('', () => { }); }); - it('should set default restoreOriginalUri callback in oktaAuth.options', () => { - oktaAuth.options = {}; - const mockProps = { - oktaAuth, - restoreOriginalUri - }; - mount(); - expect(oktaAuth.options.restoreOriginalUri).toBeDefined(); + describe('restoreOriginalUri', () => { + it('should set default restoreOriginalUri callback in oktaAuth.options', () => { + oktaAuth.options = {}; + const mockProps = { + oktaAuth, + restoreOriginalUri + }; + mount(); + expect(oktaAuth.options.restoreOriginalUri).toBeDefined(); + }); + + it('should only log warning of restoreOriginalUri option once', () => { + oktaAuth.options = { + restoreOriginalUri + }; + const mockProps = { + oktaAuth, + restoreOriginalUri + }; + const warning = 'Two custom restoreOriginalUri callbacks are detected. The one from the OktaAuth configuration will be overridden by the provided restoreOriginalUri prop from the Security component.'; + const spy = jest.spyOn(console, 'warn'); + const wrapper = mount(); + expect(spy).toBeCalledTimes(1); + expect(spy).toBeCalledWith(warning); + spy.mockClear(); + wrapper.setProps({restoreOriginalUri: 'foo'}); // forces rerender + expect(spy).toBeCalledTimes(0); + }); + + it('should await the resulting Promise when a fn returning a Promise is provided', async () => { + oktaAuth.options = {}; + + let hasResolved = false; + const restoreSpy = jest.fn().mockImplementation(() => { + return new Promise(resolve => { + // adds small sleep so non-awaited promises will "fallthrough" + // and the test will fail, unless it awaits for the sleep duration + // (meaning the resulting promise was awaited) + setTimeout(() => { + hasResolved = true; + resolve('foo'); + }, 500); + }); + }); + + mount(); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + await oktaAuth.options.restoreOriginalUri!(oktaAuth, 'foo'); + expect(hasResolved).toEqual(true); + expect(restoreSpy).toHaveBeenCalledTimes(1); + expect(restoreSpy).toHaveBeenCalledWith(oktaAuth, 'foo'); + }); }); it('gets initial state from oktaAuth and exposes it on the context', () => { @@ -394,22 +440,4 @@ describe('', () => { expect(wrapper.find(Security).html()).toBe('

AuthSdkError: No restoreOriginalUri callback passed to Security Component.

'); }); }); - - it('should only log warning of restoreOriginalUri option once', () => { - oktaAuth.options = { - restoreOriginalUri - }; - const mockProps = { - oktaAuth, - restoreOriginalUri - }; - const warning = 'Two custom restoreOriginalUri callbacks are detected. The one from the OktaAuth configuration will be overridden by the provided restoreOriginalUri prop from the Security component.'; - const spy = jest.spyOn(console, 'warn'); - const wrapper = mount(); - expect(spy).toBeCalledTimes(1); - expect(spy).toBeCalledWith(warning); - spy.mockClear(); - wrapper.setProps({restoreOriginalUri: 'foo'}); // forces rerender - expect(spy).toBeCalledTimes(0); - }); }); diff --git a/yarn.lock b/yarn.lock index 7efbd1ea..6fecf355 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1205,6 +1205,13 @@ core-js-pure "^3.30.2" regenerator-runtime "^0.14.0" +"@babel/runtime@7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.10.tgz#ae3e9631fd947cb7e3610d3e9d8fef5f76696682" + integrity sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.0", "@babel/runtime@^7.18.9", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a" @@ -1720,7 +1727,7 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@okta/okta-auth-js@*", "@okta/okta-auth-js@^7.0.0": +"@okta/okta-auth-js@*": version "7.0.0" resolved "https://registry.yarnpkg.com/@okta/okta-auth-js/-/okta-auth-js-7.0.0.tgz#d83acb76394ebc7d019d922f0e319fe6655c41ac" integrity sha512-tF+OiaAHNHc5ACKUR5lynX7LQyw9+pqKj8hzSY+E6OCKucYudjMg87AdCdyBxpFgxrirRlAFYv08sM1wwn0Eeg== @@ -1765,6 +1772,28 @@ webcrypto-shim "^0.1.5" xhr2 "0.1.3" +"@okta/okta-auth-js@^7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@okta/okta-auth-js/-/okta-auth-js-7.7.0.tgz#daac09294316a69d996a33232eb25032d1b85d70" + integrity sha512-m+WlI9TJ3J2uHI+W9Uc7zinE4CQLS2JC6AQYPJ0KHxaVE5lwPDLFleapPNfNWzYGr/30GV7oBzJMU+8+UQEsPA== + dependencies: + "@babel/runtime" "^7.12.5" + "@peculiar/webcrypto" "^1.4.0" + Base64 "1.1.0" + atob "^2.1.2" + broadcast-channel "~5.3.0" + btoa "^1.2.1" + core-js "^3.6.5" + cross-fetch "^3.1.5" + fast-text-encoding "^1.0.6" + js-cookie "^3.0.1" + jsonpath-plus "^6.0.1" + node-cache "^5.1.2" + p-cancelable "^2.0.0" + tiny-emitter "1.1.0" + webcrypto-shim "^0.1.5" + xhr2 "0.1.3" + "@okta/okta-signin-widget@^6.7.1": version "6.9.0" resolved "https://artifacts.aue1e.internal:443/artifactory/api/npm/npm-okta-all/@okta/okta-signin-widget/-/@okta/okta-signin-widget-6.9.0.tgz#252d939525a422580c51e549a6e4ed4cd20f4765" @@ -3266,6 +3295,16 @@ broadcast-channel@~4.17.0: rimraf "3.0.2" unload "2.3.1" +broadcast-channel@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/broadcast-channel/-/broadcast-channel-5.3.0.tgz#9d9e55fb8db2a1dbbe436ae6d51382a354e76fc3" + integrity sha512-0PmDYc/iUGZ4QbnCnV7u+WleygiS1bZ4oV6t4rANXYtSgEFtGhB5jimJPLOVpPtce61FVxrH8CYylfO5g7OLKw== + dependencies: + "@babel/runtime" "7.22.10" + oblivious-set "1.1.1" + p-queue "6.6.2" + unload "2.4.1" + browserslist@^4.20.2, browserslist@^4.21.9: version "4.21.10" resolved "https://artifacts.aue1e.internal:443/artifactory/api/npm/npm-okta-master/browserslist/-/browserslist-4.21.10.tgz#dbbac576628c13d3b2231332cb2ec5a46e015bb0" @@ -4903,6 +4942,11 @@ fast-levenshtein@^2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== +fast-text-encoding@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/fast-text-encoding/-/fast-text-encoding-1.0.6.tgz#0aa25f7f638222e3396d72bf936afcf1d42d6867" + integrity sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w== + fastq@^1.6.0: version "1.13.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" @@ -9193,6 +9237,11 @@ unload@2.3.1: "@babel/runtime" "^7.6.2" detect-node "2.1.0" +unload@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/unload/-/unload-2.4.1.tgz#b0c5b7fb44e17fcbf50dcb8fb53929c59dd226a5" + integrity sha512-IViSAm8Z3sRBYA+9wc0fLQmU9Nrxb16rcDmIiR6Y9LJSZzI7QY5QsDhqPpKOjAn0O9/kfK1TfNEMMAGPTIraPw== + update-browserslist-db@^1.0.11, update-browserslist-db@^1.0.5: version "1.0.11" resolved "https://artifacts.aue1e.internal:443/artifactory/api/npm/npm-okta-master/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940"