{"_id":"@aeolun/react-oidc-context","name":"@aeolun/react-oidc-context","dist-tags":{"latest":"3.0.1"},"versions":{"3.0.1":{"name":"@aeolun/react-oidc-context","version":"3.0.1","description":"OpenID Connect & OAuth2 authentication using react context api as state management","repository":{"type":"git","url":"git+https://github.com/authts/react-oidc-context.git"},"homepage":"https://github.com/authts/react-oidc-context#readme","license":"MIT","main":"dist/umd/react-oidc-context.js","types":"dist/types/react-oidc-context.d.ts","exports":{".":{"types":"./dist/types/react-oidc-context.d.ts","import":"./dist/esm/react-oidc-context.js","require":"./dist/umd/react-oidc-context.js"},"./package.json":"./package.json"},"keywords":["authentication","context-api","oauth2","oidc","openid","OpenID Connect","react-component"],"scripts":{"build":"node scripts/build.js && npm run build-types","build-types":"tsc --emitDeclarationOnly && api-extractor run","clean":"git clean -fdX dist","prepack":"npm run build","test":"tsc -p test/tsconfig.json && jest","lint":"eslint --max-warnings=0 --cache .","prepare":"husky install"},"peerDependencies":{"oidc-client-ts":"^3.0.0","react":">=16.8.0"},"devDependencies":{"@microsoft/api-extractor":"^7.35.0","@testing-library/jest-dom":"^6.1.2","@testing-library/react":"^14.0.0","@types/jest":"^29.5.4","@types/react":"^18.0.6","@types/react-dom":"^18.0.2","@types/react-test-renderer":"^18.0.0","@typescript-eslint/eslint-plugin":"^6.4.1","@typescript-eslint/parser":"^6.4.1","esbuild":"^0.20.0","eslint":"^8.4.1","eslint-plugin-testing-library":"^6.0.0","husky":"^9.0.2","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","jest-mock":"^29.3.1","lint-staged":"^15.0.1","react":"^18.0.0","react-dom":"^18.0.0","react-test-renderer":"^18.0.0","ts-jest":"^29.0.3","tslib":"^2.2.0","typescript":"~5.4.2","yn":"^5.0.0"},"engines":{"node":">=18"},"lint-staged":{"*.{js,jsx,ts,tsx}":"eslint --cache --fix"},"_id":"@aeolun/react-oidc-context@3.0.1","gitHead":"b9f8d479ef2e91a4fee39454588b11dd127ce805","bugs":{"url":"https://github.com/authts/react-oidc-context/issues"},"_nodeVersion":"20.12.0","_npmVersion":"10.5.0","dist":{"integrity":"sha512-tPNMWLrYqocNcSwXyffgzobsrd8UoNZSKkymzca88qFZdqa200nBa6x7QqujwUQ8cCX7ZjoujXEME38G7lEnDA==","shasum":"fb7b179cd355c537393bbf174fb6d7a719f2b645","tarball":"https://registry.npmjs.org/@aeolun/react-oidc-context/-/react-oidc-context-3.0.1.tgz","fileCount":10,"unpackedSize":90090,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCftmi1aRTIOsMmAEzzGGPFxRT/2FhIkWKtLF/A8p240wIhAOZi37goKOzvnrKdGL+duyh9hgNVcRofepNORMX6vR2x"}]},"_npmUser":{"name":"aeolun","email":"bart@serial-experiments.com"},"directories":{},"maintainers":[{"name":"aeolun","email":"bart@serial-experiments.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-oidc-context_3.0.1_1713244061857_0.8517422067433895"},"_hasShrinkwrap":false}},"time":{"created":"2024-04-16T05:07:41.856Z","3.0.1":"2024-04-16T05:07:42.183Z","modified":"2024-04-16T05:07:42.863Z"},"maintainers":[{"name":"aeolun","email":"bart@serial-experiments.com"}],"description":"OpenID Connect & OAuth2 authentication using react context api as state management","homepage":"https://github.com/authts/react-oidc-context#readme","keywords":["authentication","context-api","oauth2","oidc","openid","OpenID Connect","react-component"],"repository":{"type":"git","url":"git+https://github.com/authts/react-oidc-context.git"},"bugs":{"url":"https://github.com/authts/react-oidc-context/issues"},"license":"MIT","readme":"# react-oidc-context\n\n[![Stable Release](https://img.shields.io/npm/v/react-oidc-context.svg)](https://npm.im/react-oidc-context)\n[![CI](https://github.com/authts/react-oidc-context/actions/workflows/ci.yml/badge.svg)](https://github.com/authts/react-oidc-context/actions/workflows/ci.yml)\n[![Codecov](https://img.shields.io/codecov/c/github/authts/react-oidc-context)](https://app.codecov.io/gh/authts/react-oidc-context)\n\nLightweight auth library using the\n[oidc-client-ts](https://github.com/authts/oidc-client-ts) library for React\nsingle page applications (SPA). Support for\n[hooks](https://reactjs.org/docs/hooks-intro.html) and\n[higher-order components (HOC)](https://reactjs.org/docs/higher-order-components.html).\n\n## Table of Contents\n\n- [Documentation](#documentation)\n- [Installation](#installation)\n- [Getting Started](#getting-started)\n- [Contributing](#contributing)\n- [Influences](#influences)\n- [License](#license)\n\n## Documentation\n\nThis library implements an auth context provider by making use of the\n`oidc-client-ts` library. Its configuration is tight coupled to that library.\n\n- [oidc-client-ts](https://github.com/authts/oidc-client-ts)\n\nThe\n[`User`](https://authts.github.io/oidc-client-ts/classes/User.html)\nand\n[`UserManager`](https://authts.github.io/oidc-client-ts/classes/UserManager.html)\nis hold in this context, which is accessible from the\nReact application. Additionally it intercepts the auth redirects by looking at\nthe query/fragment parameters and acts accordingly. You still need to setup a\nredirect uri, which must point to your application, but you do not need to\ncreate that route.\n\nTo renew the access token, the\n[automatic silent renew](https://authts.github.io/oidc-client-ts/interfaces/UserManagerSettings.html#automaticSilentRenew)\nfeature of `oidc-client-ts` can be used.\n\n## Installation\n\nUsing [npm](https://npmjs.org/)\n\n```bash\nnpm install oidc-client-ts react-oidc-context --save\n```\n\nUsing [yarn](https://yarnpkg.com/)\n\n```bash\nyarn add oidc-client-ts react-oidc-context\n```\n\n## Getting Started\n\nConfigure the library by wrapping your application in `AuthProvider`:\n\n```jsx\n// src/index.jsx\nimport React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { AuthProvider } from \"react-oidc-context\";\nimport App from \"./App\";\n\nconst oidcConfig = {\n  authority: \"<your authority>\",\n  client_id: \"<your client id>\",\n  redirect_uri: \"<your redirect uri>\",\n  // ...\n};\n\nReactDOM.render(\n  <AuthProvider {...oidcConfig}>\n    <App />\n  </AuthProvider>,\n  document.getElementById(\"app\")\n);\n```\n\nUse the `useAuth` hook in your components to access authentication state\n(`isLoading`, `isAuthenticated` and `user`) and authentication methods\n(`signinRedirect`, `removeUser` and `signOutRedirect`):\n\n```jsx\n// src/App.jsx\nimport React from \"react\";\nimport { useAuth } from \"react-oidc-context\";\n\nfunction App() {\n    const auth = useAuth();\n\n    switch (auth.activeNavigator) {\n        case \"signinSilent\":\n            return <div>Signing you in...</div>;\n        case \"signoutRedirect\":\n            return <div>Signing you out...</div>;\n    }\n\n    if (auth.isLoading) {\n        return <div>Loading...</div>;\n    }\n\n    if (auth.error) {\n        return <div>Oops... {auth.error.message}</div>;\n    }\n\n    if (auth.isAuthenticated) {\n        return (\n        <div>\n            Hello {auth.user?.profile.sub}{\" \"}\n            <button onClick={() => void auth.removeUser()}>Log out</button>\n        </div>\n        );\n    }\n\n    return <button onClick={() => void auth.signinRedirect()}>Log in</button>;\n}\n\nexport default App;\n```\n\nYou **must** provide an implementation of `onSigninCallback` to `oidcConfig` to remove the payload from the URL upon successful login. Otherwise if you refresh the page and the payload is still there, `signinSilent` - which handles renewing your token - won't work.\n\nA working implementation is already in the code [here](https://github.com/authts/react-oidc-context/blob/f175dcba6ab09871b027d6a2f2224a17712b67c5/src/AuthProvider.tsx#L20-L30).\n\n\n### Use with a Class Component\n\nUse the `withAuth` higher-order component to add the `auth` property to class\ncomponents:\n\n```jsx\n// src/Profile.jsx\nimport React from \"react\";\nimport { withAuth } from \"react-oidc-context\";\n\nclass Profile extends React.Component {\n    render() {\n        // `this.props.auth` has all the same properties as the `useAuth` hook\n        const auth = this.props.auth;\n        return <div>Hello {auth.user?.profile.sub}</div>;\n    }\n}\n\nexport default withAuth(Profile);\n```\n\n### Call a protected API\n\nAs a child of `AuthProvider` with a user containing an access token:\n\n```jsx\n// src/Posts.jsx\nimport React from \"react\";\nimport { useAuth } from \"react-oidc-context\";\n\nconst Posts = () => {\n    const auth = useAuth();\n    const [posts, setPosts] = React.useState(Array);\n\n    React.useEffect(() => {\n        (async () => {\n            try {\n                const token = auth.user?.access_token;\n                const response = await fetch(\"https://api.example.com/posts\", {\n                    headers: {\n                        Authorization: `Bearer ${token}`,\n                    },\n                });\n                setPosts(await response.json());\n            } catch (e) {\n                console.error(e);\n            }\n        })();\n    }, [auth]);\n\n    if (!posts.length) {\n        return <div>Loading...</div>;\n    }\n\n    return (\n        <ul>\n        {posts.map((post, index) => {\n            return <li key={index}>{post}</li>;\n        })}\n        </ul>\n    );\n};\n\nexport default Posts;\n```\n\nAs **not** a child of `AuthProvider` (e.g. redux slice) when using local storage\n(`WebStorageStateStore`) for the user containing an access token:\n\n```jsx\n// src/slice.js\nimport { User } from \"oidc-client-ts\"\n\nfunction getUser() {\n    const oidcStorage = localStorage.getItem(`oidc.user:<your authority>:<your client id>`)\n    if (!oidcStorage) {\n        return null;\n    }\n\n    return User.fromStorageString(oidcStorage);\n}\n\nexport const getPosts = createAsyncThunk(\n    \"store/getPosts\",\n    async () => {\n        const user = getUser();\n        const token = user?.access_token;\n        return fetch(\"https://api.example.com/posts\", {\n            headers: {\n                Authorization: `Bearer ${token}`,\n            },\n        });\n    },\n    // ...\n)\n```\n\n### Protect a route\n\nSecure a route component by using the `withAuthenticationRequired` higher-order component. If a user attempts\nto access this route without authentication, they will be redirected to the login page.\n\n```jsx\nimport React from 'react';\nimport { withAuthenticationRequired } from \"react-oidc-context\";\n\nconst PrivateRoute = () => (<div>Private</div>);\n\nexport default withAuthenticationRequired(PrivateRoute, {\n  onRedirecting: () => (<div>Redirecting to the login page...</div>)\n});\n```\n\n### Adding event listeners\n\nThe underlying [`UserManagerEvents`](https://authts.github.io/oidc-client-ts/classes/UserManagerEvents.html) instance can be imperatively managed with the `useAuth` hook.\n\n```jsx\n// src/App.jsx\nimport React from \"react\";\nimport { useAuth } from \"react-oidc-context\";\n\nfunction App() {\n    const auth = useAuth();\n\n    React.useEffect(() => {\n        // the `return` is important - addAccessTokenExpiring() returns a cleanup function\n        return auth.events.addAccessTokenExpiring(() => {\n            if (alert(\"You're about to be signed out due to inactivity. Press continue to stay signed in.\")) {\n                auth.signinSilent();\n            }\n        })\n    }, [auth.events, auth.signinSilent]);\n\n    return <button onClick={() => void auth.signinRedirect()}>Log in</button>;\n}\n\nexport default App;\n```\n\n### Automatic sign-in\n\nAutomatically sign-in and silently reestablish your previous session, if you close the tab and reopen the application.\n\n```jsx\n// index.jsx\nconst oidcConfig: AuthProviderProps = {\n    ...\n    userStore: new WebStorageStateStore({ store: window.localStorage }),\n};\n```\n\n```jsx\n// src/App.jsx\nimport React from \"react\";\nimport { useAuth, hasAuthParams } from \"react-oidc-context\";\n\nfunction App() {\n    const auth = useAuth();\n    const [hasTriedSignin, setHasTriedSignin] = React.useState(false);\n\n    // automatically sign-in\n    React.useEffect(() => {\n        if (!hasAuthParams() &&\n            !auth.isAuthenticated && !auth.activeNavigator && !auth.isLoading &&\n            !hasTriedSignin\n        ) {\n            auth.signinRedirect();\n            setHasTriedSignin(true);\n        }\n    }, [auth, hasTriedSignin]);\n\n    if (auth.isLoading) {\n        return <div>Signing you in/out...</div>;\n    }\n\n    if (!auth.isAuthenticated) {\n        return <div>Unable to log in</div>;\n    }\n\n    return <button onClick={() => void auth.removeUser()}>Log out</button>;\n}\n\nexport default App;\n```\n\n## Contributing\n\nWe appreciate feedback and contribution to this repo!\n\n## Influences\n\nThis library is inspired by [oidc-react](https://github.com/bjerkio/oidc-react),\nwhich lacks error handling and\n[auth0-react](https://github.com/auth0/auth0-react), which is focused on auth0.\n\n## License\n\nThis project is licensed under the MIT license. See the\n[LICENSE](https://github.com/authts/react-oidc-context/blob/main/LICENSE) file\nfor more info.\n","readmeFilename":"README.md"}