@synap-core/sdk 1.3.0 → 1.4.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 +81 -7
- package/dist/{client-CVUT1Mcf.d.cts → client-C5sF20f1.d.cts} +1 -1
- package/dist/{client-CVUT1Mcf.d.ts → client-C5sF20f1.d.ts} +1 -1
- package/dist/connect.cjs +397 -116
- package/dist/connect.cjs.map +1 -1
- package/dist/connect.d.cts +220 -15
- package/dist/connect.d.ts +220 -15
- package/dist/connect.js +389 -116
- package/dist/connect.js.map +1 -1
- package/dist/public.d.cts +2 -2
- package/dist/public.d.ts +2 -2
- package/dist/testing.cjs +138 -11
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +92 -4
- package/dist/testing.d.ts +92 -4
- package/dist/testing.js +134 -11
- package/dist/testing.js.map +1 -1
- package/dist/{types-DpqPNaaa.d.cts → types-C2KGNXEn.d.cts} +20 -1
- package/dist/{types-DpqPNaaa.d.ts → types-C2KGNXEn.d.ts} +20 -1
- package/package.json +8 -8
- package/src/connect/auth.ts +161 -31
- package/src/connect/client.ts +107 -1
- package/src/connect/cloud.ts +206 -0
- package/src/connect/discovery.ts +15 -14
- package/src/connect/errors.ts +1 -1
- package/src/connect/flow.ts +41 -1
- package/src/connect/index.ts +39 -11
- package/src/connect/seal.ts +1 -1
- package/src/connect/store.ts +41 -3
- package/src/connect/types.ts +20 -0
- package/src/testing/auth-server.ts +144 -12
- package/src/testing/cloud.ts +84 -0
- package/src/testing/index.ts +3 -1
package/dist/connect.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { b as PodConnection, P as PodGrant, C as ClientMetadataDocument, A as AppRequest,
|
|
2
|
-
export { a as PodUser } from './types-
|
|
1
|
+
import { b as PodConnection, P as PodGrant, c as PodSpace, C as ClientMetadataDocument, A as AppRequest, d as PodIssuer } from './types-C2KGNXEn.js';
|
|
2
|
+
export { a as PodUser } from './types-C2KGNXEn.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* The one error type of `@synap-core/sdk/connect`. `code` is the contract a UI
|
|
@@ -15,7 +15,7 @@ type ConnectErrorCode =
|
|
|
15
15
|
| "pod_unreachable"
|
|
16
16
|
/** A Synap pod, but too old for app sign-in (no CIMD, no `iss`, no S256). */
|
|
17
17
|
| "pod_unsupported"
|
|
18
|
-
/** Connecting through Synap Cloud is not
|
|
18
|
+
/** Connecting through Synap Cloud is not configured for this app (no Control Plane URL). */
|
|
19
19
|
| "cp_unavailable"
|
|
20
20
|
/** The person said no on the consent screen. */
|
|
21
21
|
| "denied"
|
|
@@ -80,6 +80,35 @@ type PodWriteResult<T> = {
|
|
|
80
80
|
error: PodError;
|
|
81
81
|
};
|
|
82
82
|
type QueryValue = string | number | boolean | null | undefined | ReadonlyArray<string | number | boolean>;
|
|
83
|
+
/** One pending proposal, the pod's summary row (`GET /proposals?view=basic`). */
|
|
84
|
+
interface PendingProposal {
|
|
85
|
+
id: string;
|
|
86
|
+
proposalType: string;
|
|
87
|
+
targetType: string;
|
|
88
|
+
targetId: string | null;
|
|
89
|
+
workspaceId: string | null;
|
|
90
|
+
/** ISO 8601, as the pod sent it. */
|
|
91
|
+
createdAt: string;
|
|
92
|
+
/** The agent that filed it (this app's agent, or another one), when known. */
|
|
93
|
+
agentUserId: string | null;
|
|
94
|
+
sessionId: string | null;
|
|
95
|
+
summary?: string;
|
|
96
|
+
/** Where the person reviews it: the pod's deep link. */
|
|
97
|
+
reviewUrl: string;
|
|
98
|
+
}
|
|
99
|
+
interface PendingProposals {
|
|
100
|
+
/** Every pending proposal the connection can see, not only this page (the pod COUNTs it). */
|
|
101
|
+
total: number;
|
|
102
|
+
proposals: PendingProposal[];
|
|
103
|
+
hasMore: boolean;
|
|
104
|
+
}
|
|
105
|
+
interface ListPendingProposalsOptions {
|
|
106
|
+
/** One granted space only. */
|
|
107
|
+
workspaceId?: string;
|
|
108
|
+
/** 1-200, default 20. */
|
|
109
|
+
limit?: number;
|
|
110
|
+
offset?: number;
|
|
111
|
+
}
|
|
83
112
|
interface PodClientOptions {
|
|
84
113
|
fetch?: typeof fetch;
|
|
85
114
|
now?: () => number;
|
|
@@ -90,6 +119,16 @@ interface PodClient {
|
|
|
90
119
|
grant: PodGrant[];
|
|
91
120
|
/** Whether the connection was granted `permission` (in `workspaceId` when given). */
|
|
92
121
|
can(permission: string, workspaceId?: string): boolean;
|
|
122
|
+
/** The granted spaces, each with its permissions (`spaces(connection)`). */
|
|
123
|
+
spaces(): PodSpace[];
|
|
124
|
+
/**
|
|
125
|
+
* "Waiting for review: N". The person's pending proposals in the spaces this
|
|
126
|
+
* connection may read proposals in (any agent's, not only this app's), from
|
|
127
|
+
* the pod's seamed `GET /proposals` door. Needs the `proposal.read`
|
|
128
|
+
* permission (ask for it in `requests`): without it the pod would answer an
|
|
129
|
+
* empty list, so this answers `forbidden` instead, without a request.
|
|
130
|
+
*/
|
|
131
|
+
listPendingProposals(opts?: ListPendingProposalsOptions): Promise<PodResult<PendingProposals>>;
|
|
93
132
|
get<T = unknown>(path: string, query?: Record<string, QueryValue>): Promise<PodResult<T>>;
|
|
94
133
|
post<T = unknown>(path: string, body?: unknown): Promise<PodWriteResult<T>>;
|
|
95
134
|
patch<T = unknown>(path: string, body?: unknown): Promise<PodWriteResult<T>>;
|
|
@@ -98,6 +137,11 @@ interface PodClient {
|
|
|
98
137
|
}
|
|
99
138
|
/** Whether `connection` was granted `permission` (in `workspaceId` when given). Exact match: grants carry no wildcard. */
|
|
100
139
|
declare function can(connection: Pick<PodConnection, "grant">, permission: string, workspaceId?: string): boolean;
|
|
140
|
+
/**
|
|
141
|
+
* The grant by space, in the grant's order, each permission once. The pod
|
|
142
|
+
* sends one row per permission per space; a space switcher wants one per space.
|
|
143
|
+
*/
|
|
144
|
+
declare function spaces(connection: Pick<PodConnection, "grant">): PodSpace[];
|
|
101
145
|
/**
|
|
102
146
|
* Where to review a proposal: the pod's answer, resolved against the pod and
|
|
103
147
|
* kept only on the pod's own origin; else the pod's deep link `/open/<id>`.
|
|
@@ -105,7 +149,7 @@ declare function can(connection: Pick<PodConnection, "grant">, permission: strin
|
|
|
105
149
|
declare function reviewUrlFor(podUrl: string, reviewUrl: unknown, proposalId: string | null): string;
|
|
106
150
|
declare function createPodClient(connection: PodConnection, opts?: PodClientOptions): PodClient;
|
|
107
151
|
|
|
108
|
-
type SealPurpose = "synap-connect/transaction" | "synap-connect/session";
|
|
152
|
+
type SealPurpose = "synap-connect/transaction" | "synap-connect/session" | "synap-connect/cloud";
|
|
109
153
|
/** The app secret: one value, or several to rotate (the first seals, all open). */
|
|
110
154
|
type AppSecret = string | readonly string[];
|
|
111
155
|
declare const MIN_SECRET_LENGTH = 32;
|
|
@@ -143,9 +187,32 @@ interface ConnectionStore {
|
|
|
143
187
|
interface CookieNames {
|
|
144
188
|
session: string;
|
|
145
189
|
transaction: string;
|
|
190
|
+
/** A Synap Cloud sign-in in progress (sealed state, 10 minutes). */
|
|
191
|
+
cloud: string;
|
|
192
|
+
/** "This browser was connected to <pod>": the pod's URL only, no secret (`markerCookie`). */
|
|
193
|
+
marker: string;
|
|
146
194
|
}
|
|
147
195
|
/** `__Host-` names on https (Secure, Path=/, no Domain: bound to this exact host). */
|
|
148
196
|
declare function cookieNames(secure: boolean): CookieNames;
|
|
197
|
+
/** The marker outlives the connection: as long as browsers keep a cookie (400 days). */
|
|
198
|
+
declare const MARKER_TTL_SEC: number;
|
|
199
|
+
/**
|
|
200
|
+
* The marker cookie: which pod this browser was connected to, so a connection
|
|
201
|
+
* that lapsed (idle past the refresh token's life, its sealed cookie gone)
|
|
202
|
+
* reads as "expired, connect again to <pod>" rather than "never connected".
|
|
203
|
+
* It holds the pod's public URL and NOTHING else: no token, no user, nothing
|
|
204
|
+
* sealed. A forged value can only pre-fill the address the person confirms.
|
|
205
|
+
*/
|
|
206
|
+
declare function markerCookie(podUrl: string, opts: {
|
|
207
|
+
secure: boolean;
|
|
208
|
+
name?: string;
|
|
209
|
+
}): string;
|
|
210
|
+
/** The marker's pod URL, or null (absent, or not a canonical pod address). */
|
|
211
|
+
declare function readMarker(cookieHeader: string | null, opts: {
|
|
212
|
+
secure: boolean;
|
|
213
|
+
name?: string;
|
|
214
|
+
allowInsecureLoopback?: boolean;
|
|
215
|
+
}): string | null;
|
|
149
216
|
/** When the stored value stops being useful. */
|
|
150
217
|
declare function connectionExpiresAt(c: PodConnection): number;
|
|
151
218
|
interface SealedCookieStoreOptions {
|
|
@@ -169,6 +236,8 @@ interface PodAppPaths {
|
|
|
169
236
|
connect: string;
|
|
170
237
|
callback: string;
|
|
171
238
|
disconnect: string;
|
|
239
|
+
/** Synap Cloud: POST starts it, GET is the pod chooser's return (forwarded from the connect page). */
|
|
240
|
+
cloud: string;
|
|
172
241
|
/** The app's connect page (also the CIMD `initiate_login_uri`). */
|
|
173
242
|
connectPage: string;
|
|
174
243
|
/** Where a failed callback lands, with `?error=<code>`. */
|
|
@@ -195,7 +264,12 @@ interface PodAppAuthConfig {
|
|
|
195
264
|
store?: ConnectionStore;
|
|
196
265
|
/** RFC 8707 resource asked for (default the Hub API). */
|
|
197
266
|
resource?: "api/hub" | "mcp" | null;
|
|
198
|
-
/**
|
|
267
|
+
/**
|
|
268
|
+
* The Synap Control Plane's URL (e.g. https://api.synap.live): offers
|
|
269
|
+
* "Continue with Synap Cloud" (`cloudConnectAvailable`). Unset = address only.
|
|
270
|
+
*/
|
|
271
|
+
cloudUrl?: string | null;
|
|
272
|
+
/** Accept pods (and a Control Plane) on http://localhost (development against a local pod). */
|
|
199
273
|
allowInsecureLoopback?: boolean;
|
|
200
274
|
/** Developer log of every refused sign-in; messages never carry a token. Default: console.warn. */
|
|
201
275
|
onError?: (error: ConnectError, where: "connect" | "callback" | "disconnect" | "refresh") => void;
|
|
@@ -228,17 +302,31 @@ interface RefreshOutcome {
|
|
|
228
302
|
/** The request's Cookie header with the refreshed value, to forward to the render (null = unchanged). */
|
|
229
303
|
cookieHeader: string | null;
|
|
230
304
|
error?: ConnectError;
|
|
305
|
+
/**
|
|
306
|
+
* With `none`: this browser WAS connected to that pod and the connection
|
|
307
|
+
* lapsed (its sealed cookie is gone, idle past its life). Say "expired,
|
|
308
|
+
* connect again" with the pod pre-filled, not "connect your pod".
|
|
309
|
+
*/
|
|
310
|
+
lapsed?: {
|
|
311
|
+
podUrl: string;
|
|
312
|
+
};
|
|
231
313
|
}
|
|
232
314
|
interface PodAppAuth {
|
|
233
315
|
clientId: string;
|
|
234
316
|
redirectUri: string;
|
|
235
317
|
metadata: ClientMetadataDocument;
|
|
236
318
|
paths: PodAppPaths;
|
|
319
|
+
/** Whether "Continue with Synap Cloud" can be offered (`cloudUrl` is configured). */
|
|
320
|
+
cloudConnectAvailable: boolean;
|
|
237
321
|
handlers: {
|
|
238
322
|
clientMetadata(request: Request): Promise<Response>;
|
|
239
323
|
connect(request: Request): Promise<Response>;
|
|
240
324
|
callback(request: Request): Promise<Response>;
|
|
241
325
|
disconnect(request: Request): Promise<Response>;
|
|
326
|
+
/** POST: start a Synap Cloud sign-in (same-origin, form { next?, space?, prompt? }). */
|
|
327
|
+
cloudConnect(request: Request): Promise<Response>;
|
|
328
|
+
/** GET: the Synap Cloud pod chooser's return (`?iss&state`), checked against this browser's cookie. */
|
|
329
|
+
cloudReturn(request: Request): Promise<Response>;
|
|
242
330
|
};
|
|
243
331
|
/**
|
|
244
332
|
* The stored connection (no refresh, no expiry check), or null. Takes the
|
|
@@ -246,6 +334,14 @@ interface PodAppAuth {
|
|
|
246
334
|
* pass `(await headers()).get("cookie")`).
|
|
247
335
|
*/
|
|
248
336
|
readConnection(source: Request | string | null): Promise<PodConnection | null>;
|
|
337
|
+
/**
|
|
338
|
+
* The pod this browser WAS connected to, when no connection is stored any
|
|
339
|
+
* more (it lapsed); null when one is stored or this browser never connected
|
|
340
|
+
* (or disconnected). Same sources as `readConnection`.
|
|
341
|
+
*/
|
|
342
|
+
readLapsed(source: Request | string | null): Promise<{
|
|
343
|
+
podUrl: string;
|
|
344
|
+
} | null>;
|
|
249
345
|
/** For `proxy.ts` / a route handler: rotate near expiry, lost-race safe. */
|
|
250
346
|
refreshIfNeeded(request: Request): Promise<RefreshOutcome>;
|
|
251
347
|
/** A Hub REST client for the connection. */
|
|
@@ -259,6 +355,21 @@ declare function buildClientMetadata(opts: {
|
|
|
259
355
|
templates?: readonly string[];
|
|
260
356
|
paths?: Partial<PodAppPaths>;
|
|
261
357
|
}): ClientMetadataDocument;
|
|
358
|
+
/**
|
|
359
|
+
* A prefetch or a static asset: `refreshIfNeeded` answers `skipped` for these.
|
|
360
|
+
*
|
|
361
|
+
* LIMIT (Next.js 16 `proxy.ts` on the Node runtime): Next strips its router
|
|
362
|
+
* headers (`next-router-prefetch`, `rsc`, …, `FLIGHT_HEADERS` in
|
|
363
|
+
* next/dist/server/web/adapter.js) and the `_rsc` query BEFORE the proxy runs,
|
|
364
|
+
* so a router prefetch is invisible here. Skip prefetches in the proxy
|
|
365
|
+
* MATCHER, which still sees the raw headers:
|
|
366
|
+
*
|
|
367
|
+
* export const config = { matcher: [{ source: "/((?!_next/static|_next/image|.*\\.\\w+$).*)",
|
|
368
|
+
* missing: [{ type: "header", key: "next-router-prefetch" }, { type: "header", key: "purpose", value: "prefetch" }] }] };
|
|
369
|
+
*
|
|
370
|
+
* Route handlers and other frameworks see the headers, and this still checks them.
|
|
371
|
+
*/
|
|
372
|
+
declare function isPrefetchOrAsset(request: Request): boolean;
|
|
262
373
|
declare function createPodAppAuth(config: PodAppAuthConfig): PodAppAuth;
|
|
263
374
|
|
|
264
375
|
interface DiscoverOptions {
|
|
@@ -280,13 +391,6 @@ declare function canonicalPodUrl(input: string, opts?: {
|
|
|
280
391
|
* "pod.antoine.synap.live").
|
|
281
392
|
*/
|
|
282
393
|
declare function discoverPod(input: string, opts?: DiscoverOptions): Promise<PodIssuer>;
|
|
283
|
-
/** Whether "Continue with Synap Cloud" can be offered. False until the CP pod chooser (C1) ships. */
|
|
284
|
-
declare function cloudConnectAvailable(): boolean;
|
|
285
|
-
/** The Synap Cloud pod chooser (C1). Not available yet: always throws `cp_unavailable`. */
|
|
286
|
-
declare function startCloudConnect(_opts: {
|
|
287
|
-
clientId: string;
|
|
288
|
-
state?: string;
|
|
289
|
-
}): never;
|
|
290
394
|
/**
|
|
291
395
|
* A same-origin path to return to after connecting, or null. Accepts a
|
|
292
396
|
* relative path (never `//host` or `/\host`) or an absolute URL on the app's
|
|
@@ -300,16 +404,109 @@ interface LaunchHint {
|
|
|
300
404
|
next: string | null;
|
|
301
405
|
/** A space to preselect on consent (`synap_space_hint`). */
|
|
302
406
|
spaceHint: string | null;
|
|
407
|
+
/**
|
|
408
|
+
* The `state` of a Synap Cloud return (the CP pod chooser answers
|
|
409
|
+
* `initiate_login_uri?iss=…&state=…`, or `?state=…&error=access_denied` when
|
|
410
|
+
* the person cancelled), shape-checked only. NOT verified here:
|
|
411
|
+
* send the request's query to the cloud handler (GET `paths.cloud`), which
|
|
412
|
+
* checks it against this browser's sealed cookie. Never act on `pod` because
|
|
413
|
+
* a state is present.
|
|
414
|
+
*/
|
|
415
|
+
cloudState: string | null;
|
|
303
416
|
}
|
|
304
417
|
/**
|
|
305
418
|
* Read a third-party-initiated login (OIDC Core §4, spec 17 §7.2): the browser
|
|
306
419
|
* opens the app's `initiate_login_uri?iss=…&target_link_uri=…`. One parser for
|
|
307
|
-
* the browser launch and
|
|
420
|
+
* the browser launch and the Synap Cloud chooser's return (`cloudState`).
|
|
308
421
|
*/
|
|
309
422
|
declare function acceptLaunch(url: string | URL, appOrigin: string, opts?: {
|
|
310
423
|
allowInsecureLoopback?: boolean;
|
|
311
424
|
}): LaunchHint;
|
|
312
425
|
|
|
426
|
+
/** How long a Synap Cloud sign-in may take, from the click to the pod chooser's return. */
|
|
427
|
+
declare const CLOUD_TRANSACTION_TTL_MS: number;
|
|
428
|
+
/** A sealed `CloudTransaction`: opaque, safe to put in an HttpOnly cookie. */
|
|
429
|
+
type SealedCloudTransaction = string & {
|
|
430
|
+
readonly __sealedCloudTransaction: true;
|
|
431
|
+
};
|
|
432
|
+
/** What a started Synap Cloud sign-in remembers (sealed; never sent to the CP). */
|
|
433
|
+
interface CloudTransaction {
|
|
434
|
+
v: 1;
|
|
435
|
+
state: string;
|
|
436
|
+
clientId: string;
|
|
437
|
+
/** The CP base it was sent to. */
|
|
438
|
+
cloudUrl: string;
|
|
439
|
+
next: string | null;
|
|
440
|
+
spaceHint: string | null;
|
|
441
|
+
prompt: "consent" | null;
|
|
442
|
+
createdAt: number;
|
|
443
|
+
}
|
|
444
|
+
interface CloudConnectConfig {
|
|
445
|
+
/** The Control Plane's base URL, e.g. https://api.synap.live. Unset = no Synap Cloud option. */
|
|
446
|
+
cloudUrl?: string | null;
|
|
447
|
+
/** Accept a CP on http://localhost (development). */
|
|
448
|
+
allowInsecureLoopback?: boolean;
|
|
449
|
+
}
|
|
450
|
+
/** The CP base (no trailing slash), or a ConnectError (`misconfigured`). */
|
|
451
|
+
declare function cloudBaseUrl(cloudUrl: string, opts?: {
|
|
452
|
+
allowInsecureLoopback?: boolean;
|
|
453
|
+
}): string;
|
|
454
|
+
/** Whether "Continue with Synap Cloud" can be offered: a valid Control Plane URL is configured. */
|
|
455
|
+
declare function cloudConnectAvailable(config?: CloudConnectConfig | null): boolean;
|
|
456
|
+
interface StartCloudConnectOptions extends CloudConnectConfig {
|
|
457
|
+
/** The app's client_id (its CIMD URL): the CP reads `initiate_login_uri` from it. */
|
|
458
|
+
clientId: string;
|
|
459
|
+
/** SERVER-ONLY app secret that seals the transaction. */
|
|
460
|
+
secret?: AppSecret;
|
|
461
|
+
/** A same-origin path to land on afterwards (validate it first: `safeNextPath`). */
|
|
462
|
+
next?: string | null;
|
|
463
|
+
/** A space to preselect on the pod's consent. */
|
|
464
|
+
spaceHint?: string | null;
|
|
465
|
+
/** Show the pod's consent again even if this browser is already connected to the pod the person picks. */
|
|
466
|
+
prompt?: "consent" | null;
|
|
467
|
+
/** @deprecated Ignored: the SDK always draws its own 32-byte state. */
|
|
468
|
+
state?: string;
|
|
469
|
+
now?: () => number;
|
|
470
|
+
}
|
|
471
|
+
interface StartedCloudConnect {
|
|
472
|
+
/** Redirect the browser here (303): the CP's pod chooser. */
|
|
473
|
+
url: string;
|
|
474
|
+
/** Store in an HttpOnly cookie until the CP returns. */
|
|
475
|
+
transaction: SealedCloudTransaction;
|
|
476
|
+
/** ms since epoch. */
|
|
477
|
+
expiresAt: number;
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Start a Synap Cloud sign-in. Throws `cp_unavailable` at once when no CP URL
|
|
481
|
+
* is configured (as 1.3 always did), `misconfigured` without a secret.
|
|
482
|
+
*/
|
|
483
|
+
declare function startCloudConnect(opts: StartCloudConnectOptions): Promise<StartedCloudConnect>;
|
|
484
|
+
interface AcceptCloudReturnOptions {
|
|
485
|
+
/** The URL the CP sent the browser back to (`?iss=…&state=…`). */
|
|
486
|
+
url: string | URL;
|
|
487
|
+
transaction: string | null | undefined;
|
|
488
|
+
clientId: string;
|
|
489
|
+
secret: AppSecret;
|
|
490
|
+
allowInsecureLoopback?: boolean;
|
|
491
|
+
now?: () => number;
|
|
492
|
+
}
|
|
493
|
+
interface CloudReturn {
|
|
494
|
+
/** The pod the person picked (canonical issuer), still to be discovered and validated. */
|
|
495
|
+
pod: string;
|
|
496
|
+
next: string | null;
|
|
497
|
+
spaceHint: string | null;
|
|
498
|
+
prompt: "consent" | null;
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Check the CP's return against the sealed transaction of THIS browser.
|
|
502
|
+
* Throws `expired_transaction` (none, foreign, tampered or older than 10
|
|
503
|
+
* minutes), `mismatch` (the state is not this browser's, or no pod is named),
|
|
504
|
+
* `denied` (the person cancelled on the chooser: `error=access_denied`, no
|
|
505
|
+
* `iss`; nothing is started), `invalid_pod_address`.
|
|
506
|
+
* `state` is compared BEFORE anything else in the query is used.
|
|
507
|
+
*/
|
|
508
|
+
declare function acceptCloudReturn(opts: AcceptCloudReturnOptions): Promise<CloudReturn>;
|
|
509
|
+
|
|
313
510
|
/** How long a started sign-in stays valid. */
|
|
314
511
|
declare const TRANSACTION_TTL_MS: number;
|
|
315
512
|
/** The refresh token's idle life when the pod does not say (spec 17 F5: 30 days). */
|
|
@@ -351,6 +548,12 @@ interface StartConnectOptions extends FlowOptions {
|
|
|
351
548
|
spaceHint?: string | null;
|
|
352
549
|
/** A same-origin path to land on afterwards (validate it first: `safeNextPath`). */
|
|
353
550
|
next?: string | null;
|
|
551
|
+
/**
|
|
552
|
+
* `"consent"`: the person asked to see the consent screen again (to widen or
|
|
553
|
+
* narrow what the app may touch). Sent as OIDC `prompt=consent`; the sign-in
|
|
554
|
+
* is otherwise the same (fresh PKCE verifier and state).
|
|
555
|
+
*/
|
|
556
|
+
prompt?: "consent" | null;
|
|
354
557
|
allowInsecureLoopback?: boolean;
|
|
355
558
|
}
|
|
356
559
|
interface StartedConnect {
|
|
@@ -384,7 +587,9 @@ interface CallbackResult {
|
|
|
384
587
|
declare function handleCallback(opts: HandleCallbackOptions): Promise<CallbackResult>;
|
|
385
588
|
/**
|
|
386
589
|
* A token response → a connection. On a refresh, `previous` supplies what the
|
|
387
|
-
* response may omit (grant, user).
|
|
590
|
+
* response may omit (grant, user, app). `expires_in` is read as sent: a refresh
|
|
591
|
+
* answered within the pod's reuse grace (PB3b) hands back the live key the
|
|
592
|
+
* first redeem got, with less than an hour left. A refresh response WITHOUT a new
|
|
388
593
|
* refresh_token drops the old one: with single-use rotation, resending a
|
|
389
594
|
* consumed token reads as theft and revokes the whole family.
|
|
390
595
|
*/
|
|
@@ -439,4 +644,4 @@ declare function pkceChallenge(verifier: string): Promise<string>;
|
|
|
439
644
|
|
|
440
645
|
declare function isBrowserRuntime(): boolean;
|
|
441
646
|
|
|
442
|
-
export { AppRequest, type AppSecret, CONNECT_ERROR_CODES, type CallbackResult, ClientMetadataDocument, ConnectError, type ConnectErrorCode, type ConnectTransaction, type ConnectionStore, type CookieNames, DEFAULT_PATHS, DEFAULT_REFRESH_IDLE_MS, type DiscoverOptions, type FlowOptions, type HandleCallbackOptions, type LaunchHint, MIN_SECRET_LENGTH, type Opened, type PodAppAuth, type PodAppAuthConfig, type PodAppPaths, type PodClient, type PodClientOptions, PodConnection, type PodError, type PodErrorCode, PodGrant, PodIssuer, type PodResult, type PodWriteResult, type QueryValue, REFRESH_WINDOW_MS, ROTATION_MEMORY_MS, type RefreshOutcome, type RefreshStatus, type SealPurpose, type SealedCookieStoreOptions, type SealedTransaction, type StartConnectOptions, type StartedConnect, TRANSACTION_TTL_MS, acceptLaunch, applySetCookies, buildClientMetadata, can, canonicalPodUrl, cloudConnectAvailable, connectionExpiresAt, cookieNames, createPodAppAuth, createPodClient, createSealedCookieStore, discoverPod, handleCallback, isBrowserRuntime, isConnectError, openTransaction, parseConnectErrorCode, parseTokenResponse, pkceChallenge, refreshConnection, reviewUrlFor, revokeConnection, safeNextPath, seal, startCloudConnect, startConnect, unseal };
|
|
647
|
+
export { type AcceptCloudReturnOptions, AppRequest, type AppSecret, CLOUD_TRANSACTION_TTL_MS, CONNECT_ERROR_CODES, type CallbackResult, ClientMetadataDocument, type CloudConnectConfig, type CloudReturn, type CloudTransaction, ConnectError, type ConnectErrorCode, type ConnectTransaction, type ConnectionStore, type CookieNames, DEFAULT_PATHS, DEFAULT_REFRESH_IDLE_MS, type DiscoverOptions, type FlowOptions, type HandleCallbackOptions, type LaunchHint, type ListPendingProposalsOptions, MARKER_TTL_SEC, MIN_SECRET_LENGTH, type Opened, type PendingProposal, type PendingProposals, type PodAppAuth, type PodAppAuthConfig, type PodAppPaths, type PodClient, type PodClientOptions, PodConnection, type PodError, type PodErrorCode, PodGrant, PodIssuer, type PodResult, PodSpace, type PodWriteResult, type QueryValue, REFRESH_WINDOW_MS, ROTATION_MEMORY_MS, type RefreshOutcome, type RefreshStatus, type SealPurpose, type SealedCloudTransaction, type SealedCookieStoreOptions, type SealedTransaction, type StartCloudConnectOptions, type StartConnectOptions, type StartedCloudConnect, type StartedConnect, TRANSACTION_TTL_MS, acceptCloudReturn, acceptLaunch, applySetCookies, buildClientMetadata, can, canonicalPodUrl, cloudBaseUrl, cloudConnectAvailable, connectionExpiresAt, cookieNames, createPodAppAuth, createPodClient, createSealedCookieStore, discoverPod, handleCallback, isBrowserRuntime, isConnectError, isPrefetchOrAsset, markerCookie, openTransaction, parseConnectErrorCode, parseTokenResponse, pkceChallenge, readMarker, refreshConnection, reviewUrlFor, revokeConnection, safeNextPath, seal, spaces, startCloudConnect, startConnect, unseal };
|