@versini/auth-provider
v8.1.2
Published
High-level React authentication components & hooks supporting password (PKCE Code) and Passkey (WebAuthn) flows. Built on the primitives from `@versini/auth-common`.
Readme
@versini/auth-provider
High-level React authentication components & hooks supporting password (PKCE Code) and Passkey (WebAuthn) flows. Built on the primitives from @versini/auth-common.
Install
pnpm add @versini/auth-provider @versini/auth-common react react-domPeer deps: react (>= 19) & react-dom.
Packages Relationship
@versini/auth-provider -> @versini/auth-common (utilities, constants)
-> @versini/ui-hooks (local storage abstraction)Features
- PKCE Code + Refresh token flow
- Passkey (WebAuthn) registration & authentication
- Silent access token refresh with refresh token rotation
- Role / permission helpers (re-export of
isGranted&AUTH_TYPES) - Local storage isolation per
clientId - Timezone & build metadata banner injection (in distributed bundles)
Quick Start (Custom Auth Backend)
import { AuthProvider } from "@versini/auth-provider";
function App() {
return (
<AuthProvider clientId="my-web-app" sessionExpiration="3600" debug>
<MainRoutes />
</AuthProvider>
);
}Inside your components:
import { useAuth } from "@versini/auth-provider/hooks";
export function Profile() {
const { user, isAuthenticated, login, logout, getAccessToken } = useAuth();
if (!isAuthenticated) {
return <button onClick={() => login("alice", "p@ssw0rd")}>Login</button>;
}
return (
<div>
<p>User: {user?.username}</p>
<button onClick={logout}>Logout</button>
<button
onClick={async () => {
const token = await getAccessToken();
console.log("access", token.slice(0, 20) + "...");
}}
>
Get Access Token
</button>
</div>
);
}Passkey (WebAuthn) Flow
const { registeringForPasskey, loginWithPasskey } = useAuth();
// After user authenticates with password you can offer passkey registration:
await registeringForPasskey();
// Later, user can login directly with passkey:
await loginWithPasskey();Public API Summary
<AuthProvider />– Core provider. Props:clientId: string(required)sessionExpiration?: string(TTL hint sent to backend)domain?: string(multi-tenant / custom domain support)debug?: boolean(enables internal logging viauseLogger)endpoint?: string(override default auth service URL)
- Hooks (from
hooksentry):useAuth()– ReturnsAuthContextProps:- state:
isLoading,isAuthenticated,user,logoutReason,authenticationType - methods:
login(username, password),logout(),getAccessToken(),getIdToken(),registeringForPasskey(),loginWithPasskey()
- state:
- Re-exports from
@versini/auth-common:AUTH_TYPES,isGranted
Storage Strategy
Local storage keys are namespaced: @@auth@@::<clientId>::@@<token-type>@@.
On logout or token invalidation all related keys are purged atomically (removeStateAndLocalStorage).
Token Refresh
getAccessToken() validates the existing access token; if expired/invalid it attempts a silent refresh via TokenManager.refreshtoken(). Failure triggers a forced logout (security-first principle).
Error & Security Principles
- Deny-by-default: unauthorized or invalid token state leads to logout.
- All network operations funnel through typed helpers; unexpected responses cause cleanup.
- No sensitive values are logged unless
debugis enabled (still avoid including raw tokens in production logs). - PKCE flow ensures authorization code interception resistance.
Bundling Notes
Entry files are emitted without hashes (index.js, auth.js, hooks.js) for stable package exports; internal split chunks are hashed (chunks/[name].[hash].js). This is intentional for library consumption stability.
TypeScript
Distributed ESM with full .d.ts declarations; strict types encourage safe usage. Avoid any; leverage AuthContextProps for context consumers.
Roadmap / Ideas
- SSR helpers for preloading user session
- Optional cookie-based storage abstraction
- Enhanced role/permission model (attribute-based access)
License
MIT © gizmette.com
