Browse Source
- Added critical requirement that plugin MUST be notified of activeDid changes - Enhanced plugin interface with onActiveDidChange() callback method - Added clearCacheForNewIdentity() and refreshAuthenticationForNewIdentity() methods - Updated integration examples to include activeDid change listeners - Created comprehensive ActiveDid change requirements document covering: * Security implications of not detecting changes * Event-based notification pattern implementation * Cache clearing and authentication refresh requirements * Testing scenarios for identity switching * Platform-specific considerations and edge cases * Performance optimization for rapid identity changes This addresses the critical data integrity and security requirement that the plugin must know when TimeSafari users switch identities to prevent data leakage.research/notification-plugin-enhancement
2 changed files with 223 additions and 3 deletions
@ -0,0 +1,204 @@ |
|||
# 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** |
|||
```typescript |
|||
// 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** |
|||
```typescript |
|||
// 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** |
|||
```typescript |
|||
// 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** |
|||
1. **Event Dispatch**: Must dispatch `activeDidChanged` events |
|||
2. **Timing**: Dispatch immediately after updating active_identity table |
|||
3. **Reliability**: Event must reach all plugin listeners |
|||
|
|||
### **Plugin Responsibilities** |
|||
1. **Event Listening**: Must listen for `activeDidChanged` events |
|||
2. **Cache Clearing**: Must clear all cached content for new identity |
|||
3. **Authentication Refresh**: Must generate new tokens with updated activeDid |
|||
4. **Background Task Update**: Must restart background tasks with new context |
|||
5. **Error Handling**: Must handle failures gracefully during identity transition |
|||
|
|||
## Testing Requirements |
|||
|
|||
### **Integration Tests** |
|||
```typescript |
|||
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 |
Loading…
Reference in new issue