Skip to content

Commit

Permalink
feat: Add @cerbos/react package (#876)
Browse files Browse the repository at this point in the history
* @cerbos/react initial commit

Signed-off-by: Hasan Ayan <hasanayan@me.com>

* address PR comments

Signed-off-by: Hasan Ayan <hasanayan@me.com>

* move eslint-plugin-react-hooks to the react package deps

Signed-off-by: Hasan Ayan <hasanayan@me.com>

* remove unnecessary dependency

Signed-off-by: Hasan Ayan <hasanayan@me.com>

* docs improvements

Signed-off-by: Hasan Ayan <hasanayan@me.com>

* Optimise deep equality check and refactor `useCerbosRequest`

Signed-off-by: Andrew Haines <haines@cerbos.dev>
Signed-off-by: Hasan Ayan <hasanayan@me.com>

* Just add the dependency...

Signed-off-by: Andrew Haines <haines@cerbos.dev>
Signed-off-by: Hasan Ayan <hasanayan@me.com>

* improve docs

Signed-off-by: Hasan Ayan <hasanayan@me.com>

* add tests

Signed-off-by: Hasan Ayan <hasanayan@me.com>

* docs improvements

Signed-off-by: Hasan Ayan <hasanayan@me.com>

* resolve conflicts

Signed-off-by: Hasan Ayan <hasanayan@me.com>

* add changelog.yaml

Signed-off-by: Hasan Ayan <hasanayan@me.com>

* fix test env setup

Signed-off-by: Hasan Ayan <hasanayan@me.com>

* implement AbortSignal

Signed-off-by: Hasan Ayan <hasanayan@me.com>

* address PR comments

Signed-off-by: Hasan Ayan <hasanayan@me.com>

* regenerate docs

Signed-off-by: Hasan Ayan <hasanayan@me.com>

* bring back !aborted check in the then block

Signed-off-by: Hasan Ayan <hasanayan@me.com>

---------

Signed-off-by: Hasan Ayan <hasanayan@me.com>
Signed-off-by: Andrew Haines <haines@cerbos.dev>
Co-authored-by: Andrew Haines <haines@cerbos.dev>
  • Loading branch information
hasanayan and haines authored Mar 25, 2024
1 parent 6833784 commit 9f44179
Show file tree
Hide file tree
Showing 32 changed files with 2,566 additions and 9 deletions.
1 change: 0 additions & 1 deletion .eslintrc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ rules:
- devDependencies:
- private/**
optionalDependencies: false
peerDependencies: false
includeTypes: true
import/no-named-as-default: warn
import/order:
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ The [@cerbos/embedded](/packages/embedded/README.md) package provides a client (

All clients extend the base [`Client`](/docs/core.client.md) class from [@cerbos/core](/packages/core/README.md), so they can be used interchangeably in isomorphic applications.

In React applications, you can use the [@cerbos/react](/packages/react/README.md) package to use an [`HTTP`](/docs/http.http.md) or [`Embedded`](/docs/embedded.embedded.md) client in your components via hooks.

To instrument the clients with [OpenTelemetry](http://opentelemetry.io), use the [@cerbos/opentelemetry](/packages/opentelemetry/README.md) package.

To load Cerbos policies from YAML or JSON files, use the [@cerbos/files](/packages/files/README.md) package.
Expand Down
11 changes: 11 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,16 @@ Client library for interacting with the Cerbos policy decision point service ove
OpenTelemetry instrumentation for the [gRPC](./grpc.md) and [HTTP](./http.md) client libraries.


</td></tr>
<tr><td>

[@cerbos/react](./react.md)


</td><td>

A collection of React hooks for interacting with Cerbos policy decision points.


</td></tr>
</tbody></table>
25 changes: 25 additions & 0 deletions docs/react.asyncresult.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@cerbos/react](./react.md) &gt; [AsyncResult](./react.asyncresult.md)

## AsyncResult type

The result of calling an async method on a client.

**Signature:**

```typescript
export type AsyncResult<T> = {
isLoading: true;
data: undefined;
error: undefined;
} | {
isLoading: false;
data: T;
error: undefined;
} | {
isLoading: false;
data: undefined;
error: Error;
};
```
98 changes: 98 additions & 0 deletions docs/react.cerbosprovider.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@cerbos/react](./react.md) &gt; [CerbosProvider](./react.cerbosprovider.md)

## CerbosProvider() function

A component to provide a Cerbos client to your application's components.

**Signature:**

```typescript
export declare function CerbosProvider({ children, client, principal, auxData, }: CerbosProviderProps): ReactElement;
```

## Parameters

<table><thead><tr><th>

Parameter


</th><th>

Type


</th><th>

Description


</th></tr></thead>
<tbody><tr><td>

{ children, client, principal, auxData, }


</td><td>

[CerbosProviderProps](./react.cerbosproviderprops.md)


</td><td>


</td></tr>
</tbody></table>
**Returns:**

ReactElement

## Remarks

The provider should be placed close to the root of your application.

You need to provide a principal, but it can describe an anonymous user so that you can perform permission checks for unauthenticated users. You could use a single hardcoded ID for all anonymous users, or store a unique identifier in the session.

You can use whichever of the [HTTP](https://github.com/cerbos/cerbos-sdk-javascript/blob/main/packages/http/README.md) or [embedded](https://github.com/cerbos/cerbos-sdk-javascript/blob/main/packages/embedded/README.md) client libraries best fit your needs.

## Example


```typescript
import { Embedded as Cerbos } from "@cerbos/embedded";
* // or, import { HTTP as Cerbos } from "@cerbos/http";
import { CerbosProvider } from "@cerbos/react";

// Initialize the Cerbos client using any of the client libraries
// that fit the needs of your application. In this example we are
// using the client from `@cerbos/embedded`.
const client = new Cerbos();

function MyApp({ children }) {
const user = useYourAuthenticationLogic(...);

return (
<CerbosProvider
client={client}
principal={
user
? {
id: user.id,
roles: user.roles,
}
: {
// Define an arbitrary ID for unauthenticated users.
id: "###ANONYMOUS_USER###",
// Define a role that represents unauthenticated users (at least one is required).
roles: ["anonymous"],
}
}
>
{children}
</CerbosProvider>
);
}
```

18 changes: 18 additions & 0 deletions docs/react.cerbosproviderprops.auxdata.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@cerbos/react](./react.md) &gt; [CerbosProviderProps](./react.cerbosproviderprops.md) &gt; [auxData](./react.cerbosproviderprops.auxdata.md)

## CerbosProviderProps.auxData property

Auxiliary data related to the principal.

**Signature:**

```typescript
auxData?: Pick<AuxData, "jwt"> | undefined;
```

## Remarks

You can read claims directly from a JWT in your authorization policies by configuring [the Cerbos policy decision point (PDP) service](https://docs.cerbos.dev/cerbos/latest/configuration/auxdata.html) or [an embedded PDP client](https://github.com/cerbos/cerbos-sdk-javascript/blob/main/docs/embedded.options.md) to decode the token.

13 changes: 13 additions & 0 deletions docs/react.cerbosproviderprops.children.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@cerbos/react](./react.md) &gt; [CerbosProviderProps](./react.cerbosproviderprops.md) &gt; [children](./react.cerbosproviderprops.children.md)

## CerbosProviderProps.children property

Your application's component tree.

**Signature:**

```typescript
children: ReactNode;
```
13 changes: 13 additions & 0 deletions docs/react.cerbosproviderprops.client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@cerbos/react](./react.md) &gt; [CerbosProviderProps](./react.cerbosproviderprops.md) &gt; [client](./react.cerbosproviderprops.client.md)

## CerbosProviderProps.client property

The Cerbos client to provide.

**Signature:**

```typescript
client: Client;
```
114 changes: 114 additions & 0 deletions docs/react.cerbosproviderprops.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@cerbos/react](./react.md) &gt; [CerbosProviderProps](./react.cerbosproviderprops.md)

## CerbosProviderProps interface

Props for the [CerbosProvider()](./react.cerbosprovider.md) component.

**Signature:**

```typescript
export interface CerbosProviderProps
```

## Properties

<table><thead><tr><th>

Property


</th><th>

Modifiers


</th><th>

Type


</th><th>

Description


</th></tr></thead>
<tbody><tr><td>

[auxData?](./react.cerbosproviderprops.auxdata.md)


</td><td>


</td><td>

Pick&lt;[AuxData](./core.auxdata.md)<!-- -->, "jwt"&gt; \| undefined


</td><td>

_(Optional)_ Auxiliary data related to the principal.


</td></tr>
<tr><td>

[children](./react.cerbosproviderprops.children.md)


</td><td>


</td><td>

ReactNode


</td><td>

Your application's component tree.


</td></tr>
<tr><td>

[client](./react.cerbosproviderprops.client.md)


</td><td>


</td><td>

[Client](./core.client.md)


</td><td>

The Cerbos client to provide.


</td></tr>
<tr><td>

[principal](./react.cerbosproviderprops.principal.md)


</td><td>


</td><td>

[Principal](./core.principal.md)


</td><td>

The principal to check.


</td></tr>
</tbody></table>
18 changes: 18 additions & 0 deletions docs/react.cerbosproviderprops.principal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@cerbos/react](./react.md) &gt; [CerbosProviderProps](./react.cerbosproviderprops.md) &gt; [principal](./react.cerbosproviderprops.principal.md)

## CerbosProviderProps.principal property

The principal to check.

**Signature:**

```typescript
principal: Principal;
```

## Remarks

This is required, but can describe an anonymous user so that you can perform permission checks for unauthenticated users.

Loading

0 comments on commit 9f44179

Please sign in to comment.