@siyamhosan/auth-system
v1.0.1
Published
Minimal client for the auth-system API (session cookies + React helpers)
Maintainers
Readme
@siyamhosan/auth-system
A comprehensive, multi-tenant authentication SDK for React, Svelte, Next.js, and server environments.
Features
- 🔐 Multi-tenant authentication - Support for multiple applications with isolated databases
- 🎯 Framework agnostic - Works with React, Svelte, Next.js, and vanilla JavaScript
- 🔄 Token management - Automatic refresh token handling with family-based invalidation
- 🛡️ Security first - Argon2 password hashing, JWT secrets per tenant
- 🌐 OAuth integration - Built-in support for Google, GitHub, Discord, and more
- 📱 Cross-platform - Browser, Node.js, Deno, Bun support
- 🎨 Plugin architecture - Extensible authentication methods
Installation
npm install @siyamhosan/auth-systemQuick Start
Universal (Framework Agnostic)
import { createAuthClient } from '@siyamhosan/auth-system'
const client = createAuthClient({
baseUrl: 'https://your-auth-server.com',
clientId: 'your-app-id', // Your application ID
apiKey: 'your-api-key'
})
// Login
const response = await client.login({
email: '[email protected]',
password: 'password'
})
console.log('Logged in:', response.user)React
import { AuthProvider, useAuth, useLogin } from '@siyamhosan/auth-system/react'
function App() {
return (
<AuthProvider config={{
baseUrl: 'https://your-auth-server.com',
clientId: 'your-app-id',
apiKey: 'your-api-key'
}}>
<LoginForm />
</AuthProvider>
)
}
function LoginForm() {
const { login, isLoading, error } = useLogin()
const [credentials, setCredentials] = useState({ email: '', password: '' })
const handleSubmit = async (e) => {
e.preventDefault()
try {
await login(credentials)
// Redirect to dashboard
} catch (err) {
console.error('Login failed:', err)
}
}
return (
<form onSubmit={handleSubmit}>
<input
type="email"
value={credentials.email}
onChange={e => setCredentials(prev => ({ ...prev, email: e.target.value }))}
/>
<input
type="password"
value={credentials.password}
onChange={e => setCredentials(prev => ({ ...prev, password: e.target.value }))}
/>
<button disabled={isLoading}>
{isLoading ? 'Logging in...' : 'Login'}
</button>
{error && <div>{error.message}</div>}
</form>
)
}Svelte
<script>
import { createAuth, createAuthHelpers } from '@siyamhosan/auth-system/svelte'
const auth = createAuth({
baseUrl: 'https://your-auth-server.com',
clientId: 'your-app-id',
apiKey: 'your-api-key'
})
const { user, isAuthenticated, isLoading } = createAuthHelpers(auth)
let email = ''
let password = ''
async function handleLogin() {
try {
await auth.login({ email, password })
} catch (error) {
console.error('Login failed:', error)
}
}
</script>
{#if $isLoading}
<p>Loading...</p>
{:else if $isAuthenticated}
<p>Welcome, {$user?.name}!</p>
<button on:click={() => auth.logout()}>Logout</button>
{:else}
<form on:submit|preventDefault={handleLogin}>
<input bind:value={email} type="email" placeholder="Email" />
<input bind:value={password} type="password" placeholder="Password" />
<button type="submit">Login</button>
</form>
{/if}Next.js
// app/api/auth/login/route.ts
import { NextAuthAPI } from '@siyamhosan/auth-system/nextjs'
const authAPI = new NextAuthAPI({
baseUrl: process.env.AUTH_SERVER_URL!,
clientId: process.env.AUTH_CLIENT_ID!,
apiKey: process.env.AUTH_API_KEY!
})
export async function POST(request: Request) {
return authAPI.handleLogin(request)
}
// app/login/page.tsx
'use client'
import { useNextAuth } from '@siyamhosan/auth-system/nextjs'
export default function LoginPage() {
const { login, isAuthenticated } = useNextAuth({
baseUrl: process.env.NEXT_PUBLIC_AUTH_SERVER_URL!,
clientId: process.env.NEXT_PUBLIC_AUTH_CLIENT_ID!,
apiKey: process.env.NEXT_PUBLIC_AUTH_API_KEY!
})
// ... login form implementation
}Server-side (Node.js/Express)
import { createServerAuth, createExpressMiddleware } from '@siyamhosan/auth-system/server'
import express from 'express'
const auth = createServerAuth({
baseUrl: process.env.AUTH_SERVER_URL!,
clientId: process.env.AUTH_CLIENT_ID!,
apiKey: process.env.AUTH_API_KEY!,
tokenCache: { enabled: true, ttl: 3600 },
rateLimit: { enabled: true, maxRequests: 10, windowMs: 60000 }
})
const app = express()
// Authentication middleware
app.use('/api/protected', createExpressMiddleware(auth))
// Protected route
app.get('/api/protected/profile', (req, res) => {
res.json({ user: req.user })
})
app.listen(3000)URL-based Client Identification
This SDK now uses direct URL-based client identification for cleaner, more RESTful APIs. Instead of complex headers or query parameters, your client ID is embedded directly in the URL path.
How it Works
// Client configuration
const client = createAuthClient({
baseUrl: 'https://auth.example.com',
clientId: 'my-app-123', // Your app ID
apiKey: 'your-api-key'
})
// Requests are made to URLs like:
// POST https://auth.example.com/client/my-app-123/auth/login
// POST https://auth.example.com/client/my-app-123/auth/register
// GET https://auth.example.com/client/my-app-123/auth/session
await client.login({ email, password })Benefits
- Direct Access: APIs are directly accessible without complex routing logic
- RESTful: Client identification is part of the resource path
- Cache-Friendly: Different clients get different cache keys
- Simple: No need to manage headers or query parameters for client identification
- Backward Compatible: Legacy tenant methods still work for existing integrations
Migration from Tenant-based Configuration
If you're upgrading from the old tenant-based approach:
// Old way (deprecated but still supported)
const client = createAuthClient({
baseUrl: 'https://auth.example.com',
apiKey: 'your-api-key',
tenant: {
type: 'site_id',
value: 'my-app-123'
}
})
// New way (recommended)
const client = createAuthClient({
baseUrl: 'https://auth.example.com',
clientId: 'my-app-123', // Direct from tenant.value
apiKey: 'your-api-key'
})The clientId should be your app's unique identifier (UUID or slug) that you get when you create an app in your auth service dashboard.
Configuration
AuthClientConfig
interface AuthClientConfig {
baseUrl: string // Your auth server URL
clientId: string // Your application ID (required)
apiKey: string // API key for your application
headers?: Record<string, string> // Additional headers
onTokenRefresh?: (tokens: AuthTokens) => void | Promise<void>
onAuthError?: (error: AuthError) => void
}Authentication Methods
Email/Password
// Register
await client.register({
email: '[email protected]',
username: 'username', // optional
password: 'password',
name: 'Display Name' // optional
})
// Login
await client.login({
email: '[email protected]', // or username
password: 'password'
})OAuth
// Initiate OAuth flow
const { url } = await client.initiateOAuth('google', 'https://yourapp.com/callback')
// Redirect user to the URL
window.location.href = urlSession Management
// Check current session
const session = await client.getSession()
// Refresh tokens
await client.refreshTokens()
// Logout
await client.logout()Advanced Usage
Custom Storage
import { AuthClient } from '@siyamhosan/auth-system'
class CustomStorage {
get(key: string) { /* implementation */ }
set(key: string, value: string) { /* implementation */ }
remove(key: string) { /* implementation */ }
clear() { /* implementation */ }
}
const client = new AuthClient(config, new CustomStorage())Token Events
const client = createAuthClient({
baseUrl: '...',
apiKey: '...',
onTokenRefresh: (tokens) => {
console.log('Tokens refreshed:', tokens)
// Save to custom storage, update UI, etc.
},
onAuthError: (error) => {
console.error('Auth error:', error)
// Handle auth errors (redirect to login, etc.)
}
})API Reference
Core Classes
AuthClient- Main authentication clientServerAuth- Server-side authentication manager
React Hooks
useAuth()- Access auth contextuseUser()- Get current useruseAuthState()- Get auth stateuseLogin()- Login functionalityuseRegister()- Registration functionalityuseLogout()- Logout functionalityuseOAuth()- OAuth functionality
Svelte Stores
createAuth()- Create auth storecreateAuthHelpers()- Helper functions for auth store
Next.js Utilities
createNextAuthClient()- Next.js compatible clientNextAuthServer- Server-side utilitiesNextAuthAPI- API route handlers
Security Features
- Token Rotation - Automatic refresh token rotation
- Family-based Revocation - Invalidate entire token families
- Rate Limiting - Built-in rate limiting for server environments
- Secure Cookies - HTTP-only cookies in Next.js
- Argon2 Hashing - Server-side password hashing
- JWT per Tenant - Isolated JWT secrets per application
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
MIT © Siyam Hosan
Support
For questions and support, please open an issue on GitHub.
