@apteva/web-sdk 0.8.0 → 0.10.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/CHANGELOG.md CHANGED
@@ -1,3 +1,33 @@
1
+ ## 0.10.0
2
+
3
+ - Add generic opt-in managed Auth persistence (`auth.persistence: "local"`),
4
+ `auth.restore()`, credential-free restoration state, and `auth.dispose()`.
5
+ - Persist only refresh credentials and versioned scope/session metadata. Keep
6
+ access tokens and authoritative identity/permissions in memory.
7
+ - Coordinate same-origin tabs with Web Locks, notifications and durable refresh
8
+ markers; reject unsafe reuse after lost responses, crashes or uncertain commits.
9
+ - Preserve memory-only defaults, explicit app credential selection and no write
10
+ replay. Browsers without Web Locks/storage use memory-only login.
11
+ - No implicit legacy-format import; adoption requires one login.
12
+ - Pair persistence with Auth v0.12.1 for explicit retry-safe refresh errors.
13
+
14
+ ## 0.9.0
15
+
16
+ - Add `credential: "auth" | "platform"` to app handles, extensions and frontend
17
+ loaders. HTTP, MCP and SSE use the selected credential within one managed session.
18
+ - Refresh Auth and platform credentials independently with shared renewal across
19
+ handles. Auth routes remain usable when platform minting is unavailable.
20
+ - Prevent stale mints and old-session 401s from overwriting a newer session.
21
+ Both stream types reconnect at their credential expiry and close on logout or
22
+ detected session revocation. No credential fallback or HTTP replay after a 401.
23
+ - Restrict managed forwarding to the configured server, project and scoped app
24
+ routes; reject escaped paths, URL credentials, header overrides and redirects.
25
+ - Managed `getAccessToken()` now returns `undefined`; use app handles instead.
26
+ Host-owned opaque-token transport retains its existing behavior.
27
+ - Add mixed-session regression tests and an opt-in integration harness using real
28
+ Auth, API and Telephony handlers. Platform mint/Conversations gateway are fixtures.
29
+ - Requires Auth v0.12.0 or newer. No additional Auth or server release required.
30
+
1
31
  ## 0.8.0
2
32
 
3
33
  - Add unified Auth app login/signup, user lookup, session metadata, automatic
package/README.md CHANGED
@@ -557,7 +557,7 @@ bun run serve
557
557
 
558
558
  MIT
559
559
 
560
- ## One client for Auth app sessions (v0.8.0)
560
+ ## One client for Auth app sessions (v0.9.0)
561
561
 
562
562
  With Auth app v0.12.0 or newer, configure `auth` and use the same client for
563
563
  login, app requests, agents and logout:
@@ -576,7 +576,17 @@ const apteva = new AptevaClient({
576
576
  });
577
577
 
578
578
  const user = await apteva.auth.login({ email, password });
579
- await apteva.app("conversations").get("/chats");
579
+ const crm = apteva.app("api", { credential: "auth" });
580
+ const conversations = apteva.app("conversations", { credential: "platform" });
581
+ await crm.get("/YOUR_CRM_ROUTE");
582
+ await conversations.get("/chats");
583
+
584
+ const telephony = await apteva.apps.load("telephony", {
585
+ credential: "auth",
586
+ installId: YOUR_TELEPHONY_INSTALL_ID,
587
+ clientOptions: { authProvider: "YOUR_CONFIGURED_PROVIDER" },
588
+ });
589
+ // The loaded client keeps this Auth handle for /user/ calls and subscriptions.
580
590
  await apteva.auth.logout();
