diff --git a/README.md b/README.md index 5ac93d27..8a96d545 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ![Pipeline](https://github.com/authts/oidc-client-react/workflows/Release/badge.svg) -Lightweight auth library using the [oidc-client](https://github.com/IdentityModel/oidc-client-js) library for React single page applications (SPA). +Lightweight auth library using the [oidc-client-ts](https://github.com/pamapa/oidc-client-ts) library for React single page applications (SPA). Support for [hooks](https://reactjs.org/docs/hooks-intro.html) and [higher-order components (HOC)](https://reactjs.org/docs/higher-order-components.html). @@ -18,10 +18,10 @@ Support for [hooks](https://reactjs.org/docs/hooks-intro.html) and [higher-order ## Documentation -This library implements an auth context provider by making use of the `oidc-client` library. Its configuration is +This library implements an auth context provider by making use of the `oidc-client-ts` library. Its configuration is tight coupled to that library. -- [oidc-client](https://github.com/IdentityModel/oidc-client-js/wiki) +- [oidc-client-ts](https://github.com/pamapa/oidc-client-ts) The User and UserManager is hold in this context, which is accessible from the React application. Additionally it intercepts the auth redirects by looking at the query/fragment parameters and acts accordingly. You still need to setup a redirect uri, @@ -170,7 +170,7 @@ As **not** a child of `AuthProvider` (e.g. redux slice) when using local storage containing an access token: ```jsx // src/slice.js -import { User } from "oidc-client" +import { User } from "oidc-client-ts" function getUser() { const oidcStorage = localStorage.getItem(`oidc.user::`) diff --git a/package-lock.json b/package-lock.json index 312e2360..7a1562cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.1.0", "license": "MIT", "dependencies": { - "oidc-client": "^1.11.5" + "oidc-client-ts": "^2.0.0-beta.2" }, "devDependencies": { "@testing-library/jest-dom": "^5.5.0", @@ -33,7 +33,7 @@ "node": ">=10" }, "peerDependencies": { - "oidc-client": "^1.11.5", + "oidc-client-ts": "^2.0.0-beta.2", "react": ">=16" } }, @@ -2688,89 +2688,6 @@ "node": ">=10" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.32.0.tgz", - "integrity": "sha512-DK+fMSHdM216C0OM/KR1lHXjP1CNtVIhJ54kQxfOE6x8UGFAjha8cXgDMBEIYS2XCYjjCtvTkjQYwL3uvGOo0w==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.32.0", - "@typescript-eslint/visitor-keys": "4.32.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.32.0.tgz", - "integrity": "sha512-LE7Z7BAv0E2UvqzogssGf1x7GPpUalgG07nGCBYb1oK4mFsOiFC/VrSMKbZQzFJdN2JL5XYmsx7C7FX9p9ns0w==", - "dev": true, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.32.0.tgz", - "integrity": "sha512-tRYCgJ3g1UjMw1cGG8Yn1KzOzNlQ6u1h9AmEtPhb5V5a1TmiHWcRyF/Ic+91M4f43QeChyYlVTcf3DvDTZR9vw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.32.0", - "@typescript-eslint/visitor-keys": "4.32.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.32.0.tgz", - "integrity": "sha512-e7NE0qz8W+atzv3Cy9qaQ7BTLwWsm084Z0c4nIO2l3Bp6u9WIgdqCgyPyV5oSPDMIW3b20H59OOCmVk3jw3Ptw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.32.0", - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/@weiran.zsd/tsdx": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@weiran.zsd/tsdx/-/tsdx-0.16.2.tgz", @@ -5363,6 +5280,7 @@ "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=", + "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -5780,6 +5698,7 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha1-GxtEAWClv3rUC2UPCVljSBkDkwo=", + "dev": true, "funding": [ { "type": "github", @@ -6166,16 +6085,6 @@ "safe-buffer": "~5.1.1" } }, - "node_modules/core-js": { - "version": "3.11.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.11.3.tgz", - "integrity": "sha1-KDWx9NEPbQQAv4IM/m/mStBn3T8=", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "node_modules/core-js-compat": { "version": "3.11.3", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.11.3.tgz", @@ -6226,11 +6135,6 @@ "node": ">=8" } }, - "node_modules/crypto-js": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz", - "integrity": "sha1-KQSrJnep0EKFai6i74DekuSjbcw=" - }, "node_modules/css": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", @@ -9605,6 +9509,14 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsrsasign": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-10.4.1.tgz", + "integrity": "sha512-g2CP2nb8xKdmfZhuHaJEz1zVYTsZc+lUjLFvgbMX35/cUALK0G15sQfCbCpDg/UivkjCNlq0lV6FxCfPhv0shw==", + "funding": { + "url": "https://github.com/kjur/jsrsasign#donations" + } + }, "node_modules/jsx-ast-utils": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", @@ -10185,16 +10097,15 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/oidc-client": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/oidc-client/-/oidc-client-1.11.5.tgz", - "integrity": "sha1-Agqhk9aKPh+Hok/L9QBztzjekrs=", + "node_modules/oidc-client-ts": { + "version": "2.0.0-beta.2", + "resolved": "https://registry.npmjs.org/oidc-client-ts/-/oidc-client-ts-2.0.0-beta.2.tgz", + "integrity": "sha512-Jo4WBvurxAnfnkJynDDrX3hkag3MsF0wwzVNqrxFd7sXJwPIBrWjQ6FjpZRhnDJN8Lo/SJxvjn0PSE3Kxbwmmg==", "dependencies": { - "acorn": "^7.4.1", - "base64-js": "^1.5.1", - "core-js": "^3.8.3", - "crypto-js": "^4.0.0", - "serialize-javascript": "^4.0.0" + "jsrsasign": "^10.3.0" + }, + "engines": { + "node": ">=12.13.0" } }, "node_modules/once": { @@ -10555,6 +10466,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha1-32+ENy8CcNxlzfYpE0mrekc9Tyo=", + "dev": true, "dependencies": { "safe-buffer": "^5.1.0" } @@ -11022,7 +10934,8 @@ "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=" + "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=", + "dev": true }, "node_modules/safer-buffer": { "version": "2.1.2", @@ -11059,6 +10972,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", "integrity": "sha1-tSXhI4SJpez8Qq+sw/6Z5mb0sao=", + "dev": true, "dependencies": { "randombytes": "^2.1.0" } @@ -14124,55 +14038,6 @@ } } }, - "@typescript-eslint/scope-manager": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.32.0.tgz", - "integrity": "sha512-DK+fMSHdM216C0OM/KR1lHXjP1CNtVIhJ54kQxfOE6x8UGFAjha8cXgDMBEIYS2XCYjjCtvTkjQYwL3uvGOo0w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.32.0", - "@typescript-eslint/visitor-keys": "4.32.0" - } - }, - "@typescript-eslint/types": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.32.0.tgz", - "integrity": "sha512-LE7Z7BAv0E2UvqzogssGf1x7GPpUalgG07nGCBYb1oK4mFsOiFC/VrSMKbZQzFJdN2JL5XYmsx7C7FX9p9ns0w==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.32.0.tgz", - "integrity": "sha512-tRYCgJ3g1UjMw1cGG8Yn1KzOzNlQ6u1h9AmEtPhb5V5a1TmiHWcRyF/Ic+91M4f43QeChyYlVTcf3DvDTZR9vw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.32.0", - "@typescript-eslint/visitor-keys": "4.32.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.32.0.tgz", - "integrity": "sha512-e7NE0qz8W+atzv3Cy9qaQ7BTLwWsm084Z0c4nIO2l3Bp6u9WIgdqCgyPyV5oSPDMIW3b20H59OOCmVk3jw3Ptw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.32.0", - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, "@weiran.zsd/tsdx": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@weiran.zsd/tsdx/-/tsdx-0.16.2.tgz", @@ -16145,7 +16010,8 @@ "acorn": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=" + "integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=", + "dev": true }, "acorn-jsx": { "version": "5.3.2", @@ -16462,7 +16328,8 @@ "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha1-GxtEAWClv3rUC2UPCVljSBkDkwo=" + "integrity": "sha1-GxtEAWClv3rUC2UPCVljSBkDkwo=", + "dev": true }, "bl": { "version": "4.1.0", @@ -16746,11 +16613,6 @@ "safe-buffer": "~5.1.1" } }, - "core-js": { - "version": "3.11.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.11.3.tgz", - "integrity": "sha1-KDWx9NEPbQQAv4IM/m/mStBn3T8=" - }, "core-js-compat": { "version": "3.11.3", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.11.3.tgz", @@ -16788,11 +16650,6 @@ "yaml": "^1.7.2" } }, - "crypto-js": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz", - "integrity": "sha1-KQSrJnep0EKFai6i74DekuSjbcw=" - }, "css": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", @@ -19357,6 +19214,11 @@ "universalify": "^2.0.0" } }, + "jsrsasign": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-10.4.1.tgz", + "integrity": "sha512-g2CP2nb8xKdmfZhuHaJEz1zVYTsZc+lUjLFvgbMX35/cUALK0G15sQfCbCpDg/UivkjCNlq0lV6FxCfPhv0shw==" + }, "jsx-ast-utils": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", @@ -19819,16 +19681,12 @@ "has": "^1.0.3" } }, - "oidc-client": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/oidc-client/-/oidc-client-1.11.5.tgz", - "integrity": "sha1-Agqhk9aKPh+Hok/L9QBztzjekrs=", + "oidc-client-ts": { + "version": "2.0.0-beta.2", + "resolved": "https://registry.npmjs.org/oidc-client-ts/-/oidc-client-ts-2.0.0-beta.2.tgz", + "integrity": "sha512-Jo4WBvurxAnfnkJynDDrX3hkag3MsF0wwzVNqrxFd7sXJwPIBrWjQ6FjpZRhnDJN8Lo/SJxvjn0PSE3Kxbwmmg==", "requires": { - "acorn": "^7.4.1", - "base64-js": "^1.5.1", - "core-js": "^3.8.3", - "crypto-js": "^4.0.0", - "serialize-javascript": "^4.0.0" + "jsrsasign": "^10.3.0" } }, "once": { @@ -20093,6 +19951,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha1-32+ENy8CcNxlzfYpE0mrekc9Tyo=", + "dev": true, "requires": { "safe-buffer": "^5.1.0" } @@ -20445,7 +20304,8 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=" + "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=", + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -20476,6 +20336,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", "integrity": "sha1-tSXhI4SJpez8Qq+sw/6Z5mb0sao=", + "dev": true, "requires": { "randombytes": "^2.1.0" } diff --git a/package.json b/package.json index 003b9f14..5057d0a5 100644 --- a/package.json +++ b/package.json @@ -31,10 +31,10 @@ }, "peerDependencies": { "react": ">=16", - "oidc-client": "^1.11.5" + "oidc-client-ts": "^2.0.0-beta.2" }, "dependencies": { - "oidc-client": "^1.11.5" + "oidc-client-ts": "^2.0.0-beta.2" }, "devDependencies": { "@testing-library/jest-dom": "^5.5.0", diff --git a/src/AuthContext.ts b/src/AuthContext.ts index d1cb071f..827aa53b 100644 --- a/src/AuthContext.ts +++ b/src/AuthContext.ts @@ -1,21 +1,23 @@ import React from "react"; -import { UserManagerSettings, User, SessionStatus } from "oidc-client"; +import { UserManagerSettings, User, SessionStatus } from "oidc-client-ts"; +import { SigninPopupArgs, SigninSilentArgs, SigninRedirectArgs } from "oidc-client-ts"; +import { SignoutRedirectArgs, SignoutPopupArgs, QuerySessionStatusArgs } from "oidc-client-ts"; import { AuthState } from "./AuthState"; export interface AuthContextProps extends AuthState { /** - * UserManager functions. See [UserManager](https://github.com/IdentityModel/oidc-client-js/wiki#usermanager) for more details. + * UserManager functions. See [UserManager](https://github.com/pamapa/oidc-client-ts) for more details. */ readonly settings: UserManagerSettings; clearStaleState(): Promise; removeUser(): Promise; - signinPopup(args?: any): Promise; - signinSilent(args?: any): Promise; - signinRedirect(args?: any): Promise; - signoutRedirect(args?: any): Promise; - signoutPopup(args?: any): Promise; - querySessionStatus(args?: any): Promise; + signinPopup(args?: SigninPopupArgs): Promise; + signinSilent(args?: SigninSilentArgs): Promise; + signinRedirect(args?: SigninRedirectArgs): Promise; + signoutRedirect(args?: SignoutRedirectArgs): Promise; + signoutPopup(args?: SignoutPopupArgs): Promise; + querySessionStatus(args?: QuerySessionStatusArgs): Promise; revokeAccessToken(): Promise; startSilentRenew(): void; stopSilentRenew(): void; diff --git a/src/AuthProvider.tsx b/src/AuthProvider.tsx index 4de4827d..687372ce 100644 --- a/src/AuthProvider.tsx +++ b/src/AuthProvider.tsx @@ -1,5 +1,6 @@ import React from "react"; -import { UserManager, UserManagerSettings, User } from "oidc-client"; +import { UserManager, UserManagerSettings, User } from "oidc-client-ts"; +import { SignoutRedirectArgs, SignoutPopupArgs } from "oidc-client-ts"; import { AuthContext } from "./AuthContext"; import { initialAuthState } from "./AuthState"; @@ -106,7 +107,7 @@ export const AuthProvider = (props: AuthProviderProps): JSX.Element => { const [state, dispatch] = React.useReducer(reducer, initialAuthState); const userManagerContext = React.useMemo( () => ({ - settings: userManager?.settings ?? {}, + settings: userManager?.settings ?? { ...userManagerProps }, ...(Object.fromEntries( userManagerContextKeys.map((key) => [ key, @@ -173,14 +174,14 @@ export const AuthProvider = (props: AuthProviderProps): JSX.Element => { const signoutRedirect = React.useMemo( () => userManager - ? (args?: any) => userManager.signoutRedirect(args).then(onSignoutRedirect) + ? (args?: SignoutRedirectArgs) => userManager.signoutRedirect(args).then(onSignoutRedirect) : unsupportedEnvironment("signoutRedirect"), [userManager, onSignoutRedirect] ); const signoutPopup = React.useMemo( () => userManager - ? (args?: any) => userManager.signoutPopup(args).then(onSignoutPopup) + ? (args?: SignoutPopupArgs) => userManager.signoutPopup(args).then(onSignoutPopup) : unsupportedEnvironment("signoutPopup"), [userManager, onSignoutPopup] ); diff --git a/src/AuthState.ts b/src/AuthState.ts index 555a0534..08a79812 100644 --- a/src/AuthState.ts +++ b/src/AuthState.ts @@ -1,4 +1,4 @@ -import { User } from "oidc-client"; +import { User } from "oidc-client-ts"; /** * The auth state which, when combined with the auth methods, make up the return object of the `useAuth` hook. diff --git a/src/reducer.ts b/src/reducer.ts index 6bc6f405..ce5ab3e1 100644 --- a/src/reducer.ts +++ b/src/reducer.ts @@ -1,4 +1,4 @@ -import { User } from "oidc-client"; +import { User } from "oidc-client-ts"; import { AuthState } from "./AuthState"; diff --git a/test/AuthProvider.test.tsx b/test/AuthProvider.test.tsx index 4bd77f24..295656d6 100644 --- a/test/AuthProvider.test.tsx +++ b/test/AuthProvider.test.tsx @@ -1,17 +1,18 @@ -import { UserManager, User } from "oidc-client" -import { act } from "@testing-library/react" +import { UserManager, User } from "oidc-client-ts" +import { act} from "@testing-library/react" import { renderHook } from "@testing-library/react-hooks" import { mocked } from "ts-jest/utils" import { useAuth } from "../src/useAuth" import { createWrapper } from "./helpers" +const settingsStub = { authority: "authority", client_id: "client", redirect_uri: "redirect" } const user = { id_token: "__test_user__" } as User describe("AuthProvider", () => { it("should signinRedirect when asked", async () => { // arrange - const wrapper = createWrapper() + const wrapper = createWrapper({ ...settingsStub }) const { waitForNextUpdate, result } = renderHook(() => useAuth(), { wrapper, }) @@ -40,7 +41,7 @@ describe("AuthProvider", () => { "https://www.example.com/?code=__test_code__&state=__test_state__" ) - const wrapper = createWrapper({ onSigninCallback }) + const wrapper = createWrapper({ ...settingsStub, onSigninCallback }) // act const { waitForNextUpdate } = renderHook(() => useAuth(), { @@ -65,7 +66,7 @@ describe("AuthProvider", () => { "https://www.example.com/?error=__test_error__&state=__test_state__" ) - const wrapper = createWrapper({ onSigninCallback }) + const wrapper = createWrapper({ ...settingsStub, onSigninCallback }) // act const { waitForNextUpdate } = renderHook(() => useAuth(), { @@ -82,7 +83,7 @@ describe("AuthProvider", () => { // arrange const onRemoveUser = jest.fn() - const wrapper = createWrapper({ onRemoveUser }) + const wrapper = createWrapper({ ...settingsStub, onRemoveUser }) const { waitForNextUpdate, result } = renderHook(() => useAuth(), { wrapper, }) @@ -101,7 +102,7 @@ describe("AuthProvider", () => { it("should handle signoutRedirect and call onSignoutRedirect", async () => { // arrange const onSignoutRedirect = jest.fn() - const wrapper = createWrapper({ onSignoutRedirect }) + const wrapper = createWrapper({ ...settingsStub, onSignoutRedirect }) const { waitForNextUpdate, result } = renderHook(() => useAuth(), { wrapper, }) @@ -120,7 +121,7 @@ describe("AuthProvider", () => { it("should handle signoutPopup and call onSignoutPopup", async () => { // arrange const onSignoutPopup = jest.fn() - const wrapper = createWrapper({ onSignoutPopup }) + const wrapper = createWrapper({ ...settingsStub, onSignoutPopup }) const { waitForNextUpdate, result } = renderHook(() => useAuth(), { wrapper, }) @@ -139,7 +140,7 @@ describe("AuthProvider", () => { it("should get the user", async () => { // arrange mocked(UserManager.prototype).getUser.mockResolvedValueOnce(user) - const wrapper = createWrapper() + const wrapper = createWrapper({ ...settingsStub }) // act const { waitForNextUpdate, result } = renderHook(() => useAuth(), { @@ -149,17 +150,17 @@ describe("AuthProvider", () => { // assert expect(result.current.user).toBe(user) - }) + }) it("should use a custom UserManager implementation", async () => { // arrange class CustomUserManager extends UserManager { } mocked(CustomUserManager.prototype).signinRedirect = jest.fn(); - const wrapper = createWrapper({ implementation: CustomUserManager }) + const wrapper = createWrapper({ ...settingsStub, implementation: CustomUserManager }) const { waitForNextUpdate, result } = renderHook(() => useAuth(), { wrapper, - }) +}) await waitForNextUpdate() expect(result.current.user).toBeUndefined() @@ -175,7 +176,7 @@ describe("AuthProvider", () => { it("should should throw when no UserManager implementation exists", async () => { // arrange - const wrapper = createWrapper({ implementation: null }) + const wrapper = createWrapper({ ...settingsStub, implementation: null }) const { result } = renderHook(() => useAuth(), { wrapper, }) diff --git a/test/__mocks__/oidc-client.ts b/test/__mocks__/oidc-client-ts.ts similarity index 97% rename from test/__mocks__/oidc-client.ts rename to test/__mocks__/oidc-client-ts.ts index 345899e6..2cef6335 100644 --- a/test/__mocks__/oidc-client.ts +++ b/test/__mocks__/oidc-client-ts.ts @@ -1,4 +1,4 @@ -import type { UserManager, UserManagerEvents } from 'oidc-client' +import type { UserManager, UserManagerEvents } from "oidc-client-ts"; const MockUserManager: typeof UserManager = jest.fn(function (this: { events: Partial}) { this.events = { diff --git a/test/helpers.tsx b/test/helpers.tsx index e663239c..71580426 100644 --- a/test/helpers.tsx +++ b/test/helpers.tsx @@ -2,11 +2,10 @@ import React from "react" import { AuthProvider, AuthProviderProps } from "../src/AuthProvider" -export const createWrapper = (opts?: AuthProviderProps) => ({ +export const createWrapper = (opts: AuthProviderProps) => ({ children, }: React.PropsWithChildren): JSX.Element => ( {children} diff --git a/test/useAuth.test.tsx b/test/useAuth.test.tsx index 61177aaf..b882d4d4 100644 --- a/test/useAuth.test.tsx +++ b/test/useAuth.test.tsx @@ -3,10 +3,12 @@ import { renderHook } from "@testing-library/react-hooks" import { useAuth } from "../src/useAuth" import { createWrapper } from "./helpers" +const settingsStub = { authority: "authority", client_id: "client", redirect_uri: "redirect" } + describe("useAuth", () => { it("should provide the auth context", async () => { // arrange - const wrapper = createWrapper() + const wrapper = createWrapper({ ...settingsStub }) const { result, waitForNextUpdate } = renderHook(useAuth, { wrapper }) await waitForNextUpdate() diff --git a/test/withAuth.test.tsx b/test/withAuth.test.tsx index 98e17ae0..00ed10a9 100644 --- a/test/withAuth.test.tsx +++ b/test/withAuth.test.tsx @@ -4,6 +4,8 @@ import "@testing-library/jest-dom/extend-expect" import { AuthContextProps, AuthProvider, withAuth } from "../src" +const settingsStub = { authority: "authority", client_id: "client", redirect_uri: "redirect" } + describe("withAuth", () => { it("should wrap a class component", async () => { await act(async () => { @@ -14,7 +16,7 @@ describe("withAuth", () => { } const WrappedComponent = withAuth(MyComponent); render( - + )