@machinemetrics/mm-react-embeddable 1.4.0-3 → 1.4.0-5

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.
@@ -1,214 +1,307 @@
1
- import f, { createContext as J, useContext as _, useState as I, useRef as x, useCallback as h, useEffect as g, useMemo as Y } from "react";
2
- import w from "prop-types";
3
- import Z from "styled-components";
4
- const H = J(null), D = J({
1
+ import h, { createContext as oe, useContext as H, useState as C, useRef as R, useCallback as m, useEffect as k, useMemo as ue } from "react";
2
+ import T from "prop-types";
3
+ import D from "styled-components";
4
+ const Y = oe(null), J = oe({
5
5
  pending: [],
6
6
  authorize: () => {
7
7
  },
8
+ approve: () => {
9
+ },
10
+ complete: () => {
11
+ },
8
12
  dismiss: () => {
9
13
  },
10
14
  originEpochs: {},
11
15
  credentials: {},
12
16
  unsupported: {}
13
- }), N = 2e4, j = (n) => {
17
+ }), le = "access_token", te = (r) => r ? r.kind ? r : r.accessToken ? {
18
+ kind: le,
19
+ accessToken: r.accessToken,
20
+ expiresAt: r.expiresAt || null
21
+ } : null : null, ae = /* @__PURE__ */ new Set(["host_not_allowed", "invalid_token", "provider_unavailable"]), X = typeof window != "undefined" && window.location.protocol === "https:", de = 8e3, Q = (r) => {
14
22
  try {
15
- return new URL(n).origin;
23
+ return new URL(r).origin;
16
24
  } catch {
17
25
  return null;
18
26
  }
19
- }, V = (n) => {
20
- if (!n || /^\d{1,3}(?:\.\d{1,3}){3}$/.test(n) || n.includes(":"))
21
- return n;
22
- const o = n.split(".");
23
- return o.length <= 2 ? n : o.slice(-2).join(".");
24
- }, ee = (n, o) => {
27
+ }, ne = (r, i) => {
28
+ const c = i == null ? void 0 : i.origin;
29
+ return !c || Q(r == null ? void 0 : r.authUrl) !== c ? null : c;
30
+ }, re = (r) => {
31
+ if (!r || /^\d{1,3}(?:\.\d{1,3}){3}$/.test(r) || r.includes(":"))
32
+ return r;
33
+ const i = r.split(".");
34
+ return i.length <= 2 ? r : i.slice(-2).join(".");
35
+ }, fe = (r, i) => {
25
36
  try {
26
- const s = new URL(n), a = new URL(o);
27
- return s.protocol !== a.protocol ? !0 : V(s.hostname) !== V(a.hostname);
37
+ const c = new URL(r), d = new URL(i);
38
+ return c.protocol !== d.protocol ? !0 : re(c.hostname) !== re(d.hostname);
28
39
  } catch {
29
40
  return !0;
30
41
  }
31
- }, te = (n, { onBlocked: o, onClosed: s }) => {
32
- const a = window.open(
33
- n.authUrl,
42
+ }, pe = (r, { onBlocked: i, onClosed: c }) => {
43
+ const d = window.open(
44
+ r.authUrl,
34
45
  "mm-embed-auth",
35
46
  "popup,width=600,height=700"
36
47
  );
37
- if (!a)
38
- return o(), () => {
48
+ if (!d)
49
+ return i(), () => {
39
50
  };
40
- const m = setInterval(() => {
41
- a.closed && (clearInterval(m), s());
51
+ const g = setInterval(() => {
52
+ d.closed && (clearInterval(g), c());
42
53
  }, 1e3);
43
- return () => clearInterval(m);
44
- }, Q = ({ children: n, launcher: o }) => {
45
- const s = _(H), [a, m] = I({}), [R, T] = I({}), [k, L] = I({}), [q, y] = I({}), F = x(k);
46
- F.current = k;
47
- const b = x(null), U = x({}), P = x({}), z = h((e) => {
48
- const t = P.current[e];
54
+ return () => clearInterval(g);
55
+ }, ie = ({ children: r, launcher: i, broker: c }) => {
56
+ const d = H(Y), [g, w] = C({}), [P, U] = C({}), [z, M] = C({}), [L, A] = C({}), q = R(z);
57
+ q.current = z;
58
+ const f = R(null), v = R({}), $ = R({}), B = R({}), y = R(c);
59
+ y.current = c;
60
+ const O = m((e) => {
61
+ const t = $.current[e];
49
62
  if (!t)
50
63
  return;
51
- const r = (d) => !d[e] || d[e].clientId ? d : { ...d, [e]: { ...d[e], clientId: t } };
52
- m(r), y(r);
53
- }, []), A = h(
64
+ const n = (l) => !l[e] || l[e].clientId ? l : { ...l, [e]: { ...l[e], clientId: t } };
65
+ w(n), A(n);
66
+ }, []), j = m(
54
67
  (e, t) => {
55
- const r = j(e == null ? void 0 : e.authUrl);
56
- r && (y((d) => d[r] ? d : {
57
- ...d,
58
- [r]: { origin: r, reason: t, clientId: P.current[r] || null }
59
- }), z(r));
68
+ e && (A((n) => n[e] ? n : {
69
+ ...n,
70
+ [e]: { origin: e, reason: t, clientId: $.current[e] || null }
71
+ }), O(e));
60
72
  },
61
- [z]
62
- ), O = h(
63
- (e, { v2: t = !1 } = {}) => {
64
- const r = j(e == null ? void 0 : e.authUrl);
65
- r && (t && F.current[r] || (m((d) => d[r] ? d : {
66
- ...d,
67
- [r]: {
68
- origin: r,
73
+ [O]
74
+ ), s = m(
75
+ (e, { v2: t = !1, origin: n = null } = {}) => {
76
+ n && (t && q.current[n] || (w((l) => l[n] ? l : {
77
+ ...l,
78
+ [n]: {
79
+ origin: n,
69
80
  authUrl: e.authUrl,
70
81
  silentUrl: e.silentUrl || null,
71
- // v2 entries try the invisible silent resolver first; legacy
72
- // signals go straight to the host's interactive UI.
73
- status: t && e.silentUrl ? "silent" : "interactive",
82
+ // v2 entries try the invisible silent resolver first — but only on a host that can
83
+ // frame login (https). Otherwise (and for legacy signals) go straight to interactive,
84
+ // so an http host doesn't wait out a silent frame that can never load login.
85
+ status: t && y.current ? "broker" : t && e.silentUrl && X ? "silent" : "interactive",
74
86
  v2: t,
87
+ // v1.9: the scope the guest asked for; forwarded verbatim to the broker.
88
+ scope: e.scope || null,
89
+ acceptsCredentials: B.current[n] || null,
90
+ consent: null,
91
+ error: null,
75
92
  // clientId from the request payload (v2) or the cached init (legacy);
76
93
  // the host resolves the display name from it.
77
- clientId: e.clientId || P.current[r] || null,
94
+ clientId: e.clientId || $.current[n] || null,
78
95
  popupBlocked: !1
79
96
  }
80
- }), z(r)));
97
+ }), O(n)));
81
98
  },
82
- [z]
83
- ), C = h((e) => {
84
- m((t) => {
99
+ [O]
100
+ ), u = m((e) => {
101
+ w((t) => {
85
102
  if (!t[e])
86
103
  return t;
87
- const r = { ...t };
88
- return delete r[e], r;
104
+ const n = { ...t };
105
+ return delete n[e], n;
89
106
  });
90
- }, []), i = h(
107
+ }, []), o = m(
91
108
  (e) => {
92
- e && (C(e), T((t) => ({
109
+ e && (u(e), U((t) => ({
93
110
  ...t,
94
111
  [e]: (t[e] || 0) + 1
95
112
  })));
96
113
  },
97
- [C]
98
- ), u = h((e) => {
99
- m((t) => !t[e] || t[e].status === "interactive" ? t : {
114
+ [u]
115
+ ), a = m((e) => {
116
+ w((t) => !t[e] || t[e].status === "interactive" ? t : {
100
117
  ...t,
101
118
  [e]: { ...t[e], status: "interactive" }
102
119
  });
103
- }, []), c = h(
120
+ }, []), b = m(
104
121
  (e) => {
105
- C(e.origin);
122
+ u(e.origin);
106
123
  },
107
- [C]
108
- ), l = h(
109
- (e) => {
110
- const t = j(e == null ? void 0 : e.authUrl);
111
- if (t && ee(t, window.location.origin)) {
112
- A(e, "cross-site-legacy");
113
- return;
124
+ [u]
125
+ ), E = m(
126
+ (e, t) => {
127
+ const n = ne(e, t);
128
+ if (n) {
129
+ if (fe(n, window.location.origin)) {
130
+ j(n, "cross-site-legacy");
131
+ return;
132
+ }
133
+ s(e, { origin: n });
114
134
  }
115
- O(e);
116
135
  },
117
- [O, A]
136
+ [s, j]
118
137
  );
119
- g(() => {
120
- if (!s)
138
+ k(() => {
139
+ if (!d)
121
140
  return;
122
141
  const e = [
123
- // `init` carries the app's OAuth clientId. Cache it by app origin and
124
- // attach it to any entry already showing. `init` is posted before the
125
- // authorize/login/credential-request signals, so it is usually cached by
126
- // the time an entry is created. The host resolves the display name from
127
- // the clientId.
128
- s.addListener("*", "init", (t) => {
129
- t != null && t.origin && t.clientId && (P.current[t.origin] = t.clientId, z(t.origin));
142
+ // `init` carries the app's OAuth clientId. Cache it by the ATTESTED app
143
+ // origin (payload `origin` is ignored) and attach it to any entry already
144
+ // showing. `init` is posted before the authorize/login/credential-request
145
+ // signals, so it is usually cached by the time an entry is created. The
146
+ // clientId is only a lookup key: the host resolves the display name from
147
+ // it, and a broker binds it to the attested origin server-side.
148
+ d.addListener("*", "init", (t, n) => {
149
+ n != null && n.origin && (t != null && t.clientId) && ($.current[n.origin] = t.clientId, O(n.origin)), n != null && n.origin && Array.isArray(t == null ? void 0 : t.acceptsCredentials) && (B.current[n.origin] = t.acceptsCredentials);
130
150
  }),
131
- s.addListener("*", "authorize", l),
132
- s.addListener("*", "login", l),
133
- s.addListener(
151
+ d.addListener("*", "authorize", E),
152
+ d.addListener("*", "login", E),
153
+ d.addListener(
134
154
  "*",
135
155
  "credential-request",
136
- (t) => O(t, { v2: !0 })
137
- ),
138
- s.addListener("*", "authorized", (t) => {
139
- t != null && t.accessToken || i(j(t == null ? void 0 : t.authUrl));
140
- })
156
+ (t, n) => s(t, { v2: !0, origin: ne(t, n) })
157
+ )
141
158
  ];
142
159
  return () => e.forEach((t) => t());
143
- }, [s, l, O, i, z]), g(() => {
160
+ }, [d, E, s, O]), k(() => {
144
161
  const e = (t) => {
145
- const r = t == null ? void 0 : t.data;
146
- if (!r || r.type !== "authorized" && r.type !== "authorize-failed")
162
+ const n = t == null ? void 0 : t.data;
163
+ if (!n || n.type !== "authorized" && n.type !== "authorize-failed")
147
164
  return;
148
- const d = j(r.authUrl);
149
- if (!(!d || t.origin !== d)) {
150
- if (r.type === "authorized" && r.accessToken) {
151
- L((M) => ({
152
- ...M,
153
- [d]: { accessToken: r.accessToken }
154
- })), C(d);
165
+ const l = Q(n.authUrl);
166
+ if (!(!l || t.origin !== l)) {
167
+ if (n.type === "authorized") {
168
+ n.accessToken ? (M((p) => ({
169
+ ...p,
170
+ [l]: te({ accessToken: n.accessToken })
171
+ })), u(l)) : o(l);
155
172
  return;
156
173
  }
157
- r.type === "authorize-failed" && u(d);
174
+ a(l);
158
175
  }
159
176
  };
160
177
  return window.addEventListener("message", e), () => window.removeEventListener("message", e);
161
- }, [C, u]), g(() => {
162
- const e = U.current;
163
- Object.values(a).forEach((t) => {
178
+ }, [u, o, a]);
179
+ const _ = m(
180
+ (e, t) => {
181
+ const n = e == null ? void 0 : e.origin, l = te(t);
182
+ !n || !l || (M((p) => ({ ...p, [n]: l })), u(n));
183
+ },
184
+ [u]
185
+ ), x = m((e, t) => {
186
+ w((n) => n[e] ? { ...n, [e]: { ...n[e], ...t } } : n);
187
+ }, []), I = m(
188
+ async (e, { approve: t } = {}) => {
189
+ const n = y.current, { origin: l } = e;
190
+ let p;
191
+ try {
192
+ p = await n(
193
+ { origin: l, clientId: e.clientId, scope: e.scope, authUrl: e.authUrl },
194
+ { approve: t }
195
+ );
196
+ } catch {
197
+ t ? x(l, { error: { reason: "broker_unavailable" } }) : x(l, {
198
+ status: e.silentUrl && X ? "silent" : "interactive"
199
+ });
200
+ return;
201
+ }
202
+ if ((p == null ? void 0 : p.status) === 200 && p.credential) {
203
+ _(e, p.credential);
204
+ return;
205
+ }
206
+ if ((p == null ? void 0 : p.status) === 409 && p.consentRequired) {
207
+ x(l, {
208
+ status: "interactive",
209
+ consent: {
210
+ client: p.client || null,
211
+ stepUp: !!p.stepUp,
212
+ scope: p.scope || e.scope
213
+ },
214
+ error: null
215
+ });
216
+ return;
217
+ }
218
+ const G = (p == null ? void 0 : p.error) || "broker_error";
219
+ if (!t && ae.has(G)) {
220
+ x(l, {
221
+ status: e.silentUrl && X ? "silent" : "interactive"
222
+ });
223
+ return;
224
+ }
225
+ if (t && G === "consent_denied") {
226
+ x(l, { error: null });
227
+ return;
228
+ }
229
+ u(l), A((ee) => ({
230
+ ...ee,
231
+ [l]: {
232
+ origin: l,
233
+ reason: `broker:${G}`,
234
+ detail: p || null,
235
+ clientId: e.clientId || $.current[l] || null
236
+ }
237
+ }));
238
+ },
239
+ [_, x, u]
240
+ ), F = R({});
241
+ k(() => {
242
+ Object.values(g).forEach((e) => {
243
+ e.status !== "broker" || F.current[e.origin] || (F.current[e.origin] = !0, I(e).finally(() => {
244
+ delete F.current[e.origin];
245
+ }));
246
+ });
247
+ }, [g, I]);
248
+ const W = m(
249
+ (e) => !y.current || !(e != null && e.consent) ? Promise.resolve() : I(e, { approve: !0 }),
250
+ [I]
251
+ );
252
+ k(() => {
253
+ const e = v.current;
254
+ Object.values(g).forEach((t) => {
164
255
  t.status === "silent" && !e[t.origin] && (e[t.origin] = setTimeout(() => {
165
- delete e[t.origin], u(t.origin);
166
- }, N));
256
+ delete e[t.origin], a(t.origin);
257
+ }, de));
167
258
  }), Object.keys(e).forEach((t) => {
168
- (!a[t] || a[t].status !== "silent") && (clearTimeout(e[t]), delete e[t]);
259
+ (!g[t] || g[t].status !== "silent") && (clearTimeout(e[t]), delete e[t]);
169
260
  });
170
- }, [a, u]), g(() => () => {
171
- b.current && b.current(), Object.values(U.current).forEach(clearTimeout);
261
+ }, [g, a]), k(() => () => {
262
+ f.current && f.current(), Object.values(v.current).forEach(clearTimeout);
172
263
  }, []);
173
- const E = h(
264
+ const S = m(
174
265
  (e) => {
175
- b.current && (b.current(), b.current = null);
176
- const t = o || te;
177
- b.current = t(e, {
266
+ f.current && (f.current(), f.current = null);
267
+ const t = i || pe;
268
+ f.current = t(e, {
178
269
  onBlocked: () => {
179
- m((r) => r[e.origin] ? {
180
- ...r,
181
- [e.origin]: { ...r[e.origin], popupBlocked: !0 }
182
- } : r);
270
+ w((n) => n[e.origin] ? {
271
+ ...n,
272
+ [e.origin]: { ...n[e.origin], popupBlocked: !0 }
273
+ } : n);
183
274
  },
184
275
  onClosed: () => {
185
276
  if (e.v2) {
186
- m((r) => !r[e.origin] || !r[e.origin].silentUrl ? r : {
187
- ...r,
188
- [e.origin]: { ...r[e.origin], status: "silent" }
277
+ X && w((n) => !n[e.origin] || !n[e.origin].silentUrl ? n : {
278
+ ...n,
279
+ [e.origin]: { ...n[e.origin], status: "silent" }
189
280
  });
190
281
  return;
191
282
  }
192
- i(e.origin);
283
+ o(e.origin);
193
284
  }
194
285
  });
195
286
  },
196
- [o, i]
197
- ), p = {
287
+ [i, o]
288
+ ), Z = {
198
289
  // Hosts render UI for interactive entries only; silent resolution is
199
290
  // invisible by design.
200
- pending: Object.values(a).filter(
291
+ pending: Object.values(g).filter(
201
292
  (e) => e.status === "interactive"
202
293
  ),
203
- authorize: E,
204
- dismiss: c,
205
- originEpochs: R,
206
- credentials: k,
207
- unsupported: q
208
- }, $ = Object.values(a).filter(
294
+ authorize: S,
295
+ approve: W,
296
+ complete: _,
297
+ dismiss: b,
298
+ originEpochs: P,
299
+ credentials: z,
300
+ unsupported: L
301
+ }, K = Object.values(g).filter(
209
302
  (e) => e.status === "silent" && e.silentUrl
210
303
  );
211
- return /* @__PURE__ */ f.createElement(D.Provider, { value: p }, n, $.map((e) => /* @__PURE__ */ f.createElement(
304
+ return /* @__PURE__ */ h.createElement(J.Provider, { value: Z }, r, K.map((e) => /* @__PURE__ */ h.createElement(
212
305
  "iframe",
213
306
  {
214
307
  key: `mm-silent-auth-${e.origin}`,
@@ -220,159 +313,177 @@ const H = J(null), D = J({
220
313
  }
221
314
  )));
222
315
  };
223
- Q.propTypes = {
224
- children: w.node,
225
- launcher: w.func
316
+ ie.propTypes = {
317
+ children: T.node,
318
+ launcher: T.func,
319
+ /**
320
+ * `async (request, { approve }) => result` where request =
321
+ * `{ origin, clientId, scope, authUrl }` (origin is the zone-attested frame origin) and result
322
+ * mirrors the authorization server's broker response: `{ status: 200, credential, scope,
323
+ * client }`, `{ status: 409, consentRequired: true, client: { name, hostname }, stepUp }`, or
324
+ * `{ status, error }`. Provided only by hosts that are themselves first-party clients.
325
+ */
326
+ broker: T.func
226
327
  };
227
- const ne = () => _(D), re = (n) => {
228
- const { originEpochs: o } = _(D), s = j(n);
229
- return s && o[s] || 0;
230
- }, se = (n) => {
231
- const { credentials: o } = _(D), s = j(n);
232
- return s && o[s] || null;
233
- }, ie = (n) => {
234
- const { unsupported: o } = _(D), s = j(n);
235
- return s && o[s] || null;
236
- }, oe = ({ children: n, authorizationLauncher: o }) => {
237
- const [s, a] = I({}), [m, R] = I({}), T = x({}), k = x({}), L = x({}), q = h((i, u) => {
238
- var c;
239
- return !!((c = L.current[i]) != null && c.has(u));
240
- }, []), y = h((i, u, c) => {
241
- a((l) => ({ ...l, [i]: { origin: u, frameRef: c } }));
242
- }, []), F = h((i) => {
243
- a((u) => {
244
- const c = { ...u };
245
- return delete c[i], c;
246
- }), R((u) => {
247
- const c = { ...u };
248
- return delete c[i], c;
249
- }), delete L.current[i];
328
+ const ge = () => H(J), me = (r) => {
329
+ const { originEpochs: i } = H(J), c = Q(r);
330
+ return c && i[c] || 0;
331
+ }, he = (r) => {
332
+ const { credentials: i } = H(J), c = Q(r);
333
+ return c && i[c] || null;
334
+ }, be = (r) => {
335
+ const { unsupported: i } = H(J), c = Q(r);
336
+ return c && i[c] || null;
337
+ }, Ee = ({ children: r, authorizationLauncher: i, credentialBroker: c }) => {
338
+ const [d, g] = C({}), [w, P] = C({}), U = R({}), z = R({}), M = R({}), L = m((s, u) => {
339
+ var o;
340
+ return !!((o = M.current[s]) != null && o.has(u));
341
+ }, []), A = m((s, u, o) => {
342
+ g((a) => ({ ...a, [s]: { origin: u, frameRef: o } }));
343
+ }, []), q = m((s) => {
344
+ g((u) => {
345
+ const o = { ...u };
346
+ return delete o[s], o;
347
+ }), P((u) => {
348
+ const o = { ...u };
349
+ return delete o[s], o;
350
+ }), delete M.current[s];
250
351
  }, []);
251
- g(() => {
252
- const i = (c = [], l) => {
253
- c.forEach((E) => E(l));
254
- }, u = (c) => {
255
- var $, e, t, r, d;
256
- if (!(($ = c == null ? void 0 : c.data) != null && $.instanceId))
352
+ k(() => {
353
+ const s = (o = [], a, b) => {
354
+ o.forEach((E) => E(a, b));
355
+ }, u = (o) => {
356
+ var F, W, S, Z, K, e, t;
357
+ if (!((F = o == null ? void 0 : o.data) != null && F.instanceId))
358
+ return;
359
+ const { instanceId: a, type: b } = o.data, E = d[a], _ = (S = (W = E == null ? void 0 : E.frameRef) == null ? void 0 : W.current) == null ? void 0 : S.contentWindow;
360
+ if (!_ || o.source !== _ || o.origin !== E.origin)
257
361
  return;
258
- const { instanceId: l, type: E } = c.data, p = T.current;
259
- if (E === "response") {
260
- const { callbackId: M, response: B, error: W } = c.data, S = k.current[M];
261
- S && (S(B, W), delete k.current[M]);
362
+ const x = { origin: o.origin }, I = U.current;
363
+ if (b === "response") {
364
+ const { callbackId: n, response: l, error: p } = o.data, G = z.current[n];
365
+ G && (G(l, p), delete z.current[n]);
262
366
  return;
263
367
  }
264
- if (E === "mark-registered") {
265
- const { requestType: M } = c.data;
266
- L.current[l] || (L.current[l] = /* @__PURE__ */ new Set()), L.current[l].add(M);
368
+ if (b === "mark-registered") {
369
+ const { requestType: n } = o.data;
370
+ M.current[a] || (M.current[a] = /* @__PURE__ */ new Set()), M.current[a].add(n);
267
371
  return;
268
372
  }
269
- E === "ready" && R((M) => ({ ...M, [l]: !0 })), i((e = p[l]) == null ? void 0 : e[E], c.data), i((t = p["*"]) == null ? void 0 : t[E], c.data), i((r = p[l]) == null ? void 0 : r["*"], c.data), i((d = p["*"]) == null ? void 0 : d["*"], c.data);
373
+ b === "ready" && P((n) => ({ ...n, [a]: !0 })), s((Z = I[a]) == null ? void 0 : Z[b], o.data, x), s((K = I["*"]) == null ? void 0 : K[b], o.data, x), s((e = I[a]) == null ? void 0 : e["*"], o.data, x), s((t = I["*"]) == null ? void 0 : t["*"], o.data, x);
270
374
  };
271
375
  return window.addEventListener("message", u), () => {
272
376
  window.removeEventListener("message", u);
273
377
  };
274
- }, [s]);
275
- const b = h(
276
- (i, u, c) => {
277
- var E, p;
278
- const l = s[i];
279
- if (!l) {
280
- console.warn(`Origin not set for id: ${i}. Unable to send message.`);
378
+ }, [d]);
379
+ const f = m(
380
+ (s, u, o) => {
381
+ var b, E;
382
+ const a = d[s];
383
+ if (!a) {
384
+ console.warn(`Origin not set for id: ${s}. Unable to send message.`);
281
385
  return;
282
386
  }
283
- (p = (E = l == null ? void 0 : l.frameRef) == null ? void 0 : E.current) != null && p.contentWindow && l.frameRef.current.contentWindow.postMessage(
284
- { type: u, ...c, instanceId: i },
285
- l.origin
387
+ (E = (b = a == null ? void 0 : a.frameRef) == null ? void 0 : b.current) != null && E.contentWindow && a.frameRef.current.contentWindow.postMessage(
388
+ { type: u, ...o, instanceId: s },
389
+ a.origin
286
390
  );
287
391
  },
288
- [s]
289
- ), U = x(0), P = h(() => `${Date.now()}-${++U.current}`, []), z = h(
290
- async (i, u, c = {}) => new Promise((l, E) => {
291
- const p = P(), $ = (e, t) => {
292
- delete k.current[p], t ? E(t) : l(e);
392
+ [d]
393
+ ), v = R(0), $ = m(() => `${Date.now()}-${++v.current}`, []), B = m(
394
+ async (s, u, o = {}) => new Promise((a, b) => {
395
+ const E = $(), _ = (x, I) => {
396
+ delete z.current[E], I ? b(I) : a(x);
293
397
  };
294
- k.current[p] = $, b(i, "request", { callbackId: p, requestType: u, data: c });
398
+ z.current[E] = _, f(s, "request", { callbackId: E, requestType: u, data: o });
295
399
  }),
296
- [b]
297
- ), A = h(
298
- (i, u) => {
299
- b(i, "load-options", u);
400
+ [f]
401
+ ), y = m(
402
+ (s, u) => {
403
+ f(s, "load-options", u);
300
404
  },
301
- [b]
302
- ), O = h(
303
- (i, u) => {
304
- b(i, "validate", u);
405
+ [f]
406
+ ), O = m(
407
+ (s, u) => {
408
+ f(s, "validate", u);
305
409
  },
306
- [b]
307
- ), C = Y(
410
+ [f]
411
+ ), j = ue(
308
412
  () => ({
309
- registerFrame: y,
310
- unregisterFrame: F,
311
- sendMessage: b,
312
- sendRequest: z,
313
- loadOptions: A,
413
+ registerFrame: A,
414
+ unregisterFrame: q,
415
+ sendMessage: f,
416
+ sendRequest: B,
417
+ loadOptions: y,
314
418
  validate: O,
315
- hasHandler: q,
316
- readyFrames: m,
317
- addListener: (i, u, c) => (T.current[i] || (T.current[i] = {}), T.current[i][u] || (T.current[i][u] = []), T.current[i][u].push(c), () => {
318
- T.current[i][u] = T.current[i][u].filter((l) => l !== c);
419
+ hasHandler: L,
420
+ readyFrames: w,
421
+ addListener: (s, u, o) => (U.current[s] || (U.current[s] = {}), U.current[s][u] || (U.current[s][u] = []), U.current[s][u].push(o), () => {
422
+ U.current[s][u] = U.current[s][u].filter((a) => a !== o);
319
423
  })
320
424
  }),
321
425
  [
322
- y,
323
- F,
324
- b,
325
- z,
326
426
  A,
327
- O,
328
427
  q,
329
- m
428
+ f,
429
+ B,
430
+ y,
431
+ O,
432
+ L,
433
+ w
330
434
  ]
331
435
  );
332
- return /* @__PURE__ */ f.createElement(H.Provider, { value: C }, /* @__PURE__ */ f.createElement(Q, { launcher: o }, n));
333
- }, v = (n, o, s) => {
334
- const a = _(H);
335
- if (a === null)
436
+ return /* @__PURE__ */ h.createElement(Y.Provider, { value: j }, /* @__PURE__ */ h.createElement(ie, { launcher: i, broker: c }, r));
437
+ }, V = (r, i, c) => {
438
+ const d = H(Y);
439
+ if (d === null)
336
440
  throw new Error(
337
441
  "useEmbeddedEffect must be used within a MMEmbeddableZoneProvider"
338
442
  );
339
- const m = x(s);
340
- g(() => {
341
- m.current = s;
342
- }, [s]), g(() => {
343
- if (!(!n || !o)) {
344
- if (o.startsWith("key:")) {
345
- const R = o.substring(4);
346
- return a.readyFrames[n] && a.sendMessage(n, "subscribe-key", { keyChord: R }), a.addListener(
347
- n,
348
- `key-pressed:${R}`,
349
- (...k) => m.current(...k)
443
+ const g = R(c);
444
+ k(() => {
445
+ g.current = c;
446
+ }, [c]), k(() => {
447
+ if (!(!r || !i)) {
448
+ if (i.startsWith("key:")) {
449
+ const w = i.substring(4);
450
+ return d.readyFrames[r] && d.sendMessage(r, "subscribe-key", { keyChord: w }), d.addListener(
451
+ r,
452
+ `key-pressed:${w}`,
453
+ (...U) => g.current(...U)
350
454
  );
351
455
  }
352
- return a.addListener(
353
- n,
354
- o,
355
- (...R) => m.current(...R)
456
+ return d.addListener(
457
+ r,
458
+ i,
459
+ (...w) => g.current(...w)
356
460
  );
357
461
  }
358
- }, [a, n, o]);
462
+ }, [d, r, i]);
359
463
  };
360
- oe.propTypes = {
361
- children: w.node.isRequired,
464
+ Ee.propTypes = {
465
+ children: T.node.isRequired,
362
466
  /**
363
467
  * Optional interactive-step launcher for embedded authorizations,
364
468
  * `(entry, { onBlocked, onClosed }) => cleanup`. Defaults to a top-level
365
469
  * popup. Hosts that cannot open windows (Android WebView shells) drive
366
470
  * their own UI from useEmbeddedAuthorizations() instead.
367
471
  */
368
- authorizationLauncher: w.func
472
+ authorizationLauncher: T.func,
473
+ /**
474
+ * Optional credential broker for hosts that are first-party MachineMetrics clients
475
+ * (`async (request, { approve }) => result`, see EmbeddedAuthorizationManager). When present,
476
+ * v2 credential requests are brokered server-side (no popup, no hidden frame) and consent is
477
+ * rendered natively by the host from the broker's `client` identity.
478
+ */
479
+ credentialBroker: T.func
369
480
  };
370
- const K = Z.default || Z, ce = 1e4, ue = "credentials", G = (n, o) => `${n}/mm-embedded-interop?id=${o}&origin=${window.location.origin}&caps=${ue}`, le = K.iframe`
481
+ const N = D.default || D, we = 1e4, ke = "credentials", se = (r, i) => `${r}/mm-embedded-interop?id=${i}&origin=${window.location.origin}&caps=${ke}`, Re = N.iframe`
371
482
  width: 100%;
372
483
  height: 100%;
373
484
  border: none;
374
- visibility: ${(n) => n.$isReady ? "visible" : "hidden"};
375
- `, ae = K.div`
485
+ visibility: ${(r) => r.$isReady ? "visible" : "hidden"};
486
+ `, xe = N.div`
376
487
  width: 100%;
377
488
  height: 100%;
378
489
  display: flex;
@@ -385,132 +496,140 @@ const K = Z.default || Z, ce = 1e4, ue = "credentials", G = (n, o) => `${n}/mm-e
385
496
  text-align: center;
386
497
  color: #555;
387
498
  font-size: 14px;
388
- `, X = ({ entry: n }) => /* @__PURE__ */ f.createElement(ae, null, /* @__PURE__ */ f.createElement("div", { style: { fontWeight: 600 } }, n && n.origin || "This app", " can’t be embedded here"), /* @__PURE__ */ f.createElement("div", { style: { fontSize: 12, color: "#888" } }, "It needs an update to support embedding from a different domain."));
389
- X.propTypes = {
390
- entry: w.shape({
391
- origin: w.string,
392
- name: w.string,
393
- reason: w.string
499
+ `, ce = ({ entry: r }) => /* @__PURE__ */ h.createElement(xe, null, /* @__PURE__ */ h.createElement("div", { style: { fontWeight: 600 } }, r && r.origin || "This app", " can’t be embedded here"), /* @__PURE__ */ h.createElement("div", { style: { fontSize: 12, color: "#888" } }, "It needs an update to support embedding from a different domain."));
500
+ ce.propTypes = {
501
+ entry: T.shape({
502
+ origin: T.string,
503
+ name: T.string,
504
+ reason: T.string
394
505
  })
395
506
  };
396
- const de = K.div`
507
+ const Te = N.div`
397
508
  height: 100%;
398
509
  display: flex;
399
510
  flex: 1;
400
511
  align-items: center;
401
512
  justify-content: center;
402
- `, fe = () => /* @__PURE__ */ f.createElement(de, null, /* @__PURE__ */ f.createElement("div", { style: { textAlign: "center" } }, "This app couldn’t be loaded as an embeddable widget.")), me = ({
403
- id: n,
404
- src: o,
405
- path: s,
406
- onInit: a = () => {
513
+ `, Ie = () => /* @__PURE__ */ h.createElement(Te, null, /* @__PURE__ */ h.createElement("div", { style: { textAlign: "center" } }, "This app couldn’t be loaded as an embeddable widget.")), Ue = ({
514
+ id: r,
515
+ src: i,
516
+ path: c,
517
+ onInit: d = () => {
407
518
  },
408
- onTimeout: m,
409
- context: R = {},
410
- params: T = {},
411
- renderUnsupported: k,
412
- renderTimeout: L,
413
- ...q
519
+ onTimeout: g,
520
+ context: w = {},
521
+ params: P = {},
522
+ renderUnsupported: U,
523
+ renderTimeout: z,
524
+ ...M
414
525
  }) => {
415
- if ("isConfiguring" in q)
526
+ if ("isConfiguring" in M)
416
527
  return console.error(
417
528
  "isConfiguring must be passed via the params prop to MMEmbeddableZone"
418
529
  ), null;
419
- if ("colorMode" in R)
530
+ if ("colorMode" in w)
420
531
  return console.error(
421
532
  "colorMode must be passed via the params prop to MMEmbeddableZone"
422
533
  ), null;
423
- if ("isFullScreen" in R)
534
+ if ("isFullScreen" in w)
424
535
  return console.error(
425
536
  "isFullScreen must be passed via the params prop to MMEmbeddableZone"
426
537
  ), null;
427
- const y = x(), [F, b] = I(), [U, P] = I(0), [z, A] = I(!1), [O, C] = I(!1), i = re(o), u = se(o), c = ie(o);
428
- g(() => {
429
- i > 0 && P(0);
430
- }, [i]);
431
- const { registerFrame: l, unregisterFrame: E, sendMessage: p } = _(
432
- H
433
- ), [$, e] = I(), t = x(), r = x(m), d = x(a), M = x(!1);
434
- g(() => {
435
- r.current = m;
436
- }, [m]), g(() => {
437
- d.current = a;
438
- }, [a]), g(() => {
439
- U && p(n, "set-context", {
538
+ const L = R(), [A, q] = C(), [f, v] = C(0), [$, B] = C(!1), [y, O] = C(!1), j = me(i), s = he(i), u = be(i);
539
+ k(() => {
540
+ j > 0 && v(0);
541
+ }, [j]);
542
+ const { registerFrame: o, unregisterFrame: a, sendMessage: b } = H(
543
+ Y
544
+ ), [E, _] = C(), x = R(), I = R(g), F = R(d), W = R(!1);
545
+ k(() => {
546
+ I.current = g;
547
+ }, [g]), k(() => {
548
+ F.current = d;
549
+ }, [d]), k(() => {
550
+ f && b(r, "set-context", {
440
551
  context: {
441
- ...R
552
+ ...w
442
553
  }
443
554
  });
444
- }, [R, n, U]), g(() => {
445
- U && p(n, "set-params", { params: T });
446
- }, [T, n, U]), g(() => {
447
- s !== void 0 && e((s == null ? void 0 : s.indexOf("/")) === 0 ? s : `/${s}`);
448
- }, [s]), g(() => {
449
- $ === void 0 || !U || p(n, "navigate", { path: $ });
450
- }, [$, U, n, p]), g(() => {
451
- if (!o || !n || !y)
555
+ }, [w, r, f]), k(() => {
556
+ f && b(r, "set-params", { params: P });
557
+ }, [P, r, f]), k(() => {
558
+ c !== void 0 && _((c == null ? void 0 : c.indexOf("/")) === 0 ? c : `/${c}`);
559
+ }, [c]), k(() => {
560
+ E === void 0 || !f || b(r, "navigate", { path: E });
561
+ }, [E, f, r, b]), k(() => {
562
+ if (!i || !r || !L)
452
563
  return;
453
- const S = new URL(o);
454
- return l(n, S.origin, y), d.current(), b(G(S.origin, n)), () => {
455
- E(n);
564
+ const t = new URL(i);
565
+ return o(r, t.origin, L), F.current(), q(se(t.origin, r)), () => {
566
+ a(r);
456
567
  };
457
- }, [o, n, l, y]), g(() => {
458
- if (!(!F || M.current))
459
- return t.current = setTimeout(() => {
460
- A(!0), r.current && r.current();
461
- }, ce), () => clearTimeout(t.current);
462
- }, [F]);
463
- const B = h(() => {
464
- M.current = !0, clearTimeout(t.current), A(!1);
465
- }, []);
466
- v(n, "init", B), v(n, "authorize", B), v(n, "login", B), v(n, "credential-request", () => {
467
- B(), C(!0);
468
- }), g(() => {
469
- !O || !u || p(n, "credential", { accessToken: u.accessToken });
470
- }, [O, u, n, p]), v(n, "ready", () => {
471
- B(), P((S) => S + 1);
568
+ }, [i, r, o, L]), k(() => {
569
+ if (!(!A || W.current))
570
+ return x.current = setTimeout(() => {
571
+ B(!0), I.current && I.current();
572
+ }, we), () => clearTimeout(x.current);
573
+ }, [A]);
574
+ const S = m(() => {
575
+ W.current = !0, clearTimeout(x.current), B(!1);
576
+ }, []), [Z, K] = C(null);
577
+ V(r, "init", (t) => {
578
+ S(), Array.isArray(t == null ? void 0 : t.acceptsCredentials) && K(t.acceptsCredentials);
579
+ }), V(r, "authorize", S), V(r, "login", S), V(r, "credential-request", () => {
580
+ S(), O(!0);
581
+ }), k(() => {
582
+ if (!y || !s)
583
+ return;
584
+ const t = Z;
585
+ if (Array.isArray(t) && !t.includes(s.kind))
586
+ return;
587
+ const n = s.kind === "access_token" ? { accessToken: s.accessToken } : {};
588
+ b(r, "credential", { ...n, credential: s });
589
+ }, [y, s, Z, r, b]), V(r, "ready", () => {
590
+ S(), v((t) => t + 1);
472
591
  });
473
- const W = x();
474
- return v(n, "heartbeat", () => {
475
- W.current && clearTimeout(W.current), W.current = setTimeout(() => {
476
- if (y.current) {
477
- const S = new URL(o);
478
- y.current.src = G(S.origin, n);
592
+ const e = R();
593
+ return V(r, "heartbeat", () => {
594
+ e.current && clearTimeout(e.current), e.current = setTimeout(() => {
595
+ if (L.current) {
596
+ const t = new URL(i);
597
+ L.current.src = se(t.origin, r);
479
598
  }
480
599
  }, 6e3);
481
- }), g(() => () => {
482
- W.current && clearTimeout(W.current);
483
- }, []), c ? k ? k(c) : /* @__PURE__ */ f.createElement(X, { entry: c }) : z && !U ? L ? L() : /* @__PURE__ */ f.createElement(fe, null) : /* @__PURE__ */ f.createElement(
484
- le,
600
+ }), k(() => () => {
601
+ e.current && clearTimeout(e.current);
602
+ }, []), u ? U ? U(u) : /* @__PURE__ */ h.createElement(ce, { entry: u }) : $ && !f ? z ? z() : /* @__PURE__ */ h.createElement(Ie, null) : /* @__PURE__ */ h.createElement(
603
+ Re,
485
604
  {
486
- key: `auth-epoch-${i}`,
487
- $isReady: U,
488
- ref: y,
489
- src: F,
490
- ...q
605
+ key: `auth-epoch-${j}`,
606
+ $isReady: f,
607
+ ref: L,
608
+ src: A,
609
+ ...M
491
610
  }
492
611
  );
493
612
  };
494
- me.propTypes = {
495
- id: w.string,
496
- src: w.string.isRequired,
497
- path: w.string,
498
- onInit: w.func,
499
- onTimeout: w.func,
613
+ Ue.propTypes = {
614
+ id: T.string,
615
+ src: T.string.isRequired,
616
+ path: T.string,
617
+ onInit: T.func,
618
+ onTimeout: T.func,
500
619
  /**
501
620
  * Optional host-styled renderer for the structurally-unsupported embed
502
621
  * state (legacy app on a cross-site origin), `(entry) => ReactNode`. Falls
503
622
  * back to a minimal built-in placeholder.
504
623
  */
505
- renderUnsupported: w.func,
624
+ renderUnsupported: T.func,
506
625
  /**
507
626
  * Optional host-styled renderer for the handshake-timeout failure state
508
627
  * (the app is not embeddable / could not load), `() => ReactNode`. Falls
509
628
  * back to a minimal centered message.
510
629
  */
511
- renderTimeout: w.func
630
+ renderTimeout: T.func
512
631
  };
513
- const pe = Z.div`
632
+ const Ce = D.div`
514
633
  position: fixed;
515
634
  inset: 0;
516
635
  background: rgba(0, 0, 0, 0.45);
@@ -518,7 +637,7 @@ const pe = Z.div`
518
637
  align-items: center;
519
638
  justify-content: center;
520
639
  z-index: 10000;
521
- `, ge = Z.div`
640
+ `, ze = D.div`
522
641
  background: #fff;
523
642
  border-radius: 8px;
524
643
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.2);
@@ -527,13 +646,13 @@ const pe = Z.div`
527
646
  max-width: calc(100vw - 32px);
528
647
  font-family: sans-serif;
529
648
  color: #222;
530
- `, he = Z.div`
649
+ `, Me = D.div`
531
650
  display: flex;
532
651
  align-items: center;
533
652
  justify-content: space-between;
534
653
  padding: 10px 0;
535
654
  gap: 16px;
536
- `, be = Z.button`
655
+ `, Le = D.button`
537
656
  background: #16a500;
538
657
  color: #fff;
539
658
  border: none;
@@ -542,25 +661,27 @@ const pe = Z.div`
542
661
  font-size: 14px;
543
662
  cursor: pointer;
544
663
  white-space: nowrap;
545
- `, Ee = Z.p`
664
+ `, Oe = D.p`
546
665
  color: #b3261e;
547
666
  font-size: 13px;
548
667
  margin: 4px 0 0;
549
- `, Te = () => {
550
- const { pending: n, authorize: o } = ne();
551
- return n.length === 0 ? null : /* @__PURE__ */ f.createElement(pe, null, /* @__PURE__ */ f.createElement(ge, null, /* @__PURE__ */ f.createElement("h3", { style: { margin: "0 0 8px" } }, "Authorization Required"), /* @__PURE__ */ f.createElement("p", { style: { margin: "0 0 12px", fontSize: 14, color: "#555" } }, "The following apps need you to sign in and authorize them before they can load."), n.map((s) => /* @__PURE__ */ f.createElement("div", { key: s.origin }, /* @__PURE__ */ f.createElement(he, null, /* @__PURE__ */ f.createElement("div", null, /* @__PURE__ */ f.createElement("div", { style: { fontWeight: 600 } }, s.origin)), /* @__PURE__ */ f.createElement(be, { onClick: () => o(s) }, "Authorize")), s.popupBlocked && /* @__PURE__ */ f.createElement(Ee, null, "The sign-in window was blocked. Allow popups for this site, then try again.")))));
668
+ `, Se = () => {
669
+ const { pending: r, authorize: i } = ge();
670
+ return r.length === 0 ? null : /* @__PURE__ */ h.createElement(Ce, null, /* @__PURE__ */ h.createElement(ze, null, /* @__PURE__ */ h.createElement("h3", { style: { margin: "0 0 8px" } }, "Authorization Required"), /* @__PURE__ */ h.createElement("p", { style: { margin: "0 0 12px", fontSize: 14, color: "#555" } }, "The following apps need you to sign in and authorize them before they can load."), r.map((c) => /* @__PURE__ */ h.createElement("div", { key: c.origin }, /* @__PURE__ */ h.createElement(Me, null, /* @__PURE__ */ h.createElement("div", null, /* @__PURE__ */ h.createElement("div", { style: { fontWeight: 600 } }, c.origin)), /* @__PURE__ */ h.createElement(Le, { onClick: () => i(c) }, "Authorize")), c.popupBlocked && /* @__PURE__ */ h.createElement(Oe, null, "The sign-in window was blocked. Allow popups for this site, then try again.")))));
552
671
  };
553
672
  export {
554
- D as EmbeddedAuthorizationContext,
555
- Te as EmbeddedAuthorizationPrompt,
556
- me as MMEmbeddableZone,
557
- H as MMEmbeddableZoneContext,
558
- oe as MMEmbeddableZoneProvider,
559
- ee as isCrossSite,
560
- te as popupAuthorizationLauncher,
561
- ne as useEmbeddedAuthorizations,
562
- se as useEmbeddedCredential,
563
- v as useEmbeddedEffect,
564
- re as useEmbeddedOriginEpoch,
565
- ie as useEmbeddedUnsupported
673
+ le as CREDENTIAL_KIND_ACCESS_TOKEN,
674
+ J as EmbeddedAuthorizationContext,
675
+ Se as EmbeddedAuthorizationPrompt,
676
+ Ue as MMEmbeddableZone,
677
+ Y as MMEmbeddableZoneContext,
678
+ Ee as MMEmbeddableZoneProvider,
679
+ fe as isCrossSite,
680
+ te as normalizeCredential,
681
+ pe as popupAuthorizationLauncher,
682
+ ge as useEmbeddedAuthorizations,
683
+ he as useEmbeddedCredential,
684
+ V as useEmbeddedEffect,
685
+ me as useEmbeddedOriginEpoch,
686
+ be as useEmbeddedUnsupported
566
687
  };