@classic-homes/auth
v0.1.23
Published
Authentication services and Svelte bindings for Classic Theme apps
Downloads
1,901
Readme
@classic-homes/auth
Framework-agnostic authentication core with Svelte bindings for the Classic Theme design system.
Features
- JWT-based authentication with automatic token refresh
- SSO (Single Sign-On) support with configurable providers
- Multi-factor authentication (MFA/TOTP) support
- Pluggable storage adapter (localStorage, sessionStorage, or custom)
- Svelte reactive stores for authentication state
- Route guards for protected pages
- TypeScript-first with full type safety
Installation
npm install @classic-homes/authQuick Start
1. Initialize Authentication
In your app's entry point (e.g., hooks.client.ts for SvelteKit):
import { initAuth } from '@classic-homes/auth';
initAuth({
baseUrl: 'https://api.example.com',
storage: {
getItem: (key) => localStorage.getItem(key),
setItem: (key, value) => localStorage.setItem(key, value),
removeItem: (key) => localStorage.removeItem(key),
},
onAuthError: (error) => {
console.error('Auth error:', error);
},
});2. Use the Auth Store (Svelte)
<script lang="ts">
import { authStore, authActions } from '@classic-homes/auth/svelte';
async function handleLogin() {
await authActions.login({
email: '[email protected]',
password: 'password123',
});
}
async function handleLogout() {
await authActions.logout();
}
</script>
{#if $authStore.isAuthenticated}
<p>Welcome, {$authStore.user?.email}</p>
<button onclick={handleLogout}>Logout</button>
{:else}
<button onclick={handleLogin}>Login</button>
{/if}3. Protect Routes
// src/routes/dashboard/+page.ts
import { authGuard } from '@classic-homes/auth/svelte';
export const load = authGuard({
redirectTo: '/login',
});API Reference
Core Exports
import {
// Initialization
initAuth,
getAuthConfig,
// Service
authService,
AuthService,
// API
authApi,
// Types
type User,
type AuthTokens,
type LoginCredentials,
type RegisterData,
type AuthConfig,
} from '@classic-homes/auth';Svelte Exports
import {
// Store
authStore,
isAuthenticated,
currentUser,
// Actions
authActions,
// Guards
authGuard,
roleGuard,
} from '@classic-homes/auth/svelte';Configuration Options
interface AuthConfig {
/** Base URL for the auth API */
baseUrl: string;
/** Storage adapter for tokens */
storage?: {
getItem: (key: string) => string | null;
setItem: (key: string, value: string) => void;
removeItem: (key: string) => void;
};
/** SSO configuration */
sso?: {
enabled: boolean;
provider: string;
authorizeUrl?: string;
tokenUrl?: string;
};
/** Callback when auth errors occur */
onAuthError?: (error: Error) => void;
/** Custom headers for API requests */
headers?: Record<string, string>;
}Auth Actions
The authActions object provides methods for authentication operations:
// Login with email/password
await authActions.login({ email, password, rememberMe });
// Register new user
await authActions.register({ email, password, fullName });
// Logout
await authActions.logout();
// Refresh session
await authActions.refreshSession();
// Change password
await authActions.changePassword({ currentPassword, newPassword });
// MFA operations
await authActions.verifyMfa({ code, trustDevice });
await authActions.setupMfa({ secret, code });
await authActions.disableMfa({ password });
// SSO
await authActions.initiateSSO();
await authActions.handleSSOCallback(code);Auth Store State
interface AuthState {
user: User | null;
tokens: AuthTokens | null;
isAuthenticated: boolean;
isLoading: boolean;
error: string | null;
mfaRequired: boolean;
mfaToken: string | null;
}Route Guards
Basic Auth Guard
import { authGuard } from '@classic-homes/auth/svelte';
export const load = authGuard({
redirectTo: '/login',
returnUrl: true, // Append ?returnUrl= to redirect
});Role-Based Guard
import { roleGuard } from '@classic-homes/auth/svelte';
export const load = roleGuard({
roles: ['admin', 'manager'],
redirectTo: '/unauthorized',
});Using with @classic-homes/theme-svelte
The auth package integrates with the form validation from @classic-homes/theme-svelte:
<script lang="ts">
import { useForm, loginSchema } from '@classic-homes/theme-svelte';
import { authActions } from '@classic-homes/auth/svelte';
const form = useForm({
schema: loginSchema,
initialValues: {
email: '',
password: '',
rememberMe: false,
},
onSubmit: async (data) => {
await authActions.login(data);
},
});
</script>
<form onsubmit={form.handleSubmit}>
<input bind:value={form.data.email} />
{#if form.errors.email}
<span class="error">{form.errors.email}</span>
{/if}
<!-- ... -->
</form>License
MIT
