@umituz/web-auth
v2.7.2
Published
Frontend auth module for the fleet — AuthLayout, Login/Register/Forgot/Reset forms, LegalPage shell for terms/privacy docs (content stays in the app), SessionProvider with an AuthAdapter seam, org switcher, demo login, ready-made better-auth client adapte
Maintainers
Readme
@umituz/web-auth
Frontend auth module: AuthLayout + Login/Register/Forgot/Reset forms, a SessionProvider
with an AuthAdapter seam, an org switcher, and a demo login. The package performs no
authentication itself — the host adapts its backend through AuthAdapter; the forms render
whatever the host wires into onLogin-style callbacks.
Source-shipped (no build step). TypeScript + React 18/19, styling via uauth-* classes on
@umituz/web-design-system color tokens.
Subpaths
| Export | Contents |
| --- | --- |
| . | Everything below in one barrel |
| ./components | AuthLayout, LoginForm, RegisterForm, ForgotPasswordForm, ResetPasswordForm, shared inputs (EmailInput, PasswordInput, PasswordStrengthIndicator, AuthErrorBanner, SocialLoginButtons, SocialProviderIcons) |
| ./hooks | useAuth + AuthProvider interface (backend-action contract) |
| ./utils | Validators (isValidEmail, validateLogin, …), password strength, email masking, generateResetToken, i18n/validation key catalogs |
| ./types | All public types (User, LoginCredentials, RegisterData, form props, AuthConfig, …) |
| ./session | SessionProvider, useSession, AuthAdapter/SessionUser types, createInMemoryAuthAdapter, DemoLogin, OrgSwitcher |
| ./better-auth | betterAuthAdapter({ role?, baseURL? }), betterAuthRegister, betterAuthForgotPassword, betterAuthResetPassword — ready-made better-auth client wiring for the AuthAdapter seam and form on*Attempt props (better-auth is an optional peer) |
| ./styles.css | The stylesheet (import once, after the design-system stylesheet) |
Quickstart
npm install @umituz/web-auth
# peers: react, react-dom, react-router ^7 (core package — optional)Import styles once, after the design-system stylesheet:
import "@umituz/web-design-system/styles.css"; import "@umituz/web-auth/styles.css";Implement the adapter seam (or use the in-memory one for demos):
import { createInMemoryAuthAdapter } from "@umituz/web-auth/session";Mount the session provider above the routes:
import { SessionProvider } from "@umituz/web-auth/session"; <SessionProvider adapter={adapter}> <App /> </SessionProvider>Render the auth screens:
import { AuthLayout, LoginForm } from "@umituz/web-auth/components"; <AuthLayout> <LoginForm onLogin={async (credentials) => { /* call your API */ }} /> </AuthLayout>Read the session anywhere:
import { useSession } from "@umituz/web-auth/session";
useAuth (from ./hooks) is the backend-action contract used by the forms
(login/register/forgotPassword/resetPassword); DemoLogin and OrgSwitcher cover
multi-tenant demo flows.
Magic-link + demo-entry pages
Passwordless hosts configure the adapter seam and render whole pages from the package — no local page code beyond config:
import type { AuthAdapter } from "@umituz/web-auth/session";
export const authAdapter: AuthAdapter = {
login, logout, current,
requestMagicLink: (email) => apiFetch("/api/auth/magic-link", { method: "POST", json: { email } }),
verifyToken: (token) => apiFetch("/api/auth/verify", { method: "POST", json: { token } }),
listDemoUsers: () => apiFetch("/api/users"),
demoLogin: (userId) => apiFetch("/api/auth/demo", { method: "POST", json: { userId } }),
};import { MagicLinkLoginPage, MagicLinkVerifyPage } from "@umituz/web-auth";
const authConfig: AuthConfig = {
/* brand + routes */
afterLoginRoute: "/dashboard",
roleHomeRoutes: { creator: "/creator", "brand-client": "/portal" },
demoGroups: [
{ id: "agency", title: "Agency team", roles: ["owner", "admin"], roleLabels: { owner: "Owner" } },
{ id: "creators", title: "Creator studio", roles: ["creator"] },
],
};
<Route path="/auth/verify" element={<MagicLinkVerifyPage config={authConfig} />} />
{/* anywhere anonymous: */} <MagicLinkLoginPage config={authConfig} />MagicLinkForm and DemoUserPicker are also exported separately for custom compositions.
Post-login routing goes through roleHomeRoutes (fallback afterLoginRoute).
Styles
- Class prefix
uauth-*, spacing scale declared as--uauth-space-1…8(4–40px). - Colors come from
@umituz/web-design-systemcustom properties (--color-*); theme the screens by overriding those tokens (e.g.--color-primary).
Peers
react and react-dom ^18 || ^19, react-router ^7 (the core package, per the fleet's core-only router rule — react-router-dom v7 is its re-export shim and also satisfies the import). Optional peer: only the form components navigate; ./session, ./hooks, ./utils and ./types work in routerless hosts.
Development
npm run typecheck # tsc --noEmit
npm run lint # eslint src
npm test # vitest run