Remove legacy references to global auth composable and document the new dependency injection pattern with single source of truth. Key Documentation Updates: • Update authentication.md with DI architecture details and usage patterns • Update chat integration docs to reference AuthService and remove legacy patterns • Add comprehensive authentication-architecture.md with full technical details • Document migration path from legacy global auth to current DI pattern Content Changes: • Replace useAuth.ts references with useAuthService.ts • Document AuthService as singleton with dependency injection • Add code examples for both component and service usage • Explain benefits of new architecture (single source of truth, no timing issues) • Update chat integration to reflect service-based architecture 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
235 lines
No EOL
7 KiB
Markdown
235 lines
No EOL
7 KiB
Markdown
# Authentication Architecture
|
|
|
|
This document describes the current authentication architecture using dependency injection and service-based patterns.
|
|
|
|
## Overview
|
|
|
|
The authentication system has been refactored from a legacy global composable approach to a modern dependency injection pattern. This eliminates timing issues, improves maintainability, and provides a single source of truth for authentication state.
|
|
|
|
## Architecture Components
|
|
|
|
### 1. AuthService (Core Service)
|
|
**Location**: `src/modules/base/auth/auth-service.ts`
|
|
|
|
The `AuthService` is a singleton service that extends `BaseService` and provides:
|
|
- Reactive authentication state management
|
|
- LNBits API integration
|
|
- Event-driven authentication lifecycle
|
|
- Automatic token management
|
|
|
|
**Key Features**:
|
|
```typescript
|
|
export class AuthService extends BaseService {
|
|
// Public reactive state
|
|
public isAuthenticated = ref(false)
|
|
public user = ref<User | null>(null)
|
|
public isLoading = ref(false)
|
|
public error = ref<Error | null>(null)
|
|
|
|
// Computed properties for compatibility
|
|
public currentUser = computed(() => this.user.value)
|
|
public userDisplay = computed(() => { /* user display logic */ })
|
|
|
|
// Methods
|
|
async login(credentials: LoginCredentials): Promise<void>
|
|
async register(data: RegisterData): Promise<void>
|
|
async logout(): Promise<void>
|
|
async checkAuth(): Promise<boolean>
|
|
async updatePassword(current: string, newPass: string): Promise<void>
|
|
async updateProfile(data: Partial<User>): Promise<void>
|
|
}
|
|
```
|
|
|
|
### 2. useAuthService Composable (API Layer)
|
|
**Location**: `src/composables/useAuthService.ts`
|
|
|
|
The `useAuthService` composable provides a clean, unified API that bridges Vue components with the injected AuthService:
|
|
|
|
```typescript
|
|
export function useAuth() {
|
|
const authService = injectService(SERVICE_TOKENS.AUTH_SERVICE) as AuthService
|
|
|
|
return {
|
|
// State (reactive refs from service)
|
|
currentUser: authService.currentUser,
|
|
isAuthenticated: authService.isAuthenticated,
|
|
isLoading: authService.isLoading,
|
|
error: authService.error,
|
|
userDisplay: authService.userDisplay,
|
|
|
|
// Methods (delegated to service)
|
|
initialize: () => authService.initialize(),
|
|
login: (credentials: any) => authService.login(credentials),
|
|
register: (data: any) => authService.register(data),
|
|
logout: () => authService.logout(),
|
|
checkAuth: () => authService.checkAuth()
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3. Dependency Injection Container
|
|
**Location**: `src/core/di-container.ts`
|
|
|
|
The DI container manages service registration and injection:
|
|
|
|
```typescript
|
|
// Service registration (in base module)
|
|
container.provide(SERVICE_TOKENS.AUTH_SERVICE, authService)
|
|
|
|
// Service consumption (in components/other services)
|
|
const authService = injectService(SERVICE_TOKENS.AUTH_SERVICE) as AuthService
|
|
```
|
|
|
|
## Usage Patterns
|
|
|
|
### In Vue Components (Recommended)
|
|
```vue
|
|
<script setup lang="ts">
|
|
import { useAuth } from '@/composables/useAuthService'
|
|
|
|
const auth = useAuth()
|
|
|
|
// Access reactive state
|
|
const isAuthenticated = auth.isAuthenticated
|
|
const currentUser = auth.currentUser
|
|
|
|
// Call methods
|
|
const handleLogin = async (credentials) => {
|
|
await auth.login(credentials)
|
|
}
|
|
</script>
|
|
```
|
|
|
|
### In Services (Direct Injection)
|
|
```typescript
|
|
import { injectService, SERVICE_TOKENS } from '@/core/di-container'
|
|
import type { AuthService } from '@/modules/base/auth/auth-service'
|
|
|
|
export class SomeService extends BaseService {
|
|
private get authService(): AuthService {
|
|
return this.dependencies.get('AuthService') as AuthService
|
|
}
|
|
|
|
async someMethod() {
|
|
const user = this.authService.user.value
|
|
if (user?.pubkey) {
|
|
// Use authenticated user data
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Benefits of New Architecture
|
|
|
|
### 1. **Single Source of Truth**
|
|
- All authentication state managed by AuthService singleton
|
|
- No more timing issues between global and injected auth
|
|
- Consistent state across all modules and components
|
|
|
|
### 2. **Dependency Injection Benefits**
|
|
- Loose coupling between components and auth logic
|
|
- Easy to test (can inject mock services)
|
|
- Modular architecture with clear boundaries
|
|
- Service lifecycle management
|
|
|
|
### 3. **Improved Maintainability**
|
|
- Centralized authentication logic
|
|
- Event-driven architecture for auth state changes
|
|
- Clear separation of concerns
|
|
- Eliminated complex dual-auth detection patterns
|
|
|
|
### 4. **Performance Improvements**
|
|
- No duplicate service instances
|
|
- Efficient reactive state management
|
|
- Reduced complexity in components
|
|
|
|
## Migration Guide
|
|
|
|
### Before (Legacy Pattern)
|
|
```typescript
|
|
// ❌ Old global composable pattern
|
|
import { auth } from '@/composables/useAuth'
|
|
|
|
// Direct access to global singleton
|
|
const isAuthenticated = auth.isAuthenticated.value
|
|
```
|
|
|
|
### After (Current Pattern)
|
|
```typescript
|
|
// ✅ New dependency injection pattern
|
|
import { useAuth } from '@/composables/useAuthService'
|
|
|
|
const auth = useAuth()
|
|
const isAuthenticated = auth.isAuthenticated.value
|
|
```
|
|
|
|
## Service Integration
|
|
|
|
### Module Registration
|
|
Each module that needs authentication access should:
|
|
|
|
1. **Declare dependency** on AuthService in module metadata
|
|
2. **Access via dependency injection** using the DI container
|
|
3. **Use reactive state** from the service for UI updates
|
|
|
|
### Example Service Integration
|
|
```typescript
|
|
export class ChatService extends BaseService {
|
|
protected readonly metadata = {
|
|
name: 'ChatService',
|
|
dependencies: ['AuthService'] // Declare dependency
|
|
}
|
|
|
|
async sendMessage(content: string) {
|
|
// Access auth through DI
|
|
const user = this.authService.user.value
|
|
if (!user?.pubkey || !user?.prvkey) {
|
|
throw new Error('Authentication required for messaging')
|
|
}
|
|
|
|
// Use authenticated user data
|
|
const encrypted = await nip04.encrypt(user.prvkey, recipientPubkey, content)
|
|
// ... rest of implementation
|
|
}
|
|
}
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
The authentication system provides comprehensive error handling:
|
|
|
|
1. **Network Errors**: Handled in AuthService with proper error propagation
|
|
2. **Invalid Credentials**: Clear error messages passed to components
|
|
3. **Token Expiration**: Automatic logout with cleanup
|
|
4. **Service Unavailable**: Graceful degradation with retry logic
|
|
|
|
## Testing
|
|
|
|
The dependency injection architecture makes testing straightforward:
|
|
|
|
```typescript
|
|
// Mock the auth service for testing
|
|
const mockAuthService = {
|
|
isAuthenticated: ref(true),
|
|
currentUser: ref({ id: 'test-user', username: 'test' }),
|
|
login: vi.fn(),
|
|
logout: vi.fn()
|
|
}
|
|
|
|
// Inject mock in tests
|
|
container.provide(SERVICE_TOKENS.AUTH_SERVICE, mockAuthService)
|
|
```
|
|
|
|
## Security Considerations
|
|
|
|
1. **Token Storage**: Secure storage in localStorage with automatic cleanup
|
|
2. **API Integration**: All requests authenticated via LNBits tokens
|
|
3. **State Management**: Reactive state prevents stale authentication data
|
|
4. **Service Isolation**: Authentication logic isolated in dedicated service
|
|
|
|
## Future Enhancements
|
|
|
|
1. **Token Refresh**: Automatic token refresh before expiration
|
|
2. **Multi-Factor Authentication**: Support for additional auth factors
|
|
3. **Session Management**: Enhanced session handling and persistence
|
|
4. **Audit Logging**: Authentication event logging for security |