diff --git a/docs/host-request-configuration.md b/docs/host-request-configuration.md new file mode 100644 index 0000000..d6f9a51 --- /dev/null +++ b/docs/host-request-configuration.md @@ -0,0 +1,741 @@ +# TimeSafari Daily Notification Plugin - Host Request Configuration Guide + +**Author**: Matthew Raymer +**Version**: 1.0.0 +**Created**: 2025-10-08 06:24:57 UTC + +## Overview + +This guide explains how the TimeSafari PWA host application should configure HTTP requests and network settings for the Daily Notification Plugin. The plugin uses a **host-managed request pattern** where the host provides network configuration and the plugin handles the actual requests. + +## Request Configuration Architecture + +### Plugin Request Pattern +``` +Host Application (TimeSafari PWA) + ↓ (provides configuration) +Plugin Network Layer + ↓ (executes requests) +External APIs (Endorser.ch, etc.) +``` + +### Key Principles +1. **Host-Managed Configuration**: Host provides all network settings +2. **Plugin Execution**: Plugin handles actual HTTP requests +3. **Structured Logging**: All requests are logged with event IDs +4. **Circuit Breaker**: Built-in failure handling and retry logic +5. **ETag Support**: Conditional requests for efficient caching + +## Host Configuration Options + +### 1. Basic Network Configuration + +```typescript +// In TimeSafari PWA main configuration +import { DailyNotification } from '@timesafari/daily-notification-plugin'; + +await DailyNotification.configure({ + // Basic network settings + networkConfig: { + timeout: 30000, // 30 second timeout + retryAttempts: 3, // 3 retry attempts + retryDelay: 1000, // 1 second initial delay + maxConcurrent: 5, // Max 5 concurrent requests + userAgent: 'TimeSafari-PWA/1.0.0' + }, + + // Request headers + headers: { + 'Accept': 'application/json', + 'Accept-Language': 'en-US,en;q=0.9', + 'Cache-Control': 'no-cache' + } +}); +``` + +### 2. TimeSafari-Specific Configuration + +```typescript +// TimeSafari Endorser.ch API configuration +await DailyNotification.configure({ + timesafariConfig: { + // Required: Active DID for authentication + activeDid: userDid, + + // API endpoints (optional - defaults provided) + endpoints: { + offersToPerson: 'https://endorser.ch/api/v1/offers/person', + offersToPlans: 'https://endorser.ch/api/v1/offers/plans', + projectsLastUpdated: 'https://endorser.ch/api/v1/projects/last-updated' + }, + + // Sync configuration + syncConfig: { + enableParallel: true, // Enable parallel API requests + maxConcurrent: 3, // Max 3 concurrent requests + batchSize: 10 // Batch size for requests + }, + + // Credential configuration + credentialConfig: { + jwtSecret: process.env.JWT_SECRET, + tokenExpirationMinutes: 60, + refreshThresholdMinutes: 10 + }, + + // Error handling policy + errorPolicy: { + maxRetries: 3, + backoffMultiplier: 2, + activeDidChangeRetries: 5 // Special retry for DID changes + } + } +}); +``` + +### 3. Content Fetch Configuration + +```typescript +// Configure content fetching +await DailyNotification.configure({ + contentFetch: { + enabled: true, + schedule: '0 8 * * *', // Daily at 8 AM + + // Request configuration + url: 'https://endorser.ch/api/v1/community/updates', + headers: { + 'Authorization': `Bearer ${authToken}`, + 'X-User-DID': userDid, + 'X-Client-Version': '1.0.0' + }, + timeout: 15000, + retryAttempts: 2, + retryDelay: 2000, + + // Callback configuration + callbacks: { + apiService: 'https://api.timesafari.com/notifications/callback', + database: 'local://notification-storage', + reporting: 'https://analytics.timesafari.com/events' + }, + + // Cache policy + cachePolicy: { + maxAge: 3600, // 1 hour cache + staleWhileRevalidate: 1800, // 30 minutes stale + etagSupport: true + } + } +}); +``` + +## Platform-Specific Request Configuration + +### Android Configuration + +```typescript +// Android-specific network configuration +await DailyNotification.configure({ + platform: 'android', + + // Android network settings + androidConfig: { + // WorkManager constraints + workManagerConstraints: { + requiresNetworkType: 'CONNECTED', + requiresBatteryNotLow: false, + requiresCharging: false, + requiresDeviceIdle: false, + requiresStorageNotLow: false + }, + + // Network security + networkSecurityConfig: { + cleartextTrafficPermitted: false, + certificatePinning: true, + trustedCertificates: ['endorser.ch', 'api.timesafari.com'] + }, + + // Request configuration + requestConfig: { + connectTimeout: 30000, + readTimeout: 30000, + writeTimeout: 30000, + followRedirects: true, + followSslRedirects: true + } + } +}); +``` + +### iOS Configuration + +```typescript +// iOS-specific network configuration +await DailyNotification.configure({ + platform: 'ios', + + // iOS network settings + iosConfig: { + // Background task configuration + backgroundTasks: { + 'com.timesafari.daily-notification-fetch': { + identifier: 'com.timesafari.daily-notification-fetch', + requiresNetworkConnectivity: true, + requiresExternalPower: false, + requiresDeviceIdle: false + } + }, + + // URL session configuration + urlSessionConfig: { + timeoutIntervalForRequest: 30, + timeoutIntervalForResource: 60, + allowsCellularAccess: true, + allowsConstrainedNetworkAccess: true, + allowsExpensiveNetworkAccess: true + }, + + // App transport security + atsConfig: { + allowsArbitraryLoads: false, + allowsLocalNetworking: false, + exceptionDomains: { + 'endorser.ch': { + nstExceptionAllowsInsecureHTTPLoads: false, + nstExceptionMinimumTLSVersion: 'TLSv1.2' + } + } + } + } +}); +``` + +### Electron Configuration + +```typescript +// Electron-specific network configuration +await DailyNotification.configure({ + platform: 'electron', + + // Electron network settings + electronConfig: { + // Session configuration + sessionConfig: { + userAgent: 'TimeSafari-Desktop/1.0.0', + acceptLanguages: ['en-US', 'en'], + cacheEnabled: true, + cacheSize: 100 * 1024 * 1024 // 100MB cache + }, + + // Request configuration + requestConfig: { + timeout: 30000, + maxRedirects: 5, + followRedirects: true, + validateSSL: true + }, + + // Proxy configuration (if needed) + proxyConfig: { + enabled: false, + type: 'http', + host: '', + port: 0, + username: '', + password: '' + } + } +}); +``` + +## Advanced Request Configuration + +### 1. Circuit Breaker Configuration + +```typescript +// Circuit breaker for fault tolerance +await DailyNotification.configure({ + circuitBreaker: { + failureThreshold: 5, // Open after 5 failures + recoveryTimeout: 30000, // 30 second recovery timeout + monitoringPeriod: 60000 // 1 minute monitoring period + } +}); +``` + +### 2. Rate Limiting Configuration + +```typescript +// Rate limiting configuration +await DailyNotification.configure({ + rateLimiting: { + maxRequestsPerMinute: 30, + maxRequestsPerHour: 1000, + burstLimit: 10, + backoffStrategy: 'exponential', + jitterEnabled: true + } +}); +``` + +### 3. Authentication Configuration + +```typescript +// Authentication configuration +await DailyNotification.configure({ + authentication: { + // JWT configuration + jwt: { + secret: process.env.JWT_SECRET, + algorithm: 'HS256', + expirationMinutes: 60, + refreshThresholdMinutes: 10 + }, + + // API key configuration + apiKey: { + header: 'X-API-Key', + value: process.env.API_KEY + }, + + // OAuth configuration + oauth: { + clientId: process.env.OAUTH_CLIENT_ID, + clientSecret: process.env.OAUTH_CLIENT_SECRET, + tokenEndpoint: 'https://auth.timesafari.com/oauth/token', + scope: 'notifications:read notifications:write' + } + } +}); +``` + +## Request Monitoring and Observability + +### 1. Structured Logging Configuration + +```typescript +// Configure structured logging +await DailyNotification.configure({ + logging: { + level: 'INFO', + enableRequestLogging: true, + enableResponseLogging: true, + enableErrorLogging: true, + enablePerformanceLogging: true, + + // Log formatting + logFormat: 'json', + includeHeaders: false, // Don't log sensitive headers + includeBody: false, // Don't log request/response bodies + redactSensitiveData: true + } +}); +``` + +### 2. Metrics Configuration + +```typescript +// Configure metrics collection +await DailyNotification.configure({ + metrics: { + enabled: true, + collectionInterval: 60000, // 1 minute + + // Metrics to collect + requestMetrics: { + count: true, + duration: true, + statusCodes: true, + errorRates: true + }, + + // Performance metrics + performanceMetrics: { + cacheHitRate: true, + networkLatency: true, + retryCount: true, + circuitBreakerState: true + } + } +}); +``` + +## Error Handling Configuration + +### 1. Retry Configuration + +```typescript +// Retry configuration +await DailyNotification.configure({ + retry: { + // Exponential backoff + strategy: 'exponential', + initialDelay: 1000, // 1 second + maxDelay: 30000, // 30 seconds + multiplier: 2, + jitter: true, + + // Retry conditions + retryOn: { + networkErrors: true, + timeoutErrors: true, + serverErrors: true, // 5xx errors + clientErrors: false // Don't retry 4xx errors + }, + + // Max retries per request type + maxRetries: { + contentFetch: 3, + notificationDelivery: 2, + callbackDelivery: 1 + } + } +}); +``` + +### 2. Fallback Configuration + +```typescript +// Fallback configuration +await DailyNotification.configure({ + fallback: { + // Content fallbacks + contentFallbacks: [ + { + condition: 'network_unavailable', + action: 'use_cached_content', + maxAge: 3600 // 1 hour + }, + { + condition: 'api_error', + action: 'use_emergency_content', + content: { + title: 'TimeSafari Community Update', + body: 'Check back later for the latest updates!' + } + } + ], + + // Notification fallbacks + notificationFallbacks: [ + { + condition: 'permission_denied', + action: 'show_in_app_notification' + }, + { + condition: 'platform_unsupported', + action: 'log_warning' + } + ] + } +}); +``` + +## Security Configuration + +### 1. SSL/TLS Configuration + +```typescript +// SSL/TLS configuration +await DailyNotification.configure({ + security: { + // Certificate pinning + certificatePinning: { + enabled: true, + pins: [ + { + hostname: 'endorser.ch', + pins: [ + 'sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=', + 'sha256/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=' + ] + } + ] + }, + + // TLS configuration + tls: { + minVersion: '1.2', + maxVersion: '1.3', + cipherSuites: [ + 'TLS_AES_256_GCM_SHA384', + 'TLS_CHACHA20_POLY1305_SHA256', + 'TLS_AES_128_GCM_SHA256' + ] + } + } +}); +``` + +### 2. Data Protection Configuration + +```typescript +// Data protection configuration +await DailyNotification.configure({ + dataProtection: { + // Encryption at rest + encryption: { + enabled: true, + algorithm: 'AES-256-GCM', + keyDerivation: 'PBKDF2' + }, + + // Data redaction + redaction: { + enabled: true, + patterns: [ + 'password', + 'token', + 'secret', + 'key', + 'authorization' + ] + }, + + // Data retention + retention: { + maxAge: 30 * 24 * 60 * 60 * 1000, // 30 days + autoCleanup: true + } + } +}); +``` + +## Integration Examples + +### 1. TimeSafari PWA Integration + +```typescript +// In TimeSafari PWA main.ts +import { DailyNotification } from '@timesafari/daily-notification-plugin'; +import { TimeSafariIntegrationService } from '@timesafari/daily-notification-plugin'; + +// Initialize with TimeSafari configuration +const initializeDailyNotifications = async () => { + try { + // Configure plugin with TimeSafari settings + await DailyNotification.configure({ + // Basic configuration + storage: 'tiered', + ttlSeconds: 1800, + enableETagSupport: true, + + // TimeSafari-specific configuration + timesafariConfig: { + activeDid: userDid, + endpoints: { + offersToPerson: 'https://endorser.ch/api/v1/offers/person', + offersToPlans: 'https://endorser.ch/api/v1/offers/plans' + }, + syncConfig: { + enableParallel: true, + maxConcurrent: 3, + batchSize: 10 + } + }, + + // Network configuration + networkConfig: { + timeout: 30000, + retryAttempts: 3, + retryDelay: 1000, + maxConcurrent: 5 + }, + + // Authentication + authentication: { + jwt: { + secret: process.env.JWT_SECRET, + algorithm: 'HS256', + expirationMinutes: 60 + } + }, + + // Observability + logging: { + level: 'INFO', + enableRequestLogging: true, + redactSensitiveData: true + }, + + // Security + security: { + certificatePinning: { + enabled: true, + pins: [ + { + hostname: 'endorser.ch', + pins: ['sha256/...'] + } + ] + } + } + }); + + // Initialize TimeSafari integration + const integrationService = TimeSafariIntegrationService.getInstance(); + await integrationService.initialize({ + activeDid: userDid, + storageAdapter: timeSafariStorageAdapter, + endorserApiBaseUrl: 'https://endorser.ch/api/v1' + }); + + console.log('Daily notifications configured successfully'); + + } catch (error) { + console.error('Failed to configure daily notifications:', error); + } +}; + +// Initialize on app startup +initializeDailyNotifications(); +``` + +### 2. Vue.js Component Integration + +```typescript +// In TimeSafari PWA Vue component +import { defineComponent } from 'vue'; +import { DailyNotification } from '@timesafari/daily-notification-plugin'; + +export default defineComponent({ + name: 'DailyNotificationSettings', + + async mounted() { + // Configure notifications for this component + await DailyNotification.configure({ + // Component-specific configuration + contentFetch: { + enabled: true, + schedule: '0 9 * * *', // 9 AM daily + url: 'https://endorser.ch/api/v1/community/updates', + headers: { + 'Authorization': `Bearer ${this.authToken}`, + 'X-User-DID': this.userDid + }, + callbacks: { + onSuccess: async (data) => { + // Handle successful fetch + this.updateNotificationContent(data); + }, + onError: async (error) => { + // Handle fetch error + this.handleNotificationError(error); + } + } + } + }); + }, + + methods: { + async updateNotificationContent(data: Record) { + // Update UI with new content + this.notificationData = data; + }, + + async handleNotificationError(error: Error) { + // Handle error in UI + this.showError(error.message); + } + } +}); +``` + +## Troubleshooting + +### Common Configuration Issues + +#### 1. Network Timeout Issues +```typescript +// Increase timeout for slow networks +await DailyNotification.configure({ + networkConfig: { + timeout: 60000, // 60 seconds + retryAttempts: 5, + retryDelay: 2000 + } +}); +``` + +#### 2. Authentication Issues +```typescript +// Debug authentication +await DailyNotification.configure({ + logging: { + level: 'DEBUG', + enableRequestLogging: true, + includeHeaders: true // Temporarily enable for debugging + } +}); +``` + +#### 3. Certificate Issues +```typescript +// Disable certificate pinning for development +await DailyNotification.configure({ + security: { + certificatePinning: { + enabled: false // Only for development + } + } +}); +``` + +### Debugging Request Issues + +#### 1. Enable Debug Logging +```typescript +// Enable comprehensive logging +await DailyNotification.configure({ + logging: { + level: 'DEBUG', + enableRequestLogging: true, + enableResponseLogging: true, + enableErrorLogging: true, + enablePerformanceLogging: true + } +}); +``` + +#### 2. Monitor Request Metrics +```typescript +// Get request statistics +const stats = await DailyNotification.getRequestStats(); +console.log('Request Statistics:', stats); + +// Get error statistics +const errors = await DailyNotification.getErrorStats(); +console.log('Error Statistics:', errors); +``` + +## Best Practices + +### 1. Configuration Management +- **Environment Variables**: Use environment variables for sensitive data +- **Configuration Validation**: Validate configuration on startup +- **Graceful Degradation**: Provide fallbacks for missing configuration +- **Configuration Updates**: Support runtime configuration updates + +### 2. Security Best Practices +- **Certificate Pinning**: Enable for production environments +- **Data Redaction**: Always redact sensitive data in logs +- **Token Management**: Use secure token storage and rotation +- **Network Security**: Use HTTPS for all requests + +### 3. Performance Best Practices +- **Connection Pooling**: Reuse HTTP connections +- **Request Batching**: Batch multiple requests when possible +- **Caching**: Use ETag support for efficient caching +- **Rate Limiting**: Implement appropriate rate limits + +### 4. Monitoring Best Practices +- **Structured Logging**: Use structured logs with event IDs +- **Metrics Collection**: Collect relevant performance metrics +- **Error Tracking**: Track and analyze error patterns +- **Health Checks**: Implement health check endpoints + +--- + +**Note**: This configuration guide should be updated as the plugin evolves. Regular review and updates are recommended to ensure accuracy and completeness. diff --git a/docs/request-configuration-quick-reference.md b/docs/request-configuration-quick-reference.md new file mode 100644 index 0000000..9c8aa52 --- /dev/null +++ b/docs/request-configuration-quick-reference.md @@ -0,0 +1,372 @@ +# TimeSafari Daily Notification Plugin - Request Configuration Quick Reference + +**Author**: Matthew Raymer +**Version**: 1.0.0 +**Created**: 2025-10-08 06:24:57 UTC + +## Quick Setup for TimeSafari PWA + +### Basic Configuration +```typescript +import { DailyNotification } from '@timesafari/daily-notification-plugin'; + +await DailyNotification.configure({ + // Required: Active DID for TimeSafari integration + timesafariConfig: { + activeDid: userDid + }, + + // Basic network settings + networkConfig: { + timeout: 30000, + retryAttempts: 3, + maxConcurrent: 5 + } +}); +``` + +### Complete TimeSafari Configuration +```typescript +await DailyNotification.configure({ + // TimeSafari integration + timesafariConfig: { + activeDid: userDid, + endpoints: { + offersToPerson: 'https://endorser.ch/api/v1/offers/person', + offersToPlans: 'https://endorser.ch/api/v1/offers/plans' + }, + syncConfig: { + enableParallel: true, + maxConcurrent: 3, + batchSize: 10 + } + }, + + // Network configuration + networkConfig: { + timeout: 30000, + retryAttempts: 3, + retryDelay: 1000, + maxConcurrent: 5, + userAgent: 'TimeSafari-PWA/1.0.0' + }, + + // Authentication + authentication: { + jwt: { + secret: process.env.JWT_SECRET, + algorithm: 'HS256', + expirationMinutes: 60 + } + }, + + // Observability + logging: { + level: 'INFO', + enableRequestLogging: true, + redactSensitiveData: true + } +}); +``` + +## Platform-Specific Quick Configs + +### Android +```typescript +await DailyNotification.configure({ + platform: 'android', + androidConfig: { + workManagerConstraints: { + requiresNetworkType: 'CONNECTED', + requiresBatteryNotLow: false + }, + requestConfig: { + connectTimeout: 30000, + readTimeout: 30000 + } + } +}); +``` + +### iOS +```typescript +await DailyNotification.configure({ + platform: 'ios', + iosConfig: { + backgroundTasks: { + 'com.timesafari.daily-notification-fetch': { + requiresNetworkConnectivity: true + } + }, + urlSessionConfig: { + timeoutIntervalForRequest: 30, + allowsCellularAccess: true + } + } +}); +``` + +### Electron +```typescript +await DailyNotification.configure({ + platform: 'electron', + electronConfig: { + sessionConfig: { + userAgent: 'TimeSafari-Desktop/1.0.0', + cacheEnabled: true + }, + requestConfig: { + timeout: 30000, + maxRedirects: 5 + } + } +}); +``` + +## Common Request Patterns + +### 1. Content Fetching +```typescript +await DailyNotification.configure({ + contentFetch: { + enabled: true, + schedule: '0 8 * * *', // Daily at 8 AM + url: 'https://endorser.ch/api/v1/community/updates', + headers: { + 'Authorization': `Bearer ${authToken}`, + 'X-User-DID': userDid + }, + timeout: 15000, + retryAttempts: 2 + } +}); +``` + +### 2. Callback Configuration +```typescript +await DailyNotification.configure({ + callbacks: { + apiService: 'https://api.timesafari.com/notifications/callback', + database: 'local://notification-storage', + reporting: 'https://analytics.timesafari.com/events', + onSuccess: async (data) => { + // Handle successful fetch + console.log('Content fetched:', data); + }, + onError: async (error) => { + // Handle error + console.error('Fetch error:', error); + } + } +}); +``` + +### 3. Circuit Breaker +```typescript +await DailyNotification.configure({ + circuitBreaker: { + failureThreshold: 5, + recoveryTimeout: 30000, + monitoringPeriod: 60000 + } +}); +``` + +### 4. Rate Limiting +```typescript +await DailyNotification.configure({ + rateLimiting: { + maxRequestsPerMinute: 30, + maxRequestsPerHour: 1000, + burstLimit: 10, + backoffStrategy: 'exponential' + } +}); +``` + +## Security Quick Configs + +### Certificate Pinning +```typescript +await DailyNotification.configure({ + security: { + certificatePinning: { + enabled: true, + pins: [ + { + hostname: 'endorser.ch', + pins: ['sha256/YOUR_PIN_HERE'] + } + ] + } + } +}); +``` + +### Data Protection +```typescript +await DailyNotification.configure({ + dataProtection: { + encryption: { + enabled: true, + algorithm: 'AES-256-GCM' + }, + redaction: { + enabled: true, + patterns: ['password', 'token', 'secret'] + } + } +}); +``` + +## Debugging Configs + +### Enable Debug Logging +```typescript +await DailyNotification.configure({ + logging: { + level: 'DEBUG', + enableRequestLogging: true, + enableResponseLogging: true, + enableErrorLogging: true + } +}); +``` + +### Disable Security for Development +```typescript +await DailyNotification.configure({ + security: { + certificatePinning: { + enabled: false // Only for development + } + } +}); +``` + +## Error Handling Quick Configs + +### Retry Configuration +```typescript +await DailyNotification.configure({ + retry: { + strategy: 'exponential', + initialDelay: 1000, + maxDelay: 30000, + multiplier: 2, + maxRetries: { + contentFetch: 3, + notificationDelivery: 2 + } + } +}); +``` + +### Fallback Configuration +```typescript +await DailyNotification.configure({ + fallback: { + contentFallbacks: [ + { + condition: 'network_unavailable', + action: 'use_cached_content', + maxAge: 3600 + } + ] + } +}); +``` + +## Vue.js Integration Example + +```typescript +// In your Vue component +import { defineComponent } from 'vue'; +import { DailyNotification } from '@timesafari/daily-notification-plugin'; + +export default defineComponent({ + name: 'NotificationSettings', + + async mounted() { + await DailyNotification.configure({ + timesafariConfig: { + activeDid: this.userDid + }, + contentFetch: { + enabled: true, + schedule: '0 9 * * *', + callbacks: { + onSuccess: this.handleSuccess, + onError: this.handleError + } + } + }); + }, + + methods: { + handleSuccess(data: Record) { + this.notificationData = data; + }, + + handleError(error: Error) { + this.showError(error.message); + } + } +}); +``` + +## Environment Variables + +### Required Environment Variables +```bash +# TimeSafari configuration +JWT_SECRET=your_jwt_secret_here +API_KEY=your_api_key_here + +# Optional configuration +OAUTH_CLIENT_ID=your_oauth_client_id +OAUTH_CLIENT_SECRET=your_oauth_client_secret +``` + +### Development Environment +```bash +# Development settings +NODE_ENV=development +LOG_LEVEL=DEBUG +CERTIFICATE_PINNING=false +``` + +## Common Issues and Solutions + +### Issue: Network Timeout +**Solution**: Increase timeout +```typescript +networkConfig: { + timeout: 60000 // 60 seconds +} +``` + +### Issue: Authentication Errors +**Solution**: Check JWT configuration +```typescript +authentication: { + jwt: { + secret: process.env.JWT_SECRET, + algorithm: 'HS256' + } +} +``` + +### Issue: Certificate Errors +**Solution**: Disable pinning for development +```typescript +security: { + certificatePinning: { + enabled: false + } +} +``` + +--- + +**For detailed configuration options, see**: `docs/host-request-configuration.md`