Skip to content

Commit

Permalink
fix: #45 switch to oidc-client-ts
Browse files Browse the repository at this point in the history
  • Loading branch information
pamapa committed Sep 15, 2021
1 parent 015e95e commit ac47820
Show file tree
Hide file tree
Showing 12 changed files with 366 additions and 520 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
![Pipeline](https://github.com/pamapa/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).


Expand All @@ -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,
Expand Down Expand Up @@ -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:<your authority>:<your client id>`)
Expand Down
814 changes: 328 additions & 486 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@
},
"peerDependencies": {
"react": ">=16",
"oidc-client": "^1.11.5"
"oidc-client-ts": "^2.0.0-alpha2"
},
"dependencies": {
"oidc-client": "^1.11.5"
"oidc-client-ts": "^2.0.0-alpha2"
},
"devDependencies": {
"@testing-library/jest-dom": "^5.5.0",
Expand Down
16 changes: 8 additions & 8 deletions src/AuthContext.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import React from "react";
import { UserManagerSettings, User, SessionStatus } from "oidc-client";
import { UserManagerSettings, User, SessionStatus } 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<void>;
removeUser(): Promise<void>;
signinPopup(args?: any): Promise<User>;
signinSilent(args?: any): Promise<User>;
signinRedirect(args?: any): Promise<void>;
signoutRedirect(args?: any): Promise<void>;
signoutPopup(args?: any): Promise<void>;
querySessionStatus(args?: any): Promise<SessionStatus>;
signinPopup(): Promise<User>;
signinSilent(): Promise<User | null>;
signinRedirect(): Promise<void>;
signoutRedirect(): Promise<void>;
signoutPopup(): Promise<void>;
querySessionStatus(): Promise<SessionStatus | null>;
revokeAccessToken(): Promise<void>;
startSilentRenew(): void;
stopSilentRenew(): void;
Expand Down
10 changes: 5 additions & 5 deletions src/AuthProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import { UserManager, UserManagerSettings, User } from "oidc-client";
import { UserManager, UserManagerSettings, User } from "oidc-client-ts";

import { AuthContext } from "./AuthContext";
import { initialAuthState } from "./AuthState";
Expand Down Expand Up @@ -137,16 +137,16 @@ export const AuthProvider = (props: AuthProviderProps): JSX.Element => {
);

const signoutRedirect = React.useCallback(
async (args?: any): Promise<void> => {
await userManager.signoutRedirect(args);
async (): Promise<void> => {
await userManager.signoutRedirect();
onSignoutRedirect && onSignoutRedirect();
},
[userManager, onSignoutRedirect]
);

const signoutPopup = React.useCallback(
async (args?: any): Promise<void> => {
await userManager.signoutPopup(args);
async (): Promise<void> => {
await userManager.signoutPopup();
onSignoutPopup && onSignoutPopup();
},
[userManager, onSignoutPopup]
Expand Down
2 changes: 1 addition & 1 deletion src/AuthState.ts
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
2 changes: 1 addition & 1 deletion src/reducer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { User } from "oidc-client";
import { User } from "oidc-client-ts";

import { AuthState } from "./AuthState";

Expand Down
19 changes: 10 additions & 9 deletions test/AuthProvider.test.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { UserManager, User } from "oidc-client"
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 userManagerMock = mocked(new UserManager({ client_id: "" }))
const settingsStub = { authority: "authority", client_id: "client", redirect_uri: "redirect" }
const userManagerMock = mocked(new UserManager(settingsStub))
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,
})
Expand Down Expand Up @@ -41,7 +42,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(), {
Expand All @@ -66,7 +67,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(), {
Expand All @@ -83,7 +84,7 @@ describe("AuthProvider", () => {
// arrange
const onRemoveUser = jest.fn()

const wrapper = createWrapper({ onRemoveUser })
const wrapper = createWrapper({ ...settingsStub, onRemoveUser })
const { waitForNextUpdate, result } = renderHook(() => useAuth(), {
wrapper,
})
Expand All @@ -102,7 +103,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,
})
Expand All @@ -121,7 +122,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,
})
Expand All @@ -140,7 +141,7 @@ describe("AuthProvider", () => {
it("should get the user", async () => {
// arrange
userManagerMock.getUser.mockResolvedValue(user)
const wrapper = createWrapper()
const wrapper = createWrapper(settingsStub)

// act
const { waitForNextUpdate, result } = renderHook(() => useAuth(), {
Expand Down
File renamed without changes.
3 changes: 1 addition & 2 deletions test/helpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<AuthProviderProps>): JSX.Element => (
<AuthProvider
client_id={"__test_client_id__"}
{...opts}
>
{children}
Expand Down
4 changes: 3 additions & 1 deletion test/useAuth.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
4 changes: 3 additions & 1 deletion test/withAuth.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand All @@ -14,7 +16,7 @@ describe("withAuth", () => {
}
const WrappedComponent = withAuth(MyComponent);
render(
<AuthProvider>
<AuthProvider {...settingsStub}>
<WrappedComponent />
</AuthProvider>
)
Expand Down

0 comments on commit ac47820

Please sign in to comment.