@machinemetrics/mm-react-embeddable 2.0.0-2 → 2.0.0-3

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 CHANGED
@@ -4,13 +4,14 @@ Components and hooks for embedding mm-apps into an interface. Primarily used for
4
4
 
5
5
  ## Consent UI
6
6
 
7
- `useEmbeddedAuthorizations()` exposes the pending entries and the actions on them
8
- (`authorize` for the popup path, `approve`/`dismiss` for brokered entries). Every
9
- first-party host that passes a `credentialBroker` to `MMEmbeddableZoneProvider`
10
- renders its own consent UI over that hook (converge, OperatorView and operator-kiosk
11
- each have one).
7
+ The library ships no consent UI. `useEmbeddedAuthorizations()` exposes the pending
8
+ entries and the actions on them: `approve`/`dismiss` for entries the host brokered
9
+ (`entry.consent` is set), `authorize` for legacy entries that take the popup path.
10
+ Every host renders its own modal over that hook converge, OperatorView,
11
+ operator-kiosk and the mmdev playground each have one, all the same shape (rows name
12
+ the app and where it runs; footer Cancel/Approve; checkbox rows when several apps are
13
+ pending; legacy rows keep their own Authorize button because a popup must open from
14
+ the user's click on that row).
12
15
 
13
- `EmbeddedAuthorizationPrompt` is the default **popup-only** prompt for hosts that
14
- cannot broker, such as an http development host (the mmdev playground). It renders
15
- legacy entries with an Authorize button that opens the OAuth popup, ignores brokered
16
- entries, and logs a one-time error in that case so the missing host UI is noticed.
16
+ Removed in 2.0: `EmbeddedAuthorizationPrompt`, the old default popup prompt. Its only
17
+ consumer (the playground) now renders its own modal.
@@ -1,9 +1,9 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react"),he=require("prop-types"),ge=require("styled-components"),Q=r=>r&&r.__esModule?r:{default:r},E=Q(t),T=Q(he),W=Q(ge),H=t.createContext(null),K=t.createContext({pending:[],authorize:()=>{},approve:()=>{},complete:()=>{},dismiss:()=>{},originEpochs:{},credentials:{},unsupported:{}}),se="access_token",J=r=>r?r.kind?r:r.accessToken?{kind:se,accessToken:r.accessToken,expiresAt:r.expiresAt||null}:null:null,Ee=new Set(["host_not_allowed","invalid_token","provider_unavailable"]),N=typeof window!="undefined"&&window.location.protocol==="https:",ke=8e3,G=r=>{try{return new URL(r).origin}catch{return null}},ee=(r,o)=>{const c=o==null?void 0:o.origin;return!c||G(r==null?void 0:r.authUrl)!==c?null:c},te=r=>{if(!r||/^\d{1,3}(?:\.\d{1,3}){3}$/.test(r)||r.includes(":"))return r;const o=r.split(".");return o.length<=2?r:o.slice(-2).join(".")},oe=(r,o)=>{try{const c=new URL(r),l=new URL(o);return c.protocol!==l.protocol?!0:te(c.hostname)!==te(l.hostname)}catch{return!0}},ue=(r,{onBlocked:o,onClosed:c})=>{const l=window.open(r.authUrl,"mm-embed-auth","popup,width=600,height=700");if(!l)return o(),()=>{};const b=setInterval(()=>{l.closed&&(clearInterval(b),c())},1e3);return()=>clearInterval(b)},ie=({children:r,launcher:o,broker:c})=>{const l=t.useContext(H),[b,m]=t.useState({}),[A,C]=t.useState({}),[z,f]=t.useState({}),[w,I]=t.useState({}),L=t.useRef(z);L.current=z;const g=t.useRef(b);g.current=b;const U=t.useRef(null),Z=t.useRef({}),S=t.useRef({}),F=t.useRef({}),$=t.useRef(c);$.current=c;const y=t.useCallback(e=>{const n=S.current[e];if(!n)return;const s=i=>!i[e]||i[e].clientId?i:{...i,[e]:{...i[e],clientId:n}};m(s),I(s)},[]),a=t.useCallback((e,n)=>{e&&(I(s=>s[e]?s:{...s,[e]:{origin:e,reason:n,clientId:S.current[e]||null}}),y(e))},[y]),d=t.useCallback((e,{v2:n=!1,origin:s=null}={})=>{s&&(n&&L.current[s]||(m(i=>i[s]?i:{...i,[s]:{origin:s,authUrl:e.authUrl,silentUrl:e.silentUrl||null,status:n&&$.current?"broker":n&&e.silentUrl&&N?"silent":"interactive",v2:n,scope:e.scope||null,acceptsCredentials:F.current[s]||null,consent:null,error:null,clientId:e.clientId||S.current[s]||null,popupBlocked:!1}}),y(s)))},[y]),u=t.useCallback(e=>{m(n=>{if(!n[e])return n;const s={...n};return delete s[e],s})},[]),p=t.useCallback(e=>{e&&(u(e),C(n=>({...n,[e]:(n[e]||0)+1})))},[u]),R=t.useCallback(e=>{m(n=>!n[e]||n[e].status==="interactive"?n:{...n,[e]:{...n[e],status:"interactive"}})},[]),x=t.useCallback(e=>{u(e.origin)},[u]),M=t.useCallback((e,n)=>{const s=ee(e,n);if(s){if(oe(s,window.location.origin)){a(s,"cross-site-legacy");return}d(e,{origin:s})}},[d,a]);t.useEffect(()=>{if(!l)return;const e=[l.addListener("*","init",(n,s)=>{s!=null&&s.origin&&(n!=null&&n.clientId)&&(S.current[s.origin]=n.clientId,y(s.origin)),s!=null&&s.origin&&Array.isArray(n==null?void 0:n.acceptsCredentials)&&(F.current[s.origin]=n.acceptsCredentials)}),l.addListener("*","authorize",M),l.addListener("*","login",M),l.addListener("*","credential-request",(n,s)=>d(n,{v2:!0,origin:ee(n,s)}))];return()=>e.forEach(n=>n())},[l,M,d,y]),t.useEffect(()=>{const e=n=>{const s=n==null?void 0:n.data;if(!s||s.type!=="authorized"&&s.type!=="authorize-failed")return;const i=G(s.authUrl);if(!(!i||n.origin!==i)){if(s.type==="authorized"){if(s.accessToken){if(!g.current[i])return;f(h=>({...h,[i]:J({accessToken:s.accessToken})})),u(i)}else p(i);return}R(i)}};return window.addEventListener("message",e),()=>window.removeEventListener("message",e)},[u,p,R]);const _=t.useCallback((e,n)=>{const s=e==null?void 0:e.origin,i=J(n);!s||!i||(f(h=>({...h,[s]:i})),u(s))},[u]),k=t.useCallback((e,n)=>{m(s=>s[e]?{...s,[e]:{...s[e],...n}}:s)},[]),O=t.useCallback(async(e,{approve:n}={})=>{const s=$.current,{origin:i}=e;let h;try{h=await s({origin:i,clientId:e.clientId,scope:e.scope,authUrl:e.authUrl},{approve:n})}catch{n?k(i,{error:{reason:"broker_unavailable"}}):k(i,{status:e.silentUrl&&N?"silent":"interactive"});return}if((h==null?void 0:h.status)===200&&h.credential){_(e,h.credential);return}if((h==null?void 0:h.status)===409&&h.consentRequired){k(i,{status:"interactive",consent:{client:h.client||null,stepUp:!!h.stepUp,scope:h.scope||e.scope},error:null});return}const V=(h==null?void 0:h.error)||"broker_error";if(!n&&Ee.has(V)){k(i,{status:e.silentUrl&&N?"silent":"interactive"});return}if(n&&V==="consent_denied"){k(i,{error:null});return}u(i),I(Y=>({...Y,[i]:{origin:i,reason:`broker:${V}`,detail:h||null,clientId:e.clientId||S.current[i]||null}}))},[_,k,u]),v=t.useRef({});t.useEffect(()=>{Object.values(b).forEach(e=>{e.status!=="broker"||v.current[e.origin]||(v.current[e.origin]=!0,O(e).finally(()=>{delete v.current[e.origin]}))})},[b,O]);const P=t.useCallback(e=>!$.current||!(e!=null&&e.consent)?Promise.resolve():O(e,{approve:!0}),[O]);t.useEffect(()=>{const e=Z.current;Object.values(b).forEach(n=>{n.status==="silent"&&!e[n.origin]&&(e[n.origin]=setTimeout(()=>{delete e[n.origin],R(n.origin)},ke))}),Object.keys(e).forEach(n=>{(!b[n]||b[n].status!=="silent")&&(clearTimeout(e[n]),delete e[n])})},[b,R]),t.useEffect(()=>()=>{U.current&&U.current(),Object.values(Z.current).forEach(clearTimeout)},[]);const q=t.useCallback(e=>{U.current&&(U.current(),U.current=null);const n=o||ue;U.current=n(e,{onBlocked:()=>{m(s=>s[e.origin]?{...s,[e.origin]:{...s[e.origin],popupBlocked:!0}}:s)},onClosed:()=>{if(e.v2){N&&m(s=>!s[e.origin]||!s[e.origin].silentUrl?s:{...s,[e.origin]:{...s[e.origin],status:"silent"}});return}p(e.origin)}})},[o,p]),j={pending:Object.values(b).filter(e=>e.status==="interactive"),authorize:q,approve:P,complete:_,dismiss:x,originEpochs:A,credentials:z,unsupported:w},B=Object.values(b).filter(e=>e.status==="silent"&&e.silentUrl);return E.default.createElement(K.Provider,{value:j},r,B.map(e=>E.default.createElement("iframe",{key:`mm-silent-auth-${e.origin}`,src:e.silentUrl,title:`MachineMetrics silent authorization (${e.origin})`,"aria-hidden":"true",tabIndex:-1,style:{display:"none"}})))};ie.propTypes={children:T.default.node,launcher:T.default.func,broker:T.default.func};const ce=()=>t.useContext(K),ae=r=>{const{originEpochs:o}=t.useContext(K),c=G(r);return c&&o[c]||0},le=r=>{const{credentials:o}=t.useContext(K),c=G(r);return c&&o[c]||null},de=r=>{const{unsupported:o}=t.useContext(K),c=G(r);return c&&o[c]||null},fe=({children:r,authorizationLauncher:o,credentialBroker:c})=>{const[l,b]=t.useState({}),[m,A]=t.useState({}),C=t.useRef({}),z=t.useRef({}),f=t.useRef({}),w=t.useCallback((a,d)=>{var u;return!!((u=f.current[a])!=null&&u.has(d))},[]),I=t.useCallback((a,d,u)=>{b(p=>({...p,[a]:{origin:d,frameRef:u}}))},[]),L=t.useCallback(a=>{b(d=>{const u={...d};return delete u[a],u}),A(d=>{const u={...d};return delete u[a],u}),delete f.current[a]},[]);t.useEffect(()=>{const a=(u=[],p,R)=>{u.forEach(x=>x(p,R))},d=u=>{var O,v,P,q,j,B,e;if(!((O=u==null?void 0:u.data)!=null&&O.instanceId))return;const{instanceId:p,type:R}=u.data,x=l[p],M=(P=(v=x==null?void 0:x.frameRef)==null?void 0:v.current)==null?void 0:P.contentWindow;if(!M||u.source!==M||u.origin!==x.origin)return;const _={origin:u.origin},k=C.current;if(R==="response"){const{callbackId:n,response:s,error:i}=u.data,h=z.current[n];h&&(h(s,i),delete z.current[n]);return}if(R==="mark-registered"){const{requestType:n}=u.data;f.current[p]||(f.current[p]=new Set),f.current[p].add(n);return}R==="ready"&&A(n=>({...n,[p]:!0})),a((q=k[p])==null?void 0:q[R],u.data,_),a((j=k["*"])==null?void 0:j[R],u.data,_),a((B=k[p])==null?void 0:B["*"],u.data,_),a((e=k["*"])==null?void 0:e["*"],u.data,_)};return window.addEventListener("message",d),()=>{window.removeEventListener("message",d)}},[l]);const g=t.useCallback((a,d,u)=>{var R,x;const p=l[a];if(!p){console.warn(`Origin not set for id: ${a}. Unable to send message.`);return}(x=(R=p==null?void 0:p.frameRef)==null?void 0:R.current)!=null&&x.contentWindow&&p.frameRef.current.contentWindow.postMessage({type:d,...u,instanceId:a},p.origin)},[l]),U=t.useRef(0),Z=t.useCallback(()=>`${Date.now()}-${++U.current}`,[]),S=t.useCallback(async(a,d,u={})=>new Promise((p,R)=>{const x=Z(),M=(_,k)=>{delete z.current[x],k?R(k):p(_)};z.current[x]=M,g(a,"request",{callbackId:x,requestType:d,data:u})}),[g]),F=t.useCallback((a,d)=>{g(a,"load-options",d)},[g]),$=t.useCallback((a,d)=>{g(a,"validate",d)},[g]),y=t.useMemo(()=>({registerFrame:I,unregisterFrame:L,sendMessage:g,sendRequest:S,loadOptions:F,validate:$,hasHandler:w,readyFrames:m,addListener:(a,d,u)=>(C.current[a]||(C.current[a]={}),C.current[a][d]||(C.current[a][d]=[]),C.current[a][d].push(u),()=>{C.current[a][d]=C.current[a][d].filter(p=>p!==u)})}),[I,L,g,S,F,$,w,m]);return E.default.createElement(H.Provider,{value:y},E.default.createElement(ie,{launcher:o,broker:c},r))},D=(r,o,c)=>{const l=t.useContext(H);if(l===null)throw new Error("useEmbeddedEffect must be used within a MMEmbeddableZoneProvider");const b=t.useRef(c);t.useEffect(()=>{b.current=c},[c]),t.useEffect(()=>{if(!(!r||!o)){if(o.startsWith("key:")){const m=o.substring(4);return l.readyFrames[r]&&l.sendMessage(r,"subscribe-key",{keyChord:m}),l.addListener(r,`key-pressed:${m}`,(...C)=>b.current(...C))}return l.addListener(r,o,(...m)=>b.current(...m))}},[l,r,o])};fe.propTypes={children:T.default.node.isRequired,authorizationLauncher:T.default.func,credentialBroker:T.default.func};const X=W.default.default||W.default,Re=1e4,Ce="credentials",we=(r,o)=>`${r}/mm-embedded-interop?id=${encodeURIComponent(o)}&origin=${encodeURIComponent(window.location.origin)}&caps=${Ce}`,xe=X.iframe`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react"),pe=require("prop-types"),be=require("styled-components"),J=r=>r&&r.__esModule?r:{default:r},I=J(t),C=J(pe),Y=J(be),v=t.createContext(null),H=t.createContext({pending:[],authorize:()=>{},approve:()=>{},complete:()=>{},dismiss:()=>{},originEpochs:{},credentials:{},unsupported:{}}),re="access_token",V=r=>r?r.kind?r:r.accessToken?{kind:re,accessToken:r.accessToken,expiresAt:r.expiresAt||null}:null:null,he=new Set(["host_not_allowed","unbound_host_bound_guest","invalid_token","provider_unavailable"]),G=typeof window!="undefined"&&window.location.protocol==="https:",me=8e3,K=r=>{try{return new URL(r).origin}catch{return null}},ee=(r,c)=>{const a=c==null?void 0:c.origin;return!a||K(r==null?void 0:r.authUrl)!==a?null:a},te=r=>{if(!r||/^\d{1,3}(?:\.\d{1,3}){3}$/.test(r)||r.includes(":"))return r;const c=r.split(".");return c.length<=2?r:c.slice(-2).join(".")},ne=(r,c)=>{try{const a=new URL(r),f=new URL(c);return a.protocol!==f.protocol?!0:te(a.hostname)!==te(f.hostname)}catch{return!0}},se=(r,{onBlocked:c,onClosed:a})=>{const f=window.open(r.authUrl,"mm-embed-auth","popup,width=600,height=700");if(!f)return c(),()=>{};const b=setInterval(()=>{f.closed&&(clearInterval(b),a())},1e3);return()=>clearInterval(b)},oe=({children:r,launcher:c,broker:a})=>{const f=t.useContext(v),[b,m]=t.useState({}),[y,R]=t.useState({}),[M,U]=t.useState({}),[A,O]=t.useState({}),Z=t.useRef(M);Z.current=M;const g=t.useRef(b);g.current=b;const S=t.useRef(null),W=t.useRef({}),T=t.useRef({}),F=t.useRef({}),L=t.useRef(a);L.current=a;const w=t.useCallback(e=>{const n=T.current[e];if(!n)return;const s=u=>!u[e]||u[e].clientId?u:{...u,[e]:{...u[e],clientId:n}};m(s),O(s)},[]),i=t.useCallback((e,n)=>{e&&(O(s=>s[e]?s:{...s,[e]:{origin:e,reason:n,clientId:T.current[e]||null}}),w(e))},[w]),l=t.useCallback((e,{v2:n=!1,origin:s=null}={})=>{s&&(n&&Z.current[s]||(m(u=>u[s]?u:{...u,[s]:{origin:s,authUrl:e.authUrl,silentUrl:e.silentUrl||null,status:n&&L.current?"broker":n&&e.silentUrl&&G?"silent":"interactive",v2:n,scope:e.scope||null,acceptsCredentials:F.current[s]||null,consent:null,error:null,clientId:e.clientId||T.current[s]||null,popupBlocked:!1}}),w(s)))},[w]),o=t.useCallback(e=>{m(n=>{if(!n[e])return n;const s={...n};return delete s[e],s})},[]),d=t.useCallback(e=>{e&&(o(e),R(n=>({...n,[e]:(n[e]||0)+1})))},[o]),E=t.useCallback(e=>{m(n=>!n[e]||n[e].status==="interactive"?n:{...n,[e]:{...n[e],status:"interactive"}})},[]),k=t.useCallback(e=>{o(e.origin)},[o]),x=t.useCallback((e,n)=>{const s=ee(e,n);if(s){if(ne(s,window.location.origin)){i(s,"cross-site-legacy");return}l(e,{origin:s})}},[l,i]);t.useEffect(()=>{if(!f)return;const e=[f.addListener("*","init",(n,s)=>{s!=null&&s.origin&&(n!=null&&n.clientId)&&(T.current[s.origin]=n.clientId,w(s.origin)),s!=null&&s.origin&&Array.isArray(n==null?void 0:n.acceptsCredentials)&&(F.current[s.origin]=n.acceptsCredentials)}),f.addListener("*","authorize",x),f.addListener("*","login",x),f.addListener("*","credential-request",(n,s)=>l(n,{v2:!0,origin:ee(n,s)}))];return()=>e.forEach(n=>n())},[f,x,l,w]),t.useEffect(()=>{const e=n=>{const s=n==null?void 0:n.data;if(!s||s.type!=="authorized"&&s.type!=="authorize-failed")return;const u=K(s.authUrl);if(!(!u||n.origin!==u)){if(s.type==="authorized"){if(s.accessToken){if(!g.current[u])return;U(p=>({...p,[u]:V({accessToken:s.accessToken})})),o(u)}else d(u);return}E(u)}};return window.addEventListener("message",e),()=>window.removeEventListener("message",e)},[o,d,E]);const _=t.useCallback((e,n)=>{const s=e==null?void 0:e.origin,u=V(n);!s||!u||(U(p=>({...p,[s]:u})),o(s))},[o]),h=t.useCallback((e,n)=>{m(s=>s[e]?{...s,[e]:{...s[e],...n}}:s)},[]),z=t.useCallback(async(e,{approve:n}={})=>{const s=L.current,{origin:u}=e;let p;try{p=await s({origin:u,clientId:e.clientId,scope:e.scope,authUrl:e.authUrl},{approve:n})}catch{n?h(u,{error:{reason:"broker_unavailable"}}):h(u,{status:e.silentUrl&&G?"silent":"interactive"});return}if((p==null?void 0:p.status)===200&&p.credential){_(e,p.credential);return}if((p==null?void 0:p.status)===409&&p.consentRequired){h(u,{status:"interactive",consent:{client:p.client||null,stepUp:!!p.stepUp,scope:p.scope||e.scope},error:null});return}const N=(p==null?void 0:p.error)||"broker_error";if(!n&&he.has(N)){h(u,{status:e.silentUrl&&G?"silent":"interactive"});return}if(n&&N==="consent_denied"){h(u,{error:null});return}o(u),O(X=>({...X,[u]:{origin:u,reason:`broker:${N}`,detail:p||null,clientId:e.clientId||T.current[u]||null}}))},[_,h,o]),P=t.useRef({});t.useEffect(()=>{Object.values(b).forEach(e=>{e.status!=="broker"||P.current[e.origin]||(P.current[e.origin]=!0,z(e).finally(()=>{delete P.current[e.origin]}))})},[b,z]);const $=t.useCallback(e=>!L.current||!(e!=null&&e.consent)?Promise.resolve():z(e,{approve:!0}),[z]);t.useEffect(()=>{const e=W.current;Object.values(b).forEach(n=>{n.status==="silent"&&!e[n.origin]&&(e[n.origin]=setTimeout(()=>{delete e[n.origin],E(n.origin)},me))}),Object.keys(e).forEach(n=>{(!b[n]||b[n].status!=="silent")&&(clearTimeout(e[n]),delete e[n])})},[b,E]),t.useEffect(()=>()=>{S.current&&S.current(),Object.values(W.current).forEach(clearTimeout)},[]);const q=t.useCallback(e=>{S.current&&(S.current(),S.current=null);const n=c||se;S.current=n(e,{onBlocked:()=>{m(s=>s[e.origin]?{...s,[e.origin]:{...s[e.origin],popupBlocked:!0}}:s)},onClosed:()=>{if(e.v2){G&&m(s=>!s[e.origin]||!s[e.origin].silentUrl?s:{...s,[e.origin]:{...s[e.origin],status:"silent"}});return}d(e.origin)}})},[c,d]),B={pending:Object.values(b).filter(e=>e.status==="interactive"),authorize:q,approve:$,complete:_,dismiss:k,originEpochs:y,credentials:M,unsupported:A},j=Object.values(b).filter(e=>e.status==="silent"&&e.silentUrl);return I.default.createElement(H.Provider,{value:B},r,j.map(e=>I.default.createElement("iframe",{key:`mm-silent-auth-${e.origin}`,src:e.silentUrl,title:`MachineMetrics silent authorization (${e.origin})`,"aria-hidden":"true",tabIndex:-1,style:{display:"none"}})))};oe.propTypes={children:C.default.node,launcher:C.default.func,broker:C.default.func};const ge=()=>t.useContext(H),ue=r=>{const{originEpochs:c}=t.useContext(H),a=K(r);return a&&c[a]||0},ce=r=>{const{credentials:c}=t.useContext(H),a=K(r);return a&&c[a]||null},ie=r=>{const{unsupported:c}=t.useContext(H),a=K(r);return a&&c[a]||null},ae=({children:r,authorizationLauncher:c,credentialBroker:a})=>{const[f,b]=t.useState({}),[m,y]=t.useState({}),R=t.useRef({}),M=t.useRef({}),U=t.useRef({}),A=t.useCallback((i,l)=>{var o;return!!((o=U.current[i])!=null&&o.has(l))},[]),O=t.useCallback((i,l,o)=>{b(d=>({...d,[i]:{origin:l,frameRef:o}}))},[]),Z=t.useCallback(i=>{b(l=>{const o={...l};return delete o[i],o}),y(l=>{const o={...l};return delete o[i],o}),delete U.current[i]},[]);t.useEffect(()=>{const i=(o=[],d,E)=>{o.forEach(k=>k(d,E))},l=o=>{var z,P,$,q,B,j,e;if(!((z=o==null?void 0:o.data)!=null&&z.instanceId))return;const{instanceId:d,type:E}=o.data,k=f[d],x=($=(P=k==null?void 0:k.frameRef)==null?void 0:P.current)==null?void 0:$.contentWindow;if(!x||o.source!==x||o.origin!==k.origin)return;const _={origin:o.origin},h=R.current;if(E==="response"){const{callbackId:n,response:s,error:u}=o.data,p=M.current[n];p&&(p(s,u),delete M.current[n]);return}if(E==="mark-registered"){const{requestType:n}=o.data;U.current[d]||(U.current[d]=new Set),U.current[d].add(n);return}E==="ready"&&y(n=>({...n,[d]:!0})),i((q=h[d])==null?void 0:q[E],o.data,_),i((B=h["*"])==null?void 0:B[E],o.data,_),i((j=h[d])==null?void 0:j["*"],o.data,_),i((e=h["*"])==null?void 0:e["*"],o.data,_)};return window.addEventListener("message",l),()=>{window.removeEventListener("message",l)}},[f]);const g=t.useCallback((i,l,o)=>{var E,k;const d=f[i];if(!d){console.warn(`Origin not set for id: ${i}. Unable to send message.`);return}(k=(E=d==null?void 0:d.frameRef)==null?void 0:E.current)!=null&&k.contentWindow&&d.frameRef.current.contentWindow.postMessage({type:l,...o,instanceId:i},d.origin)},[f]),S=t.useRef(0),W=t.useCallback(()=>`${Date.now()}-${++S.current}`,[]),T=t.useCallback(async(i,l,o={})=>new Promise((d,E)=>{const k=W(),x=(_,h)=>{delete M.current[k],h?E(h):d(_)};M.current[k]=x,g(i,"request",{callbackId:k,requestType:l,data:o})}),[g]),F=t.useCallback((i,l)=>{g(i,"load-options",l)},[g]),L=t.useCallback((i,l)=>{g(i,"validate",l)},[g]),w=t.useMemo(()=>({registerFrame:O,unregisterFrame:Z,sendMessage:g,sendRequest:T,loadOptions:F,validate:L,hasHandler:A,readyFrames:m,addListener:(i,l,o)=>(R.current[i]||(R.current[i]={}),R.current[i][l]||(R.current[i][l]=[]),R.current[i][l].push(o),()=>{R.current[i][l]=R.current[i][l].filter(d=>d!==o)})}),[O,Z,g,T,F,L,A,m]);return I.default.createElement(v.Provider,{value:w},I.default.createElement(oe,{launcher:c,broker:a},r))},D=(r,c,a)=>{const f=t.useContext(v);if(f===null)throw new Error("useEmbeddedEffect must be used within a MMEmbeddableZoneProvider");const b=t.useRef(a);t.useEffect(()=>{b.current=a},[a]),t.useEffect(()=>{if(!(!r||!c)){if(c.startsWith("key:")){const m=c.substring(4);return f.readyFrames[r]&&f.sendMessage(r,"subscribe-key",{keyChord:m}),f.addListener(r,`key-pressed:${m}`,(...R)=>b.current(...R))}return f.addListener(r,c,(...m)=>b.current(...m))}},[f,r,c])};ae.propTypes={children:C.default.node.isRequired,authorizationLauncher:C.default.func,credentialBroker:C.default.func};const Q=Y.default.default||Y.default,Ee=1e4,ke="credentials",Ce=(r,c)=>`${r}/mm-embedded-interop?id=${encodeURIComponent(c)}&origin=${encodeURIComponent(window.location.origin)}&caps=${ke}`,Re=Q.iframe`
2
2
  width: 100%;
3
3
  height: 100%;
4
4
  border: none;
5
5
  visibility: ${r=>r.$isReady?"visible":"hidden"};
6
- `,Te=X.div`
6
+ `,we=Q.div`
7
7
  width: 100%;
8
8
  height: 100%;
9
9
  display: flex;
@@ -16,46 +16,10 @@
16
16
  text-align: center;
17
17
  color: #555;
18
18
  font-size: 14px;
19
- `,pe=r=>{const o=r&&r.origin||"This app",c=r&&r.reason||"";switch(c){case"broker:scope_above_ceiling":return{title:`${o} can’t be authorized here`,detail:"It asks for permissions your role doesn’t have."};case"broker:origin_mismatch":case"broker:unknown_client":return{title:`${o} can’t be authorized here`,detail:"It isn’t registered to run at this address."};case"broker:cross_company_principal":return{title:`${o} can’t be authorized here`,detail:"It can’t be authorized for this account."};default:return c.startsWith("broker:")?{title:`${o} can’t be authorized here`,detail:"Authorization was refused."}:{title:`${o} can’t be embedded here`,detail:"It needs an update to support embedding from a different domain."}}},be=({entry:r})=>{const o=pe(r);return E.default.createElement(Te,{"data-reason":r&&r.reason||void 0},E.default.createElement("div",{style:{fontWeight:600}},o.title),E.default.createElement("div",{style:{fontSize:12,color:"#888"}},o.detail))};be.propTypes={entry:T.default.shape({origin:T.default.string,name:T.default.string,reason:T.default.string,detail:T.default.object})};const ze=X.div`
19
+ `,le=r=>{const c=r&&r.origin||"This app",a=r&&r.reason||"";switch(a){case"broker:scope_above_ceiling":return{title:`${c} can’t be authorized here`,detail:"It asks for permissions your role doesn’t have."};case"broker:origin_mismatch":case"broker:unknown_client":return{title:`${c} can’t be authorized here`,detail:"It isn’t registered to run at this address."};case"broker:cross_company_principal":return{title:`${c} can’t be authorized here`,detail:"It can’t be authorized for this account."};default:return a.startsWith("broker:")?{title:`${c} can’t be authorized here`,detail:"Authorization was refused."}:{title:`${c} can’t be embedded here`,detail:"It needs an update to support embedding from a different domain."}}},de=({entry:r})=>{const c=le(r);return I.default.createElement(we,{"data-reason":r&&r.reason||void 0},I.default.createElement("div",{style:{fontWeight:600}},c.title),I.default.createElement("div",{style:{fontSize:12,color:"#888"}},c.detail))};de.propTypes={entry:C.default.shape({origin:C.default.string,name:C.default.string,reason:C.default.string,detail:C.default.object})};const Te=Q.div`
20
20
  height: 100%;
21
21
  display: flex;
22
22
  flex: 1;
23
23
  align-items: center;
24
24
  justify-content: center;
25
- `,Ie=()=>E.default.createElement(ze,null,E.default.createElement("div",{style:{textAlign:"center"}},"This app couldn’t be loaded as an embeddable widget.")),me=({id:r,src:o,path:c,onInit:l=()=>{},onTimeout:b,context:m={},params:A={},renderUnsupported:C,renderTimeout:z,...f})=>{if("isConfiguring"in f)return console.error("isConfiguring must be passed via the params prop to MMEmbeddableZone"),null;if("colorMode"in m)return console.error("colorMode must be passed via the params prop to MMEmbeddableZone"),null;if("isFullScreen"in m)return console.error("isFullScreen must be passed via the params prop to MMEmbeddableZone"),null;const w=t.useRef(),[I,L]=t.useState(),[g,U]=t.useState(0),[Z,S]=t.useState(!1),[F,$]=t.useState(!1),y=ae(o),a=le(o),d=de(o),[u,p]=t.useState(0),[R,x]=t.useState(null),{registerFrame:M,unregisterFrame:_,sendMessage:k}=t.useContext(H),[O,v]=t.useState(),P=t.useRef(),q=t.useRef(b),j=t.useRef(l),B=t.useRef(!1),e=t.useCallback(()=>{B.current=!1,clearTimeout(P.current),U(0),S(!1),$(!1),x(null)},[]);t.useEffect(()=>{(y>0||u>0)&&e()},[y,u,e]),t.useEffect(()=>{q.current=b},[b]),t.useEffect(()=>{j.current=l},[l]),t.useEffect(()=>{g&&k(r,"set-context",{context:{...m}})},[m,r,g]),t.useEffect(()=>{g&&k(r,"set-params",{params:A})},[A,r,g]),t.useEffect(()=>{c!==void 0&&v((c==null?void 0:c.indexOf("/"))===0?c:`/${c}`)},[c]),t.useEffect(()=>{O===void 0||!g||k(r,"navigate",{path:O})},[O,g,r,k]),t.useEffect(()=>{if(!o||!r||!w)return;e();const i=new URL(o);return M(r,i.origin,w),j.current(),L(we(i.origin,r)),()=>{_(r)}},[o,r,M,w,e]),t.useEffect(()=>{if(!(!I||B.current))return P.current=setTimeout(()=>{S(!0),q.current&&q.current()},Re),()=>clearTimeout(P.current)},[I,o,y,u]);const n=t.useCallback(()=>{B.current=!0,clearTimeout(P.current),S(!1)},[]);D(r,"init",i=>{n(),Array.isArray(i==null?void 0:i.acceptsCredentials)&&x(i.acceptsCredentials)}),D(r,"authorize",n),D(r,"login",n),D(r,"credential-request",()=>{n(),$(!0)}),t.useEffect(()=>{if(!F||!a)return;const i=R;if(Array.isArray(i)&&!i.includes(a.kind))return;const h=a.kind==="access_token"?{accessToken:a.accessToken}:{};k(r,"credential",{...h,credential:a})},[F,a,R,r,k]),D(r,"ready",()=>{n(),U(i=>i+1)});const s=t.useRef();return D(r,"heartbeat",()=>{s.current&&clearTimeout(s.current),s.current=setTimeout(()=>{p(i=>i+1)},6e3)}),t.useEffect(()=>()=>{s.current&&clearTimeout(s.current)},[]),d?C?C(d):E.default.createElement(be,{entry:d}):Z&&!g?z?z():E.default.createElement(Ie,null):E.default.createElement(xe,{key:`auth-epoch-${y}-frame-${u}`,$isReady:g,ref:w,src:I,...f})};me.propTypes={id:T.default.string,src:T.default.string.isRequired,path:T.default.string,onInit:T.default.func,onTimeout:T.default.func,renderUnsupported:T.default.func,renderTimeout:T.default.func};const ye=W.default.div`
26
- position: fixed;
27
- inset: 0;
28
- background: rgba(0, 0, 0, 0.45);
29
- display: flex;
30
- align-items: center;
31
- justify-content: center;
32
- z-index: 10000;
33
- `,Se=W.default.div`
34
- background: #fff;
35
- border-radius: 8px;
36
- box-shadow: 0 4px 24px rgba(0, 0, 0, 0.2);
37
- padding: 24px;
38
- width: 480px;
39
- max-width: calc(100vw - 32px);
40
- font-family: sans-serif;
41
- color: #222;
42
- `,_e=W.default.div`
43
- display: flex;
44
- align-items: center;
45
- justify-content: space-between;
46
- padding: 10px 0;
47
- gap: 16px;
48
- `,Ae=W.default.button`
49
- background: #16a500;
50
- color: #fff;
51
- border: none;
52
- border-radius: 6px;
53
- padding: 9px 18px;
54
- font-size: 14px;
55
- cursor: pointer;
56
- white-space: nowrap;
57
- `,Ue=W.default.p`
58
- color: #b3261e;
59
- font-size: 13px;
60
- margin: 4px 0 0;
61
- `,re='button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';let ne=!1;const Me=()=>{const{pending:r,authorize:o,dismiss:c}=ce(),l=r.filter(f=>!f.consent),b=r.length-l.length,m=t.useRef(null),A=t.useRef(null),C=l.length>0;if(t.useEffect(()=>{b>0&&!ne&&(ne=!0,console.error("[mm-react-embeddable] EmbeddedAuthorizationPrompt received a brokered consent entry. A host with a credentialBroker must render its own consent UI (useEmbeddedAuthorizations: approve/dismiss); this default prompt only handles the popup path."))},[b]),t.useEffect(()=>{if(!C||!m.current)return;A.current=document.activeElement;const f=m.current.querySelector(re);return f&&f.focus(),()=>{const w=A.current;w&&typeof w.focus=="function"&&w.focus()}},[C]),!C)return null;const z=f=>{if(f.key==="Escape"){f.preventDefault(),l.forEach(g=>c(g));return}if(f.key!=="Tab"||!m.current)return;const w=Array.from(m.current.querySelectorAll(re));if(w.length===0)return;const I=w[0],L=w[w.length-1];f.shiftKey&&document.activeElement===I?(f.preventDefault(),L.focus()):!f.shiftKey&&document.activeElement===L&&(f.preventDefault(),I.focus())};return E.default.createElement(ye,null,E.default.createElement(Se,{ref:m,role:"dialog","aria-modal":"true","aria-labelledby":"mm-embedded-authorization-title",onKeyDown:z},E.default.createElement("h3",{id:"mm-embedded-authorization-title",style:{margin:"0 0 8px"}},"Authorization Required"),E.default.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."),l.map(f=>E.default.createElement("div",{key:f.origin},E.default.createElement(_e,null,E.default.createElement("div",null,E.default.createElement("div",{style:{fontWeight:600}},f.origin)),E.default.createElement(Ae,{onClick:()=>o(f)},"Authorize")),f.popupBlocked&&E.default.createElement(Ue,null,"The sign-in window was blocked. Allow popups for this site, then try again.")))))};exports.CREDENTIAL_KIND_ACCESS_TOKEN=se;exports.EmbeddedAuthorizationContext=K;exports.EmbeddedAuthorizationPrompt=Me;exports.MMEmbeddableZone=me;exports.MMEmbeddableZoneContext=H;exports.MMEmbeddableZoneProvider=fe;exports.isCrossSite=oe;exports.normalizeCredential=J;exports.popupAuthorizationLauncher=ue;exports.unsupportedCopy=pe;exports.useEmbeddedAuthorizations=ce;exports.useEmbeddedCredential=le;exports.useEmbeddedEffect=D;exports.useEmbeddedOriginEpoch=ae;exports.useEmbeddedUnsupported=de;
25
+ `,_e=()=>I.default.createElement(Te,null,I.default.createElement("div",{style:{textAlign:"center"}},"This app couldn’t be loaded as an embeddable widget.")),fe=({id:r,src:c,path:a,onInit:f=()=>{},onTimeout:b,context:m={},params:y={},renderUnsupported:R,renderTimeout:M,...U})=>{if("isConfiguring"in U)return console.error("isConfiguring must be passed via the params prop to MMEmbeddableZone"),null;if("colorMode"in m)return console.error("colorMode must be passed via the params prop to MMEmbeddableZone"),null;if("isFullScreen"in m)return console.error("isFullScreen must be passed via the params prop to MMEmbeddableZone"),null;const A=t.useRef(),[O,Z]=t.useState(),[g,S]=t.useState(0),[W,T]=t.useState(!1),[F,L]=t.useState(!1),w=ue(c),i=ce(c),l=ie(c),[o,d]=t.useState(0),[E,k]=t.useState(null),{registerFrame:x,unregisterFrame:_,sendMessage:h}=t.useContext(v),[z,P]=t.useState(),$=t.useRef(),q=t.useRef(b),B=t.useRef(f),j=t.useRef(!1),e=t.useCallback(()=>{j.current=!1,clearTimeout($.current),S(0),T(!1),L(!1),k(null)},[]);t.useEffect(()=>{(w>0||o>0)&&e()},[w,o,e]),t.useEffect(()=>{q.current=b},[b]),t.useEffect(()=>{B.current=f},[f]),t.useEffect(()=>{g&&h(r,"set-context",{context:{...m}})},[m,r,g]),t.useEffect(()=>{g&&h(r,"set-params",{params:y})},[y,r,g]),t.useEffect(()=>{a!==void 0&&P((a==null?void 0:a.indexOf("/"))===0?a:`/${a}`)},[a]),t.useEffect(()=>{z===void 0||!g||h(r,"navigate",{path:z})},[z,g,r,h]),t.useEffect(()=>{if(!c||!r||!A)return;e();const u=new URL(c);return x(r,u.origin,A),B.current(),Z(Ce(u.origin,r)),()=>{_(r)}},[c,r,x,A,e]),t.useEffect(()=>{if(!(!O||j.current))return $.current=setTimeout(()=>{T(!0),q.current&&q.current()},Ee),()=>clearTimeout($.current)},[O,c,w,o]);const n=t.useCallback(()=>{j.current=!0,clearTimeout($.current),T(!1)},[]);D(r,"init",u=>{n(),Array.isArray(u==null?void 0:u.acceptsCredentials)&&k(u.acceptsCredentials)}),D(r,"authorize",n),D(r,"login",n),D(r,"credential-request",()=>{n(),L(!0)}),t.useEffect(()=>{if(!F||!i)return;const u=E;if(Array.isArray(u)&&!u.includes(i.kind))return;const p=i.kind==="access_token"?{accessToken:i.accessToken}:{};h(r,"credential",{...p,credential:i})},[F,i,E,r,h]),D(r,"ready",()=>{n(),S(u=>u+1)});const s=t.useRef();return D(r,"heartbeat",()=>{s.current&&clearTimeout(s.current),s.current=setTimeout(()=>{d(u=>u+1)},6e3)}),t.useEffect(()=>()=>{s.current&&clearTimeout(s.current)},[]),l?R?R(l):I.default.createElement(de,{entry:l}):W&&!g?M?M():I.default.createElement(_e,null):I.default.createElement(Re,{key:`auth-epoch-${w}-frame-${o}`,$isReady:g,ref:A,src:O,...U})};fe.propTypes={id:C.default.string,src:C.default.string.isRequired,path:C.default.string,onInit:C.default.func,onTimeout:C.default.func,renderUnsupported:C.default.func,renderTimeout:C.default.func};exports.CREDENTIAL_KIND_ACCESS_TOKEN=re;exports.EmbeddedAuthorizationContext=H;exports.MMEmbeddableZone=fe;exports.MMEmbeddableZoneContext=v;exports.MMEmbeddableZoneProvider=ae;exports.isCrossSite=ne;exports.normalizeCredential=V;exports.popupAuthorizationLauncher=se;exports.unsupportedCopy=le;exports.useEmbeddedAuthorizations=ge;exports.useEmbeddedCredential=ce;exports.useEmbeddedEffect=D;exports.useEmbeddedOriginEpoch=ue;exports.useEmbeddedUnsupported=ie;