# 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