@quadcore-lib/auth
v0.1.7
Published
React authentication package for Quadcore applications. Wraps Auth0 with a typed context, role-based guards, and pre-built UI components.
Downloads
1,108
Readme
@quadcore-lib/auth
React authentication package for Quadcore applications. Wraps Auth0 with a typed context, role-based guards, and pre-built UI components.
Installation
npm install @quadcore-lib/auth @auth0/auth0-react react react-domEnvironment variables
Create a .env file in your app (never committed):
VITE_AUTH0_DOMAIN=your-tenant.auth0.com
VITE_AUTH0_CLIENT_ID=your-client-id
VITE_AUTH0_AUDIENCE=https://your-api-audienceSetup
Wrap your app with QuadcoreAuthProvider. It handles the Auth0 flow, fetches the user from your backend (GET /auth/me), and exposes everything through context.
import { QuadcoreAuthProvider } from '@quadcore-lib/auth';
import '@quadcore-lib/auth/styles';
function App() {
return (
<QuadcoreAuthProvider apiUrl="https://api.your-app.com">
<YourRoutes />
</QuadcoreAuthProvider>
);
}apiUrl is the base URL of your backend (pairs with @quadcore-lib/auth-server).
Components
<LoginButton />
Renders a styled login button. Calls loginWithRedirect via Auth0.
import { LoginButton } from '@quadcore-lib/auth';
// Default button
<LoginButton />
// Custom class + CSS variable theming
<LoginButton className="my-btn" theme={{ '--qc-auth-primary': '#0070f3' }} />
// Render slot — bring your own element
<LoginButton renderButton={(login) => <a onClick={login}>Sign in</a>} />Props
| Prop | Type | Description |
|------|------|-------------|
| className | string | Added to the button element |
| theme | AuthTheme | CSS custom properties applied inline |
| children | ReactNode | Button label (default: "Iniciar sesión") |
| renderButton | (login: () => void) => ReactNode | Replaces the default button entirely |
<RegisterButton />
Same API as LoginButton, but opens Auth0's signup screen.
import { RegisterButton } from '@quadcore-lib/auth';
<RegisterButton />
<RegisterButton renderButton={(register) => <a onClick={register}>Create account</a>} /><UserAvatar />
Shows the authenticated user's avatar. Falls back to the first letter of their email when no picture is set. Renders nothing when there is no user.
import { UserAvatar } from '@quadcore-lib/auth';
// Default avatar
<UserAvatar />
// Custom class
<UserAvatar className="navbar-avatar" />
// Render slot
<UserAvatar renderAvatar={(user) => <img src={user.picture} alt={user.name} />} />Props
| Prop | Type | Description |
|------|------|-------------|
| className | string | Added to the container element |
| theme | AuthTheme | CSS custom properties applied inline |
| renderAvatar | (user: AuthUser) => ReactNode | Replaces the default avatar |
<AuthLoadingSpinner />
Accessible spinner (role="status", aria-label="Cargando").
import { AuthLoadingSpinner } from '@quadcore-lib/auth';
<AuthLoadingSpinner />
<AuthLoadingSpinner className="my-spinner" theme={{ '--qc-auth-primary': '#ff0000' }} /><PrivateRoute />
Redirects unauthenticated users to login. Shows the spinner while Auth0 is loading.
import { PrivateRoute } from '@quadcore-lib/auth';
<PrivateRoute>
<Dashboard />
</PrivateRoute><RequireRole />
Conditionally renders children based on the authenticated user's role.
import { RequireRole } from '@quadcore-lib/auth';
<RequireRole role="admin">
<AdminPanel />
</RequireRole>
// With fallback UI
<RequireRole role="admin" fallback={<p>Access denied</p>}>
<AdminPanel />
</RequireRole>
// With callback
<RequireRole role="admin" onRoleError={() => navigate('/403')}>
<AdminPanel />
</RequireRole>Props
| Prop | Type | Description |
|------|------|-------------|
| role | string | Required role string |
| fallback | ReactNode | Rendered when role doesn't match |
| onRoleError | () => void | Called when the user lacks the required role |
Hook
import { useAuth } from '@quadcore-lib/auth';
function Navbar() {
const { user, isLoading, isAuthenticated, login, logout } = useAuth();
if (isLoading) return <AuthLoadingSpinner />;
if (!isAuthenticated) return <LoginButton />;
return (
<>
<UserAvatar />
<button onClick={logout}>Sign out</button>
</>
);
}AuthContextValue
| Field | Type | Description |
|-------|------|-------------|
| user | AuthUser \| null | Authenticated user from your DB |
| isLoading | boolean | Auth0 + user fetch in progress |
| isAuthenticated | boolean | Auth0 authenticated AND DB user loaded |
| login | () => void | Calls loginWithRedirect |
| logout | () => void | Clears token and logs out |
Types
interface AuthUser {
id: string;
email: string;
role: string;
auth0Id: string;
name?: string;
picture?: string;
}
// Keys accepted by the `theme` prop
type AuthTheme = Partial<{
'--qc-auth-primary': string;
'--qc-auth-bg': string;
'--qc-auth-radius': string;
'--qc-auth-font': string;
'--qc-auth-border': string;
}>;Theming
Import the base stylesheet and override CSS variables per-component or globally:
/* global override */
:root {
--qc-auth-primary: #0070f3;
--qc-auth-radius: 8px;
}Or inline per component:
<LoginButton theme={{ '--qc-auth-primary': '#e11d48' }} />Backend pairing
This package expects your backend to expose GET /auth/me returning an AuthUser object. Use @quadcore-lib/auth-server for a ready-made NestJS implementation.