581
591
  ```
582
592
 
@@ -588,40 +598,161 @@ metadata without credentials. `auth.status()` reports local session presence.
588
598
  `auth.refresh()` explicitly requests a fresh platform credential when needed.
589
599
 
590
600
  Auth owns identity and authorization. Configure its trusted role bindings and
591
- matching platform policies with `token_ttl_seconds: 60` before enabling protected
592
- app access. Login can succeed without app permissions; app calls then fail closed
593
- until an authorized policy can mint a token. A requested profile never grants a
601
+ matching platform policies with `token_ttl_seconds: 60` before enabling platform
602
+ app access. Login can succeed without platform permissions; platform calls fail
603
+ closed until an authorized policy can mint a token. Auth-credential routes remain
604
+ available according to their own current user permissions. A requested profile never grants a
594
605
  role. The SDK does not infer permissions or mint credentials itself.
595
606
 
596
607
  The SDK privately maintains the normal Auth session plus its short-lived
597
- platform token. Before an app request it renews a platform token that is within
598
- ten seconds of expiry. Expired/stale Auth credentials use the normal refresh
599
- flow. Concurrent operations share renewal and refresh-token rotation; no custom
608
+ platform token. Choose `credential: "auth"` for API Auth-policy routes and
609
+ Telephony `/user/` routes; choose `"platform"` for Conversations. Omitted choices
610
+ default to `"platform"`. The choice applies to every HTTP method, MCP tool and
611
+ subscription on that handle, and to `client.use` and `client.apps.load`. Loaded
612
+ frontend assets and the resulting app client share the selected handle.
613
+
614
+ Before a request, the SDK renews the selected credential when it is within ten
615
+ seconds of expiry. Auth tokens use the normal Auth refresh flow; platform tokens
616
+ use `/delegated-token`. Auth requests do not require a working mint policy. Concurrent operations share renewal and refresh-token rotation; no custom
600
617
  refresh callback or application token endpoint is required. Both the returned
601
618
  absolute expiry and remaining lifetime limit credential use. Fetch streams
602
619
  reconnect at token expiry and close on local logout. SDK stream reconnection is
603
620
  not server-side revocation: already-admitted work or a modified client may outlive
604
621
  token expiry unless the receiving app enforces its own lifetime.
605
622
 
606
- Sessions are kept **in memory**, not written to localStorage, sessionStorage or
607
- cookies. Reuse one client per application session. Reloads/new tabs require
608
- login and do not implicitly share a rotating refresh credential. Do not copy
609
- refresh tokens between clients/tabs. This release deliberately does not provide
610
- persistent/shared browser sessions.
623
+ Sessions default to **memory-only**. Reuse one client per application session.
624
+ Reloads/new tabs require login unless the host explicitly enables persistent
625
+ sessions as described below. Do not manage or copy refresh credentials yourself.
611
626
 
612
627
  `auth` mode cannot be combined with `apiKey`, `accessToken` or
613
628
  `refreshAccessToken`; `setApiKey` and `setAccessToken` are unavailable in this
614
- mode. User requests omit cookies and never fall back to a kiosk or administrator
629
+ mode. `getAccessToken()` now returns `undefined` in managed mode: use scoped
630
+ handles instead of extracting either credential. Host-owned opaque tokens retain
631
+ the existing getter behavior. Auth handles cannot change the configured project
632
+ or escape their app routes; credentials are never forwarded through redirects
633
+ or accepted from URL parameters or header overrides.
634
+
635
+ User requests omit cookies and never fall back to a kiosk or administrator
615
636
  credential. Platform administrator operations such as `auth.listKeys()` are
616
637
  rejected in app Auth mode. Without `auth` configuration, existing platform
617
638
  login and opaque-token APIs retain their original behavior.
618
639
 
619
- A temporary mint failure preserves the normal Auth session and blocks protected
620
- app requests. A rejected Auth refresh clears the session. Local logout clears
640
+ A temporary mint failure preserves the normal Auth session and blocks only
641
+ platform-credential requests. Credential types never switch after an error. A rejected Auth refresh clears the session. Local logout clears
621
642
  credentials and streams immediately; a failed network logout still throws so the
622
643
  host can report that server-side revocation could not be confirmed. A late
623
644
  renewal cannot restore a logged-out session. HTTP writes are never automatically
624
645
  replayed after a 401; successful renewal prepares subsequent calls. Unlike legacy
625
- transport mode, a successfully recovered platform 401 does not trigger the
646
+ transport mode, a successfully recovered 401 does not trigger the
626
647
  `onUnauthorized` callback in managed Auth mode, although the original call still
627
648
  rejects. Reconcile a write's outcome before retrying it.
649
+
650
+
651
+ ### Mixed-app integration check
652
+
653
+ Run `APTEVA_APPS_DIR=/path/to/apps bun run test:mixed-apps` with a compatible Go
654
+ compiler (`GO_BINARY` can select it). This uses real Auth handlers, API's
655
+ `auth_jwt` validator and Telephony's `/user/` handler, temporary databases and
656
+ local fixture servers. The platform mint API and protected Conversations gateway
657
+ are simulated. It verifies routing, role downgrade, and server-side session
658
+ revocation without accessing live accounts or carriers. Set `SDK_TEST_MODULE` to
659
+ an unpacked package's `dist/index.js` to check the release artifact.
660
+
661
+
662
+ ## Optional persistent Auth sessions
663
+
664
+ Persistence is application-independent and opt-in. It uses the same managed Auth
665
+ session as HTTP, MCP, frontend loaders and streams; app credential selection does
666
+ not change. No customer-specific storage key, legacy session format or routing is
667
+ built into the SDK.
668
+
669
+ ```ts
670
+ const client = new AptevaClient({
671
+ baseURL,
672
+ projectId,
673
+ auth: {
674
+ clientId,
675
+ persistence: "local", // default: "memory"
676
+ onStateChange: state => renderSessionState(state),
677
+ onSessionChange: session => renderUser(session?.user),
678
+ },
679
+ });
680
+
681
+ try {
682
+ await client.auth.restore();
683
+ } catch {
684
+ // Show a retry action or login, according to client.auth.getState().
685
+ }
686
+
687
+ const crm = client.app("api", { credential: "auth" });
688
+ const conversations = client.app("conversations", { credential: "platform" });
689
+ ```
690
+
691
+ `auth.getState()` reports `status` (`idle`, `restoring`, `authenticated`,
692
+ `unauthenticated`, or `error`), effective `persistence` (`memory`, `local`, or
693
+ `unavailable`) and optional credential-free error metadata. Render loading for
694
+ `idle`/`restoring`, rather than briefly displaying the login screen. Concurrent
695
+ `restore()` calls share one promise. Protected requests await pending restoration
696
+ and can start initial restoration themselves. After a restoration error, retry
697
+ explicitly with `restore()` or log in; requests do not repeatedly retry it.
698
+
699
+ Only the refresh credential, format version, configuration scope and locally
700
+ generated session/revision identifiers are persisted in localStorage. Normal Auth
701
+ and platform access tokens, user details and permissions stay in memory. The
702
+ `/refresh` response supplies the authoritative user and authorization context.
703
+ `getSession()`, `getState()`, callbacks and cross-tab notifications expose no
704
+ credentials. Browser storage is JavaScript-readable: enabling it deliberately
705
+ accepts the same-origin script/XSS exposure of a persisted refresh credential.
706
+
707
+ Storage and lock namespaces include the canonical server URL, project, Auth
708
+ installation (or automatic routing), organization, public client and profile.
709
+ Use consistent configuration across tabs that should share a session. Cross-tab
710
+ sharing is limited to the same browser origin and storage partition. Different
711
+ scopes do not import each other's credentials or identities.
712
+
713
+ Native Web Locks serialize login, restore, refresh and logout. Each refresh reads
714
+ the latest saved credential under the lock, writes an in-progress marker before
715
+ sending it, then saves the replacement before releasing the lock. Other tabs are
716
+ notified without broadcasting credentials. Switching accounts invalidates the
717
+ previous local session and closes its streams. Disposed clients release browser
718
+ listeners and local streams through `client.auth.dispose()` without revoking or
719
+ deleting the saved session.
720
+
721
+ If localStorage or Web Locks are unavailable, `persistence` reports `unavailable`
722
+ and a fresh login works in memory-only mode. There is no localStorage-based lock
723
+ fallback. If saving a rotated credential fails, the replacement remains in memory
724
+ and the durable in-progress marker prevents other tabs from reusing the old one.
725
+ A failure reading previously shared credentials requires a new login; the SDK
726
+ cannot safely promote a potentially stale in-memory refresh to an independent
727
+ session.
728
+
729
+ Logout clears local credentials and streams immediately. It then clears the
730
+ saved refresh credential under the shared lock, notifies other tabs, and asks
731
+ Auth to revoke the session. A failed network logout still rejects: local logout
732
+ does not guarantee server-side revocation while offline. Late refresh results
733
+ cannot replace a newer login or resurrect a completed logout.
734
+
735
+ Restoration failure handling:
736
+
737
+ | Result | SDK behavior |
738
+ | --- | --- |
739
+ | Auth rejects an invalid/revoked refresh with 401 | Clear the saved and local session; login is required. |
740
+ | Browser is already offline before sending | Preserve the saved credential; retry restoration when connected. |
741
+ | Auth returns `refresh_unavailable` with 503 | Auth confirms rotation did not commit; preserve the credential for explicit retry. |
742
+ | Network failure, generic proxy 5xx, malformed response, or `refresh_uncertain` | Preserve an uncertain marker; do not reuse the old credential. If no replacement was saved, require login. |
743
+ | Platform mint denied | Restore the Auth session; platform-protected access remains blocked. |
744
+ | Unsupported or malformed storage format | Fail closed; login or logout replaces the record. |
745
+
746
+ The explicit retry-safe and uncertain response codes require Auth v0.12.1
747
+ or newer. With older Auth versions, generic errors
748
+ are handled conservatively. A tab crash after server rotation but before saving
749
+ the response cannot be recovered transparently with single-use refresh tokens.
750
+
751
+ There is no automatic legacy-session migration. Existing customer storage is not
752
+ read or deleted; hosts should remove their old refresh loops and require one
753
+ login when adopting persistence. Any future import must be a separate explicit,
754
+ tested SDK API. HTTP writes are never replayed automatically after a 401.
755
+
756
+ Validate native browser behavior with `bunx playwright install chromium` followed
757
+ by `bun run test:persistence:browser`. These checks use isolated local fixtures,
758
+ real tabs, Web Locks and localStorage; they do not contact customer accounts.
@@ -1,3 +1,5 @@
1
+ import { type PersistenceEnvironment } from "./session-persistence.js";
2
+ import type { AppCredential } from "./extensions.js";
1
3
  import type { User } from "./types.js";
2
4
  export interface AuthLoginInput {
3
5
  email: string;
@@ -24,6 +26,14 @@ export interface AuthSessionInfo {
24
26
  expiresAt: string;
25
27
  platformExpiresAt?: string;
26
28
  }
29
+ export interface AuthState {
30
+ status: "idle" | "restoring" | "authenticated" | "unauthenticated" | "error";
31
+ persistence: "memory" | "local" | "unavailable";
32
+ error?: {
33
+ code: string;
34
+ message: string;
35
+ };
36
+ }
27
37
  export interface AppAuthOptions {
28
38
  /** Public Auth app OAuth client identifier; never a private client secret. */
29
39
  clientId: string;
@@ -31,9 +41,19 @@ export interface AppAuthOptions {
31
41
  organizationSlug?: string;
32
42
  /** Requested Auth policy profile. Auth independently checks current roles. */
33
43
  profile?: string;
34
- /** Receives user/session metadata, never credentials. Sessions are memory-only. */
44
+ /** Explicit opt-in. Local persistence requires browser storage and Web Locks. */
45
+ persistence?: "memory" | "local";
46
+ /** Restoration and persistence availability, without credentials. */
47
+ onStateChange?: (state: AuthState) => void;
48
+ /** Receives user/session metadata, never credentials. */
35
49
  onSessionChange?: (session: AuthSessionInfo | undefined) => void;
36
50
  }
51
+ export interface SessionCredential {
52
+ token: string;
53
+ epoch: number;
54
+ revision: number;
55
+ deadline: number;
56
+ }
37
57
  /** Internal issuer-specific session lifecycle. AptevaClient is the public API. */
38
58
  export declare class AuthSession {
39
59
  private readonly baseURL;
@@ -42,12 +62,27 @@ export declare class AuthSession {
42
62
  private readonly fetchImpl;
43
63
  private readonly changed;
44
64
  private state?;
65
+ private persistence?;
66
+ private stored?;
67
+ private restoration?;
68
+ private lifecycle;
69
+ private disposed;
45
70
  private epoch;
71
+ private authRevision;
72
+ private platformRevision;
46
73
  private pending?;
47
74
  private pendingAuth?;
48
75
  private controllers;
49
76
  private listeners;
50
- constructor(baseURL: string, projectId: string, options: AppAuthOptions, fetchImpl: typeof fetch, changed: (token: string | undefined) => void);
77
+ constructor(baseURL: string, projectId: string, options: AppAuthOptions, fetchImpl: typeof fetch, changed: (token: string | undefined) => void, environment?: PersistenceEnvironment);
78
+ getState(): AuthState;
79
+ private emitState;
80
+ private status;
81
+ private synchronize;
82
+ private ready;
83
+ restore(): Promise<AuthSessionInfo | undefined>;
84
+ private restoreSaved;
85
+ dispose(): void;
51
86
  info(): AuthSessionInfo | undefined;
52
87
  onClear(listener: () => void): () => void;
53
88
  private notify;
@@ -56,18 +91,22 @@ export declare class AuthSession {
56
91
  private call;
57
92
  private input;
58
93
  private platform;
94
+ private validateResponse;
59
95
  private accept;
96
+ private establish;
60
97
  login(input: AuthLoginInput): Promise<AuthUser>;
61
98
  register(input: AuthSignupInput): Promise<{
62
99
  user: AuthUser;
63
100
  verification_required?: boolean;
64
101
  }>;
65
102
  logout(): Promise<void>;
103
+ private refreshSaved;
66
104
  private refreshAuth;
67
105
  private performAuthRefresh;
68
106
  private renew;
69
107
  token(force?: boolean): Promise<string>;
70
108
  me(): Promise<AuthUser>;
71
- platformDeadline(): number;
109
+ credential(kind: AppCredential): Promise<SessionCredential>;
110
+ recover(kind: AppCredential, used: SessionCredential): Promise<boolean>;
72
111
  }
73
112
  //# sourceMappingURL=auth-session.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth-session.d.ts","sourceRoot":"","sources":["../src/auth-session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,cAAc;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE;AACnE,MAAM,WAAW,eAAgB,SAAQ,cAAc;IAAG,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE;AAChF,MAAM,WAAW,QAAS,SAAQ,IAAI;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AACD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AACD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,QAAQ,CAAC;IACf,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AACD,MAAM,WAAW,cAAc;IAC7B,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mFAAmF;IACnF,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,GAAG,SAAS,KAAK,IAAI,CAAC;CAClE;AAeD,kFAAkF;AAClF,qBAAa,WAAW;IAQpB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAX1B,OAAO,CAAC,KAAK,CAAC,CAAQ;IACtB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,OAAO,CAAC,CAAkB;IAClC,OAAO,CAAC,WAAW,CAAC,CAAgB;IACpC,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,SAAS,CAAyB;gBAEvB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,OAAO,KAAK,EACvB,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI;IAK/D,IAAI,IAAI,eAAe,GAAG,SAAS;IAMnC,OAAO,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IACzC,OAAO,CAAC,MAAM;IAGd,KAAK,IAAI,IAAI;IAWb,OAAO,CAAC,WAAW;YAGL,IAAI;IAelB,OAAO,CAAC,KAAK;IAGb,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,MAAM;IAcR,KAAK,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC;IAK/C,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,qBAAqB,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAO9F,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;YAKf,WAAW;YAMX,kBAAkB;YAWlB,KAAK;IAyBb,KAAK,CAAC,KAAK,UAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAcrC,EAAE,IAAI,OAAO,CAAC,QAAQ,CAAC;IAmB7B,gBAAgB,IAAI,MAAM;CAC3B"}
1
+ {"version":3,"file":"auth-session.d.ts","sourceRoot":"","sources":["../src/auth-session.ts"],"names":[],"mappings":"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"}