Package Exports
- @sp-uvb/core
- @sp-uvb/core/session
- @sp-uvb/core/totp
- @sp-uvb/core/webauthn
Readme
@sp-uvb/core
Standalone authentication core for UVB - Client-side MFA without backend dependency.
Overview
@sp-uvb/core provides client-side authentication capabilities that work completely offline without requiring a UVB backend server. Perfect for:
- Offline/standalone applications
- Embedded authentication (Electron, mobile apps, CLIs)
- Client-side verification (reduce backend load)
- Development/testing without infrastructure
- Hybrid deployments (works with or without backend)
Features
- Client-side TOTP - Generate and verify TOTP codes locally
- WebAuthn Helpers - Browser-based WebAuthn flows (coming soon)
- Local Session Management - JWT generation and validation (coming soon)
- Zero backend dependency - All cryptography runs client-side
- Compatible with UVB server - Drop-in replacement for backend mode
Installation
npm install @sp-uvb/core
# or
yarn add @sp-uvb/core
# or
pnpm add @sp-uvb/core
# or
bun add @sp-uvb/coreQuick Start
TOTP (Time-based One-Time Password)
import { generateTOTPSecret, generateTOTP, verifyTOTP, generateQRCodeURI } from '@sp-uvb/core/totp';
// 1. Generate a secret during enrollment
const secret = generateTOTPSecret(); // e.g., "JBSWY3DPEHPK3PXP"
// 2. Generate QR code URI for scanning
const qrUri = generateQRCodeURI(secret, 'user@example.com', 'MyApp');
// Display as QR code for user to scan with Google Authenticator, Authy, etc.
// 3. Later: Generate a code
const code = generateTOTP(secret); // e.g., "123456"
// 4. Verify user-provided code
const isValid = verifyTOTP(secret, userProvidedCode);
if (isValid) {
console.log('Authentication successful!');
}Configuration Options
import type { TOTPConfig } from '@sp-uvb/core/totp';
const config: TOTPConfig = {
timeStep: 30, // Time window (seconds)
digits: 6, // Code length
skew: 1, // Allow ±1 time step for clock drift
algorithm: 'SHA1', // 'SHA1' | 'SHA256' | 'SHA512'
};
const code = generateTOTP(secret, config);
const isValid = verifyTOTP(secret, userCode, config);API Reference
TOTP Module
generateTOTPSecret(length?: number): string
Generate a cryptographically secure random secret.
length- Secret length in bytes (default: 20, min recommended: 16)- Returns - Base32-encoded secret string
generateTOTP(secret: string, config?: TOTPConfig): string
Generate a TOTP code from a secret.
secret- Base32-encoded secret stringconfig- Optional TOTP configuration- Returns - 6-digit (or configured) TOTP code
verifyTOTP(secret: string, code: string, config?: TOTPConfig): boolean
Verify a TOTP code against a secret with time skew support.
secret- Base32-encoded secret stringcode- User-provided TOTP codeconfig- Optional TOTP configuration- Returns -
trueif valid,falseotherwise
generateQRCodeURI(secret: string, account: string, issuer: string, config?: TOTPConfig): string
Generate a provisioning URI for QR code enrollment.
secret- Base32-encoded secret stringaccount- User identifier (email, username, etc.)issuer- Application/service nameconfig- Optional TOTP configuration- Returns -
otpauth://URI string
getCurrentTimeStep(config?: TOTPConfig): number
Get the current time step for TOTP calculations.
- Returns - Current Unix timestamp divided by time step
getSecondsRemaining(config?: TOTPConfig): number
Get seconds remaining until the next TOTP code generation.
- Returns - Seconds remaining (0-30 typically)
Comparison: Backend vs Standalone
| Feature | Backend Mode | Standalone Mode (@sp-uvb/core) |
|---|---|---|
| TOTP Generation | ❌ Backend only | ✅ Client-side |
| TOTP Verification | ❌ Backend only | ✅ Client-side |
| WebAuthn | ❌ Backend only | ⏳ Coming soon |
| Session Management | ❌ Backend only | ⏳ Coming soon |
| Network Required | ✅ Yes | ❌ No |
| Backend Dependency | ✅ Required | ❌ None |
| Offline Support | ❌ No | ✅ Yes |
Integration with UVB Packages
All UVB framework packages (@sp-uvb/vue, @sp-uvb/react, @sp-uvb/next, etc.) will support both modes:
import { useUVB } from '@sp-uvb/vue';
// Backend mode (current)
const { session } = useUVB({
uvbUrl: 'https://your-uvb-server.com',
mode: 'backend', // default
});
// Standalone mode (new)
const { session, generateTOTP, verifyTOTP } = useUVB({
mode: 'standalone', // uses @sp-uvb/core internally
});Architecture
┌─────────────────────────────────────────────┐
│ Application Layer │
│ (@sp-uvb/vue, @sp-uvb/react, @sp-uvb/next, etc.) │
└─────────────────────────────────────────────┘
│
┌────────────┴────────────┐
│ │
┌──────▼──────┐ ┌──────▼──────┐
│ Backend Mode│ │Standalone │
│ (HTTP API) │ │ Mode │
└─────────────┘ │ (@sp-uvb/core) │
└─────────────┘
│
┌──────────┼──────────┐
│ │ │
┌─────▼───┐ ┌───▼────┐ ┌──▼─────┐
│ TOTP │ │WebAuthn│ │Session │
│otpauth │ │Browser │ │ jose │
└─────────┘ └────────┘ └────────┘Roadmap
- Client-side TOTP generation/verification
- WebAuthn browser helpers
- Local JWT/session management
- Backup code generation
- Rate limiting (client-side)
- WASM-compiled Rust core (future)
Security Considerations
Secret Storage: Never store TOTP secrets in plaintext! Always encrypt secrets before storing:
// ❌ BAD: Plaintext storage
localStorage.setItem('totp_secret', secret);
// ✅ GOOD: Encrypted storage
import { encrypt } from 'your-encryption-library';
const encrypted = await encrypt(secret, userMasterKey);
localStorage.setItem('totp_secret_encrypted', encrypted);Time Synchronization: TOTP relies on accurate time. Ensure client clocks are synchronized (NTP).
Skew Window: Default skew of 1 allows ±30 seconds of clock drift. Increase only if needed.
Contributing
Contributions welcome! This package is part of the UVB monorepo.
License
MIT