Skip to content

Commit

Permalink
feat: add permissions to Auth provider values, add a few more deps in
Browse files Browse the repository at this point in the history
Toolbox effect's deps array
  • Loading branch information
mkarajohn committed Mar 13, 2024
1 parent f51b2a1 commit 8e0256b
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 36 deletions.
17 changes: 17 additions & 0 deletions documentation/docs/api/Types/GetAccessTokenSilently.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
id: 'GetAccessTokenSilently'
title: 'GetAccessTokenSilently'
sidebar_label: 'GetAccessTokenSilently'
sidebar_position: 1
---
import Type from '../_type-definitions/GetAccessTokenSilently.md';


```ts
import { type GetAccessTokenSilently } from '@orfium/toolbox';
```

### Definition

<Type />

17 changes: 17 additions & 0 deletions documentation/docs/api/Types/Permissions.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
id: 'Permissions'
title: 'Permissions'
sidebar_label: 'Permissions'
sidebar_position: 1
---
import Type from '../_type-definitions/Permissions.md';


```ts
import { type Permissions } from '@orfium/toolbox';
```

### Definition

<Type />

23 changes: 11 additions & 12 deletions documentation/docs/api/_type-definitions/DecodedTokenResponse.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
| Name | Type |
| :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `iss?` | `string` |
| `sub?` | `string` |
| `aud?` | `string[]` |
| `iat?` | `number` |
| `exp?` | `number` |
| `azp?` | `string` |
| `scope?` | `string` |
| `org_id?` | `string` (_the organization id of the user currently selected_) |
| `permissions?` | `string[]` (_the permissions defined on the user for more info visit https://orfium.atlassian.net/wiki/spaces/OPS/pages/2554134739/Roles+and+Permissions#Organization-Roles_) |

| Name | Type | Info |
| :------------- | :------------------------------------------- |:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `iss?` | `string` | |
| `sub?` | `string` | |
| `aud?` | `string[]` | |
| `iat?` | `number` | |
| `exp?` | `number` | |
| `azp?` | `string` | |
| `scope?` | `string` | |
| `org_id?` | `string` | The organization id of the user currently selected |
| `permissions?` | [`Permissions`](/docs/api/Types/Permissions) | The permissions defined on the user. For more info visit [this page](https://orfium.atlassian.net/wiki/spaces/OPS/pages/2554134739/Roles+and+Permissions#Organization-Roles) |
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<pre>(opts?: GetTokenSilentlyOptions) => Promise\<<br/> void &#124; <br/> \{ <br/> decodedToken: [DecodedTokenResponse](/docs/api/Types/DecodedTokenResponse) &#124; Record\<string, never\>; <br/> token: string; <br/> \}<br/>\></pre>
1 change: 1 addition & 0 deletions documentation/docs/api/_type-definitions/Permissions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
`string[]`
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
| Name | Type |
| :----------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `isAuthenticated` | `boolean` |
| `isLoading` | `boolean` |
| `user` | <code>[User](/docs/api/Types/User) &#124; undefined</code> |
| `getAccessTokenSilently` | <pre>(opts?: GetTokenSilentlyOptions) => Promise\<<br/> void &#124; <br/> \{ <br/> decodedToken: [DecodedTokenResponse](/docs/api/Types/DecodedTokenResponse) &#124; Record\<string, never\>; <br/> token: string; <br/> \}<br/>\></pre> |
| `loginWithRedirect` | <code>(o?: RedirectLoginOptions\<any\>) => Promise\<void\></code> |
| `logout` | `() => void` |
| Name | Type |
| :----------------------- |:------------------------------------------------------------------|
| `isAuthenticated` | `boolean` |
| `isLoading` | `boolean` |
| `permissions` | [`Permissions`](/docs/api/Types/Permissions) |
| `user` | <code>[User](/docs/api/Types/User) &#124; undefined</code> |
| `getAccessTokenSilently` | [`GetAccessTokenSilently`](/docs/api/Types/GetAccessTokenSilently) |
| `loginWithRedirect` | <code>(o?: RedirectLoginOptions\<any\>) => Promise\<void\></code> |
| `logout` | `() => void` |
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[`Product`](../Types/Product)`[] | null`
<code>[Product](/docs/api/Types/Product)[] | null</code>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
| Name | Type |
| :--------------------- | :--------------------------------------------------------------- |
| `organizations` | <code>[Organization](../Types/Organization)[]</code> |
| `selectedOrganization` | <code>[Organization](../Types/Organization)[] &#124; null</code> |
| `switchOrganization` | `(organisation: string) => void` |
| Name | Type |
| :--------------------- | :------------------------------------------------------------- |
| `organizations` | <code>[Organization](../Types/Organization)[]</code> |
| `selectedOrganization` | <code>[Organization](../Types/Organization) &#124; null</code> |
| `switchOrganization` | `(organisation: string) => void` |
18 changes: 12 additions & 6 deletions src/contexts/authentication.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { type GetTokenSilentlyOptions, type RedirectLoginOptions } from '@auth0/auth0-spa-js';
import { createContext } from 'react';

export type Permissions = string[];

export type DecodedTokenResponse = {
iss?: string;
sub?: string;
Expand All @@ -12,7 +14,7 @@ export type DecodedTokenResponse = {
/** the organization id of the user currently selected **/
org_id?: string;
/** the permissions defined on the user for more info visit https://orfium.atlassian.net/wiki/spaces/OPS/pages/2554134739/Roles+and+Permissions#Organization-Roles **/
permissions?: string[];
permissions?: Permissions;
};

export type User = {
Expand All @@ -39,16 +41,19 @@ export type User = {
[key: string]: any;
};

export type GetAccessTokenSilently = (opts?: GetTokenSilentlyOptions) => Promise<{
token: string;
decodedToken: DecodedTokenResponse | Record<string, never>;
} | void>;

export type AuthenticationContextValue = {
isAuthenticated: boolean;
isLoading: boolean;
loginWithRedirect(o?: RedirectLoginOptions): Promise<void>;
logout: (props?: { force?: boolean }) => void;
getAccessTokenSilently: (opts?: GetTokenSilentlyOptions) => Promise<{
token: string;
decodedToken: DecodedTokenResponse | Record<string, never>;
} | void>;
logout: () => void;
getAccessTokenSilently: GetAccessTokenSilently;
user: User | undefined;
permissions: Permissions;
};

export const defaultAuthenticationContextValues: AuthenticationContextValue = {
Expand All @@ -58,6 +63,7 @@ export const defaultAuthenticationContextValues: AuthenticationContextValue = {
loginWithRedirect: () => Promise.resolve(),
logout: () => Promise.resolve('logged out'),
getAccessTokenSilently: () => Promise.resolve({ token: '', decodedToken: {} }),
permissions: [],
};

export const AuthenticationContext = createContext<AuthenticationContextValue>(
Expand Down
7 changes: 6 additions & 1 deletion src/contexts/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
export { type DecodedTokenResponse, type User } from './authentication';
export {
type DecodedTokenResponse,
type GetAccessTokenSilently,
type Permissions,
type User,
} from './authentication';
export { type Product } from './orfium-products';
15 changes: 12 additions & 3 deletions src/providers/Authentication.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import {
} from '@auth0/auth0-spa-js';
import { useCallback, useEffect, useState, type ReactNode } from 'react';
import { useErrorHandler } from 'react-error-boundary';
import { AuthenticationContext } from '../contexts/authentication';
import {
AuthenticationContext,
type GetAccessTokenSilently,
type Permissions,
} from '../contexts/authentication';
import { _useOrganizations } from '../hooks/useOrganizations';
import { getAuth0Client, getTokenSilently, logoutAuth, onRedirectCallback } from '../utils/auth';

Expand All @@ -17,6 +21,7 @@ export function Authentication({ children }: AuthenticationProps) {
const [user, setUser] = useState<Record<string, unknown>>();
const [auth0Client, setAuth0Client] = useState<Auth0Client>();
const [isLoading, setIsLoading] = useState(true);
const [permissions, setPermissions] = useState<Permissions>([]);

// handleError is referentially stable, so it's safe to use as a dep in dep array
// https://github.com/bvaughn/react-error-boundary/blob/v3.1.4/src/index.tsx#L165C10-L165C18
Expand All @@ -39,7 +44,7 @@ export function Authentication({ children }: AuthenticationProps) {
[handleError]
);

const getAccessTokenSilently = useCallback(
const getAccessTokenSilently: GetAccessTokenSilently = useCallback(
async (opts?: GetTokenSilentlyOptions) => {
try {
const result = await getTokenSilently(opts);
Expand Down Expand Up @@ -84,6 +89,9 @@ export function Authentication({ children }: AuthenticationProps) {
if (clientIsAuthenticated) {
const clientUser = await client.getUser();
setUser(clientUser);

const decodedTokenResponse = await getAccessTokenSilently();
setPermissions(decodedTokenResponse?.decodedToken.permissions || []);
}

setIsLoading(false);
Expand All @@ -102,7 +110,7 @@ export function Authentication({ children }: AuthenticationProps) {
handleError(error);
}
})();
}, [handleError, invitation, loginWithRedirect, organization]);
}, [getAccessTokenSilently, handleError, invitation, loginWithRedirect, organization]);

useEffect(() => {
if (!isLoading && !isAuthenticated) {
Expand Down Expand Up @@ -142,6 +150,7 @@ export function Authentication({ children }: AuthenticationProps) {
logout: logoutAuth,
getAccessTokenSilently: (opts?: GetTokenSilentlyOptions) => getAccessTokenSilently(opts),
user,
permissions,
}}
>
{children}
Expand Down

0 comments on commit 8e0256b

Please sign in to comment.