Modern authentication library for React applications with OAuth2 and credentials support. Simplified API, automatic token refresh, and full TypeScript support.
npm install @grasp-labs/ds-auth-webModern authentication library for React applications with OAuth2 and credentials support. Simplified API, automatic token refresh, and full TypeScript support.
``bash`
npm install @grasp-labs/ds-auth-web
For beta releases:
`bash`
npm install @grasp-labs/ds-auth-web@beta
`tsx
import { AuthProvider, useAuth } from "@grasp-labs/ds-auth-web";
function App() {
return (
credentials={{
loginUrl: "/api/auth/login",
mfaUrl: "/api/auth/mfa",
userInfoUrl: "/api/auth/user",
cors: true, // Enable CORS for credentials-based auth
}}
oauth2={{
google: {
clientId: "your-google-client-id",
redirectUri: window.location.origin,
authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth",
tokenUrl: "https://oauth2.googleapis.com/token",
scope: ["openid", "profile", "email"],
},
}}
>
);
}
function YourApp() {
const { isAuthenticated, user, loginOAuth2, loginCredentials, logout } =
useAuth();
if (isAuthenticated) {
return (
return (
{/ OAuth2 login with provider key /}
Features
- 🔐 OAuth2 with PKCE - Secure authorization code flow
- 📝 Credentials login - Email/password with MFA support
- 🔄 Auto token refresh - Keeps sessions alive automatically
- 💾 Flexible storage - Session, local, or memory storage
- 🎣 React 19 ready - No unnecessary hooks or memoization
- 🌐 CORS support - Built-in CORS handling for credentials auth
- 🔌 Axios integration - Auto-inject auth headers with one flag
- �️ Error handling - Typed errors with user-friendly messages
- �📦 Small bundle - ~25KB gzipped
- 🚀 TypeScript - Full type safety
API Reference
$3
The main hook for accessing authentication state and methods:
`typescript
const {
// State
isAuthenticated: boolean,
user: User | null,
tokens: Tokens | null,
method: 'oauth2' | 'credentials' | null,
error: Error | null,
mfa: MFAState | undefined, // Loading states
isLoggingIn: boolean,
isVerifyingMFA: boolean,
isRefreshing: boolean,
isFetchingUserInfo: boolean,
// Methods
loginOAuth2: (providerKey: string) => Promise,
loginCredentials: (email, password, rememberMe?) => Promise,
verifyMFA: (code: string) => Promise,
logout: () => Promise,
refresh: () => Promise,
// Utilities
getAuthHeader: () => string | null,
} = useAuth();
`Configuration
AuthProvider accepts individual props instead of a config object:
`typescript
interface IAuthProviderProps {
children: ReactNode; // Storage
storage?: "local" | "session" | "memory"; // Default: 'session'
// Auto refresh
autoRefresh?: boolean; // Default: true
refreshBuffer?: number; // Buffer before expiry in seconds
refreshInterval?: number; // Check interval in ms
// OAuth2 providers
oauth2?: Record;
// Credentials configuration
credentials?: CredentialsConfig;
// Callbacks
onAuthChange?: (isAuthenticated: boolean) => void;
onError?: (error: Error) => void;
}
interface OAuth2Config {
clientId: string;
redirectUri: string;
authorizationUrl: string;
tokenUrl: string;
userInfoUrl?: string;
scope?: string[];
clientSecret?: string;
usePKCE?: boolean; // Default: true
revokeUrl?: string;
}
interface CredentialsConfig {
loginUrl: string;
mfaUrl?: string;
userInfoUrl?: string;
refreshUrl?: string;
logoutUrl?: string;
cors?: boolean;
}
`Development
$3
Want to contribute or run the project locally? Here's what you need:
Requirements:
- Node.js 22 or higher
- npm or your favorite package manager
Setup:
`bash
Install dependencies
npm install(Optional) configure example server secrets
cp examples/.env.example examples/.env.localRun the example dev server (loads
examples/.env automatically)
npm run dev:examplesRun tests
npm testRun tests in watch mode (great for development)
npm run test:watchBuild the library
npm run build
`#### External IDP toggle
The credential form in
examples/ includes a "Use External IDP" checkbox powered by the IDP_LOGIN_URL, IDP_MFA_URL, and IDP_USERINFO_URL variables. Point those URLs at any identity provider that exposes compatible JSON endpoints—Grasp DP, Keycloak, Auth0, etc.—and the example app will proxy email/password + MFA requests through your backend instead of the mock database. When the toggle is off, everything runs against the mocked routes so you can develop without touching real infrastructure.The build output goes into the
dist/ folder, which is what gets published to npm.$3
We use Vitest for testing because it's fast and works great with TypeScript:
`bash
npm test # Run all tests once
npm run test:watch # Watch mode - tests run as you make changes
npm run test:coverage # Generate a coverage report
`Coverage reports are generated as HTML in the
coverage/ directory.$3
Before submitting a PR, make sure your code passes linting and formatting:
`bash
npm run lint # Check for issues
npm run lint:fix # Auto-fix what we can
npm run format # Format all files with Prettier
`$3
To generate and publish a beta release locally:
`bash
npm run build
npm version prerelease --preid=beta
npm publish --tag beta
``