@machinemetrics/mm-react-embeddable 2.0.0-2 → 2.0.0-4
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 +10 -9
- package/dist/mm-react-embeddable.cjs.js +4 -40
- package/dist/mm-react-embeddable.es.js +422 -486
- package/dist/mm-react-embeddable.umd.js +5 -41
- package/package.json +1 -1
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
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
renders its own
|
|
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
|
|
14
|
-
|
|
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"),Ee=require("prop-types"),ge=require("styled-components"),ee=r=>r&&r.__esModule?r:{default:r},L=ee(t),k=ee(Ee),re=ee(ge),Y=t.createContext(null),N=t.createContext({pending:[],authorize:()=>{},approve:()=>{},complete:()=>{},dismiss:()=>{},originEpochs:{},credentials:{},unsupported:{}}),ue="access_token",Q=r=>r?r.kind?r:r.accessToken?{kind:ue,accessToken:r.accessToken,expiresAt:r.expiresAt||null}:null:null,Re=60,ke=120,Ce=new Set(["host_not_allowed","unbound_host_bound_guest","invalid_token","provider_unavailable"]),J=typeof window!="undefined"&&window.location.protocol==="https:",Te=8e3,G=r=>{try{return new URL(r).origin}catch{return null}},ne=(r,u)=>{const i=u==null?void 0:u.origin;return!i||G(r==null?void 0:r.authUrl)!==i?null:i},se=r=>{if(!r||/^\d{1,3}(?:\.\d{1,3}){3}$/.test(r)||r.includes(":"))return r;const u=r.split(".");return u.length<=2?r:u.slice(-2).join(".")},oe=(r,u)=>{try{const i=new URL(r),f=new URL(u);return i.protocol!==f.protocol?!0:se(i.hostname)!==se(f.hostname)}catch{return!0}},ce=(r,{onBlocked:u,onClosed:i})=>{const f=window.open(r.authUrl,"mm-embed-auth","popup,width=600,height=700");if(!f)return u(),()=>{};const m=setInterval(()=>{f.closed&&(clearInterval(m),i())},1e3);return()=>clearInterval(m)},ie=({children:r,launcher:u,broker:i})=>{const f=t.useContext(Y),[m,E]=t.useState({}),[B,C]=t.useState({}),[x,A]=t.useState({}),[P,O]=t.useState({}),v=t.useRef(x);v.current=x;const g=t.useRef(m);g.current=m;const z=t.useRef(null),K=t.useRef({}),M=t.useRef({}),D=t.useRef({}),$=t.useRef(i);$.current=i;const _=t.useCallback(e=>{const n=M.current[e];if(!n)return;const s=a=>!a[e]||a[e].clientId?a:{...a,[e]:{...a[e],clientId:n}};E(s),O(s)},[]),c=t.useCallback((e,n)=>{e&&(O(s=>s[e]?s:{...s,[e]:{origin:e,reason:n,clientId:M.current[e]||null}}),_(e))},[_]),l=t.useCallback((e,{v2:n=!1,origin:s=null}={})=>{s&&(n&&v.current[s]||(E(a=>a[s]?a:{...a,[s]:{origin:s,authUrl:e.authUrl,silentUrl:e.silentUrl||null,status:n&&$.current?"broker":n&&e.silentUrl&&J?"silent":"interactive",v2:n,scope:e.scope||null,acceptsCredentials:D.current[s]||null,consent:null,error:null,clientId:e.clientId||M.current[s]||null,popupBlocked:!1}}),_(s)))},[_]),o=t.useRef({}),d=t.useCallback(e=>{o.current[e]&&(clearTimeout(o.current[e]),delete o.current[e])},[]),p=t.useCallback(e=>{d(e),E(n=>{if(!n[e])return n;const s={...n};return delete s[e],s})},[d]),h=t.useCallback(e=>{e&&(p(e),C(n=>({...n,[e]:(n[e]||0)+1})))},[p]),S=t.useCallback(e=>{E(n=>!n[e]||n[e].status==="interactive"?n:{...n,[e]:{...n[e],status:"interactive"}})},[]),y=t.useCallback(e=>{p(e.origin)},[p]),R=t.useCallback((e,n)=>{const s=ne(e,n);if(s){if(oe(s,window.location.origin)){c(s,"cross-site-legacy");return}l(e,{origin:s})}},[l,c]);t.useEffect(()=>{if(!f)return;const e=[f.addListener("*","init",(n,s)=>{s!=null&&s.origin&&(n!=null&&n.clientId)&&(M.current[s.origin]=n.clientId,_(s.origin)),s!=null&&s.origin&&Array.isArray(n==null?void 0:n.acceptsCredentials)&&(D.current[s.origin]=n.acceptsCredentials)}),f.addListener("*","authorize",R),f.addListener("*","login",R),f.addListener("*","credential-request",(n,s)=>l(n,{v2:!0,origin:ne(n,s)}))];return()=>e.forEach(n=>n())},[f,R,l,_]),t.useEffect(()=>{const e=n=>{const s=n==null?void 0:n.data;if(!s||s.type!=="authorized"&&s.type!=="authorize-failed")return;const a=G(s.authUrl);if(!(!a||n.origin!==a)){if(s.type==="authorized"){if(s.accessToken){if(!g.current[a])return;A(b=>({...b,[a]:Q({accessToken:s.accessToken})})),p(a)}else h(a);return}S(a)}};return window.addEventListener("message",e),()=>window.removeEventListener("message",e)},[p,h,S]);const F=t.useCallback((e,n)=>{const s=e==null?void 0:e.origin,a=Q(n);!s||!a||(A(b=>({...b,[s]:a})),p(s))},[p]),U=t.useCallback((e,n)=>{E(s=>s[e]?{...s,[e]:{...s[e],...n}}:s)},[]),w=t.useRef({}),I=t.useCallback(async(e,{approve:n}={})=>{const s=$.current,{origin:a}=e;let b;try{b=await s({origin:a,clientId:e.clientId,scope:e.scope,authUrl:e.authUrl},{approve:n})}catch{n?U(a,{error:{reason:"broker_unavailable"}}):U(a,{status:e.silentUrl&&J?"silent":"interactive"});return}if((b==null?void 0:b.status)===200&&b.credential){F(e,b.credential);return}if((b==null?void 0:b.status)===409&&b.consentRequired){U(a,{status:"interactive",consent:{client:b.client||null,stepUp:!!b.stepUp,scope:b.scope||e.scope},error:null});return}const V=(b==null?void 0:b.error)||"broker_error";if(!n&&Ce.has(V)){U(a,{status:e.silentUrl&&J?"silent":"interactive"});return}if(n&&V==="consent_denied"){U(a,{error:null});return}if(V==="rate_limited"&&!e.rateLimitRetried){const X=Math.min(Number(b==null?void 0:b.retryAfter)>0?Number(b.retryAfter):Re,ke),he={...e,rateLimitRetried:!0};d(a),o.current[a]=setTimeout(()=>{delete o.current[a],w.current[a]=!0,Z.current(he,{approve:n}).finally(()=>{delete w.current[a]})},X*1e3),U(a,{rateLimitRetried:!0});return}p(a),O(X=>({...X,[a]:{origin:a,reason:`broker:${V}`,detail:b||null,clientId:e.clientId||M.current[a]||null}}))},[F,U,p,d]),Z=t.useRef(I);Z.current=I,t.useEffect(()=>{Object.values(m).forEach(e=>{e.status!=="broker"||w.current[e.origin]||o.current[e.origin]||(w.current[e.origin]=!0,I(e).finally(()=>{delete w.current[e.origin]}))})},[m,I]);const W=t.useCallback(e=>!$.current||!(e!=null&&e.consent)?Promise.resolve():I(e,{approve:!0}),[I]);t.useEffect(()=>{const e=K.current;Object.values(m).forEach(n=>{n.status==="silent"&&!e[n.origin]&&(e[n.origin]=setTimeout(()=>{delete e[n.origin],S(n.origin)},Te))}),Object.keys(e).forEach(n=>{(!m[n]||m[n].status!=="silent")&&(clearTimeout(e[n]),delete e[n])})},[m,S]),t.useEffect(()=>()=>{z.current&&z.current(),Object.values(K.current).forEach(clearTimeout),Object.values(o.current).forEach(clearTimeout)},[]);const j=t.useCallback(e=>{z.current&&(z.current(),z.current=null);const n=u||ce;z.current=n(e,{onBlocked:()=>{E(s=>s[e.origin]?{...s,[e.origin]:{...s[e.origin],popupBlocked:!0}}:s)},onClosed:()=>{if(e.v2){J&&E(s=>!s[e.origin]||!s[e.origin].silentUrl?s:{...s,[e.origin]:{...s[e.origin],status:"silent"}});return}h(e.origin)}})},[u,h]),T={pending:Object.values(m).filter(e=>e.status==="interactive"),authorize:j,approve:W,complete:F,dismiss:y,originEpochs:B,credentials:x,unsupported:P},q=Object.values(m).filter(e=>e.status==="silent"&&e.silentUrl);return L.default.createElement(N.Provider,{value:T},r,q.map(e=>L.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:k.default.node,launcher:k.default.func,broker:k.default.func};const _e=()=>t.useContext(N),ae=r=>{const{originEpochs:u}=t.useContext(N),i=G(r);return i&&u[i]||0},le=r=>{const{credentials:u}=t.useContext(N),i=G(r);return i&&u[i]||null},de=r=>{const{unsupported:u}=t.useContext(N),i=G(r);return i&&u[i]||null},fe=({children:r,authorizationLauncher:u,credentialBroker:i})=>{const[f,m]=t.useState({}),[E,B]=t.useState({}),C=t.useRef({}),x=t.useRef({}),A=t.useRef({}),P=t.useCallback((c,l)=>{var o;return!!((o=A.current[c])!=null&&o.has(l))},[]),O=t.useCallback((c,l,o)=>{m(d=>({...d,[c]:{origin:l,frameRef:o}}))},[]),v=t.useCallback(c=>{m(l=>{const o={...l};return delete o[c],o}),B(l=>{const o={...l};return delete o[c],o}),delete A.current[c]},[]);t.useEffect(()=>{const c=(o=[],d,p)=>{o.forEach(h=>h(d,p))},l=o=>{var F,U,w,I,Z,W,j;if(!((F=o==null?void 0:o.data)!=null&&F.instanceId))return;const{instanceId:d,type:p}=o.data,h=f[d],S=(w=(U=h==null?void 0:h.frameRef)==null?void 0:U.current)==null?void 0:w.contentWindow;if(!S||o.source!==S||o.origin!==h.origin)return;const y={origin:o.origin},R=C.current;if(p==="response"){const{callbackId:T,response:q,error:e}=o.data,n=x.current[T];n&&(n(q,e),delete x.current[T]);return}if(p==="mark-registered"){const{requestType:T}=o.data;A.current[d]||(A.current[d]=new Set),A.current[d].add(T);return}p==="ready"&&B(T=>({...T,[d]:!0})),c((I=R[d])==null?void 0:I[p],o.data,y),c((Z=R["*"])==null?void 0:Z[p],o.data,y),c((W=R[d])==null?void 0:W["*"],o.data,y),c((j=R["*"])==null?void 0:j["*"],o.data,y)};return window.addEventListener("message",l),()=>{window.removeEventListener("message",l)}},[f]);const g=t.useCallback((c,l,o)=>{var p,h;const d=f[c];if(!d){console.warn(`Origin not set for id: ${c}. Unable to send message.`);return}(h=(p=d==null?void 0:d.frameRef)==null?void 0:p.current)!=null&&h.contentWindow&&d.frameRef.current.contentWindow.postMessage({type:l,...o,instanceId:c},d.origin)},[f]),z=t.useRef(0),K=t.useCallback(()=>`${Date.now()}-${++z.current}`,[]),M=t.useCallback(async(c,l,o={})=>new Promise((d,p)=>{const h=K(),S=(y,R)=>{delete x.current[h],R?p(R):d(y)};x.current[h]=S,g(c,"request",{callbackId:h,requestType:l,data:o})}),[g]),D=t.useCallback((c,l)=>{g(c,"load-options",l)},[g]),$=t.useCallback((c,l)=>{g(c,"validate",l)},[g]),_=t.useMemo(()=>({registerFrame:O,unregisterFrame:v,sendMessage:g,sendRequest:M,loadOptions:D,validate:$,hasHandler:P,readyFrames:E,addListener:(c,l,o)=>(C.current[c]||(C.current[c]={}),C.current[c][l]||(C.current[c][l]=[]),C.current[c][l].push(o),()=>{C.current[c][l]=C.current[c][l].filter(d=>d!==o)})}),[O,v,g,M,D,$,P,E]);return L.default.createElement(Y.Provider,{value:_},L.default.createElement(ie,{launcher:u,broker:i},r))},H=(r,u,i)=>{const f=t.useContext(Y);if(f===null)throw new Error("useEmbeddedEffect must be used within a MMEmbeddableZoneProvider");const m=t.useRef(i);t.useEffect(()=>{m.current=i},[i]),t.useEffect(()=>{if(!(!r||!u)){if(u.startsWith("key:")){const E=u.substring(4);return f.readyFrames[r]&&f.sendMessage(r,"subscribe-key",{keyChord:E}),f.addListener(r,`key-pressed:${E}`,(...C)=>m.current(...C))}return f.addListener(r,u,(...E)=>m.current(...E))}},[f,r,u])};fe.propTypes={children:k.default.node.isRequired,authorizationLauncher:k.default.func,credentialBroker:k.default.func};const te=re.default.default||re.default,we=1e4,Ie="credentials",Me=(r,u)=>`${r}/mm-embedded-interop?id=${encodeURIComponent(u)}&origin=${encodeURIComponent(window.location.origin)}&caps=${Ie}`,Se=te.iframe`
|
|
2
2
|
width: 100%;
|
|
3
3
|
height: 100%;
|
|
4
4
|
border: none;
|
|
5
5
|
visibility: ${r=>r.$isReady?"visible":"hidden"};
|
|
6
|
-
`,
|
|
6
|
+
`,Ue=te.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
|
|
19
|
+
`,pe=r=>{const u=r&&r.origin||"This app",i=r&&r.reason||"";switch(i){case"broker:scope_above_ceiling":return{title:`${u} 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:`${u} can’t be authorized here`,detail:"It isn’t registered to run at this address."};case"broker:cross_company_principal":return{title:`${u} can’t be authorized here`,detail:"It can’t be authorized for this account."};default:return i.startsWith("broker:")?{title:`${u} can’t be authorized here`,detail:"Authorization was refused."}:{title:`${u} can’t be embedded here`,detail:"It needs an update to support embedding from a different domain."}}},be=({entry:r})=>{const u=pe(r);return L.default.createElement(Ue,{"data-reason":r&&r.reason||void 0},L.default.createElement("div",{style:{fontWeight:600}},u.title),L.default.createElement("div",{style:{fontSize:12,color:"#888"}},u.detail))};be.propTypes={entry:k.default.shape({origin:k.default.string,name:k.default.string,reason:k.default.string,detail:k.default.object})};const Le=te.div`
|
|
20
20
|
height: 100%;
|
|
21
21
|
display: flex;
|
|
22
22
|
flex: 1;
|
|
23
23
|
align-items: center;
|
|
24
24
|
justify-content: center;
|
|
25
|
-
`,
|
|
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
|
+
`,xe=()=>L.default.createElement(Le,null,L.default.createElement("div",{style:{textAlign:"center"}},"This app couldn’t be loaded as an embeddable widget.")),me=({id:r,src:u,path:i,onInit:f=()=>{},onTimeout:m,context:E={},params:B={},renderUnsupported:C,renderTimeout:x,...A})=>{if("isConfiguring"in A)return console.error("isConfiguring must be passed via the params prop to MMEmbeddableZone"),null;if("colorMode"in E)return console.error("colorMode must be passed via the params prop to MMEmbeddableZone"),null;if("isFullScreen"in E)return console.error("isFullScreen must be passed via the params prop to MMEmbeddableZone"),null;const P=t.useRef(),[O,v]=t.useState(),[g,z]=t.useState(0),[K,M]=t.useState(!1),[D,$]=t.useState(!1),_=ae(u),c=le(u),l=de(u),[o,d]=t.useState(0),[p,h]=t.useState(null),{registerFrame:S,unregisterFrame:y,sendMessage:R}=t.useContext(Y),[F,U]=t.useState(),w=t.useRef(),I=t.useRef(m),Z=t.useRef(f),W=t.useRef(!1),j=t.useCallback(()=>{W.current=!1,clearTimeout(w.current),z(0),M(!1),$(!1),h(null)},[]);t.useEffect(()=>{(_>0||o>0)&&j()},[_,o,j]),t.useEffect(()=>{I.current=m},[m]),t.useEffect(()=>{Z.current=f},[f]),t.useEffect(()=>{g&&R(r,"set-context",{context:{...E}})},[E,r,g]),t.useEffect(()=>{g&&R(r,"set-params",{params:B})},[B,r,g]),t.useEffect(()=>{i!==void 0&&U((i==null?void 0:i.indexOf("/"))===0?i:`/${i}`)},[i]),t.useEffect(()=>{F===void 0||!g||R(r,"navigate",{path:F})},[F,g,r,R]),t.useEffect(()=>{if(!u||!r||!P)return;j();const e=new URL(u);return S(r,e.origin,P),Z.current(),v(Me(e.origin,r)),()=>{y(r)}},[u,r,S,P,j]),t.useEffect(()=>{if(!(!O||W.current))return w.current=setTimeout(()=>{M(!0),I.current&&I.current()},we),()=>clearTimeout(w.current)},[O,u,_,o]);const T=t.useCallback(()=>{W.current=!0,clearTimeout(w.current),M(!1)},[]);H(r,"init",e=>{T(),Array.isArray(e==null?void 0:e.acceptsCredentials)&&h(e.acceptsCredentials)}),H(r,"authorize",T),H(r,"login",T),H(r,"credential-request",()=>{T(),$(!0)}),t.useEffect(()=>{if(!D||!c)return;const e=p;if(Array.isArray(e)&&!e.includes(c.kind))return;const n=c.kind==="access_token"?{accessToken:c.accessToken}:{};R(r,"credential",{...n,credential:c})},[D,c,p,r,R]),H(r,"ready",()=>{T(),z(e=>e+1)});const q=t.useRef();return H(r,"heartbeat",()=>{q.current&&clearTimeout(q.current),q.current=setTimeout(()=>{d(e=>e+1)},6e3)}),t.useEffect(()=>()=>{q.current&&clearTimeout(q.current)},[]),l?C?C(l):L.default.createElement(be,{entry:l}):K&&!g?x?x():L.default.createElement(xe,null):L.default.createElement(Se,{key:`auth-epoch-${_}-frame-${o}`,$isReady:g,ref:P,src:O,...A})};me.propTypes={id:k.default.string,src:k.default.string.isRequired,path:k.default.string,onInit:k.default.func,onTimeout:k.default.func,renderUnsupported:k.default.func,renderTimeout:k.default.func};exports.CREDENTIAL_KIND_ACCESS_TOKEN=ue;exports.EmbeddedAuthorizationContext=N;exports.MMEmbeddableZone=me;exports.MMEmbeddableZoneContext=Y;exports.MMEmbeddableZoneProvider=fe;exports.isCrossSite=oe;exports.normalizeCredential=Q;exports.popupAuthorizationLauncher=ce;exports.unsupportedCopy=pe;exports.useEmbeddedAuthorizations=_e;exports.useEmbeddedCredential=le;exports.useEmbeddedEffect=H;exports.useEmbeddedOriginEpoch=ae;exports.useEmbeddedUnsupported=de;
|