https://github.com/warrant-dev/react-warrant-js
React Client SDK for Warrant
https://github.com/warrant-dev/react-warrant-js
abac access-control acl attribute-based-access-control authorization authz javascript permissions rbac react role-based-access-control
Last synced: 6 months ago
JSON representation
React Client SDK for Warrant
- Host: GitHub
- URL: https://github.com/warrant-dev/react-warrant-js
- Owner: warrant-dev
- License: mit
- Created: 2021-06-25T20:34:40.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2024-06-18T04:21:58.000Z (over 1 year ago)
- Last Synced: 2025-04-13T21:13:15.660Z (6 months ago)
- Topics: abac, access-control, acl, attribute-based-access-control, authorization, authz, javascript, permissions, rbac, react, role-based-access-control
- Language: TypeScript
- Homepage:
- Size: 327 KB
- Stars: 16
- Watchers: 2
- Forks: 1
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# @warrantdev/react-warrant-js
[](https://www.npmjs.com/package/@warrantdev/react-warrant-js)
## Overview
The Warrant React library provides components, hooks, and helper methods for controlling access to pages and components in React using [Warrant](https://warrant.dev/). The library interacts directly with the Warrant API using short-lived session tokens that must be created server-side using your API key. Refer to [this guide](https://docs.warrant.dev/guides/creating-session-tokens) to see how to generate session tokens for your users.
## Installation
Use `npm` to install the core Warrant client module [`@warrantdev/warrant-js`](https://github.com/warrant-dev/warrant-js). This module includes methods shared across our client libraries (Vue, Angular, etc.) and additional types (for TypeScript users).
```sh
npm install @warrantdev/warrant-js
```Use `npm` to install `@warrantdev/react-warrant-js`:
```sh
npm install @warrantdev/react-warrant-js
```## Usage
### `WarrantProvider`
Wrap your application with `WarrantProvider`, passing it your Client Key using the `clientKey` prop. `WarrantProvider` uses [React Context](https://reactjs.org/docs/context.html) to allow you to access utility methods for performing access checks anywhere in your app.
```jsx
// App.jsx
import React from "react";
import { WarrantProvider } from "@warrantdev/react-warrant-js";const App = () => {
return (
{/* Routes, ThemeProviders, etc. */}
);
};export default App;
```#### **Setting the Session Token**
In order to finish initializing the library and begin performing access checks in your app, you must provide a server-generated session token and set it using the `setSessionToken` method. Otherwise your requests will be denied by the Warrant API.
Set the session token using the `useWarrant` hook:
```jsx
// Login.jsx
import React from "react";
import { useWarrant } from "@warrantdev/react-warrant-js";const Login = () => {
const { setSessionToken } = useWarrant();const loginUser = async (event) => {
const response = await login(email, password);// NOTE: This session token must be generated
// server-side when logging users into your
// application and then passed to the client.
// Access check calls in this library will fail
// if the session token is invalid or not set.
setSessionToken(response.warrantSessionToken);//
// Redirect user to logged in page
//
};return (
{/* email & password inputs, etc. */}
);
};export default Login;
```Or using `Context.Consumer`:
```jsx
import React from "react";
import { WarrantContext } from "@warrantdev/react-warrant-js";const Login = () => {
const loginUser = (setSessionToken) => {
return async (event) => {
const response = await login(email, password);// NOTE: This session token must be generated
// server-side when logging users into your
// application and then passed to the client.
// Access check calls in this library will fail
// if the session token is invalid or not set.
setSessionToken(response.warrantSessionToken);//
// Redirect user to logged in page
//
};
};return (
{({ setSessionToken }) => (
{/* email & password inputs, etc. */}
)}
);
};export default Login;
```### `check`
`check` is a utility function that returns a `Promise` which resolves with `true` if the user for the current session token has the specified `relation` on the specified `object` and returns `false` otherwise. Use it for fine-grained conditional rendering or for specific logic within components.
Using `check` through the `useWarrant` hook:
```jsx
import React, { useEffect } from "react";
import { useWarrant } from "@warrantdev/react-warrant-js";const MyComponent = () => {
const { check } = useWarrant();useEffect(() => {
const fetchProtectedInfo = async () => {
// Only fetch protected info from server if
// user can "view" the info object "protected_info".
const userIsAuthorized = await check({
object: {
objectType: "info",
objectId: "protected_info",
},
relation: "viewer",
});
if (userIsAuthorized) {
// request protected info from server
}
};fetchProtectedInfo();
});return (
{protectedInfo && {protectedInfo}}
);
};export default MyComponent;
```Or using the React Context API:
```jsx
import React, { useEffect } from "react";
import { WarrantContext } from "@warrantdev/react-warrant-js";class MyComponent extends React.Component {
async componentDidMount() {
const { check } = this.context;// Only fetch protected info from server if
// user can "view" the info object "protected_info".
const userIsAuthorized = await check({
object: {
objectType: "info",
objectId: "protected_info",
},
relation: "viewer",
});
if (userIsAuthorized) {
await fetchProtectedInfo();
}
}async fetchProtectedInfo() {
// request protected info from server
}render() {
return (
{protectedInfo && {protectedInfo}}
);
}
}MyComponent.contextType = WarrantContext;
export default MyComponent;
```### `checkMany`
`checkMany` is a utility function that returns a `Promise` which resolves with `true` if the user for the current session token has _all of_ or _any of_ (based on a specified `op`) a set of specified `warrants` and returns `false` otherwise.
```jsx
import { CheckOp } from "@warrantdev/warrant-js";const { checkMany } = useWarrant();
// userIsAuthorized will only be true if the user is
// a member of tenant-A AND has permission view-protected-info
const userIsAuthorized = await checkMany({
op: CheckOp.AllOf,
warrants: [
{
object: {
objectType: "tenant",
objectId: "tenant-A",
},
relation: "member",
},
{
object: {
objectType: "permission",
objectId: "view-protected-info",
},
relation: "member",
},
],
});
```### `hasPermission`
`hasPermission` is a utility function that returns a `Promise` which resolves with `true` if the user for the current session token has the specified `permissionId` and returns `false` otherwise.
```jsx
import { CheckOp } from "@warrantdev/warrant-js";const { hasPermission } = useWarrant();
// userHasPermission will only be true if the user
// has the permission view-protected-info
const userHasPermission = await hasPermission({
permissionId: "view-protected-info",
});
```### `hasFeature`
`hasFeature` is a utility function that returns a `Promise` which resolves with `true` if the user for the current session token has the specified `featureId` and returns `false` otherwise.
```jsx
import { CheckOp } from "@warrantdev/warrant-js";const { hasFeature } = useWarrant();
// userHasFeature will only be true if the user
// has the feature protected-info
const userHasFeature = await hasFeature({
featureId: "protected-info",
});
```### `ProtectedComponent`
`ProtectedComponent` is a utility component you can wrap around markup or components that should only be accessible to users with certain privileges. It only renders the components it wraps if the user has the given warrants.
```jsx
import React from "react";
import { ProtectedComponent } from "@warrantdev/react-warrant-js";const MyComponent = () => {
return (
{/* hides MyProtectedComponent unless the user can "view" myObject with id object.id */}
);
};export default MyComponent;
```### `PermissionProtectedComponent`
`PermissionProtectedComponent` is a utility component you can wrap around markup or components that should only be accessible to users with certain privileges. It only renders the components it wraps if the user has the given permission.
```jsx
import React from "react";
import { PermissionProtectedComponent } from "@warrantdev/react-warrant-js";const MyComponent = () => {
return (
{/* hides MyProtectedComponent unless the user has permission "view-protected-info" */}
);
};export default MyComponent;
```### `FeatureProtectedComponent`
`FeatureProtectedComponent` is a utility component you can wrap around markup or components that should only be accessible to users with certain privileges. It only renders the components it wraps if the user has the given feature.
```jsx
import React from "react";
import { FeatureProtectedComponent } from "@warrantdev/react-warrant-js";const MyComponent = () => {
return (
{/* hides MyProtectedComponent unless the user has feature "protected-info" */}
);
};export default MyComponent;
```### `withWarrantCheck`
Use the `withWarrantCheck` Higher Order Component (HOC) to protect components that should only be accessible to users with certain privileges.
#### **Protecting Routes**
NOTE: This example uses `react-router` but you can use any routing library.
```jsx
// App.jsx
import React from "react";
import { Router, Route, Switch } from "react-router-dom";
import { createBrowserHistory } from "history";
import { WarrantProvider, withWarrantCheck } from "@warrantdev/react-warrant-js";
import PublicPage from "./PublicPage";
import ProtectedPage from "./ProtectedPage";const history = createBrowserHistory();
const App = () => {
return
{/*
Only render ProtectedPage if the user
can "view" the route "protected_route".
*/}
;
};export default App;
```#### **Protecting Components**
```jsx
import React from "react";
import { withWarrantCheck } from "@warrantdev/react-warrant-js";const MySecretComponent = () => {
returnSuper secret text;
};// Only render MySecretComponent if the user
// can "view" the component "MySecretComponent".
export default withWarrantCheck(MySecretComponent, {
warrants: [
{
object: {
objectType: "component",
objectId: "MySecretComponent",
},
relation: "view",
},
],
redirectTo: "/",
});
```### `withPermissionCheck`
Use the `withPermissionCheck` Higher Order Component (HOC) to protect components that should only be accessible to users with a certain permission.
#### **Protecting Routes**
NOTE: This example uses `react-router` but you can use any routing library.
```jsx
// App.jsx
import React from "react";
import { Router, Route, Switch } from "react-router-dom";
import { createBrowserHistory } from "history";
import { WarrantProvider, withPermissionCheck } from "@warrantdev/react-warrant-js";
import PublicPage from "./PublicPage";
import ProtectedPage from "./ProtectedPage";const history = createBrowserHistory();
const App = () => {
return
{/*
Only render ProtectedPage if the user
has the "view-protected-route" permission.
*/}
;
};export default App;
```#### **Protecting Components**
```jsx
import React from "react";
import { withPermissionCheck } from "@warrantdev/react-warrant-js";const MySecretComponent = () => {
returnSuper secret text;
};// Only render MySecretComponent if the user
// has the "view-protected-route" permission.
export default withPermissionCheck(MySecretComponent, {
permissionId: "view-protected-route",
redirectTo: "/",
});
```### `withFeatureCheck`
Use the `withFeatureCheck` Higher Order Component (HOC) to protect components that should only be accessible to users with a certain feature.
#### **Protecting Routes**
NOTE: This example uses `react-router` but you can use any routing library.
```jsx
// App.jsx
import React from "react";
import { Router, Route, Switch } from "react-router-dom";
import { createBrowserHistory } from "history";
import { WarrantProvider, withFeatureCheck } from "@warrantdev/react-warrant-js";
import PublicPage from "./PublicPage";
import ProtectedPage from "./ProtectedPage";const history = createBrowserHistory();
const App = () => {
return
{/*
Only render ProtectedPage if the user
has the "protected-route" feature.
*/}
;
};export default App;
```#### **Protecting Components**
```jsx
import React from "react";
import { withFeatureCheck } from "@warrantdev/react-warrant-js";const MySecretComponent = () => {
returnSuper secret text;
};// Only render MySecretComponent if the user
// has the "protected-route" feature.
export default withFeatureCheck(MySecretComponent, {
featureId: "protected-route",
redirectTo: "/",
});
```## Notes
We’ve used a random Client Key in these code examples. Be sure to replace it with your
[actual Client Key](https://app.warrant.dev) to
test this code through your own Warrant account.For more information on how to use the Warrant API, please refer to the
[Warrant API reference](https://docs.warrant.dev).## TypeScript support
This package includes TypeScript declarations for Warrant.
Note that we may release new [minor and patch](https://semver.org/) versions of
`@warrantdev/react-warrant-js` with small but backwards-incompatible fixes to the type
declarations. These changes will not affect Warrant itself.## Warrant Documentation
- [Warrant Docs](https://docs.warrant.dev/)