Skip to content

Commit 9b812a8

Browse files
committed
update security (end)
1 parent 1c98b3d commit 9b812a8

File tree

12 files changed

+94
-130
lines changed

12 files changed

+94
-130
lines changed

docs_headless/src/content/docs/security/AuthProviderList.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ title: "Supported Auth Provider Backends"
66
It's very common that your auth logic is so specific that you'll need to write your own `authProvider`. However, the community has built a few open-source Auth Providers that may fit your need:
77

88
<div class="providers-list" markdown="1">
9+
910
- ![Appwrite Logo](../img/backend-logos/appwrite.svg "Appwrite Logo")**[Appwrite](https://appwrite.io/)**: [marmelab/ra-appwrite](https://github.com/marmelab/ra-appwrite)
1011
- ![auth0 Logo](../img/backend-logos/auth0.svg "auth0 Logo")**[Auth0 by Okta](https://auth0.com/)**: [marmelab/ra-auth-auth0](https://github.com/marmelab/ra-auth-auth0/blob/main/packages/ra-auth-auth0/Readme.md)
1112
- ![amplify Logo](../img/backend-logos/amplify.svg "amplify Logo")**[AWS Amplify](https://docs.amplify.aws)**: [MrHertal/react-admin-amplify](https://github.com/MrHertal/react-admin-amplify)
@@ -18,13 +19,16 @@ It's very common that your auth logic is so specific that you'll need to write y
1819
- ![keycloak Logo](../img/backend-logos/keycloak.svg "keycloak Logo")**[Keycloak](https://www.keycloak.org/)**: [marmelab/ra-keycloak](https://github.com/marmelab/ra-keycloak/blob/main/packages/ra-keycloak/Readme.md)
1920
- ![supabase Logo](../img/backend-logos/supabase.svg "supabase Logo")**[Supabase](https://supabase.io/)**: [marmelab/ra-supabase](https://github.com/marmelab/ra-supabase/blob/main/packages/ra-supabase/README.md)
2021
- ![surrealdb Logo](../img/backend-logos/surrealdb.svg "surrealdb Logo")**[SurrealDB](https://surrealdb.com/)**: [djedi23/ra-surrealdb](https://github.com/djedi23/ra-surrealdb)
22+
2123
</div>
2224

2325
Beyond ready-to-use providers, you may find help in these third-party tutorials about integrating more authentication backends:
2426

2527
<div class="providers-list" markdown="1">
28+
2629
- ![loopback Logo](../img/backend-logos/loopback4.svg "loopback Logo")**[Loopback](https://loopback.io/doc/en/lb4/Authentication-overview.html)**: [appsmith dev.to tutorial](https://dev.to/appsmith/building-an-admin-dashboard-with-react-admin-86i#adding-authentication-to-reactadmin)
2730
- ![openid Logo](../img/backend-logos/openid.svg "openid Logo")**[OpenID Connect (OIDC)](https://openid.net/connect/)**: [marmelab/ra-example-oauth](https://github.com/marmelab/ra-example-oauth)
31+
2832
</div>
2933

3034
If you have released a reusable `authProvider`, or a tutorial for another auth backend, please open a PR to add it to this list!

docs_headless/src/content/docs/security/AuthProviderWriting.md

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -446,9 +446,6 @@ const authProvider = {
446446

447447
Check the [Access Control documentation](./Permissions.md#access-control) for more information on how to use the `canAccess` method.
448448

449-
**Tip**: [The Role-Based Access Control (RBAC) module](./AuthRBAC.md) allows fined-grained permissions in react-admin apps leveraging the `canAccess` method. Check [the RBAC documentation](./AuthRBAC.md) for more information.
450-
451-
452449
### `getPermissions`
453450

454451
As an alternative to `canAccess()`, `getPermissions()` lets you return an arbitrary permissions object. This object can be used by React components to enable or disable UI elements based on the user's role.
@@ -490,12 +487,12 @@ React-admin calls the `authProvider` methods with the following params:
490487

491488
| Method | Resolve if | Response format |
492489
| ---------------- | ----------------------------------- | --------------- |
493-
| `login` | Login credentials were accepted | `void | { redirectTo?: string | boolean }` route to redirect to after login |
490+
| `login` | Login credentials were accepted | `void \| { redirectTo?: string \| boolean }` route to redirect to after login |
494491
| `checkError` | Error is not an auth error | `void` |
495492
| `checkAuth` | User is authenticated | `void` |
496-
| `logout` | Auth backend acknowledged logout | `string | false | void` route to redirect to after logout, defaults to `/login` |
497-
| `getIdentity` | Auth backend returned identity | `{ id: string | number, fullName?: string, avatar?: string }` |
498-
| `handleCallback` | User is authenticated | `void | { redirectTo?: string | boolean }` route to redirect to after login |
493+
| `logout` | Auth backend acknowledged logout | `string \| false \| void` route to redirect to after logout, defaults to `/login` |
494+
| `getIdentity` | Auth backend returned identity | `{ id: string \| number, fullName?: string, avatar?: string }` |
495+
| `handleCallback` | User is authenticated | `void \| { redirectTo?: string \| boolean }` route to redirect to after login |
499496
| `canAccess` | Auth backend returned authorization | `boolean` |
500497
| `getPermissions` | Auth backend returned permissions | Free format. |
501498

@@ -505,12 +502,12 @@ When the auth backend returns an error, the Auth Provider should return a reject
505502

506503
| Method | Reject if | Error format |
507504
| ---------------- | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
508-
| `login` | Login credentials weren't accepted | `string | { message?: string }` error message to display |
509-
| `checkError` | Error is an auth error | `void | { redirectTo?: string, message?: string | boolean }` route to redirect to after logout, message to notify the user or `false` to disable notification |
510-
| `checkAuth` | User is not authenticated | `void | { redirectTo?: string, message?: string }` route to redirect to after logout, message to notify the user |
505+
| `login` | Login credentials weren't accepted | `string \| { message?: string }` error message to display |
506+
| `checkError` | Error is an auth error | `void \| { redirectTo?: string, message?: string \| boolean }` route to redirect to after logout, message to notify the user or `false` to disable notification |
507+
| `checkAuth` | User is not authenticated | `void \| { redirectTo?: string, message?: string }` route to redirect to after logout, message to notify the user |
511508
| `logout` | Auth backend failed to log the user out | `void` |
512509
| `getIdentity` | Auth backend failed to return identity | `Object` free format - returned as `error` when `useGetIdentity()` is called |
513-
| `handleCallback` | Failed to authenticate users after redirection | `void | { redirectTo?: string, logoutOnFailure?: boolean, message?: string }` |
510+
| `handleCallback` | Failed to authenticate users after redirection | `void \| { redirectTo?: string, logoutOnFailure?: boolean, message?: string }` |
514511
| `canAccess` | Auth backend failed to return authorization | `Object` free format - returned as `error` when `useCanAccess()` is called. |
515512
| `getPermissions` | Auth backend failed to return permissions | `Object` free format - returned as `error` when `usePermissions()` is called. The error will be passed to `checkError` |
516513

docs_headless/src/content/docs/security/Authentication.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ const App = () => (
226226

227227
## Adding A Login Page
228228

229-
You can add a login page by setting the [`<CoreAdmin loginPage>`](./CoreAdmin.md#loginpage) prop.
229+
You can add a login page by setting the [`<CoreAdmin loginPage>`](../app-configuration/CoreAdmin.md#loginpage) prop.
230230

231231
For headless applications, you should build custom login pages using the [`useLogin` hook](./useLogin.md) to handle the login form submission. Here's an example:
232232

@@ -378,7 +378,7 @@ export const authProvider = {
378378
};
379379
```
380380
381-
You can choose when to redirect users to the third-party authentication service, such as directly in the `AuthProvider.checkAuth()` method or when they click a button on a [custom login page](#customizing-the-login-component).
381+
You can choose when to redirect users to the third-party authentication service, such as directly in the `AuthProvider.checkAuth()` method or when they click a button on a [custom login page](#adding-a-login-page).
382382
383383
## Handling Refresh Tokens
384384

docs_headless/src/content/docs/security/useAuthProvider.md

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
---
2-
layout: default
32
title: "useAuthProvider"
43
---
54

6-
# `useAuthProvider`
7-
8-
React-admin stores the `authProvider` object in a React context, so it's available from anywhere in your application code. The `useAuthProvider` hook reads this context to let you call the `authProvider` directly.
5+
Ra-core stores the `authProvider` object in a React context, so it's available from anywhere in your application code. The `useAuthProvider` hook reads this context to let you call the `authProvider` directly.
96

107
## Usage
118

129
For instance, here is how to call the Auth Provider to get the identity of the current logged-in user:
1310

1411
```jsx
1512
import { useState, useEffect } from 'react';
16-
import { useAuthProvider } from 'react-admin';
13+
import { useAuthProvider } from 'ra-core';
1714

1815
import { Loading, Error } from './MyComponents';
1916

@@ -46,7 +43,7 @@ But the recommended way to query the Data Provider is to use the authProvider me
4643

4744
```jsx
4845
import { useState, useEffect } from 'react';
49-
import { useGetIdentity } from 'react-admin';
46+
import { useGetIdentity } from 'ra-core';
5047

5148
import { Loading, Error } from './MyComponents';
5249

@@ -67,7 +64,7 @@ The `useAuthProvider` hook accepts a generic parameter for the `authProvider` ty
6764

6865
```tsx
6966
// In src/authProvider.ts
70-
import { AuthProvider } from 'react-admin';
67+
import { AuthProvider } from 'ra-core';
7168

7269
export interface CustomAuthProviderMethods extends AuthProvider {
7370
refreshToken: () => Promise<any>
@@ -81,7 +78,7 @@ export const authProvider: CustomAuthProviderMethods = {
8178
}
8279

8380
// In src/RefreshToken.tsx
84-
import { useAuthProvider } from 'react-admin';
81+
import { useAuthProvider } from 'ra-core';
8582
import { CustomAuthProviderMethods } from './src/authProvider';
8683

8784
const THIRTY_MINUTES = 1000 * 60 * 30;

docs_headless/src/content/docs/security/useAuthState.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
---
2-
layout: default
32
title: "useAuthState"
43
---
54

6-
# `useAuthState`
7-
85
If you want to check if the user is authenticated and decide what to render based on the result, use the `useAuthState` hook. It calls the `authProvider.checkAuth()` method on mount and returns a state object.
96

107
- Loading: `{ isPending: true }`
@@ -19,7 +16,8 @@ Contrary to [`useAuthenticated()`](./useAuthenticated.md), `useAuthState` does n
1916
Use `useAuthState()` to render different content depending on the authenticated state.
2017

2118
```jsx
22-
import { useAuthState, Loading } from 'react-admin';
19+
import { useAuthState } from 'ra-core';
20+
import { Loading } from './Loading';
2321

2422
const MyPage = () => {
2523
const { isPending, authenticated } = useAuthState();

docs_headless/src/content/docs/security/useAuthenticated.md

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
11
---
2-
layout: default
32
title: "useAuthenticated"
43
---
54

6-
# `useAuthenticated`
7-
85
This hook checks if the current user is authenticated by calling the [`authProvider.checkAuth()`](./AuthProviderWriting.md#checkauth) method on mount, and redirects to login if the method throws an error.
96

10-
React-admin uses this hook in page components (e.g., the `<Edit>` component) to forbid access to unauthenticated users.
7+
Ra-core uses this hook in page components (e.g., the `<EditBase>` component) to forbid access to unauthenticated users.
118

129
## Usage
1310

14-
If you add [custom pages](./Admin.md#adding-custom-pages), and you want to restrict access to authenticated users, use `useAuthenticated()` as follows:
11+
If you add [custom pages](../app-configuration/CoreAdmin.md#adding-custom-pages), and you want to restrict access to authenticated users, use `useAuthenticated()` as follows:
1512

1613
```tsx
1714
// in src/MyPage.js
18-
import { useAuthenticated } from 'react-admin';
15+
import { useAuthenticated } from 'ra-core';
1916

2017
const MyPage = () => {
2118
const { isPending } = useAuthenticated(); // redirects to login if not authenticated
@@ -63,7 +60,7 @@ The [`<Authenticated>`](./Authenticated.md) component wraps the `useAuthenticate
6360
It is useful when you can't use hooks, for instance because of the rules of hooks.
6461

6562
```jsx
66-
import { Authenticated } from 'react-admin';
63+
import { Authenticated } from 'ra-core';
6764

6865
const MyAuthenticatedPage = () => (
6966
<Authenticated>

docs_headless/src/content/docs/security/useCanAccess.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
---
2-
layout: default
32
title: "useCanAccess"
43
storybook_path: ra-core-auth-usecanaccess--basic
54
---
65

7-
# `useCanAccess`
8-
96
This hook controls access to a resource and action (and, optionally, a record). It calls the `authProvider.canAccess()` method on mount and returns an object containing a `canAccess` boolean set to `true` if users can access the resource and action.
107

11-
It is part of the [Access Control](./Permissions.md#access-control) mechanism in react-admin.
8+
It is part of the [Access Control](./Permissions.md#access-control) mechanism in ra-core.
129

1310
## Usage
1411

1512
`useCanAccess` takes an object `{ action, resource, record }` as argument. It returns an object describing the state of the request. As calls to the `authProvider` are asynchronous, the hook returns a `isPending` state in addition to the `canAccess` key.
1613

1714
```jsx
18-
import { useCanAccess, useRecordContext, DeleteButton } from 'react-admin';
15+
import { useCanAccess, useRecordContext } from 'ra-core';
16+
import { DeleteButton } from './DeleteButton';
1917

2018
const DeleteUserButton = () => {
2119
const record = useRecordContext();
@@ -47,7 +45,8 @@ const DeleteUserButton = () => {
4745
The `checkAccess` function expects an argument with the shape `{ action, resource, record }`. This function resolves to a boolean indicating whether users can access the provided resource and action.
4846

4947
```jsx
50-
import { DataTable, List, useCanAccessCallback } from 'react-admin';
48+
import { useCanAccessCallback, ListBase } from 'ra-core';
49+
import { DataTable } from './DataTable';
5150

5251
export const UserList = () => {
5352
const checkAccess = useCanAccessCallback();
@@ -60,13 +59,13 @@ export const UserList = () => {
6059
}
6160
};
6261
return (
63-
<List>
62+
<ListBase>
6463
<DataTable onClick={handleRowClick}>
6564
<DataTable.Col source="id" />
6665
<DataTable.Col source="name" />
6766
<DataTable.Col source="email" />
6867
</DataTable>
69-
</List>
68+
</ListBase>
7069
);
7170
};
7271
```
@@ -78,11 +77,12 @@ export const UserList = () => {
7877
It takes an object `{ action, resources, record }` as argument. The `resources` parameter is an array of resource names for which to check the access permission. In addition to react-query result properties, it returns a `canAccess` object with a property for each provided resource, determining whether the user can access it.
7978

8079
```jsx
81-
import { useCanAccessResources, SimpleList } from 'react-admin';
80+
import { useCanAccessResources } from 'ra-core';
81+
import { SimpleList } from './SimpleList';
8282

8383
const UserList = () => {
8484
const { isPending, canAccess } = useCanAccessResources({
85-
action: 'delete',
85+
action: 'read',
8686
resources: ['users.id', 'users.name', 'users.email'],
8787
});
8888
if (isPending) {
@@ -102,10 +102,10 @@ const UserList = () => {
102102

103103
`useRequireAccess` is an alternative to `useCanAccess` that logs out the user if the access check fails. It takes the same parameters as `useCanAccess`.
104104

105-
For instance, here's how you can protect a [custom route](./CustomRoutes.md) for editing users settings:
105+
For instance, here's how you can protect a [custom route](../app-configuration/CustomRoutes.md) for editing users settings:
106106

107107
```tsx
108-
import { useRequireAccess } from 'react-admin';
108+
import { useRequireAccess } from 'ra-core';
109109

110110
export export const SettingsPage = () => {
111111
const { isPending } = useRequireAccess({

docs_headless/src/content/docs/security/useGetIdentity.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
---
2-
layout: default
32
title: "useGetIdentity"
43
storybook_path: ra-core-auth-usegetidentity--basic
54
---
65

7-
# `useGetIdentity`
8-
9-
React-admin calls `authProvider.getIdentity()` to retrieve and display the current logged-in username and avatar. The logic for calling this method is packaged into a custom hook, `useGetIdentity`, which you can use in your own code.
6+
Ra-core calls `authProvider.getIdentity()` to retrieve and display the current logged-in username and avatar. The logic for calling this method is packaged into a custom hook, `useGetIdentity`, which you can use in your own code.
107

118
![identity](../img/identity.png)
129

@@ -31,7 +28,7 @@ const { id, fullName, avatar } = data;
3128
Here is an example Edit component, which falls back to a Show component if the record is locked for edition by another user:
3229

3330
```jsx
34-
import { useGetIdentity, useGetOne } from 'react-admin';
31+
import { useGetIdentity, useGetOne } from 'ra-core';
3532

3633
const PostDetail = ({ id }) => {
3734
const { data: post, isPending: isPendingPost } = useGetOne('posts', { id });

docs_headless/src/content/docs/security/useLogin.md

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
---
2-
layout: default
32
title: "useLogin"
43
---
54

6-
# `useLogin`
7-
85
This hook returns a callback allowing to call `authProvider.login()`. It's used in Login forms.
96

107
## Usage
@@ -15,7 +12,7 @@ Here is how to build a custom Login page based on email rather than username:
1512
// in src/MyLoginPage.js
1613
import * as React from 'react';
1714
import { useState } from 'react';
18-
import { useLogin, useNotify, Notification } from 'react-admin';
15+
import { useLogin, useNotify } from 'ra-core';
1916

2017
const MyLoginPage = ({ theme }) => {
2118
const [email, setEmail] = useState('');
@@ -52,18 +49,18 @@ const MyLoginPage = ({ theme }) => {
5249
export default MyLoginPage;
5350
```
5451

55-
Then pass the custom Login form to `<Admin>`, as follows:
52+
Then pass the custom Login form to `<CoreAdmin>`, as follows:
5653

5754
```jsx
5855
// in src/App.js
5956
import * as React from "react";
60-
import { Admin } from 'react-admin';
57+
import { CoreAdmin } from 'ra-core';
6158

6259
import MyLoginPage from './MyLoginPage';
6360

6461
const App = () => (
65-
<Admin loginPage={MyLoginPage} authProvider={authProvider}>
62+
<CoreAdmin loginPage={MyLoginPage} authProvider={authProvider}>
6663
...
67-
</Admin>
64+
</CoreAdmin>
6865
);
6966
```

0 commit comments

Comments
 (0)