@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 +30 -0
- package/README.md +148 -17
- package/dist/auth-session.d.ts +42 -3
- package/dist/auth-session.d.ts.map +1 -1
- package/dist/auth-session.js +331 -23
- package/dist/auth-session.js.map +1 -1
- package/dist/client.d.ts +9 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +67 -25
- package/dist/client.js.map +1 -1
- package/dist/extensions.d.ts +3 -0
- package/dist/extensions.d.ts.map +1 -1
- package/dist/extensions.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/session-persistence.d.ts +42 -0
- package/dist/session-persistence.d.ts.map +1 -0
- package/dist/session-persistence.js +149 -0
- package/dist/session-persistence.js.map +1 -0
- package/package.json +4 -1
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.
|
|
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
|
-
|
|
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
|
|
592
|
-
app access. Login can succeed without
|
|
593
|
-
until an authorized policy can mint a token.
|
|
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.
|
|
598
|
-
|
|
599
|
-
|
|
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
|
|
607
|
-
|
|
608
|
-
|
|
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.
|
|
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
|
|
620
|
-
|
|
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
|
|
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.
|
package/dist/auth-session.d.ts
CHANGED
|
@@ -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
|
-
/**
|
|
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
|
-
|
|
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":"
|
|
1
|
+
{"version":3,"file":"auth-session.d.ts","sourceRoot":"","sources":["../src/auth-session.ts"],"names":[],"mappings":"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"}
|