@armco/iam-client
v0.1.2
Published
Browser/SPA client for IAM - OIDC/OAuth2 authentication with PKCE
Maintainers
Readme
@armco/iam-client
Browser/SPA client for IAM - OIDC/OAuth2 authentication with PKCE.
Installation
npm install @armco/iam-clientQuick Start
Vanilla JavaScript/TypeScript
import { createIAMClient } from '@armco/iam-client';
const iam = createIAMClient({
issuer: 'http://localhost:5000',
clientId: 'my-app',
redirectUri: 'http://localhost:3000/callback',
scopes: ['openid', 'profile', 'email', 'offline_access'],
});
// Login
document.getElementById('login-btn').onclick = () => iam.login();
// Signup
document.getElementById('signup-btn').onclick = () => iam.signup();
// Handle callback (on /callback page)
const result = await iam.handleCallback();
if (result.success) {
console.log('Logged in:', result.user);
} else {
console.error('Login failed:', result.error);
}
// Get current user
const user = iam.getUser();
// Get access token (auto-refreshes if needed)
const token = await iam.getAccessToken();
// Logout
await iam.logout();React
import { IAMProvider, useAuth } from '@armco/iam-client/react';
// Wrap your app
function App() {
return (
<IAMProvider
issuer="http://localhost:5000"
clientId="my-app"
redirectUri="http://localhost:3000/callback"
onLoginSuccess={(result) => {
console.log('Logged in:', result.user);
// Navigate to dashboard
}}
>
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/callback" element={<Callback />} />
<Route path="/dashboard" element={<Dashboard />} />
</Routes>
</Router>
</StuffleIAMProvider>
);
}
// Use the hook
function Home() {
const { isAuthenticated, isLoading, user, login, signup, logout } = useAuth();
if (isLoading) return <div>Loading...</div>;
if (!isAuthenticated) {
return (
<div>
<button onClick={() => login()}>Login</button>
<button onClick={() => signup()}>Sign Up</button>
</div>
);
}
return (
<div>
<p>Welcome, {user?.name || user?.email}</p>
<button onClick={() => logout()}>Logout</button>
</div>
);
}
// Callback page (auto-handled by provider)
function Callback() {
const { isLoading, error } = useAuth();
if (isLoading) return <div>Processing login...</div>;
if (error) return <div>Error: {error.message}</div>;
return <Navigate to="/dashboard" />;
}Configuration
interface StuffleIAMConfig {
/** IAM server base URL */
issuer: string;
/** OAuth2 client ID */
clientId: string;
/** Redirect URI after login */
redirectUri: string;
/** Requested scopes (default: openid profile email) */
scopes?: string[];
/** Post-logout redirect URI */
postLogoutRedirectUri?: string;
/** Enable PKCE (default: true) */
usePkce?: boolean;
/** Storage type (default: sessionStorage) */
storage?: 'localStorage' | 'sessionStorage' | 'memory';
/** Auto-refresh tokens (default: true) */
autoRefresh?: boolean;
/** Seconds before expiry to refresh (default: 60) */
refreshThreshold?: number;
}React Hooks
| Hook | Description |
|------|-------------|
| useAuth() | Full auth context (user, login, logout, etc.) |
| useUser() | Current user object |
| useIsAuthenticated() | Boolean auth status |
| useAccessToken() | Function to get access token |
| useHasRole(roles) | Check if user has role(s) |
Protected Routes (HOC)
import { withAuth } from '@armco/iam-client/react';
const ProtectedPage = withAuth(MyComponent, {
LoadingComponent: () => <div>Loading...</div>,
UnauthorizedComponent: () => <div>Please login</div>,
roles: ['admin'], // Optional: require specific roles
});API Reference
StuffleIAMClient Methods
| Method | Description |
|--------|-------------|
| login(options?) | Start login flow |
| signup(options?) | Start signup flow |
| logout(options?) | End session |
| handleCallback(url?) | Process OAuth callback |
| getUser() | Get current user from ID token |
| getAccessToken() | Get access token (refreshes if needed) |
| isAuthenticated() | Check if user is logged in |
| refreshToken() | Manually refresh tokens |
| subscribe(listener) | Subscribe to auth state changes |
Development
cd packages/sdk-js
npm install
npm run build
npm run dev # Watch mode