From e6f18cb958aa0b598fff2d5012178a753e2d73c1 Mon Sep 17 00:00:00 2001 From: Sakuk Date: Fri, 28 Jul 2023 17:12:44 +0000 Subject: [PATCH 01/13] initial test hook --- src/DirectusProvider.tsx | 50 +++++++++++++++++++++++++++++-- src/auth.tsx | 63 ++++++++++++++++++++++++++++++++++++++++ src/types.ts | 38 +++++++++++++++++++++++- 3 files changed, 147 insertions(+), 4 deletions(-) create mode 100644 src/auth.tsx diff --git a/src/DirectusProvider.tsx b/src/DirectusProvider.tsx index 92231cd8..58f7b1cc 100644 --- a/src/DirectusProvider.tsx +++ b/src/DirectusProvider.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; -import { Directus, TypeMap } from '@directus/sdk'; import { + AuthStates, DirectusAssetProps, DirectusContextType, DirectusContextTypeGeneric, @@ -9,6 +9,8 @@ import { DirectusProviderProps, } from '@/types'; +import { Directus, TypeMap, UserType } from '@directus/sdk'; + import { DirectusAsset } from '@components/DirectusAsset'; import { DirectusImage } from '@components/DirectusImage'; @@ -22,12 +24,18 @@ export const DirectusContext = React.createContext({ apiUrl, options, + autoLogin, children, }: DirectusProviderProps): JSX.Element => { + const [user, setUser] = React.useState(null); + const [authState, setAuthState] = React.useState('loading'); + + const directus = React.useMemo(() => new Directus(apiUrl, options), [apiUrl, options]); + const value = React.useMemo>( () => ({ apiUrl: apiUrl, - directus: new Directus(apiUrl, options), + directus: directus, DirectusAsset: ({ asset, render, ...props }: DirectusAssetProps) => { console.warn('Deprecated: Please import DirectusAsset directly from react-directus'); return ; @@ -36,10 +44,46 @@ export const DirectusProvider = ({ console.warn('Deprecated: Please import DirectusImage directly from react-directus'); return ; }, + _directusUser: user, + _setDirecctusUser: setUser, + _authState: authState, + _setAuthState: setAuthState, }), - [apiUrl, options] + [apiUrl, directus, user, authState] ); + React.useEffect(() => { + const checkAuth = async () => { + let newAuthState: AuthStates = 'unauthenticated'; + try { + await directus.auth.refresh(); + const token = await directus.auth.token; + + if (token) { + const dUser = (await directus.users.me.read({ + // * is a valid field, but typescript doesn't like it + // It's a wildcard, so it will return all fields + // This is the only way to get all fields + // eslint-disable-next-line @typescript-eslint/no-explicit-any + fields: ['*'] as any, + })) as UserType; + + if (dUser) { + newAuthState = 'authenticated'; + setUser(dUser); + } + } + } catch (error) { + console.log('auth-error', error); + } finally { + setAuthState(newAuthState || 'unauthenticated'); + } + }; + if (autoLogin) { + checkAuth(); + } + }, [directus, autoLogin]); + return {children}; }; diff --git a/src/auth.tsx b/src/auth.tsx new file mode 100644 index 00000000..2047940b --- /dev/null +++ b/src/auth.tsx @@ -0,0 +1,63 @@ +import { DirectusAuthHook } from './types'; +import { DirectusContext } from './DirectusProvider'; +import React from 'react'; +import { UserType } from '@directus/sdk'; + +export const useAuth = (): DirectusAuthHook => { + const directusContext = React.useContext(DirectusContext); + + if (!directusContext) { + throw new Error('useAuth has to be used within the DirectusProvider'); + } + + const { + directus, + _authState: authState, + _setAuthState: setAuthState, + _directusUser: directusUser, + _setDirecctusUser: setDirectusUser, + } = directusContext; + + const login = React.useCallback( + async (email: string, password: string) => { + await directus.auth.login({ + email, + password, + }); + + const dUser = (await directus.users.me.read({ + fields: ['*'], + })) as UserType; + + if (dUser) { + setDirectusUser(dUser); + setAuthState('authenticated'); + } else { + setDirectusUser(null); + setAuthState('unauthenticated'); + } + }, + [directus] + ); + + const logout = React.useCallback(async () => { + try { + await directus.auth.logout(); + } finally { + setAuthState('unauthenticated'); + setDirectusUser(null); + } + }, [directus]); + + const value = React.useMemo( + () => ({ + user: directusUser, + authState, + login, + logout, + }), + [directus, directusUser, authState] + ); + + return value; +}; diff --git a/src/types.ts b/src/types.ts index db2c382e..56015f43 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,5 @@ import * as React from 'react'; -import { DirectusOptions, IDirectus, TypeMap } from '@directus/sdk'; +import { DirectusOptions, IDirectus, TypeMap, UserType } from '@directus/sdk'; import { DirectusAsset } from '@components/DirectusAsset'; import { DirectusImage } from '@components/DirectusImage'; @@ -61,9 +61,16 @@ export interface DirectusProviderProps { apiUrl: string; /** A set of options to pass to the Directus client. */ options?: DirectusOptions; + /** + * If `true`, the provider will try to login the user automatically on mount. + * @default false + */ + autoLogin?: boolean; children: React.ReactNode; } +export type AuthStates = 'loading' | 'authenticated' | 'unauthenticated'; + /** * Shape of the main context. */ @@ -75,6 +82,35 @@ export interface DirectusContextType { DirectusAsset: typeof DirectusAsset; /** The context-aware `DirectusImage` component, with pre-filled props. */ DirectusImage: typeof DirectusImage; + /** + * @internal + */ + _authState: AuthStates; + /** + * @internal + */ + _setAuthState: React.Dispatch>; + /** + * @internal + */ + _directusUser: UserType | null; + /** + * @internal + */ + _setDirecctusUser: React.Dispatch>; } export type DirectusContextTypeGeneric = DirectusContextType | null; + +export interface DirectusAuthHook { + /** + * @throws + */ + login: (email: string, password: string) => Promise; + /** + * @throws + */ + logout: () => Promise; + authState: AuthStates; + user: UserType | null; +} From 61dac52630890e638a4274f1fd6b37f288916b8b Mon Sep 17 00:00:00 2001 From: Sakuk Date: Fri, 28 Jul 2023 17:16:33 +0000 Subject: [PATCH 02/13] Added TSDoc to types --- src/types.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/types.ts b/src/types.ts index 56015f43..108b3c96 100644 --- a/src/types.ts +++ b/src/types.ts @@ -104,13 +104,25 @@ export type DirectusContextTypeGeneric = DirectusContextType< export interface DirectusAuthHook { /** - * @throws + * Login the user. If successful, the user will be stored in the context. + * Else, an error will be thrown. + * @param email - The user email. + * @param password - The user password. */ login: (email: string, password: string) => Promise; /** - * @throws + * Logout the user. If successful, the user will be removed from the context. + * Else, an error will be thrown. */ logout: () => Promise; + /** + * Represents the current authentication state. + * @default 'loading' + */ authState: AuthStates; + /** + * The current authenticated user. + * @default null + */ user: UserType | null; } From 07b48893b49415c54efe3ab198087497526a119a Mon Sep 17 00:00:00 2001 From: Sakuk Date: Fri, 28 Jul 2023 17:27:55 +0000 Subject: [PATCH 03/13] More TSDoc --- src/auth.tsx | 31 +++++++++++++++++++++++++++++++ src/types.ts | 8 ++++++++ 2 files changed, 39 insertions(+) diff --git a/src/auth.tsx b/src/auth.tsx index 2047940b..c402bc04 100644 --- a/src/auth.tsx +++ b/src/auth.tsx @@ -3,6 +3,37 @@ import { DirectusContext } from './DirectusProvider'; import React from 'react'; import { UserType } from '@directus/sdk'; +/** + * A hook to access the Directus authentication state and methods. + * @example + * ```tsx + * import { useAuth } from 'react-directus'; + * + * const Login = () => { + * const { login } = useAuth(); + * + * const handleSubmit = (e: React.FormEvent) => { + * e.preventDefault(); + * const { email, password } = e.currentTarget.elements; + * login(email.value, password.value) + * .catch((err) => { + * console.error(err); + * }); + * }; + * + * return ( + *
+ * + * + * + *
+ * ); + * }; + * + * export default Login; + * ``` + */ + export const useAuth = (): DirectusAuthHook => { const directusContext = React.useContext(DirectusContext); diff --git a/src/types.ts b/src/types.ts index 108b3c96..47bee383 100644 --- a/src/types.ts +++ b/src/types.ts @@ -83,18 +83,24 @@ export interface DirectusContextType { /** The context-aware `DirectusImage` component, with pre-filled props. */ DirectusImage: typeof DirectusImage; /** + * Please use the data provided by the `useDirectusAuth` hook instead. + * @default 'loading' * @internal */ _authState: AuthStates; /** + * Please use the functions provided by the `useDirectusAuth` hook instead. * @internal */ _setAuthState: React.Dispatch>; /** + * Please use the data provided by the `useDirectusAuth` hook instead. + * @default null * @internal */ _directusUser: UserType | null; /** + * Please use the functions provided by the `useDirectusAuth` hook instead. * @internal */ _setDirecctusUser: React.Dispatch>; @@ -108,11 +114,13 @@ export interface DirectusAuthHook { * Else, an error will be thrown. * @param email - The user email. * @param password - The user password. + * @throws {Error} - If the login fails. */ login: (email: string, password: string) => Promise; /** * Logout the user. If successful, the user will be removed from the context. * Else, an error will be thrown. + * @throws {Error} - If the logout fails. */ logout: () => Promise; /** From 660e61b11295e52203164fcd9cc06ee01aa71825 Mon Sep 17 00:00:00 2001 From: Sakuk Date: Fri, 28 Jul 2023 17:29:51 +0000 Subject: [PATCH 04/13] better typing --- src/auth.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/auth.tsx b/src/auth.tsx index c402bc04..e600452b 100644 --- a/src/auth.tsx +++ b/src/auth.tsx @@ -49,7 +49,7 @@ export const useAuth = (): DirectusAuthHook => { _setDirecctusUser: setDirectusUser, } = directusContext; - const login = React.useCallback( + const login = React.useCallback( async (email: string, password: string) => { await directus.auth.login({ email, @@ -71,7 +71,7 @@ export const useAuth = (): DirectusAuthHook => { [directus] ); - const logout = React.useCallback(async () => { + const logout = React.useCallback(async () => { try { await directus.auth.logout(); } finally { From 6d8d71bfac054bb4e0a3eff52ddaf974e9ffe811 Mon Sep 17 00:00:00 2001 From: Sakuk Date: Fri, 28 Jul 2023 17:31:14 +0000 Subject: [PATCH 05/13] make useDirectusAuth importable --- src/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/index.ts b/src/index.ts index 00a88336..4fb01065 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,4 @@ export { DirectusProvider, useDirectus } from '@/DirectusProvider'; export { DirectusAsset } from '@components/DirectusAsset'; export { DirectusImage } from '@components/DirectusImage'; +export { useDirectusAuth } from '@hooks/useDirectusAuth'; From ef53797c7bd7d539cc59969259d5c4afaa4ecea4 Mon Sep 17 00:00:00 2001 From: Sakuk Date: Fri, 28 Jul 2023 17:31:18 +0000 Subject: [PATCH 06/13] rename useDirectusAuth --- src/{auth.tsx => useDirectusAuth.tsx} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename src/{auth.tsx => useDirectusAuth.tsx} (89%) diff --git a/src/auth.tsx b/src/useDirectusAuth.tsx similarity index 89% rename from src/auth.tsx rename to src/useDirectusAuth.tsx index e600452b..b5af8eb2 100644 --- a/src/auth.tsx +++ b/src/useDirectusAuth.tsx @@ -7,10 +7,10 @@ import { UserType } from '@directus/sdk'; * A hook to access the Directus authentication state and methods. * @example * ```tsx - * import { useAuth } from 'react-directus'; + * import { useDirectusAuth } from 'react-directus'; * * const Login = () => { - * const { login } = useAuth(); + * const { login } = useDirectusAuth(); * * const handleSubmit = (e: React.FormEvent) => { * e.preventDefault(); @@ -34,11 +34,11 @@ import { UserType } from '@directus/sdk'; * ``` */ -export const useAuth = (): DirectusAuthHook => { +export const useDirectusAuth = (): DirectusAuthHook => { const directusContext = React.useContext(DirectusContext); if (!directusContext) { - throw new Error('useAuth has to be used within the DirectusProvider'); + throw new Error('useDirectusAuth has to be used within the DirectusProvider'); } const { From f66f873583347b70b56ed8717f5d96921618f690 Mon Sep 17 00:00:00 2001 From: Sakuk Date: Fri, 28 Jul 2023 17:31:55 +0000 Subject: [PATCH 07/13] created seperate hooks folder --- src/{ => hooks}/useDirectusAuth.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename src/{ => hooks}/useDirectusAuth.tsx (95%) diff --git a/src/useDirectusAuth.tsx b/src/hooks/useDirectusAuth.tsx similarity index 95% rename from src/useDirectusAuth.tsx rename to src/hooks/useDirectusAuth.tsx index b5af8eb2..6ac6751c 100644 --- a/src/useDirectusAuth.tsx +++ b/src/hooks/useDirectusAuth.tsx @@ -1,5 +1,5 @@ -import { DirectusAuthHook } from './types'; -import { DirectusContext } from './DirectusProvider'; +import { DirectusAuthHook } from '../types'; +import { DirectusContext } from '../DirectusProvider'; import React from 'react'; import { UserType } from '@directus/sdk'; From bf4243aedfbe55855d667e1ff5458dba7c737969 Mon Sep 17 00:00:00 2001 From: Sakuk Date: Sat, 29 Jul 2023 23:31:45 +0000 Subject: [PATCH 08/13] fixed imports --- jest.config.json | 3 ++- tsconfig.json | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/jest.config.json b/jest.config.json index 84047850..26f2d16c 100644 --- a/jest.config.json +++ b/jest.config.json @@ -5,6 +5,7 @@ "testMatch": ["/src/**/*(*.)@(spec|test).[tj]s?(x)"], "moduleNameMapper": { "^@/(.*)$": "/src/$1", - "^@components/(.*)$": "/src/components/$1" + "^@components/(.*)$": "/src/components/$1", + "^@hooks/(.*)$": "/src/hooks/$1" } } diff --git a/tsconfig.json b/tsconfig.json index c0a2bf0d..0702e4d8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,6 +15,7 @@ "paths": { "@/*": ["*"], "@components/*": ["components/*"], + "@hooks/*": ["hooks/*"] } } } From 2cff6436727e0399ad402008f61da004c56a5be9 Mon Sep 17 00:00:00 2001 From: Sakuk Date: Sun, 30 Jul 2023 22:23:15 +0000 Subject: [PATCH 09/13] rem redundant directus and apiUrl --- src/DirectusProvider.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DirectusProvider.tsx b/src/DirectusProvider.tsx index 58f7b1cc..a0384c87 100644 --- a/src/DirectusProvider.tsx +++ b/src/DirectusProvider.tsx @@ -34,8 +34,8 @@ export const DirectusProvider = ({ const value = React.useMemo>( () => ({ - apiUrl: apiUrl, - directus: directus, + apiUrl, + directus, DirectusAsset: ({ asset, render, ...props }: DirectusAssetProps) => { console.warn('Deprecated: Please import DirectusAsset directly from react-directus'); return ; From f75184cafe644c393d7e10510b544dcaa21453c5 Mon Sep 17 00:00:00 2001 From: Marco Polichetti Date: Mon, 31 Jul 2023 09:42:41 +0200 Subject: [PATCH 10/13] Update useDirectusAuth.tsx --- src/hooks/useDirectusAuth.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/hooks/useDirectusAuth.tsx b/src/hooks/useDirectusAuth.tsx index 6ac6751c..09b3a023 100644 --- a/src/hooks/useDirectusAuth.tsx +++ b/src/hooks/useDirectusAuth.tsx @@ -5,6 +5,7 @@ import { UserType } from '@directus/sdk'; /** * A hook to access the Directus authentication state and methods. + * * @example * ```tsx * import { useDirectusAuth } from 'react-directus'; @@ -14,11 +15,12 @@ import { UserType } from '@directus/sdk'; * * const handleSubmit = (e: React.FormEvent) => { * e.preventDefault(); + * * const { email, password } = e.currentTarget.elements; * login(email.value, password.value) - * .catch((err) => { - * console.error(err); - * }); + * .catch((err) => { + * console.error(err); + * }); * }; * * return ( @@ -33,7 +35,6 @@ import { UserType } from '@directus/sdk'; * export default Login; * ``` */ - export const useDirectusAuth = (): DirectusAuthHook => { const directusContext = React.useContext(DirectusContext); From b1e5ea4ccd28d268bd0347e60e9f2c2fcf8a0675 Mon Sep 17 00:00:00 2001 From: Sakuk Date: Mon, 31 Jul 2023 08:19:15 +0000 Subject: [PATCH 11/13] added hook to README --- README.md | 59 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 0a6ef9ce..79c41cd9 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,9 @@ root.render( ); ``` -## ⚙️ The hook `useDirectus` +## ⚙️ Hooks + +### `useDirectus` After adding the provider, you can access the configured client anywhere in the app, using the `useDirectus` hook: @@ -93,6 +95,43 @@ export const TodoList = () => { }; ``` +### `useDirectusAuth` + +The `useDirectusAuth` hook provides a few methods for working with the [Directus Authentication API](https://docs.directus.io/reference/old-sdk.html#authentication): + +* `login` - a function that accepts an email and password and returns a promise that resolves to the user object if the login is successful or rejects with an error otherwise. +* `logout` - a function that logs out the current user. +* `user` - the current user object +* `authState` - the current authentication state, one of `loading` (the initial state), `logged-in` or `logged-out`. + +```jsx +import { useDirectusAuth } from 'react-directus'; + +const Login = () => { + const { login } = useDirectusAuth(); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + + const { email, password } = e.currentTarget.elements; + login(email.value, password.value).catch(err => { + console.error(err); + }); + }; + + return ( +
+ + + +
+ ); +}; + +export default Login; + +``` + ## 🧩 Components (so far...) This package contains a few components for working with Direcuts [files](https://docs.directus.io/reference/files/). They are all configured for using the `apiUrl` specified in the provider. Hopefully, more will come in the future 🤗. @@ -103,9 +142,9 @@ This package contains a few components for working with Direcuts [files](https:/ Computes the URL of the given resource `asset`, rendering it using the `render` prop: -- `asset`: the asset representing the resource (`string` or `object` with an `id` property) -- `download`: force browser to download the asset (force the `Content-Disposition` header) -- `render`: a function (which receives an object with the `url` property) that provides the component to render +* `asset`: the asset representing the resource (`string` or `object` with an `id` property) +* `download`: force browser to download the asset (force the `Content-Disposition` header) +* `render`: a function (which receives an object with the `url` property) that provides the component to render ```jsx import React from 'react'; @@ -126,12 +165,12 @@ export const TodoItem = ({ item }) => { Computes the URL of the given resource `asset`, rendering it using the `render` prop: -- `asset`: the asset representing the resource (`string` or `object` with an `id` property) -- `fit`: fit of the thumbnail while always preserving the aspect ratio, can be any of the following options: `cover`, `contain`, `inside` or `outside` -- `height`: height of the thumbnail in pixels -- `quality`: quality of the thumbnail (`1` to `100`) -- `width`: width of the thumbnail in pixels -- `render`: a function (which receives an object with the `url` property) that provides the component to render +* `asset`: the asset representing the resource (`string` or `object` with an `id` property) +* `fit`: fit of the thumbnail while always preserving the aspect ratio, can be any of the following options: `cover`, `contain`, `inside` or `outside` +* `height`: height of the thumbnail in pixels +* `quality`: quality of the thumbnail (`1` to `100`) +* `width`: width of the thumbnail in pixels +* `render`: a function (which receives an object with the `url` property) that provides the component to render ```jsx import React from 'react'; From 238e7757040eea0998d9dabfa728b92c2044dac2 Mon Sep 17 00:00:00 2001 From: Marco Polichetti Date: Mon, 31 Jul 2023 10:48:04 +0200 Subject: [PATCH 12/13] Update README.md --- README.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 79c41cd9..7fe7ba99 100644 --- a/README.md +++ b/README.md @@ -99,10 +99,10 @@ export const TodoList = () => { The `useDirectusAuth` hook provides a few methods for working with the [Directus Authentication API](https://docs.directus.io/reference/old-sdk.html#authentication): -* `login` - a function that accepts an email and password and returns a promise that resolves to the user object if the login is successful or rejects with an error otherwise. -* `logout` - a function that logs out the current user. -* `user` - the current user object -* `authState` - the current authentication state, one of `loading` (the initial state), `logged-in` or `logged-out`. +- `login` - a function that accepts an email and password and returns a promise that resolves to the user object if the login is successful or rejects with an error otherwise +- `logout` - a function that logs out the current user +- `user` - the current user object +- `authState` - the current authentication state, one of `loading` (the initial state), `logged-in` or `logged-out`. ```jsx import { useDirectusAuth } from 'react-directus'; @@ -142,9 +142,9 @@ This package contains a few components for working with Direcuts [files](https:/ Computes the URL of the given resource `asset`, rendering it using the `render` prop: -* `asset`: the asset representing the resource (`string` or `object` with an `id` property) -* `download`: force browser to download the asset (force the `Content-Disposition` header) -* `render`: a function (which receives an object with the `url` property) that provides the component to render +- `asset`: the asset representing the resource (`string` or `object` with an `id` property) +- `download`: force browser to download the asset (force the `Content-Disposition` header) +- `render`: a function (which receives an object with the `url` property) that provides the component to render ```jsx import React from 'react'; @@ -165,12 +165,12 @@ export const TodoItem = ({ item }) => { Computes the URL of the given resource `asset`, rendering it using the `render` prop: -* `asset`: the asset representing the resource (`string` or `object` with an `id` property) -* `fit`: fit of the thumbnail while always preserving the aspect ratio, can be any of the following options: `cover`, `contain`, `inside` or `outside` -* `height`: height of the thumbnail in pixels -* `quality`: quality of the thumbnail (`1` to `100`) -* `width`: width of the thumbnail in pixels -* `render`: a function (which receives an object with the `url` property) that provides the component to render +- `asset`: the asset representing the resource (`string` or `object` with an `id` property) +- `fit`: fit of the thumbnail while always preserving the aspect ratio, can be any of the following options: `cover`, `contain`, `inside` or `outside` +- `height`: height of the thumbnail in pixels +- `quality`: quality of the thumbnail (`1` to `100`) +- `width`: width of the thumbnail in pixels +- `render`: a function (which receives an object with the `url` property) that provides the component to render ```jsx import React from 'react'; From 62727e10fce9f1ded5f47ea8d9631dabb35c9cfd Mon Sep 17 00:00:00 2001 From: Marco Polichetti Date: Mon, 31 Jul 2023 10:48:38 +0200 Subject: [PATCH 13/13] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7fe7ba99..ce547036 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ The `useDirectusAuth` hook provides a few methods for working with the [Directus - `login` - a function that accepts an email and password and returns a promise that resolves to the user object if the login is successful or rejects with an error otherwise - `logout` - a function that logs out the current user - `user` - the current user object -- `authState` - the current authentication state, one of `loading` (the initial state), `logged-in` or `logged-out`. +- `authState` - the current authentication state, one of `loading` (the initial state), `logged-in` or `logged-out` ```jsx import { useDirectusAuth } from 'react-directus';