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