@agentmatrix.pro/browser-sdk 0.1.0-rc.1 → 0.1.0-rc.2
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 +12 -0
- package/README.md +115 -56
- package/dist/index.d.ts +26 -7
- package/dist/index.js +51 -13
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.0-rc.2
|
|
4
|
+
|
|
5
|
+
_Release prepared 2026-10-30 for the official npm `next` channel._
|
|
6
|
+
|
|
7
|
+
Requires Platform `0.160.0`. The matching API contract is deployed in AgentMatrix
|
|
8
|
+
`release-2026-10-30.3`; Guest/profile/Worker enablement and real takeover
|
|
9
|
+
qualification remain pending. This package stays a prerelease.
|
|
10
|
+
|
|
11
|
+
- Support backend owner-bound API keys for get/acquire/release without UserJWT or CSRF (Platform 0.160.0).
|
|
12
|
+
- Add one-use `BrowserViewer.takeAccess()` and `createBrowserViewer()` for authenticated backend-to-frontend capability transfer; keep API keys off the frontend.
|
|
13
|
+
- Preserve Workspace authentication, single-attempt transport, explicit handback, and unknown-result readback.
|
|
14
|
+
|
|
3
15
|
## 0.1.0-rc.1
|
|
4
16
|
|
|
5
17
|
First AgentMatrix browser SDK prerelease, prepared for the official npm `next`
|
package/README.md
CHANGED
|
@@ -1,77 +1,136 @@
|
|
|
1
1
|
# AgentMatrix browser control
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Owner-authorized control of an existing Agent browser. Applications can use an
|
|
4
|
+
owner-bound data-plane API key on their backend; users do not need a separate
|
|
5
|
+
AgentMatrix login. Existing Workspace JWT + selected key ID + CSRF calls remain
|
|
6
|
+
supported.
|
|
7
|
+
|
|
8
|
+
This source targets **Platform 0.160.0**. The API-key path and capability transfer
|
|
9
|
+
are introduced in `@agentmatrix.pro/browser-sdk@0.1.0-rc.2`; the earlier
|
|
10
|
+
`0.1.0-rc.1` does not include them. Install that exact prerelease for integration:
|
|
5
11
|
|
|
6
12
|
```bash
|
|
7
|
-
npm install @agentmatrix.pro/browser-sdk@0.1.0-rc.
|
|
13
|
+
npm install @agentmatrix.pro/browser-sdk@0.1.0-rc.2
|
|
8
14
|
```
|
|
9
15
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
The deployment must enable browser control and approve the frontend's exact
|
|
17
|
+
parent origin in both Guest and Preview configuration. Installing the SDK does
|
|
18
|
+
not enable the server feature or exit Q0. This remains a prerelease while real
|
|
19
|
+
Identity/Guest enablement qualification is pending.
|
|
20
|
+
|
|
21
|
+
## Backend with an API key
|
|
14
22
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
create browsers or establish cross-origin cookie/CORS policy.
|
|
23
|
+
Keep the key on your server. It must belong to the Session owner, include
|
|
24
|
+
`session.full`, and permit the selected namespace. Tenant and owner are derived
|
|
25
|
+
from the verified key; do not supply a JWT, tenant ID, key ID or CSRF token.
|
|
19
26
|
|
|
20
27
|
```ts
|
|
21
28
|
import { BrowserControlClient } from "@agentmatrix.pro/browser-sdk";
|
|
22
29
|
|
|
23
30
|
const control = new BrowserControlClient({ baseURL: gatewayOrigin });
|
|
24
|
-
|
|
25
|
-
const context = { userJWT, tenantId, namespaceId, apiKeyId, sessionId, csrfToken };
|
|
31
|
+
const context = { apiKey: serverSecret, sessionId, namespaceId: "default" };
|
|
26
32
|
const current = await control.get(context);
|
|
33
|
+
// In your endpoint, authorize the application's own user for this Session first.
|
|
34
|
+
// Only continue for an explicit takeover action. Persist/reuse its operation ID.
|
|
27
35
|
if (current.data.allowed_actions.includes("acquire") && current.data.control_id) {
|
|
28
36
|
const result = await control.acquire(context, {
|
|
29
|
-
operation_id:
|
|
37
|
+
operation_id: operationId,
|
|
30
38
|
expected_control_id: current.data.control_id,
|
|
31
39
|
expected_revision: current.data.revision,
|
|
32
40
|
});
|
|
33
|
-
|
|
34
|
-
result.
|
|
35
|
-
|
|
36
|
-
}
|
|
41
|
+
const response = {
|
|
42
|
+
data: result.data,
|
|
43
|
+
viewer_access: result.viewer?.takeAccess(),
|
|
44
|
+
};
|
|
45
|
+
// Return response only to that authenticated user over HTTPS, Cache-Control: no-store.
|
|
46
|
+
// It contains a short-lived secret: never log, cache or persist it.
|
|
37
47
|
}
|
|
38
48
|
```
|
|
39
49
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
The
|
|
66
|
-
|
|
67
|
-
input and hides the frame while leaving
|
|
68
|
-
`
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
50
|
+
Omitting `namespaceId` uses the deployment's ordinary API-key default namespace.
|
|
51
|
+
The SDK sends only Bearer authentication, the contract version and the optional
|
|
52
|
+
namespace, with `credentials: omit`. It never exchanges the key for a user JWT.
|
|
53
|
+
A key authorizes its owner, not arbitrary users of your application: your backend
|
|
54
|
+
must enforce its own Session access checks before returning a viewer capability.
|
|
55
|
+
|
|
56
|
+
## Frontend with the transferred capability
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
import { createBrowserViewer } from "@agentmatrix.pro/browser-sdk";
|
|
60
|
+
|
|
61
|
+
// Received from your authenticated backend; never contains the API key.
|
|
62
|
+
const viewer = createBrowserViewer(response.viewer_access);
|
|
63
|
+
viewer.attach(iframe); // once, on a deployment-approved parent origin
|
|
64
|
+
// Keep viewer and the original control_id in memory for handback.
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`takeAccess()` consumes an unused handle once and returns `{ url, token,
|
|
68
|
+
expires_at }`. The returned object intentionally contains secrets; ordinary
|
|
69
|
+
handle serialization and Node inspection remain redacted. After transfer, the
|
|
70
|
+
original handle can neither attach nor export again. `createBrowserViewer`
|
|
71
|
+
validates and copies that capability; it does not mint, renew, reacquire or prove
|
|
72
|
+
server authorization. Do not duplicate it for multiple clients or put it in a
|
|
73
|
+
URL, log, localStorage, sessionStorage or persistent application state.
|
|
74
|
+
|
|
75
|
+
The helper binds both message source and exact viewer origin, delivers the token
|
|
76
|
+
once, and keeps it out of the iframe URL. The Preview URL itself is sensitive.
|
|
77
|
+
Grant expiry stops input and hides the frame while leaving the cleanup connection
|
|
78
|
+
alive. Use `viewer.expiresAt`, together with the latest lease, for local input
|
|
79
|
+
expiry. On unknown/stale state, also call `stopInput()`.
|
|
80
|
+
|
|
81
|
+
## Existing Workspace authentication
|
|
82
|
+
|
|
83
|
+
Workspace applications can continue to call the same client directly with their
|
|
84
|
+
current authenticated user/scope context:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
const context = { userJWT, tenantId, namespaceId, apiKeyId, sessionId, csrfToken };
|
|
88
|
+
const current = await control.get(context);
|
|
89
|
+
// acquire/release use the same intent fields as the backend API-key example.
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
This selects the Workspace routes with `credentials: include`. The key **ID** is
|
|
93
|
+
not a key secret; mutations require the existing matching CSRF cookie/header.
|
|
94
|
+
The SDK does not sign users in, refresh credentials, select tenants/keys, create
|
|
95
|
+
browsers or configure CORS/cookies. Mixing API-key and JWT context fields is
|
|
96
|
+
rejected before transport.
|
|
97
|
+
|
|
98
|
+
## Handback and failed replies
|
|
99
|
+
|
|
100
|
+
On explicit handback, first call `viewer.stopInput()` on the frontend. Keep the
|
|
101
|
+
iframe mounted. Your backend reads a fresh status for the **original control_id**
|
|
102
|
+
and calls `release(context, { operation_id, expected_control_id,
|
|
103
|
+
expected_revision, lease_id })` using that observation. If the control changed,
|
|
104
|
+
discard the old intent rather than switching it to another browser.
|
|
105
|
+
|
|
106
|
+
A `202` or `revoking` state retains responsibility: the iframe must receive the
|
|
107
|
+
Guest's real clear challenge. After confirmed Agent handback, call
|
|
108
|
+
`viewer.dispose()`. When `allowed_actions` includes `release`, offer an explicit
|
|
109
|
+
**Continue handback** action using a fresh observation and a new user intent.
|
|
110
|
+
Do not automatically change operation IDs or resend mutations. A replay never
|
|
111
|
+
reconstructs a viewer; `takeAccess()` cannot recover a lost response.
|
|
112
|
+
|
|
113
|
+
Each `get`, `acquire` or `release` makes one HTTP attempt, with no implicit retry,
|
|
114
|
+
authentication refresh, polling or generated operation ID. Defaults are a
|
|
115
|
+
15-second read and 200-second mutation total deadline; per-call
|
|
116
|
+
`{ signal, timeoutMs }` includes headers and the complete body. An injected
|
|
117
|
+
`fetch` must also avoid hidden retries. A proxy in your application must allow
|
|
118
|
+
this mutation budget.
|
|
119
|
+
|
|
120
|
+
`BrowserControlError` exposes only a bounded code, optional status and reason.
|
|
121
|
+
After dispatch, a lost, timed-out or cancelled reply has `replyUnproven: true`:
|
|
122
|
+
read state before offering another action. A refusal cannot clear earlier debt.
|
|
123
|
+
The legacy reason `browser_control_human_required` also covers insufficient
|
|
124
|
+
API-key owner/scope/current authority; it does not require an API-key caller to log in.
|
|
125
|
+
HTTP 202, expiry, iframe closure and native browser closure do not prove handback.
|
|
126
|
+
|
|
127
|
+
`BrowserViewer` is a TypeScript interface, with no runtime constructor or
|
|
128
|
+
`instanceof` value. `stopInput()` before attachment permanently prevents that
|
|
129
|
+
handle from attaching or transferring. `dispose()` is local teardown, not server
|
|
130
|
+
cleanup proof. On user, tenant or Session changes, cancel calls, discard late
|
|
131
|
+
replies and dispose the old viewer; the server retains unresolved responsibility.
|
|
132
|
+
|
|
133
|
+
The root data-plane SDK still provides the convenient read-only
|
|
134
|
+
`AgentMatrix.sessions.browserControl.get(sessionId)`. Use this separate browser package
|
|
135
|
+
for API-key or Workspace control and iframe handling; Tenant Management grants
|
|
136
|
+
no browser control.
|
package/dist/index.d.ts
CHANGED
|
@@ -123,6 +123,8 @@ type components = {
|
|
|
123
123
|
};
|
|
124
124
|
};
|
|
125
125
|
parameters: {
|
|
126
|
+
/** @example ssn_01HX... */
|
|
127
|
+
SessionId: string;
|
|
126
128
|
/** @description Tenant selected in the User Dashboard resource URL. Identity verifies that the authenticated user has an active membership in this tenant before forwarding to canonical data-plane APIs. */
|
|
127
129
|
WorkspaceTenantId: string;
|
|
128
130
|
/** @example default */
|
|
@@ -145,6 +147,10 @@ type components = {
|
|
|
145
147
|
pathItems: never;
|
|
146
148
|
};
|
|
147
149
|
|
|
150
|
+
/** Sensitive short-lived capability. Deliver only to your authenticated frontend; never log or store it. */
|
|
151
|
+
type BrowserViewerAccess = components["schemas"]["BrowserViewerAccess"];
|
|
152
|
+
/** Import a capability delivered by your own trusted backend, without exposing its API key. */
|
|
153
|
+
declare function createBrowserViewer(access: BrowserViewerAccess): BrowserViewer;
|
|
148
154
|
/** Structural DOM types keep Node clients importable without a DOM global or shim. */
|
|
149
155
|
interface BrowserViewerMessage {
|
|
150
156
|
source: unknown;
|
|
@@ -173,6 +179,8 @@ interface BrowserViewerFrame {
|
|
|
173
179
|
/** Acquired handle only; no public constructor or runtime BrowserViewer export. */
|
|
174
180
|
interface BrowserViewer {
|
|
175
181
|
readonly expiresAt: string;
|
|
182
|
+
/** Consume once for an authenticated backend-to-frontend response. The returned value contains secrets. */
|
|
183
|
+
takeAccess(): BrowserViewerAccess;
|
|
176
184
|
/** Attach once, before the iframe loads. */
|
|
177
185
|
attach(frame: BrowserViewerFrame): void;
|
|
178
186
|
/** Stop local input while retaining the iframe for the Guest's actual clear ACK. */
|
|
@@ -201,6 +209,17 @@ interface BrowserControlMutationContext extends BrowserControlContext {
|
|
|
201
209
|
/** Must match the browser's ariadra_csrf_token cookie on the Gateway origin. */
|
|
202
210
|
csrfToken: string;
|
|
203
211
|
}
|
|
212
|
+
/** Server-side API-key context. Never pass this credential to a user browser. */
|
|
213
|
+
interface BrowserControlAPIKeyContext {
|
|
214
|
+
apiKey: string;
|
|
215
|
+
sessionId: string;
|
|
216
|
+
/** Omission uses the key's default namespace routing. */
|
|
217
|
+
namespaceId?: string;
|
|
218
|
+
userJWT?: never;
|
|
219
|
+
tenantId?: never;
|
|
220
|
+
apiKeyId?: never;
|
|
221
|
+
csrfToken?: never;
|
|
222
|
+
}
|
|
204
223
|
interface BrowserControlRequestOptions {
|
|
205
224
|
signal?: AbortSignal;
|
|
206
225
|
/** Total budget including the complete response body. Defaults to 15s read / 200s mutation. */
|
|
@@ -223,13 +242,13 @@ interface BrowserControlClientOptions {
|
|
|
223
242
|
fetch?: typeof globalThis.fetch;
|
|
224
243
|
}
|
|
225
244
|
|
|
226
|
-
/**
|
|
245
|
+
/** Owner-authorized client. No cached context, automatic reads, retries, grants or operation IDs. */
|
|
227
246
|
declare class BrowserControlClient {
|
|
228
247
|
#private;
|
|
229
248
|
constructor(options: BrowserControlClientOptions);
|
|
230
|
-
get(context: BrowserControlContext, options?: BrowserControlRequestOptions): Promise<BrowserControlResult>;
|
|
231
|
-
acquire(context: BrowserControlMutationContext, intent: AcquireBrowserControlRequest, options?: BrowserControlRequestOptions): Promise<BrowserControlAcquisition>;
|
|
232
|
-
release(context: BrowserControlMutationContext, intent: ReleaseBrowserControlRequest, options?: BrowserControlRequestOptions): Promise<BrowserControlResult>;
|
|
249
|
+
get(context: BrowserControlContext | BrowserControlAPIKeyContext, options?: BrowserControlRequestOptions): Promise<BrowserControlResult>;
|
|
250
|
+
acquire(context: BrowserControlMutationContext | BrowserControlAPIKeyContext, intent: AcquireBrowserControlRequest, options?: BrowserControlRequestOptions): Promise<BrowserControlAcquisition>;
|
|
251
|
+
release(context: BrowserControlMutationContext | BrowserControlAPIKeyContext, intent: ReleaseBrowserControlRequest, options?: BrowserControlRequestOptions): Promise<BrowserControlResult>;
|
|
233
252
|
}
|
|
234
253
|
|
|
235
254
|
type BrowserControlFailure = "invalid_input" | "aborted" | "timeout" | "transport_unproven" | "response_unproven" | "refused";
|
|
@@ -246,8 +265,8 @@ declare class BrowserControlError extends Error {
|
|
|
246
265
|
constructor(code: BrowserControlFailure, replyUnproven: boolean, status?: number | undefined, reason?: BrowserControlErrorReason | undefined);
|
|
247
266
|
}
|
|
248
267
|
|
|
249
|
-
declare const CONTRACT_VERSION = "0.
|
|
268
|
+
declare const CONTRACT_VERSION = "0.160.0";
|
|
250
269
|
|
|
251
|
-
declare const BROWSER_SDK_VERSION = "0.1.0-rc.
|
|
270
|
+
declare const BROWSER_SDK_VERSION = "0.1.0-rc.2";
|
|
252
271
|
|
|
253
|
-
export { type AcquireBrowserControlRequest, BROWSER_SDK_VERSION, type BrowserControlAcquisition, type BrowserControlAction, BrowserControlClient, type BrowserControlClientOptions, type BrowserControlContext, BrowserControlError, type BrowserControlErrorReason, type BrowserControlFailure, type BrowserControlMutationContext, type BrowserControlReason, type BrowserControlRequestOptions, type BrowserControlResult, type BrowserControlState, type BrowserControlStatus, type BrowserViewer, type BrowserViewerFrame, type BrowserViewerMessage, type BrowserViewerWindow, CONTRACT_VERSION, type ReleaseBrowserControlRequest };
|
|
272
|
+
export { type AcquireBrowserControlRequest, BROWSER_SDK_VERSION, type BrowserControlAPIKeyContext, type BrowserControlAcquisition, type BrowserControlAction, BrowserControlClient, type BrowserControlClientOptions, type BrowserControlContext, BrowserControlError, type BrowserControlErrorReason, type BrowserControlFailure, type BrowserControlMutationContext, type BrowserControlReason, type BrowserControlRequestOptions, type BrowserControlResult, type BrowserControlState, type BrowserControlStatus, type BrowserViewer, type BrowserViewerAccess, type BrowserViewerFrame, type BrowserViewerMessage, type BrowserViewerWindow, CONTRACT_VERSION, type ReleaseBrowserControlRequest, createBrowserViewer };
|
package/dist/index.js
CHANGED
|
@@ -15,7 +15,7 @@ var BrowserControlError = class extends Error {
|
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
// ../../packages/browser-sdk/src/generated/contract-version.ts
|
|
18
|
-
var CONTRACT_VERSION = "0.
|
|
18
|
+
var CONTRACT_VERSION = "0.160.0";
|
|
19
19
|
|
|
20
20
|
// ../../packages/browser-sdk/src/validation.ts
|
|
21
21
|
var identifier = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/;
|
|
@@ -55,10 +55,27 @@ function secret(v, max) {
|
|
|
55
55
|
return typeof v === "string" && v.length > 0 && v.length <= max && /^[\x21-\x7e]+$/.test(v);
|
|
56
56
|
}
|
|
57
57
|
function contextPath(c, mutation) {
|
|
58
|
+
if (record(c) && "apiKey" in c) {
|
|
59
|
+
if (!keys(c, ["apiKey", "sessionId", "namespaceId"]) || !secret(c.apiKey, 8192) || !id(c.sessionId) || c.namespaceId !== void 0 && (typeof c.namespaceId !== "string" || c.namespaceId.length > 63 || !/^[a-z0-9]([-a-z0-9]*[a-z0-9])?$/.test(c.namespaceId)))
|
|
60
|
+
invalidInput();
|
|
61
|
+
return `/v1/sessions/${encodeURIComponent(c.sessionId)}/browser-control`;
|
|
62
|
+
}
|
|
58
63
|
if (!record(c) || !secret(c.userJWT, 8192) || typeof c.tenantId !== "string" || !/^tnt_[0-9A-HJKMNP-TV-Z]{26}$/.test(c.tenantId) || typeof c.apiKeyId !== "string" || !/^ak_[0-9A-HJKMNP-TV-Z]{26}$/.test(c.apiKeyId) || typeof c.namespaceId !== "string" || c.namespaceId.length > 63 || !/^[a-z0-9]([-a-z0-9]*[a-z0-9])?$/.test(c.namespaceId) || !id(c.sessionId) || mutation && !secret(c.csrfToken, 8192))
|
|
59
64
|
invalidInput();
|
|
60
65
|
return `/v1/users/me/resources/t/${encodeURIComponent(c.tenantId)}/n/${encodeURIComponent(c.namespaceId)}/sessions/${encodeURIComponent(c.sessionId)}/browser-control`;
|
|
61
66
|
}
|
|
67
|
+
function validateViewerAccess(value) {
|
|
68
|
+
if (!record(value) || !keys(value, ["url", "token", "expires_at"]) || typeof value.url !== "string" || value.url.length > 8192 || typeof value.token !== "string" || !/^[a-f0-9]{64}$/.test(value.token) || !date(value.expires_at) || Date.parse(value.expires_at) <= Date.now())
|
|
69
|
+
invalidInput();
|
|
70
|
+
try {
|
|
71
|
+
const url = new URL(value.url);
|
|
72
|
+
if (!safeURL(url) || url.hash || decodeURIComponent(value.url).includes(value.token))
|
|
73
|
+
invalidInput();
|
|
74
|
+
} catch {
|
|
75
|
+
invalidInput();
|
|
76
|
+
}
|
|
77
|
+
return { url: value.url, token: value.token, expires_at: value.expires_at };
|
|
78
|
+
}
|
|
62
79
|
function validateIntent(value, release) {
|
|
63
80
|
if (!record(value) || !keys(value, [
|
|
64
81
|
"operation_id",
|
|
@@ -143,6 +160,9 @@ function safeURL(url) {
|
|
|
143
160
|
}
|
|
144
161
|
|
|
145
162
|
// ../../packages/browser-sdk/src/viewer.ts
|
|
163
|
+
function createBrowserViewer(access) {
|
|
164
|
+
return new BrowserViewerHandle(validateViewerAccess(access));
|
|
165
|
+
}
|
|
146
166
|
var BrowserViewerHandle = class {
|
|
147
167
|
expiresAt;
|
|
148
168
|
#url;
|
|
@@ -157,6 +177,19 @@ var BrowserViewerHandle = class {
|
|
|
157
177
|
this.#url = access.url;
|
|
158
178
|
this.#token = access.token;
|
|
159
179
|
}
|
|
180
|
+
takeAccess() {
|
|
181
|
+
if (this.#used || !this.#token || Date.parse(this.expiresAt) <= Date.now())
|
|
182
|
+
throw new BrowserControlError("invalid_input", false);
|
|
183
|
+
const access = {
|
|
184
|
+
url: this.#url,
|
|
185
|
+
token: this.#token,
|
|
186
|
+
expires_at: this.expiresAt
|
|
187
|
+
};
|
|
188
|
+
this.#used = true;
|
|
189
|
+
this.#url = "";
|
|
190
|
+
this.#token = void 0;
|
|
191
|
+
return access;
|
|
192
|
+
}
|
|
160
193
|
/** Attach once, before the iframe loads. Use the exact Workspace origin approved by the deployment. */
|
|
161
194
|
attach(frame) {
|
|
162
195
|
if (this.#used || !frame.ownerDocument.defaultView || Date.parse(this.expiresAt) <= Date.now()) {
|
|
@@ -265,20 +298,25 @@ var BrowserControlClient = class {
|
|
|
265
298
|
if (options.signal?.aborted)
|
|
266
299
|
throw new BrowserControlError("aborted", false);
|
|
267
300
|
const sessionId = context.sessionId;
|
|
301
|
+
const apiKey = "apiKey" in context;
|
|
268
302
|
const headers = new Headers({
|
|
269
303
|
accept: "application/json",
|
|
270
|
-
authorization: `Bearer ${context.userJWT}`,
|
|
271
|
-
"x-ariadra-api-version": CONTRACT_VERSION
|
|
272
|
-
"x-ariadra-current-tenant-id": context.tenantId,
|
|
273
|
-
"x-ariadra-namespace-id": context.namespaceId,
|
|
274
|
-
"x-ariadra-dashboard-api-key-id": context.apiKeyId
|
|
304
|
+
authorization: `Bearer ${apiKey ? context.apiKey : context.userJWT}`,
|
|
305
|
+
"x-ariadra-api-version": CONTRACT_VERSION
|
|
275
306
|
});
|
|
307
|
+
if (context.namespaceId !== void 0)
|
|
308
|
+
headers.set("x-ariadra-namespace-id", context.namespaceId);
|
|
309
|
+
if (!apiKey) {
|
|
310
|
+
headers.set("x-ariadra-current-tenant-id", context.tenantId);
|
|
311
|
+
headers.set("x-ariadra-dashboard-api-key-id", context.apiKeyId);
|
|
312
|
+
}
|
|
276
313
|
if (mutation) {
|
|
277
314
|
headers.set("content-type", "application/json");
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
315
|
+
if (!apiKey)
|
|
316
|
+
headers.set(
|
|
317
|
+
"x-csrf-token",
|
|
318
|
+
context.csrfToken
|
|
319
|
+
);
|
|
282
320
|
}
|
|
283
321
|
const body = frozenIntent ? JSON.stringify(frozenIntent) : void 0;
|
|
284
322
|
const expectedControl = frozenIntent?.expected_control_id;
|
|
@@ -306,7 +344,7 @@ var BrowserControlClient = class {
|
|
|
306
344
|
headers,
|
|
307
345
|
...body === void 0 ? {} : { body },
|
|
308
346
|
cache: "no-store",
|
|
309
|
-
credentials: "include",
|
|
347
|
+
credentials: apiKey ? "omit" : "include",
|
|
310
348
|
redirect: "error",
|
|
311
349
|
signal: controller.signal
|
|
312
350
|
};
|
|
@@ -399,6 +437,6 @@ async function readBody(response, signal) {
|
|
|
399
437
|
}
|
|
400
438
|
|
|
401
439
|
// src/version.ts
|
|
402
|
-
var BROWSER_SDK_VERSION = "0.1.0-rc.
|
|
440
|
+
var BROWSER_SDK_VERSION = "0.1.0-rc.2";
|
|
403
441
|
|
|
404
|
-
export { BROWSER_SDK_VERSION, BrowserControlClient, BrowserControlError, CONTRACT_VERSION };
|
|
442
|
+
export { BROWSER_SDK_VERSION, BrowserControlClient, BrowserControlError, CONTRACT_VERSION, createBrowserViewer };
|
package/package.json
CHANGED