Add plan-background-jwt-pool-and-expiry.md (Phase A/B, expiryDays + buffer sizing, pool size 100). Add plugin-feedback-daily-notification-configureNativeFetcher-jwt-pool.md for daily-notification-plugin: optional jwtTokens on configureNativeFetcher. Link plan to plugin doc and endorser-jwt-background-prefetch-options.md.
4.1 KiB
Plugin feedback: configureNativeFetcher — optional JWT pool for background API calls
Date: 2026-03-27 PST
Target repo: @timesafari/daily-notification-plugin (daily-notification-plugin)
Consuming app: crowd-funder-for-time-pwa (TimeSafari)
Related app plan: doc/plan-background-jwt-pool-and-expiry.md (Phase B, Option B1)
Summary
The host app’s NativeNotificationContentFetcher (TimeSafariNativeFetcher on Android) calls Endorser with a Bearer JWT set via configureNativeFetcher. For background prefetch, the token must stay valid until WorkManager runs (often minutes later); Endorser may also reject duplicate JWT strings across days.
The app will mint a pool of distinct JWTs (see app plan) and needs the plugin to accept and persist that pool so native code can select a token without JavaScript at prefetch time.
Requested change (plugin): extend configureNativeFetcher to accept an optional JWT pool alongside the existing jwtToken, persist it in the same storage the host already relies on (e.g. SharedPreferences / app group), and document how NativeNotificationContentFetcher implementations should read it.
Motivation
| Issue | Why plugin support helps |
|---|---|
Single short-lived jwtToken |
Expires before background fetch |
| Server duplicate-JWT rules | Need many distinct bearer strings over time |
| No JS in WorkManager | Pool must be readable only from native |
Proposed API (TypeScript / Capacitor)
Extend existing configureNativeFetcher options (names indicative — align with plugin naming conventions):
configureNativeFetcher(options: {
apiBaseUrl: string;
activeDid: string;
/** Primary token; keep for backward compatibility and Phase A (single long-lived JWT). */
jwtToken: string;
/**
* Optional. Distinct JWT strings for background use (e.g. one per day slot).
* If omitted, behavior matches today (single jwtToken only).
*/
jwtTokens?: string[];
});
Alternatives (if size limits matter for bridge payload):
jwtTokenPoolJson: string— JSON array string of JWT strings (single string across the bridge).
Validation (plugin):
- If
jwtTokenspresent: length ≤ a sane cap (host will use ~100; plugin may enforce max e.g. 128). - Empty array: treat as “no pool” (same as omitting).
Android
- Parse new fields in
DailyNotificationPlugin.configureNativeFetcher(or equivalent). - Persist pool under the same prefs namespace used for other TimeSafari / dual-schedule data, or a documented key prefix (e.g.
jwt_token_poolas JSON array string). - Document for host implementers:
NativeNotificationContentFetchershould:- Prefer pool entry for
fetchContentwhen pool is non-empty (selection policy is host responsibility — e.g. day index % length), or - Expose a small helper the host fetcher calls to resolve “current” bearer.
- Prefer pool entry for
- Clear pool when
configureNativeFetcheris called with a new identity / empty pool / logout path (coordinate with host). - Backward compatibility: if only
jwtTokenis sent, behavior unchanged from current release.
iOS
When configureNativeFetcher exists on iOS, mirror Android: accept optional pool, persist, document read path for native fetcher.
Versioning & release
- Bump plugin semver (minor: new optional fields).
- Publish package; consuming app bumps
@timesafari/daily-notification-pluginand updatesnativeFetcherConfig.tsto passjwtTokenswhen Phase B ships.
References (host app)
| Topic | Location |
|---|---|
| End-to-end plan (Phase A/B, pool sizing) | doc/plan-background-jwt-pool-and-expiry.md |
| Android fetcher | android/.../TimeSafariNativeFetcher.java |
| Current configure call | src/services/notifications/nativeFetcherConfig.ts |
| JWT options (expired token context) | doc/endorser-jwt-background-prefetch-options.md |
This document is intended to be copied or linked from PRs in daily-notification-plugin; keep app-specific details in the app plan.