@domino-sdk/relay 1.61.0 → 1.63.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 +276 -8
- package/README.md +3 -2
- package/dist/{schema-CZ6Rj0ZF.d.ts → accounts-nz3mzfRQ.d.ts} +3146 -1765
- package/dist/action-9Xl0StBg.d.ts +33 -0
- package/dist/{attempt-captures-DYnJVkfg.d.ts → attempt-captures-DMi8oR9T.d.ts} +1 -1
- package/dist/authoring.d.ts +171 -49
- package/dist/authoring.js +158 -49
- package/dist/{automatic-outcomes-If88LR9f.d.ts → automatic-outcomes-C_LLQU1p.d.ts} +15 -1
- package/dist/avatar.d.ts +1 -1
- package/dist/browser.d.ts +15 -11
- package/dist/browser.js +18 -12
- package/dist/capability-error-CuI_F7yM.d.ts +296 -0
- package/dist/{pages-K7-KjSXw.d.ts → catalog-BaTOKpNw.d.ts} +56 -567
- package/dist/{chunk-XBV2CK2H.js → chunk-3RFP6GT5.js} +15 -3
- package/dist/{chunk-VURRFVNP.js → chunk-4GQW43UU.js} +239 -361
- package/dist/chunk-4NOFSGAL.js +320 -0
- package/dist/{chunk-24I4R732.js → chunk-5XLZ34PV.js} +34 -19
- package/dist/{chunk-L77O64I4.js → chunk-7X67QLPB.js} +43 -43
- package/dist/{chunk-RHBS5FJL.js → chunk-7Z4SZ6YM.js} +3 -3
- package/dist/{chunk-QEAS4ZGS.js → chunk-AQOL3SK5.js} +1 -1
- package/dist/chunk-EHUSD3O2.js +377 -0
- package/dist/chunk-FO2LCZTL.js +19 -0
- package/dist/{chunk-DYXDZFKA.js → chunk-FU5CGNTR.js} +166 -178
- package/dist/chunk-FWLQ5XCS.js +21 -0
- package/dist/chunk-GLH6MEI2.js +193 -0
- package/dist/chunk-ICXZZNPS.js +199 -0
- package/dist/{chunk-ZDJLPN4L.js → chunk-ID3BZXFZ.js} +2696 -2693
- package/dist/chunk-KP2MCX3R.js +587 -0
- package/dist/{chunk-SKGTNTLF.js → chunk-LZWXCBUB.js} +213 -297
- package/dist/chunk-MTKRIQEU.js +31 -0
- package/dist/{chunk-4OC7REYX.js → chunk-MWMCQLCG.js} +3 -3
- package/dist/{chunk-PPB7HALD.js → chunk-N4BDKS6Y.js} +27 -26
- package/dist/{chunk-5I54XBK2.js → chunk-N4LNEGQX.js} +2 -2
- package/dist/chunk-NQDEWJWE.js +554 -0
- package/dist/chunk-QR6HH4DI.js +508 -0
- package/dist/chunk-TLSQETTY.js +41 -0
- package/dist/{chunk-MHPKEVEW.js → chunk-U66GUVSG.js} +7 -2
- package/dist/{chunk-KDR2VAJP.js → chunk-UYVJZR33.js} +2 -2
- package/dist/chunk-UZ765UGH.js +18 -0
- package/dist/{chunk-7A4J67ZL.js → chunk-VWQGWGCH.js} +7 -7
- package/dist/chunk-W7YSMSGC.js +725 -0
- package/dist/{client-C51w7fMb.d.ts → client-DHmG7rn6.d.ts} +126 -93
- package/dist/{announcements-CHx3-HBw.d.ts → dashboards-CLemT6kj.d.ts} +14 -137
- package/dist/{deployments-kWoHFaqj.d.ts → deployments-DTULi7dF.d.ts} +450 -18
- package/dist/identity-integration-DOeNZaxF.d.ts +1271 -0
- package/dist/index.d.ts +13 -11
- package/dist/index.js +16 -11
- package/dist/internal.d.ts +29 -13
- package/dist/internal.js +57 -17
- package/dist/{integrations-B3y36OaB.d.ts → limits-kNzYdZ00.d.ts} +464 -53
- package/dist/{offers-BoV4ryUc.d.ts → offers-CYeN_I0Y.d.ts} +22 -4
- package/dist/{participant-activity-DHL8QYks.d.ts → participant-activity-D-Drp24G.d.ts} +16 -3
- package/dist/portal-proxy.d.ts +75 -2
- package/dist/portal-proxy.js +153 -25
- package/dist/react/index.d.ts +214 -27
- package/dist/react/index.js +196 -42
- package/dist/{action-DBzILFx9.d.ts → request-error-D_dUPLwo.d.ts} +1 -31
- package/dist/reward-deliveries-drp-x1G-.d.ts +782 -0
- package/dist/runtime/authoring.js +1 -1
- package/dist/runtime/chunks/UGDV5W4N.js +1 -0
- package/dist/runtime/manifest.json +3 -3
- package/dist/runtime/schema.js +1 -1
- package/dist/schema.d.ts +330 -31
- package/dist/schema.js +147 -91
- package/dist/server/index.d.ts +14 -12
- package/dist/server/index.js +6425 -6260
- package/dist/sign-in-providers-B1Q9eDRm.d.ts +44 -0
- package/dist/submission-input-DZCbjQUH.d.ts +343 -0
- package/dist/{telegram-browser-BUceZIGZ.d.ts → telegram-browser-NL0Asmsi.d.ts} +46 -6
- package/dist/telegram.d.ts +64 -0
- package/dist/telegram.js +23 -0
- package/dist/testing.d.ts +326 -27
- package/dist/testing.js +440 -90
- package/dist/tracker-data-esm3WG8R.d.ts +1881 -0
- package/dist/{transport-BrX9pIGN.d.ts → transport-Czht_irp.d.ts} +43483 -38512
- package/dist/{wallet-CIqFoxdm.d.ts → wallet-B7e06v4m.d.ts} +32 -9
- package/package.json +5 -1
- package/dist/accounts-DoabriBX.d.ts +0 -306
- package/dist/capability-error-DufwG3G0.d.ts +0 -159
- package/dist/chunk-3Y3L2F54.js +0 -982
- package/dist/chunk-DHXDBAJF.js +0 -544
- package/dist/chunk-EN3M5Z4J.js +0 -13
- package/dist/chunk-QNUHWK7R.js +0 -602
- package/dist/chunk-SE4PFJPT.js +0 -247
- package/dist/groups-CqcA2Ycs.d.ts +0 -2827
- package/dist/runtime/chunks/5QVFB4TU.js +0 -1
- package/dist/submission-input-C54Q8yAD.d.ts +0 -146
- package/dist/x-D1PGi8Sq.d.ts +0 -331
|
@@ -92,14 +92,23 @@ declare function sessionMember(session: {
|
|
|
92
92
|
declare const memberSummarySchema: z.ZodObject<{
|
|
93
93
|
member: z.ZodString;
|
|
94
94
|
avatarSeed: z.ZodString;
|
|
95
|
-
email: z.
|
|
96
|
-
emails: z.
|
|
95
|
+
email: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
96
|
+
emails: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
97
97
|
clock: z.ZodOptional<z.ZodObject<{
|
|
98
98
|
now: z.ZodNumber;
|
|
99
99
|
offsetMs: z.ZodNumber;
|
|
100
100
|
}, z.core.$strip>>;
|
|
101
101
|
}, z.core.$strip>;
|
|
102
|
-
type
|
|
102
|
+
type MemberSummaryResponse = z.infer<typeof memberSummarySchema>;
|
|
103
|
+
/** @compat output */
|
|
104
|
+
type MemberSummary = Omit<MemberSummaryResponse, "clock"> & {
|
|
105
|
+
clock: NonNullable<MemberSummaryResponse["clock"]>;
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* @deprecated `POST /v1/auth/exchange` refuses this body with 400: it takes `{ subject, accounts?,
|
|
109
|
+
* previousToken? }` with an identity integration server key as the bearer. Use
|
|
110
|
+
* `exchangeParticipant` from `@domino-sdk/relay/portal-proxy`. Removed in 2.0.0.
|
|
111
|
+
*/
|
|
103
112
|
declare const exchangeSchema: z.ZodObject<{
|
|
104
113
|
organization: z.ZodString;
|
|
105
114
|
project: z.ZodString;
|
|
@@ -117,6 +126,10 @@ declare const exchangeSchema: z.ZodObject<{
|
|
|
117
126
|
operator: "operator";
|
|
118
127
|
}>;
|
|
119
128
|
}, z.core.$strict>;
|
|
129
|
+
/**
|
|
130
|
+
* @deprecated `POST /v1/auth/exchange` refuses this body with 400. Use `exchangeParticipant` from
|
|
131
|
+
* `@domino-sdk/relay/portal-proxy`. Removed in 2.0.0.
|
|
132
|
+
*/
|
|
120
133
|
type ExchangeInput = z.infer<typeof exchangeSchema>;
|
|
121
134
|
declare const exchangeResultSchema: z.ZodObject<{
|
|
122
135
|
token: z.ZodString;
|
package/dist/portal-proxy.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import { M as MemberImportVouchedAccount, P as ParticipantExchangeAccountResult, a as ParticipantExchangeResult, I as IdentityIntegrationKey } from './identity-integration-DOeNZaxF.js';
|
|
2
|
+
import { R as RequestError } from './request-error-D_dUPLwo.js';
|
|
3
|
+
import './tracker-data-esm3WG8R.js';
|
|
4
|
+
import 'zod';
|
|
5
|
+
|
|
1
6
|
/**
|
|
2
7
|
* Server-only proxy: browser cookies stay on the participant origin.
|
|
3
8
|
* The shared API resolves the app's origin to its registered preview or staging
|
|
@@ -14,14 +19,82 @@ declare function proxyParticipant(request: Request, upstream: {
|
|
|
14
19
|
*/
|
|
15
20
|
hosted?: boolean;
|
|
16
21
|
}): Promise<Response>;
|
|
17
|
-
|
|
22
|
+
declare const participantExchangeErrorBrand: unique symbol;
|
|
23
|
+
/**
|
|
24
|
+
* Whether `value` is a `ParticipantExchangeError` from any copy of the SDK. Prefer it to
|
|
25
|
+
* `instanceof`.
|
|
26
|
+
*/
|
|
27
|
+
declare function isParticipantExchangeError(value: unknown): value is ParticipantExchangeError;
|
|
28
|
+
/**
|
|
29
|
+
* An exchange Domino refused: a `RequestError` of kind `http`, with `status` and `code` as the
|
|
30
|
+
* exchange answered them, and `retryAfter` the milliseconds its `Retry-After` asked to wait, such
|
|
31
|
+
* as on a rate-limited exchange.
|
|
32
|
+
*
|
|
33
|
+
* @compat sealed
|
|
34
|
+
*/
|
|
35
|
+
declare class ParticipantExchangeError extends RequestError {
|
|
36
|
+
readonly name: string;
|
|
37
|
+
readonly [participantExchangeErrorBrand] = true;
|
|
38
|
+
readonly status: number;
|
|
39
|
+
readonly code: string;
|
|
40
|
+
constructor(message: string, details: {
|
|
41
|
+
status: number;
|
|
42
|
+
code: string;
|
|
43
|
+
retryAfter?: number;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Signs a member in from your server, without a browser: trades your identity integration key and
|
|
48
|
+
* the stable ID of a user your server verified for a participant session. Use it when no browser
|
|
49
|
+
* reaches Domino through `createParticipantBackend`, such as a backend that calls Domino for its
|
|
50
|
+
* users. `accounts` vouches for the user's accounts as `createParticipantBackend`'s does, and the
|
|
51
|
+
* answer's `accounts` gives each one's outcome. Pass the previous answer's `token` as
|
|
52
|
+
* `previousToken` to keep using that session while it lasts. Throws ParticipantExchangeError when
|
|
53
|
+
* Domino refuses the exchange.
|
|
54
|
+
*/
|
|
55
|
+
declare function exchangeParticipant(options: {
|
|
56
|
+
baseUrl: string;
|
|
57
|
+
integrationKey: string;
|
|
58
|
+
subject: string;
|
|
59
|
+
previousToken?: string;
|
|
60
|
+
accounts?: MemberImportVouchedAccount[];
|
|
61
|
+
fetch?: typeof fetch;
|
|
62
|
+
}): Promise<ParticipantExchangeResult>;
|
|
63
|
+
/**
|
|
64
|
+
* Which integration an app login key (`di_…`) belongs to: its organization, project, environment,
|
|
65
|
+
* origin and the expiry of this key, never a secret. Checking a key does not count as using it.
|
|
66
|
+
* `baseUrl` is the participant API origin: HTTPS, or a loopback HTTP origin for a local stack.
|
|
67
|
+
* Throws ParticipantExchangeError when Domino refuses the key: 401 `invalid-credential` for a key
|
|
68
|
+
* that is unknown, expired or revoked, or whose project was deleted.
|
|
69
|
+
*/
|
|
70
|
+
declare function inspectIntegrationKey(options: {
|
|
71
|
+
baseUrl: string;
|
|
72
|
+
integrationKey: string;
|
|
73
|
+
fetch?: typeof fetch;
|
|
74
|
+
}): Promise<IdentityIntegrationKey>;
|
|
75
|
+
/**
|
|
76
|
+
* Use only in an app server route. authenticate must verify the app's own session.
|
|
77
|
+
* `origin` is the app's exact HTTPS origin, or a loopback HTTP origin
|
|
78
|
+
* (`http://localhost`, `http://127.0.0.1`, `http://[::1]`, any port) for a
|
|
79
|
+
* local browser test. Relay registers only HTTPS origins, so a loopback origin
|
|
80
|
+
* works only against an injected `fetch`, such as `createFakeRelay`'s.
|
|
81
|
+
* `authenticate` may also return `accounts` the app vouches belong to the user, which needs the
|
|
82
|
+
* key's **Vouches accounts** setting; `onAccounts` receives each one's outcome, such as an account
|
|
83
|
+
* another member holds.
|
|
84
|
+
* `onExchangeError` receives each refused exchange as Domino answered it (status, code, message and
|
|
85
|
+
* `retryAfter`) before the browser gets its answer, so the server can log why sign-in failed. The
|
|
86
|
+
* browser's answer does not change, and a callback that throws does not change it either.
|
|
87
|
+
*/
|
|
18
88
|
declare function createParticipantBackend(options: {
|
|
19
89
|
baseUrl: string;
|
|
20
90
|
integrationKey: string;
|
|
21
91
|
origin: string;
|
|
22
92
|
authenticate: (request: Request) => Promise<{
|
|
23
93
|
subject: string;
|
|
94
|
+
accounts?: MemberImportVouchedAccount[];
|
|
24
95
|
} | null>;
|
|
96
|
+
onAccounts?: (results: ParticipantExchangeAccountResult[], request: Request) => void | Promise<void>;
|
|
97
|
+
onExchangeError?: (error: ParticipantExchangeError, request: Request) => void | Promise<void>;
|
|
25
98
|
fetch?: typeof fetch;
|
|
26
99
|
}): (request: Request) => Promise<Response>;
|
|
27
100
|
/**
|
|
@@ -60,4 +133,4 @@ declare function signedInMember(request: Request, env: HostedAppEnv, options: {
|
|
|
60
133
|
fetch?: typeof fetch;
|
|
61
134
|
}): Promise<string | null>;
|
|
62
135
|
|
|
63
|
-
export { type HostedAppEnv, createParticipantBackend, handleHostedApp, hostedAppRequest, proxyParticipant, signedInMember };
|
|
136
|
+
export { type HostedAppEnv, ParticipantExchangeError, createParticipantBackend, exchangeParticipant, handleHostedApp, hostedAppRequest, inspectIntegrationKey, isParticipantExchangeError, proxyParticipant, signedInMember };
|
package/dist/portal-proxy.js
CHANGED
|
@@ -1,15 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
secureOrLoopbackOrigin
|
|
3
|
+
} from "./chunk-UZ765UGH.js";
|
|
4
|
+
import {
|
|
5
|
+
identityIntegrationKeySchema,
|
|
6
|
+
participantExchangeAccountsSchema,
|
|
7
|
+
participantExchangeResultSchema
|
|
8
|
+
} from "./chunk-KP2MCX3R.js";
|
|
1
9
|
import {
|
|
2
10
|
isParticipantRoute
|
|
3
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-U66GUVSG.js";
|
|
4
12
|
import {
|
|
5
|
-
clientIdentity
|
|
6
|
-
|
|
13
|
+
clientIdentity,
|
|
14
|
+
retryAfter
|
|
15
|
+
} from "./chunk-3RFP6GT5.js";
|
|
7
16
|
import {
|
|
8
|
-
exchangeResultSchema,
|
|
9
17
|
participantPrincipalSchema,
|
|
10
18
|
sessionMember
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
19
|
+
} from "./chunk-N4BDKS6Y.js";
|
|
20
|
+
import "./chunk-ID3BZXFZ.js";
|
|
21
|
+
import {
|
|
22
|
+
RequestError,
|
|
23
|
+
isRequestError
|
|
24
|
+
} from "./chunk-GLH6MEI2.js";
|
|
13
25
|
|
|
14
26
|
// src/portal-proxy.ts
|
|
15
27
|
import * as z from "zod";
|
|
@@ -86,10 +98,98 @@ async function proxyParticipant(request, upstream) {
|
|
|
86
98
|
headers: resultHeaders
|
|
87
99
|
});
|
|
88
100
|
}
|
|
101
|
+
function requestExchange(options, body) {
|
|
102
|
+
return (options.fetch ?? fetch)(options.baseUrl + "/v1/auth/exchange", {
|
|
103
|
+
method: "POST",
|
|
104
|
+
redirect: "manual",
|
|
105
|
+
headers: {
|
|
106
|
+
Authorization: "Bearer " + options.integrationKey,
|
|
107
|
+
"X-Domino-Client": clientIdentity(),
|
|
108
|
+
"Content-Type": "application/json"
|
|
109
|
+
},
|
|
110
|
+
body: JSON.stringify({
|
|
111
|
+
subject: body.subject,
|
|
112
|
+
previousToken: body.previousToken,
|
|
113
|
+
accounts: body.accounts?.length ? participantExchangeAccountsSchema.parse(body.accounts) : void 0
|
|
114
|
+
})
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
var participantExchangeErrorBrand = /* @__PURE__ */ (() => /* @__PURE__ */ Symbol.for(
|
|
118
|
+
"@domino-sdk/relay.ParticipantExchangeError"
|
|
119
|
+
))();
|
|
120
|
+
function isParticipantExchangeError(value) {
|
|
121
|
+
return isRequestError(value) && value[participantExchangeErrorBrand] === true;
|
|
122
|
+
}
|
|
123
|
+
var ParticipantExchangeError = class extends RequestError {
|
|
124
|
+
name = "ParticipantExchangeError";
|
|
125
|
+
[participantExchangeErrorBrand] = true;
|
|
126
|
+
constructor(message, details) {
|
|
127
|
+
super(message, { ...details, kind: "http" });
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
async function exchangeParticipant(options) {
|
|
131
|
+
const base = new URL(options.baseUrl);
|
|
132
|
+
if (base.protocol !== "https:" || base.origin !== options.baseUrl) {
|
|
133
|
+
throw new Error("Configure the exact HTTPS participant API origin");
|
|
134
|
+
}
|
|
135
|
+
if (!options.integrationKey.startsWith("di_")) {
|
|
136
|
+
throw new Error(
|
|
137
|
+
"Use an identity integration server key from Console Settings"
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
const exchanged = await requestExchange(options, {
|
|
141
|
+
subject: options.subject,
|
|
142
|
+
previousToken: options.previousToken,
|
|
143
|
+
accounts: options.accounts
|
|
144
|
+
});
|
|
145
|
+
if (!exchanged.ok) {
|
|
146
|
+
throw await refusal(exchanged, "Domino identity exchange");
|
|
147
|
+
}
|
|
148
|
+
return participantExchangeResultSchema.parse(await exchanged.json());
|
|
149
|
+
}
|
|
150
|
+
async function refusal(response, what) {
|
|
151
|
+
return refusalError(response, await response.json().catch(() => null), what);
|
|
152
|
+
}
|
|
153
|
+
function refusalError(response, body, what) {
|
|
154
|
+
return new ParticipantExchangeError(
|
|
155
|
+
typeof body?.error === "string" ? body.error : `${what} failed with status ${response.status}`,
|
|
156
|
+
{
|
|
157
|
+
status: response.status,
|
|
158
|
+
code: typeof body?.code === "string" ? body.code : statusCode(response.status),
|
|
159
|
+
retryAfter: retryAfter(response.headers)
|
|
160
|
+
}
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
async function inspectIntegrationKey(options) {
|
|
164
|
+
const base = new URL(options.baseUrl);
|
|
165
|
+
if (!secureOrLoopbackOrigin(base) || base.origin !== options.baseUrl) {
|
|
166
|
+
throw new Error("Configure the exact participant API origin");
|
|
167
|
+
}
|
|
168
|
+
if (!options.integrationKey.startsWith("di_")) {
|
|
169
|
+
throw new Error(
|
|
170
|
+
"Use an identity integration server key from Console Settings"
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
const answered = await (options.fetch ?? fetch)(
|
|
174
|
+
options.baseUrl + "/v1/auth/integration",
|
|
175
|
+
{
|
|
176
|
+
method: "GET",
|
|
177
|
+
redirect: "manual",
|
|
178
|
+
headers: {
|
|
179
|
+
Authorization: "Bearer " + options.integrationKey,
|
|
180
|
+
"X-Domino-Client": clientIdentity()
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
);
|
|
184
|
+
if (!answered.ok) {
|
|
185
|
+
throw await refusal(answered, "Domino app login key check");
|
|
186
|
+
}
|
|
187
|
+
return identityIntegrationKeySchema.parse(await answered.json());
|
|
188
|
+
}
|
|
89
189
|
function createParticipantBackend(options) {
|
|
90
190
|
const origin = new URL(options.origin);
|
|
91
191
|
const base = new URL(options.baseUrl);
|
|
92
|
-
if (origin
|
|
192
|
+
if (!secureOrLoopbackOrigin(origin) || origin.origin !== options.origin || base.protocol !== "https:" || base.origin !== options.baseUrl) {
|
|
93
193
|
throw new Error(
|
|
94
194
|
"Configure exact HTTPS application and participant API origins"
|
|
95
195
|
);
|
|
@@ -100,7 +200,11 @@ function createParticipantBackend(options) {
|
|
|
100
200
|
);
|
|
101
201
|
}
|
|
102
202
|
const send = options.fetch ?? fetch;
|
|
103
|
-
const
|
|
203
|
+
const loopback = origin.protocol === "http:";
|
|
204
|
+
const cookie = (token) => (
|
|
205
|
+
// WebKit drops a Secure cookie on http://localhost, so a loopback origin sets it without.
|
|
206
|
+
`domino_app_session=${token}; Path=/relay; HttpOnly;${loopback ? "" : " Secure;"} SameSite=Lax; Max-Age=${token ? 28800 : 0}`
|
|
207
|
+
);
|
|
104
208
|
return async (request) => {
|
|
105
209
|
const url = new URL(request.url);
|
|
106
210
|
const reject = (error, status, code) => Response.json(
|
|
@@ -126,24 +230,26 @@ function createParticipantBackend(options) {
|
|
|
126
230
|
}
|
|
127
231
|
);
|
|
128
232
|
}
|
|
129
|
-
const previousToken = request.headers.get("Cookie")
|
|
130
|
-
const exchanged = await
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
Authorization: "Bearer " + options.integrationKey,
|
|
135
|
-
"X-Domino-Client": clientIdentity(),
|
|
136
|
-
"Content-Type": "application/json"
|
|
137
|
-
},
|
|
138
|
-
body: JSON.stringify({ subject: identity.subject, previousToken })
|
|
233
|
+
const previousToken = onlyCookie(request.headers.get("Cookie"), "domino_app_session") ?? void 0;
|
|
234
|
+
const exchanged = await requestExchange(options, {
|
|
235
|
+
subject: identity.subject,
|
|
236
|
+
previousToken,
|
|
237
|
+
accounts: identity.accounts
|
|
139
238
|
});
|
|
140
239
|
if (!exchanged.ok) {
|
|
141
240
|
const body = await exchanged.json().catch(() => null);
|
|
142
|
-
const
|
|
143
|
-
const
|
|
241
|
+
const failure = refusalError(exchanged, body, "Domino identity exchange");
|
|
242
|
+
const { code } = failure;
|
|
243
|
+
const wait = exchanged.headers.get("Retry-After");
|
|
244
|
+
if (options.onExchangeError) {
|
|
245
|
+
try {
|
|
246
|
+
await options.onExchangeError(failure, request);
|
|
247
|
+
} catch {
|
|
248
|
+
}
|
|
249
|
+
}
|
|
144
250
|
return Response.json(
|
|
145
251
|
{
|
|
146
|
-
error: exchanged.status === 409 && typeof body?.error === "string" ? body.error : exchanged.status === 409 ? "Domino refused this account. Ask an organizer." : "Domino identity exchange failed. Check the server integration key and its expiry in Console Settings.",
|
|
252
|
+
error: (exchanged.status === 409 || code === "ACCOUNT_VOUCHING_OFF") && typeof body?.error === "string" ? body.error : exchanged.status === 409 ? "Domino refused this account. Ask an organizer." : "Domino identity exchange failed. Check the server integration key and its expiry in Console Settings.",
|
|
147
253
|
code
|
|
148
254
|
},
|
|
149
255
|
{
|
|
@@ -151,18 +257,23 @@ function createParticipantBackend(options) {
|
|
|
151
257
|
headers: {
|
|
152
258
|
"Set-Cookie": cookie(""),
|
|
153
259
|
"Cache-Control": "no-store",
|
|
154
|
-
...
|
|
260
|
+
...wait ? { "Retry-After": wait } : {}
|
|
155
261
|
}
|
|
156
262
|
}
|
|
157
263
|
);
|
|
158
264
|
}
|
|
159
|
-
const { token } =
|
|
265
|
+
const { token, accounts } = participantExchangeResultSchema.parse(
|
|
266
|
+
await exchanged.json()
|
|
267
|
+
);
|
|
268
|
+
if (accounts?.length && options.onAccounts) {
|
|
269
|
+
await options.onAccounts(accounts, request);
|
|
270
|
+
}
|
|
160
271
|
const response = await proxyParticipant(request, {
|
|
161
272
|
baseUrl: options.baseUrl,
|
|
162
273
|
fetch: async (target, init) => {
|
|
163
274
|
const headers2 = new Headers(init?.headers);
|
|
164
275
|
headers2.delete("Cookie");
|
|
165
|
-
const returnBinding = request.headers.get("Cookie")
|
|
276
|
+
const returnBinding = oauthReturnBinding(request.headers.get("Cookie"));
|
|
166
277
|
if (returnBinding) {
|
|
167
278
|
headers2.set("Cookie", returnBinding);
|
|
168
279
|
}
|
|
@@ -180,6 +291,19 @@ function createParticipantBackend(options) {
|
|
|
180
291
|
return new Response(response.body, { status: response.status, headers });
|
|
181
292
|
};
|
|
182
293
|
}
|
|
294
|
+
function onlyCookie(header, name) {
|
|
295
|
+
const values = (header ?? "").split(";").map((value) => value.trim()).filter((value) => value.startsWith(name + "="));
|
|
296
|
+
return values.length === 1 ? values[0].slice(name.length + 1) : null;
|
|
297
|
+
}
|
|
298
|
+
function oauthReturnBinding(header) {
|
|
299
|
+
for (const name of ["__Host-relay_auth_return", "relay_auth_return"]) {
|
|
300
|
+
if (header?.split(";").some((value) => value.trim().startsWith(name + "="))) {
|
|
301
|
+
const value = onlyCookie(header, name);
|
|
302
|
+
return value === null ? null : `${name}=${value}`;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
183
307
|
function hostedAppRequest(request, env) {
|
|
184
308
|
if (!env.DOMINO_PREVIEW_ORIGIN) {
|
|
185
309
|
return request;
|
|
@@ -237,11 +361,15 @@ async function signedInMember(request, env, options) {
|
|
|
237
361
|
);
|
|
238
362
|
return session.success ? sessionMember(session.data) : null;
|
|
239
363
|
}
|
|
240
|
-
var signedInSessionSchema = z.object({ principal: participantPrincipalSchema }).nullable();
|
|
364
|
+
var signedInSessionSchema = /* @__PURE__ */ (() => z.object({ principal: participantPrincipalSchema }).nullable())();
|
|
241
365
|
export {
|
|
366
|
+
ParticipantExchangeError,
|
|
242
367
|
createParticipantBackend,
|
|
368
|
+
exchangeParticipant,
|
|
243
369
|
handleHostedApp,
|
|
244
370
|
hostedAppRequest,
|
|
371
|
+
inspectIntegrationKey,
|
|
372
|
+
isParticipantExchangeError,
|
|
245
373
|
proxyParticipant,
|
|
246
374
|
signedInMember
|
|
247
375
|
};
|