feat: implement 72-hour JWT token refresh for daily notification plugin
- Add accessTokenForBackground() with 72-hour default expiration - Supports offline-first prefetch operations - Balances security with offline capability - Implement proactive token refresh strategy - Refresh on component mount (DailyNotificationSection) - Refresh on app resume (Capacitor 'resume' event) - Refresh when notifications are enabled - Automatic refresh without user interaction - Update CapacitorPlatformService.configureNativeFetcher() - Automatically retrieves activeDid from database - Generates 72-hour JWT tokens for background operations - Includes starred plans in configuration - Add BroadcastReceivers to AndroidManifest.xml - DailyNotificationReceiver for scheduled notifications - BootReceiver for rescheduling after device reboot - Add comprehensive documentation - JSDoc comments for all token-related functions - Inline comments explaining refresh strategy - Documentation section on authentication & token management Benefits: - No app wake-up required (refresh when app already open) - Works offline (72-hour validity supports extended periods) - Automatic (no user interaction required) - Graceful degradation (uses cached content if refresh fails)
This commit is contained in:
@@ -241,7 +241,7 @@ export interface ScheduleOptions {
|
||||
|
||||
export interface NativeFetcherConfig {
|
||||
apiServer: string;
|
||||
jwt: string;
|
||||
jwt: string; // Ignored - generated automatically by configureNativeFetcher
|
||||
starredPlanHandleIds: string[];
|
||||
}
|
||||
```
|
||||
@@ -250,6 +250,63 @@ export interface NativeFetcherConfig {
|
||||
- **Capacitor**: Full implementation, all methods functional
|
||||
- **Web/Electron**: Status/permission methods return `null`, scheduling methods throw errors with clear messages
|
||||
|
||||
### Authentication & Token Management
|
||||
|
||||
#### Background Prefetch Authentication
|
||||
|
||||
The daily notification plugin requires authentication tokens for background prefetch operations. The implementation uses a **hybrid token refresh strategy** that balances security with offline capability.
|
||||
|
||||
**Token Generation** (`src/libs/crypto/index.ts`):
|
||||
- Function: `accessTokenForBackground(did, expirationMinutes?)`
|
||||
- Default expiration: **72 hours** (4320 minutes)
|
||||
- Token type: JWT with ES256K signing
|
||||
- Payload: `{ exp, iat, iss: did }`
|
||||
|
||||
**Why 72 Hours?**
|
||||
- Balances security (read-only prefetch operations) with offline capability
|
||||
- Reduces need for app to wake itself for token refresh
|
||||
- Allows plugin to work offline for extended periods (e.g., weekend trips)
|
||||
- Longer than typical prefetch windows (5 minutes before notification)
|
||||
|
||||
**Token Refresh Strategy (Hybrid Approach)**:
|
||||
|
||||
1. **Proactive Refresh Triggers**:
|
||||
- Component mount (`DailyNotificationSection.mounted()`)
|
||||
- App resume (Capacitor `resume` event)
|
||||
- Notification enabled (when user enables daily notifications)
|
||||
|
||||
2. **Refresh Implementation** (`DailyNotificationSection.refreshNativeFetcherConfig()`):
|
||||
- Checks if notifications are supported and enabled
|
||||
- Retrieves API server URL from settings
|
||||
- Retrieves starred plans from settings
|
||||
- Calls `configureNativeFetcher()` to generate fresh token
|
||||
- Errors are logged but don't interrupt user experience
|
||||
|
||||
3. **Offline Behavior**:
|
||||
- If token expires while offline → plugin uses cached content
|
||||
- Next time app opens → token automatically refreshed
|
||||
- No app wake-up required (refresh happens when app is already open)
|
||||
|
||||
**Configuration Flow** (`CapacitorPlatformService.configureNativeFetcher()`):
|
||||
|
||||
1. Retrieves active DID from `active_identity` table (single source of truth)
|
||||
2. Generates JWT token with 72-hour expiration using `accessTokenForBackground()`
|
||||
3. Configures plugin with API server URL, active DID, and JWT token
|
||||
4. Plugin stores token in its Room database for background workers
|
||||
|
||||
**Security Considerations**:
|
||||
- Tokens are used only for read-only prefetch operations
|
||||
- Tokens are stored securely in plugin's Room database
|
||||
- Tokens are refreshed proactively to minimize exposure window
|
||||
- No private keys are exposed to native code
|
||||
- Token generation happens in TypeScript (no Java crypto compatibility issues)
|
||||
|
||||
**Error Handling**:
|
||||
- Returns `null` if active DID not found (no user logged in)
|
||||
- Returns `null` if JWT generation fails
|
||||
- Logs errors but doesn't throw (allows graceful degradation)
|
||||
- Refresh failures don't interrupt user experience (plugin uses cached content)
|
||||
|
||||
### Component Architecture
|
||||
|
||||
#### Views Structure
|
||||
|
||||
Reference in New Issue
Block a user