You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6.8 KiB
6.8 KiB
ActiveDid Change Requirements
Author: Matthew Raymer
Version: 1.0.0
Created: 2025-10-02 12:00:00 UTC
Last Updated: 2025-10-02 12:00:00 UTC
Critical Requirement: Plugin Must Know When activeDid Changes
CONFIRMED: The plugin must be notified when activeDid changes to maintain data integrity and security.
Why This Is Critical
Security Implications
- Authentication Isolation: Each activeDid has different authentication tokens
- Data Privacy: Cached content belongs to specific user identity
- Authorization: API calls must use correct activeDid for proper authorization
Data Integrity Issues
- Cache Pollution: Wrong user's data could leak between identities
- Stale Authentication: Old JWT tokens become invalid for new identity
- Background Tasks: Tasks running with wrong identity context
User Experience Problems
// PROBLEMATIC SCENARIO WITHOUT CHANGE NOTIFICATION:
// 1. User A schedules notification for "my offers"
// 2. User switches to User B
// 3. Plugin doesn't know about change
// 4. Plugin delivers User A's personal offer data to User B ❌
Solution: Event-Based Change Notification
TimeSafari Host Application
// In PlatformServiceMixin.ts - CRITICAL PATTERN
async $updateActiveDid(newDid: string | null): Promise<void> {
// ... existing activeDid update logic ...
// MUST notify Daily Notification Plugin
await this.$notifyDailyNotificationService(newDid);
}
async $notifyDailyNotificationService(newActiveDid: string): Promise<void> {
const event = new CustomEvent('activeDidChanged', {
detail: { activeDid: newActiveDid }
});
document.dispatchEvent(event);
}
Plugin Side Implementation
// In Daily Notification Plugin - MANDATORY LISTENING
export class EnhancedDailyNotificationPlugin {
private currentActiveDid: string | null = null;
constructor() {
this.setupActiveDidChangeListener();
}
private setupActiveDidChangeListener(): void {
document.addEventListener('activeDidChanged', (event: CustomEvent) => {
this.handleActiveDidChange(event.detail.activeDid);
});
}
private async handleActiveDidChange(newActiveDid: string): Promise<void> {
if (newActiveDid !== this.currentActiveDid) {
logger.info(`[Plugin] ActiveDid changing from ${this.currentActiveDid} to ${newActiveDid}`);
// CRITICAL ACTIONS REQUIRED:
await this.clearCacheForNewIdentity();
await this.refreshAuthenticationForNewIdentity(newActiveDid);
await this.updateBackgroundTaskIdentity(newActiveDid);
this.currentActiveDid = newActiveDid;
}
}
async clearCacheForNewIdentity(): Promise<void> {
// Clear all cached content to prevent data leakage
await this.clearStoredContent();
await this.clearAuthenticationTokens();
}
async refreshAuthenticationForNewIdentity(activeDid: string): Promise<void> {
// Generate new JWT tokens with correct activeDid
const newJwt = await this.generateJWT(activeDid);
this.currentAuthToken = newJwt;
}
async updateBackgroundTaskIdentity(activeDid: string): Promise<void> {
// Update background tasks to use new identity
await this.pauseBackgroundTasks();
await this.configureBackgroundTasksForIdentity(activeDid);
await this.resumeBackgroundTasks();
}
}
Implementation Requirements
Host Application Responsibilities
- Event Dispatch: Must dispatch
activeDidChanged
events - Timing: Dispatch immediately after updating active_identity table
- Reliability: Event must reach all plugin listeners
Plugin Responsibilities
- Event Listening: Must listen for
activeDidChanged
events - Cache Clearing: Must clear all cached content for new identity
- Authentication Refresh: Must generate new tokens with updated activeDid
- Background Task Update: Must restart background tasks with new context
- Error Handling: Must handle failures gracefully during identity transition
Testing Requirements
Integration Tests
describe('ActiveDid Change Handling', () => {
it('should clear cache when activeDid changes', async () => {
// Set up initial identity
await plugin.setActiveDidFromHost('did:alice:123');
await plugin.cacheContentData({ /* Alice's data */ });
// Simulate identity change
const event = new CustomEvent('activeDidChanged', {
detail: { activeDid: 'did:bob:456' }
});
document.dispatchEvent(event);
// Verify cache is cleared
expect(await plugin.getCachedContent()).toBeNull();
});
it('should refresh authentication tokens', async () => {
// Set initial identity
const aliceToken = await plugin.generateJWT('did:alice:123');
// Change identity
document.dispatchEvent(new CustomEvent('activeDidChanged', {
detail: { activeDid: 'did:bob:456' }
}));
// Verify new token with correct identity
const bobToken = await plugin.getCurrentAuthToken();
expect(bobToken.payload.sub).toBe('did:bob:456');
});
it('should handle multiple rapid identity changes', async () => {
// Test rapid switching between identities
const identities = ['did:alice:123', 'did:bob:456', 'did:alice:123'];
for (const identity of identities) {
document.dispatchEvent(new CustomEvent('activeDidChanged', {
detail: { activeDid: identity }
}));
await new Promise(resolve => setTimeout(resolve, 100)); // Brief pause
}
// Ensure plugin ends up in correct state
expect(plugin.currentActiveDid).toBe('did:alice:123');
});
});
Edge Case Testing
- Network Failure: Identity changes during network failures
- Background Mode: Identity changes when app is backgrounded
- Rapid Switches: Multiple identity changes in quick succession
- Invalid activeDid: Change to empty or invalid activeDid
Platform-Specific Considerations
Android/Electron
- Plugin can detect activeDid changes in background via database polling
- Backup mechanism if event-based notification fails
Web
- Event-based notification is primary mechanism
- Fallback to periodic activeDid checking
iOS
- Background tasks can check activeDid changes
- Event-based notification for foreground changes
Performance Considerations
Change Detection Optimization
- Debounce rapid identity changes
- Batch cache clearing operations
- Minimize background task restarts
Resource Cleanup
- Clear authentication tokens immediately
- Clean up cached content efficiently
- Avoid memory leaks during transitions
Status: Critical requirement documented - Implementation required
Next Steps: Add activeDid change listeners to plugin implementation
Security Impact: HIGH - Prevents data leakage between user identities