@passflow/core 0.20.1 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +504 -86
- package/dist/index.d.ts +504 -86
- package/dist/index.mjs +2644 -880
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -517,6 +517,52 @@ const handleRedirect = () => {
|
|
|
517
517
|
};
|
|
518
518
|
```
|
|
519
519
|
|
|
520
|
+
### Token refresh across tabs
|
|
521
|
+
|
|
522
|
+
Every refresh in a `Passflow` instance (`refreshToken()`, `getTokens(true)`,
|
|
523
|
+
`getTokensWithRefresh()`, the refresh before an SDK API call whose access token expires within
|
|
524
|
+
30 s, and the step-up commit) goes through one refresh controller. In a browser it coordinates
|
|
525
|
+
with the other tabs of the origin, so the engine's one-time refresh tokens are never replayed:
|
|
526
|
+
|
|
527
|
+
- **One refresh per browser.** One tab refreshes under the Web Lock `passflow-refresh`; the others
|
|
528
|
+
adopt its tokens through the `BroadcastChannel` `passflow-auth` and send nothing.
|
|
529
|
+
- **Compare-and-set save.** An answer is saved only if storage still holds the token that was
|
|
530
|
+
sent; a late answer never rolls a newer token back.
|
|
531
|
+
- **Failures are classified.** Network errors, timeouts, 429 and 5xx keep the tokens and retry
|
|
532
|
+
on one shared schedule: 1, 3, 10, 30 s, then every 60 s, plus up to 20 % jitter, never sooner
|
|
533
|
+
than a `Retry-After`. Authentication failures end the session after `refreshStrikes` (default
|
|
534
|
+
3). `error.token.blocked` (the token was already used by another tab) never signs anyone out.
|
|
535
|
+
- **Events.** `RefreshFailing` once when an outage starts, `RefreshRecovered` once when it ends,
|
|
536
|
+
`Refresh` with `source: 'refresh' | 'upgrade' | 'adopted'`, `SessionExpired` only for a real end,
|
|
537
|
+
and exactly one `SignOut` per sign-out in every tab of the user.
|
|
538
|
+
|
|
539
|
+
```javascript
|
|
540
|
+
const passflow = new Passflow({
|
|
541
|
+
appId: "your-app-id",
|
|
542
|
+
refreshCoordination: "web-locks", // default; 'none' or a custom coordinator
|
|
543
|
+
refreshStrikes: 3, // default
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
passflow.subscribe({
|
|
547
|
+
onAuthChange: (event, payload) => {
|
|
548
|
+
if (event === "refresh:failing") showNotice("Reconnecting…"); // tokens are kept
|
|
549
|
+
if (event === "refresh:recovered") hideNotice();
|
|
550
|
+
if (event === "session:expired" || event === "signout") goToSignIn();
|
|
551
|
+
},
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
// On SPA teardown (never called by the SDK itself):
|
|
555
|
+
passflow.dispose();
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
Without `navigator.locks` or `BroadcastChannel` each tab refreshes on its own, still with the
|
|
559
|
+
compare-and-set save, and the SDK writes one `[passflow]` warning at the first refresh. Cookie and
|
|
560
|
+
BFF modes use the same lock, schedule and strikes.
|
|
561
|
+
|
|
562
|
+
The full contract (options, exact event payloads and order, the classification table, the exact
|
|
563
|
+
retry schedule and what resets it, the wire protocol, fallback, cookie/BFF, and migration from
|
|
564
|
+
0.20.1) is in [docs/token-refresh.md](docs/token-refresh.md).
|
|
565
|
+
|
|
520
566
|
## Tenant Management
|
|
521
567
|
|
|
522
568
|
```javascript
|
|
@@ -762,6 +808,8 @@ type PassflowConfig = {
|
|
|
762
808
|
createTenantForNewUser?: boolean;
|
|
763
809
|
parseQueryParams?: boolean;
|
|
764
810
|
keyStoragePrefix?: string;
|
|
811
|
+
refreshCoordination?: "web-locks" | "none" | RefreshCoordinator; // see docs/token-refresh.md
|
|
812
|
+
refreshStrikes?: number;
|
|
765
813
|
};
|
|
766
814
|
```
|
|
767
815
|
|
|
@@ -836,6 +884,12 @@ enum PassflowEvent {
|
|
|
836
884
|
SignOut = "signout",
|
|
837
885
|
Error = "error",
|
|
838
886
|
Refresh = "refresh",
|
|
887
|
+
RefreshStart = "refresh:start",
|
|
888
|
+
RefreshFailing = "refresh:failing",
|
|
889
|
+
RefreshRecovered = "refresh:recovered",
|
|
890
|
+
SessionExpired = "session:expired",
|
|
891
|
+
TokenCacheExpired = "token-cache-expired",
|
|
892
|
+
// ...and the sign-in, 2FA and session events; see lib/store.ts
|
|
839
893
|
}
|
|
840
894
|
```
|
|
841
895
|
|