dauth-context-react
v4.0.3
Published
React context provider and hook for token-based authentication with the [Dauth](https://dauth.ovh) service. Provides `DauthProvider` and `useDauth()` hook for seamless integration of Dauth tenant authentication into React applications.
Readme
dauth-context-react
React context provider and hook for token-based authentication with the Dauth service. Provides DauthProvider and useDauth() hook for seamless integration of Dauth tenant authentication into React applications.
Installation
npm install dauth-context-react
# or
yarn add dauth-context-reactPeer Dependencies
react>= 16
Quick Start
1. Wrap your app with DauthProvider
import React from 'react';
import ReactDOM from 'react-dom/client';
import { RouterProvider } from 'react-router-dom';
import { DauthProvider } from 'dauth-context-react';
import router from './router/router';
ReactDOM.createRoot(document.getElementById('root')!).render(
<DauthProvider
domainName="your-domain-name"
tsk="your-tenant-secret-key"
>
<RouterProvider router={router} fallbackElement={<></>} />
</DauthProvider>
);2. Use the useDauth() hook in your components
import { useDauth } from 'dauth-context-react';
function MyComponent() {
const {
isAuthenticated,
isLoading,
user,
loginWithRedirect,
logout,
getAccessToken,
} = useDauth();
if (isLoading) return <div>Loading...</div>;
if (isAuthenticated) {
return (
<div>
<p>Hello, {user.name}!</p>
<button onClick={logout}>Logout</button>
</div>
);
}
return <button onClick={loginWithRedirect}>Login</button>;
}API
<DauthProvider>
| Prop | Type | Description |
|---|---|---|
| domainName | string | Your Dauth domain name (used for API routing and tenant resolution) |
| tsk | string | Tenant Secret Key for JWT verification |
| children | React.ReactNode | Child components |
useDauth() Hook
Returns the current authentication state and action methods:
| Property | Type | Description |
|---|---|---|
| user | IDauthUser | Authenticated user object |
| domain | IDauthDomainState | Domain configuration (name, loginRedirect, allowedOrigins) |
| isLoading | boolean | true while initial auth check is in progress |
| isAuthenticated | boolean | true if user is authenticated |
| loginWithRedirect | () => void | Redirects to the Dauth tenant sign-in page |
| logout | () => void | Clears token and resets auth state |
| getAccessToken | () => Promise<string> | Returns a fresh access token (refreshes if needed) |
| updateUser | (fields: Partial<IDauthUser>) => Promise<boolean> | Updates user profile fields |
| updateUserWithRedirect | () => void | Redirects to the Dauth user update page |
| sendEmailVerification | () => Promise<boolean> | Sends a verification email to the user |
| sendEmailVerificationStatus | { status: IActionStatus, isLoading: boolean } | Status of the email verification request |
IDauthUser
interface IDauthUser {
_id: string;
name: string;
lastname: string;
nickname: string;
email: string;
isVerified: boolean;
language: string;
avatar: { id: string; url: string };
role: string;
telPrefix: string;
telSuffix: string;
birthDate?: Date;
country?: string;
metadata?: any;
createdAt: Date;
updatedAt: Date;
lastLogin: Date;
}Real-World Integration Example
This is the pattern used in easymediacloud-frontend-react, which delegates all user authentication to Dauth.
1. Provider hierarchy in App.tsx
// src/App.tsx
import { DauthProvider } from 'dauth-context-react';
import { LicensesProvider } from './context/licenses/LicensesProvider';
import { RouterProvider } from 'react-router-dom';
import router from './router/router';
import config from './config/config';
function App() {
return (
<DauthProvider
domainName={config.services.dauth.DOMAIN_NAME as string}
tsk={config.services.dauth.TSK as string}
>
<LicensesProvider>
<RouterProvider router={router} fallbackElement={<></>} />
</LicensesProvider>
</DauthProvider>
);
}Environment variables (.env.development):
REACT_APP_DAUTH_DOMAIN_NAME=your-domain-name
REACT_APP_DAUTH_TSK=your-tenant-secret-key2. Route protection with EnsureAuthenticated
// src/router/middlewares.tsx
import { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { useDauth } from 'dauth-context-react';
import { routes } from './routes';
export function EnsureAuthenticated({ children }: { children: React.ReactNode }) {
const { isAuthenticated, isLoading } = useDauth();
const navigate = useNavigate();
useEffect(() => {
if (!isAuthenticated && !isLoading) {
navigate(routes.home);
}
}, [isAuthenticated, isLoading, navigate]);
return <>{children}</>;
}
// In router config:
{
path: '/license/:id',
element: (
<EnsureAuthenticated>
<LicenseDetail />
</EnsureAuthenticated>
),
}3. Passing tokens to API calls from a context provider
// src/context/licenses/LicensesProvider.tsx
import { useCallback, useReducer } from 'react';
import { useDauth } from 'dauth-context-react';
function LicensesProvider({ children }: { children: React.ReactNode }) {
const [state, dispatch] = useReducer(licenseReducer, initialState);
const { getAccessToken } = useDauth();
const getLicenses = useCallback(async () => {
const token = await getAccessToken();
const { data } = await fetchLicenses(token);
dispatch({ type: 'SET_LICENSES', payload: data });
}, [getAccessToken]);
const createLicense = useCallback(async (name: string) => {
const token = await getAccessToken();
await postLicense({ name, token });
}, [getAccessToken]);
return (
<LicensesContext.Provider value={{ ...state, getLicenses, createLicense }}>
{children}
</LicensesContext.Provider>
);
}4. Using useDauth() in components
// src/views/components/ProfileIcon.tsx
import { useDauth } from 'dauth-context-react';
function ProfileIcon() {
const { user, isAuthenticated, loginWithRedirect, logout, updateUserWithRedirect } = useDauth();
return (
<Popover title={user.email}>
{isAuthenticated ? (
<>
<Avatar src={user.avatar?.url} />
<button onClick={updateUserWithRedirect}>My Profile</button>
<button onClick={logout}>Logout</button>
</>
) : (
<button onClick={loginWithRedirect}>Login</button>
)}
</Popover>
);
}5. Language sync from dauth user
// src/views/layouts/LayoutBasic.tsx
import { useDauth } from 'dauth-context-react';
import i18n from 'i18next';
function LayoutMain() {
const { user } = useDauth();
useEffect(() => {
i18n.changeLanguage(user.language);
}, [user.language]);
return <Outlet />;
}How It Works
- On mount: Checks the URL for a redirect token (
?dauth_state=...), then attempts auto-login from localStorage. - Token refresh: Proactively refreshes the access token before expiry (5 minutes before). Falls back to periodic refresh every 5 minutes if decode fails.
- Localhost detection: Automatically routes API calls to
localhost:4012during development (detectslocalhost,127.0.0.1,[::1], and192.168.x.x) and tohttps://dauth.ovhin production. - Token storage: Access token stored in localStorage under
dauth_state, refresh token underdauth_refresh_token.
Development
pnpm start # Watch mode (tsdx watch)
pnpm build # Production build (CJS + ESM)
pnpm test # Run Jest tests
pnpm lint # ESLint via tsdx
pnpm size # Check bundle size (10KB budget per entry)
pnpm analyze # Bundle size analysis with visualizationBundle Outputs
- CJS:
dist/index.js(with.development.jsand.production.min.jsvariants) - ESM:
dist/dauth-context-react.esm.js - Types:
dist/index.d.ts
CI/CD
- CI: GitHub Actions runs lint, test, and build on push to
mainand PRs. Self-hosted runner, Node 22. - Publish: Automated npm publish on
v*tags via GitHub Actions.
Author
David T. Pizarro Frick
License
MIT
