@genzzi/oauth-client
v1.5.2
Published
Official Genzzi OAuth UI — customizable button + callback handler. Vanilla JS, React, Tailwind, any icon library.
Downloads
868
Maintainers
Readme
@genzzi/oauth-client
Official Genzzi OAuth UI library — a customizable button and callback handler for React apps. Supports vanilla inline styles, Tailwind CSS, and any icon library.
Table of Contents
- Features
- Installation
- Quick Start
- Usage
- API Reference
- OAuth Flow
- Error Handling
- TypeScript
- Peer Dependencies
Features
- One-click OAuth — handles PKCE, state, and token exchange automatically
- Flexible styling — inline styles by default; opt into Tailwind with
useTailwind - Multiple variants & sizes —
primary,secondary,ghost,danger,light,dark,link× five sizes - Logo / text / both — control display with the
displayprop - Provider pattern — use
GenzziProviderto centralize callbacks at the app level - Fallback mode — works without a Provider for simple, single-page setups
- Dev plugin — Vite plugin for better error stack traces in development
- TypeScript-first — full type definitions included
Installation
npm install @genzzi/oauth-client
# or
yarn add @genzzi/oauth-client
# or
pnpm add @genzzi/oauth-clientTailwind CSS is optional. Install it only if you plan to use useTailwind.
Quick Start
import { Button } from "@genzzi/oauth-client";
export default function App() {
return (
<Button
oauthConfig={{ client_id: "your-client-id" }}
onSuccess={(data) => console.log("Logged in!", data)}
onGenzziError={(err) => console.error(err)}
>
Sign in with Genzzi
</Button>
);
}Usage
Basic Button
The Button component handles the entire OAuth flow — fetching your app's config from Genzzi, generating PKCE, redirecting the user, and exchanging the code on the callback page.
import { Button } from "@genzzi/oauth-client";
<Button
oauthConfig={{ client_id: "your-client-id" }}
variant="primary"
size="md"
onSuccess={(data) => {
// data is whatever your backend returns after token exchange
console.log(data);
}}
onGenzziError={(err) => {
console.error(err.message);
}}
>
Sign in with Genzzi
</Button>With GenzziProvider (Recommended)
Wrap your app (or page) with GenzziProvider to centralize onSuccess and onError callbacks. This ensures the OAuth callback is handled once at the top level, no matter how many Button instances exist.
import { GenzziProvider, Button } from "@genzzi/oauth-client";
export default function App() {
return (
<GenzziProvider
onSuccess={(data) => {
console.log("Auth success:", data);
// redirect user, set auth state, etc.
}}
onError={(err) => {
console.error("Auth error:", err.message);
}}
>
<YourApp />
</GenzziProvider>
);
}
// Anywhere inside your app:
function LoginPage() {
return (
<Button oauthConfig={{ client_id: "your-client-id" }}>
Sign in with Genzzi
</Button>
);
}Note: When
GenzziProvideris present, individualonSuccess/onGenzziErrorprops onButtontake precedence over the Provider's callbacks.
Tailwind CSS Mode
Pass useTailwind to switch from inline styles to Tailwind utility classes. Make sure Tailwind is configured in your project and its classes are not purged.
<Button
oauthConfig={{ client_id: "your-client-id" }}
useTailwind
variant="primary"
size="lg"
onSuccess={handleSuccess}
>
Sign in with Genzzi
</Button>Vite Dev Plugin
Add the Genzzi Vite plugin to get accurate source locations in error messages during development. It injects a stack trace into every <Button /> so misconfiguration errors point to the right file and line.
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { genzziDevPlugin } from "@genzzi/oauth-client/vite-plugin";
export default defineConfig({
plugins: [
react(),
genzziDevPlugin(), // development only — safe to include, only runs in non-node_modules files
],
});API Reference
Button Props
Extends all native <button> HTML attributes.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| oauthConfig | GenzziOAuthConfig | — | Required. Your Genzzi app credentials. |
| variant | "primary" \| "secondary" \| "ghost" \| "danger" \| "light" \| "dark" \| "link" | "primary" | Visual style of the button. |
| size | "sm" \| "md" \| "lg" \| "xl" \| "2xl" | "md" | Size of the button. |
| display | "logo-only" \| "text-only" \| "logo-text" | "logo-text" | Controls what is rendered inside the button. |
| icon | React.ReactNode | — | Custom icon element. |
| iconPosition | "left" \| "right" | "left" | Position of the custom icon relative to children. |
| loading | boolean | false | Shows a spinner and disables the button. |
| disabled | boolean | false | Disables the button. |
| useTailwind | boolean | false | Use Tailwind utility classes instead of inline styles. |
| onSuccess | (data: any) => void | — | Called with the token exchange response on successful auth. |
| onGenzziError | (err: Error) => void | — | Called when an OAuth error occurs. |
| className | string | — | Extra CSS class names (combined via clsx + tailwind-merge). |
GenzziProvider Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| children | React.ReactNode | — | Required. Your app's component tree. |
| onSuccess | (data: any) => void | () => {} | Called on successful OAuth callback. |
| onError | (err: Error) => void | () => {} | Called when an OAuth error occurs. |
GenzziOAuthConfig
| Field | Type | Description |
|-------|------|-------------|
| client_id | string | Required. Your Genzzi application's client ID. |
All other OAuth parameters (redirect_uri, backend_uri, scope) are fetched automatically from the Genzzi server using your client_id. Configure them in your Genzzi dashboard.
Utility Exports
import {
GenzziOAuthError, // Custom error class for Genzzi-specific errors
getErrorMessage, // Validates a GenzziOAuthConfig, returns an error string or null
installGenzziErrorReporter, // Installs a global window error listener for GenzziOAuthErrors
useGenzziContext, // React hook — returns the nearest GenzziProvider context
} from "@genzzi/oauth-client";installGenzziErrorReporter()
Call this once at the root of your app to catch uncaught GenzziOAuthErrors without crashing. Logs the full stack trace to the console and suppresses the error from propagating.
import { installGenzziErrorReporter } from "@genzzi/oauth-client";
installGenzziErrorReporter();OAuth Flow
The library implements Authorization Code Flow with PKCE (RFC 7636).
User clicks Button
│
▼
Fetch OAuth config from Genzzi (backend_uri, redirect_uri, scope)
│
▼
Generate PKCE verifier + S256 challenge
Generate random state value
│
▼
Write { backendUrl, state, codeVerifier } to sessionStorage
│
▼
Redirect to https://genzzi.in/oauth/authorize?...
│
▼ (user authenticates on Genzzi)
│
▼
Redirect back to your redirect_uri with ?code=...&state=...
│
▼
handleOAuthCallback() runs (via GenzziProvider or Button fallback)
• Validates state against sessionStorage (CSRF protection)
• Deletes sessionStorage entry (replay protection)
• POSTs code + code_verifier to your backend_uri
│
▼
onSuccess(data) called with your backend's responseSecurity notes:
backendUrlis read fromsessionStorageonly — never from URL params, preventing SSRF.- State is validated before any sensitive data is used.
- The
sessionStoragekey is deleted immediately after reading, preventing replay attacks. - The URL is cleaned via
history.replaceStateafter all validation passes.
Error Handling
<Button
oauthConfig={{ client_id: "your-client-id" }}
onGenzziError={(err) => {
if (err.message.includes("State mismatch")) {
// Possible CSRF attack
alert("Security error. Please try again.");
} else if (err.message.includes("Token exchange failed")) {
// Your backend returned a non-2xx response
alert("Login failed. Please contact support.");
} else {
console.error(err);
}
}}
>
Sign in
</Button>If oauthConfig is missing or client_id is not provided, the button automatically renders as a disabled error state with a tooltip describing the problem — no crash, no silent failure.
TypeScript
All types are exported from the package root:
import type {
ButtonProps,
GenzziOAuthConfig,
buttonVariant,
buttonSize,
ButtonDisplay,
buttonIconPosition,
} from "@genzzi/oauth-client";Peer Dependencies
| Package | Required Version |
|---------|-----------------|
| react | ^17 \|\| ^18 \|\| ^19 |
| react-dom | ^17 \|\| ^18 \|\| ^19 |
| tailwindcss | >=3.0.0 (optional) |
License
MIT © Genzzi
