@supernal/sdk-auth
v1.0.0
Published
Supernal Authentication SDK - Lightweight auth client for OAuth flows and token management
Downloads
120
Maintainers
Readme
@supernal/sdk-auth
Lightweight authentication SDK for Supernal's multi-project authentication system. Handles OAuth flows, token management, and user authentication.
🚀 Installation
npm install @supernal/sdk-auth📋 Quick Start
Basic Authentication
import {
SupernalAuth,
AuthFlowHandler,
TokenManager,
} from '@supernal/sdk-auth';
// Initialize auth client
const auth = new SupernalAuth({
authUrl: 'https://auth.supernal.ai',
clientId: 'your-client-id',
projectId: 'your-project-id', // Optional: for project-specific auth
redirectUri: 'https://yourapp.com/callback',
scopes: ['openid', 'email', 'profile'],
});
// Handle authentication flow
const flowHandler = new AuthFlowHandler(auth);
const tokenManager = new TokenManager(auth);Web Application Flow
// Redirect to login
const authUrl = auth.getAuthorizationUrl('optional-state');
window.location.href = authUrl;
// Handle callback
const { user, tokens } = await flowHandler.handleWebCallback();
// Store tokens securely
await tokenManager.storeTokens(tokens);
console.log('User authenticated:', user);Chrome Extension Flow
// In your extension background script
const { user, tokens } = await flowHandler.handleExtensionFlow();
// Store in chrome.storage
await chrome.storage.local.set({
access_token: tokens.access_token,
user: user,
});Token Management
// Get valid token (automatically refreshes if needed)
const token = await tokenManager.getValidToken();
// Check if user is authenticated
const isAuth = await tokenManager.isAuthenticated();
// Clear tokens (logout)
tokenManager.clearTokens();🔧 API Reference
SupernalAuth
Main authentication client.
class SupernalAuth {
constructor(config: AuthConfig);
getAuthorizationUrl(state?: string): string;
exchangeCodeForToken(code: string, state?: string): Promise<AuthTokens>;
getUser(accessToken: string): Promise<AuthUser>;
validateToken(accessToken: string): Promise<TokenValidationResult>;
refreshToken(refreshToken: string): Promise<AuthTokens>;
revokeToken(accessToken: string): Promise<void>;
}AuthFlowHandler
Handles OAuth flows for different platforms.
class AuthFlowHandler {
constructor(auth: SupernalAuth);
handleWebFlow(state?: string): Promise<string>;
handleWebCallback(): Promise<AuthResult>;
handleExtensionFlow(state?: string): Promise<AuthResult>;
}TokenManager
Manages token storage and automatic refresh.
class TokenManager {
constructor(auth: SupernalAuth, storage?: Storage);
storeTokens(tokens: AuthTokens): Promise<void>;
getValidToken(): Promise<string | null>;
clearTokens(): void;
isAuthenticated(): Promise<boolean>;
}🎯 Types
interface AuthConfig {
authUrl: string;
clientId: string;
clientSecret?: string;
projectId?: string;
redirectUri: string;
scopes?: string[];
}
interface AuthUser {
id: string;
email: string;
name: string;
avatar_url?: string;
project_role?: string;
project_permissions?: string[];
tenant_id?: string;
is_admin?: boolean;
}
interface AuthTokens {
access_token: string;
token_type: 'Bearer';
expires_in: number;
refresh_token?: string;
scope?: string;
}🌐 Platform Support
- Web Applications: Full OAuth 2.0 flow with redirects
- Chrome Extensions: Uses
chrome.identity.launchWebAuthFlow - Mobile Apps: OAuth flow with custom URL schemes
- Desktop Apps: System browser integration (coming soon)
🔐 Security Features
- Automatic Token Refresh: Handles token expiration transparently
- Secure Storage: Configurable storage backend
- CSRF Protection: State parameter validation
- Error Handling: Comprehensive error types and messages
📚 Examples
React Hook
import { useEffect, useState } from 'react';
import { SupernalAuth, TokenManager } from '@supernal/sdk-auth';
export function useSupernalAuth() {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const auth = new SupernalAuth({
authUrl: process.env.REACT_APP_SUPERNAL_AUTH_URL!,
clientId: process.env.REACT_APP_SUPERNAL_CLIENT_ID!,
redirectUri: `${window.location.origin}/callback`,
});
const tokenManager = new TokenManager(auth);
useEffect(() => {
checkAuth();
}, []);
const checkAuth = async () => {
try {
const token = await tokenManager.getValidToken();
if (token) {
const userInfo = await auth.getUser(token);
setUser(userInfo);
}
} catch (error) {
console.error('Auth check failed:', error);
} finally {
setLoading(false);
}
};
const login = () => {
const authUrl = auth.getAuthorizationUrl();
window.location.href = authUrl;
};
const logout = () => {
tokenManager.clearTokens();
setUser(null);
};
return { user, loading, login, logout };
}Node.js Server
import { SupernalAuth } from '@supernal/sdk-auth';
const auth = new SupernalAuth({
authUrl: 'https://auth.supernal.ai',
clientId: process.env.SUPERNAL_CLIENT_ID!,
clientSecret: process.env.SUPERNAL_CLIENT_SECRET!,
redirectUri: 'https://yourapp.com/callback',
});
// Validate token from request
async function validateRequest(req: Request) {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) {
throw new Error('No token provided');
}
const result = await auth.validateToken(token);
if (!result.valid) {
throw new Error('Invalid token');
}
return result.user;
}🐛 Error Handling
try {
const { user, tokens } = await flowHandler.handleWebCallback();
} catch (error) {
if (error.message.includes('access_denied')) {
// User denied access
} else if (error.message.includes('invalid_client')) {
// Configuration error
} else {
// Other errors
}
}📞 Support
- Documentation: https://docs.supernal.ai/sdk/auth
- GitHub: https://github.com/supernal-ai/supernal-sdk
- Discord: https://discord.gg/supernal-ai
Version: 1.0.0
License: MIT
