unleash-server
Version:
Unleash is an enterprise ready feature flag service. It provides different strategies for handling feature flags.
4 lines • 196 kB
JavaScript
import{dD as Wn,j as e,dE as ve,dF as Ys,dG as Js,dH as Ae,aC as te,aD as se,ax as ce,dI as zn,dJ as qn,dK as va,dL as Ca,dM as Ot,dN as wa,x as Hn,dO as Ta,s as h,bR as ka,e as K,bc as H,bt as Ce,r as u,cT as $t,bK as ke,dP as Vn,dQ as ks,h as V,dR as Ie,A as Yn,l as X,C as w,dS as Jn,ba as _t,b9 as ne,dT as Ea,dU as Kn,bb as ue,dV as Fe,de as f,dW as re,dX as ge,F as Nt,u as xe,dY as Ke,V as J,I as Ra,S as Da,M as Ge,i as q,aY as Q,T as D,dZ as Zn,ch as Ee,L as ae,B as F,c1 as xt,dy as Es,d_ as Ze,d$ as Aa,cW as Qe,cX as N,e0 as Qn,E as Mt,e1 as Xe,e2 as Xn,e3 as ft,e4 as eo,e5 as to,e6 as Ia,e7 as Pa,d as Rs,e8 as Ba,e9 as Ds,ea as La,N as gt,eb as Ua,ac as G,ad as fe,ak as oe,ae as Oa,af as $a,ag as As,ah as jt,ai as _a,ay as de,ec as je,D as Oe,ed as Na,bd as Ma,ee,bs as so,ef as Fa,eg as no,eh as oo,ei as le,bv as ao,dh as Ks,ej as io,ek as ro,G as Ft,H as Gt,J as lo,y as we,a_ as co,a$ as uo,b0 as ls,b1 as yt,b2 as Pt,b3 as Pe,bm as Ga,bn as Wa,b4 as Wt,el as za,em as Is,b8 as Zs,en as Bt,eo as qa,ep as Ha,eq as Va,er as Ya,es as Ja,et as cs,m as zt,n as Ka,o as Za,eu as ze,an as Se,ap as ye,bC as ho,cY as qt,ev as po,at as mo,al as me,dd as Be,ew as Ps,bh as Ht,ex as Qa,az as Ne,w as qe,ey as Xa,t as ei,ez as ti,eA as si,eB as Ye,eC as ni,eD as oi,aQ as Vt,eE as Bs,aE as Ls,ar as ai,b as bt,eF as _e,eG as ii,aw as et,cB as Le,eH as ri,eI as li,eJ as ci,eK as di,d7 as Qs,eL as xo,v as ui,as as Us,eM as hi,dg as tt,dv as go,dw as jo,av as fo,eN as Xs,eO as Ue,eP as Je,eQ as en,bZ as pi,cF as yo,eR as bo,bp as So,cG as vo,eS as mi,eT as Co,eU as xi,eV as wo,eW as gi,eX as ji,c_ as fi,eY as yi,eZ as bi,e_ as Si,e$ as To,aj as ko,f0 as vi,ao as St,f1 as tn,f2 as Ci,f3 as Eo,f4 as Lt,f5 as Ro,f6 as wi,c0 as Os,f7 as Ti,f8 as sn,f9 as Yt,fa as ds,fb as ki,fc as Ei,fd as Ri,aT as Do,b5 as Di,fe as Ai,ff as Jt,fg as Ao,fh as Ii,fi as Pi,fj as Bi,fk as Li,au as Kt,fl as Ui,fm as Oi,fn as $i,fo as _i,fp as Ni,fq as Mi,cJ as Fi,fr as Io,K as Po,fs as Bo,aq as Gi,dj as Wi,aA as zi,dl as nn,ft as Lo,fu as Uo,fv as qi,fw as Hi,fx as Vi,fy as Oo,fz as Yi,fA as Ji,fB as Ki,fC as Zi}from"./index-CBxzHo9v.js";import{u as Qi,C as Xi,A as er,a as tr,R as sr,S as nr,T as or,b as ar,c as ir,d as rr,e as lr,E as cr,f as dr,m as ur,g as vt,h as Zt,i as $s}from"./RoleCell-C2bUEPUX.js";import{u as Qt}from"./useApiTokens-CUb6SDEP.js";const hr=()=>{const{tokens:t,loading:s,refetch:n}=Qt(),{deleteToken:o}=Wn(),{headerGroups:a,rows:i,prepareRow:r,state:{globalFilter:c},setGlobalFilter:l,setHiddenColumns:m,columns:p}=Qi(t,d=>{const g=d.row.original.type==="client"?Ys:d.row.original.type==="frontend"?Js:Ae,x=d.row.original.type==="client"?va:d.row.original.type==="frontend"?Ca:Ae;return e.jsxs(Ot,{children:[e.jsx(tr,{token:d.row.original,permission:g}),e.jsx(sr,{token:d.row.original,permission:x,onRemove:async()=>{await o(d.row.original.secret),n()}})]})});return e.jsx(ve,{permissions:[Ys,Js,Ae],children:e.jsx(te,{header:e.jsx(se,{title:`API access (${i.length})`,actions:e.jsxs(e.Fragment,{children:[e.jsx(ce,{initialValue:c,onChange:l}),e.jsx(se.Divider,{}),e.jsx(Xi,{permission:[zn,qn,Ae],path:"/admin/api/create-token"})]})}),children:e.jsx(er,{loading:s,headerGroups:a,setHiddenColumns:m,prepareRow:r,rows:i,columns:p,globalFilter:c})})})},pr=({type:t,projects:s,setProjects:n,errors:o,clearErrors:a})=>{const i=wa("projectId"),{projects:r}=Hn(),c=r.map(l=>({value:l.id,label:l.name}));return i?null:e.jsxs(e.Fragment,{children:[e.jsx(nr,{children:"Which project do you want to give access to?"}),e.jsx(Ta,{disabled:t===or.ADMIN,options:c,defaultValue:s,onChange:n,error:o==null?void 0:o.projects,onFocus:()=>a("projects")})]})},on="Create API token",mr=h(ka)(({theme:t})=>({margin:t.spacing(2,0,4)})),xr=()=>{const{tokens:t,loading:s}=Qt(),{uiConfig:n,loading:o}=H(),a=n.resourceLimits.apiTokens;return{limit:a,currentValue:t.length,limitReached:t.length>=a,loading:o||s}},gr=({modal:t=!1})=>{const{setToastApiError:s}=K(),{uiConfig:n}=H(),o=Ce(),[a,i]=u.useState(!1),[r,c]=u.useState(""),{limit:l,currentValue:m,limitReached:p,loading:d}=xr(),{getApiTokenPayload:g,tokenName:x,type:j,projects:b,environment:y,setTokenName:S,setTokenType:k,setProjects:E,setEnvironment:A,isValid:v,errors:B,clearErrors:L,apiTokenTypes:C}=ar(),{createToken:W,loading:P}=Wn(),{refetch:O}=Qt();$t(on);const T="api/admin/api-tokens",R=async U=>{if(U.preventDefault(),!!v())try{const _=g();await W(_).then(M=>M.json()).then(M=>{ks(),c(M.secret),i(!0),O()})}catch(_){s(V(_))}},I=()=>{i(!1),o(Ie)},$=()=>`curl --location --request POST '${n.unleashUrl}/${T}' \\
--header 'Authorization: INSERT_API_KEY' \\
--header 'Content-Type: application/json' \\
--data-raw '${JSON.stringify(g(),void 0,2)}'`,Y=()=>{o(Ie)};return e.jsxs(ke,{loading:P,title:on,modal:t,description:"Unleash SDKs use API tokens to authenticate to the Unleash API. Client SDKs need a token with 'client privileges', which allows them to fetch feature flag configurations and post usage metrics.",documentationLink:"https://docs.getunleash.io/reference/api-tokens-and-client-keys",documentationLinkLabel:"API tokens documentation",formatApiCode:$,children:[e.jsxs(ir,{handleSubmit:R,handleCancel:Y,mode:"Create",actions:e.jsx(Vn,{name:"token",permission:[Ae,qn,zn],disabled:p||d||P}),children:[e.jsx(rr,{tokenName:x,setTokenName:S,errors:B,clearErrors:L}),e.jsx(lr,{type:j,setType:k,apiTokenTypes:C}),e.jsx(pr,{type:j,projects:b,setProjects:E,errors:B,clearErrors:L}),e.jsx(cr,{type:j,environment:y,setEnvironment:A}),e.jsx(mr,{name:"API tokens",shortName:"tokens",currentValue:m,limit:l})]}),e.jsx(dr,{open:a,setOpen:i,closeConfirm:I,token:r,type:j})]})},jr=h("div")(({theme:t})=>({display:"flex",flexDirection:"column","& > span:last-of-type":{fontSize:t.fontSizes.smallerBody,color:t.palette.text.secondary}})),Xt=({roles:t,value:s,setValue:n,required:o,hideDescription:a,...i})=>{const r=(c,l)=>e.jsx("li",{...c,children:e.jsxs(jr,{children:[e.jsx("span",{children:l.name}),e.jsx("span",{children:l.description})]})});return e.jsxs(e.Fragment,{children:[e.jsx(Yn,{openOnFocus:!0,size:"small",value:s,onChange:(c,l)=>n(l||null),options:t,renderOption:r,getOptionLabel:c=>c.name,renderInput:c=>e.jsx(X,{...c,label:"Role",required:o}),...i}),e.jsx(w,{condition:!!s&&!a,show:()=>e.jsx(Jn,{sx:{marginTop:1},roleId:s.id})})]})},Ct=()=>{const{isEnterprise:t}=H(),{data:s,error:n,mutate:o}=_t(t(),{roles:[],projectRoles:[]},ne("api/admin/roles"),fr);return u.useMemo(()=>({roles:(s==null?void 0:s.roles.filter(({type:a})=>Ea.includes(a)).sort(an))??[],projectRoles:(s==null?void 0:s.roles.filter(({type:a})=>Kn.includes(a)).sort(an))??[],loading:!n&&!s,refetch:()=>o(),error:n}),[s,n,o])},fr=t=>fetch(t).then(ue("Roles")).then(s=>s.json()),an=(t,s)=>Fe.includes(t.type)&&!Fe.includes(s.type)?-1:!Fe.includes(t.type)&&Fe.includes(s.type)?1:t.name.localeCompare(s.name),$o=({data:t={enabled:!1,autoCreate:!1},setValue:s,onUpdateRole:n,disabled:o=!1})=>{const{roles:a}=Ct(),i=()=>{s("autoCreate",!t.autoCreate)},r=l=>{s(l.target.name,l.target.value)},c=({defaultRootRole:l,defaultRootRoleId:m})=>m?a.find(({id:p})=>p===m)||null:a.find(({name:p})=>p===l)||null;return e.jsxs(u.Fragment,{children:[e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"Auto-create users"}),e.jsx("p",{children:"Enable automatic creation of new users when signing in."})]}),e.jsx(f,{item:!0,md:6,style:{padding:"20px"},children:e.jsx(re,{control:e.jsx(ge,{onChange:i,name:"enabled",checked:t.autoCreate,disabled:!t.enabled||o}),label:"Auto-create users"})})]}),e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"Default Root Role"}),e.jsx("p",{children:"Choose which root role the user should get when no explicit role mapping exists."})]}),e.jsx(f,{item:!0,md:6,children:e.jsx(Nt,{style:{width:"400px"},children:e.jsx(Xt,{roles:a,value:c(t),setValue:n,disabled:!t.autoCreate||!t.enabled||o,required:!0,hideDescription:!0})})})]}),e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"Email domains"}),e.jsx("p",{children:"Comma separated list of email domains that should be allowed to sign in."})]}),e.jsx(f,{item:!0,md:6,children:e.jsx(X,{onChange:r,label:"Email domains",name:"emailDomains",disabled:!t.autoCreate||!t.enabled||o,required:!!t.autoCreate,value:t.emailDomains||"",placeholder:"@company.com, @anotherCompany.com",style:{width:"400px"},rows:2,variant:"outlined",size:"small"})})]})]})},yr=async(t,s)=>{var n,o;if(t){if(s){const a=await s.json(),i=((o=(n=a.details)==null?void 0:n[0])==null?void 0:o.message)??a.message;throw t({message:i}),new Error(i)}throw new Error}},es=t=>{const{makeRequest:s,createRequest:n,errors:o,loading:a}=xe({propagateErrors:!0,handleBadRequest:yr});return{updateSettings:async r=>{const c=`api/admin/auth/${t}/settings`,l=n(c,{method:"POST",body:JSON.stringify(r)});await s(l.caller,l.id)},errors:o,loading:a}},_s=t=>{const n=Object.entries(t).filter(([,o])=>o!=="");return Object.fromEntries(n)},_o=({ssoType:t,data:s={enabled:!1,enableGroupSyncing:!1,groupJsonPath:"",addGroupsScope:!1},setValue:n,disabled:o=!1})=>{const a=()=>{n("enableGroupSyncing",!s.enableGroupSyncing)},i=c=>{n(c.target.name,c.target.value)},r=()=>{n("addGroupsScope",!s.addGroupsScope)};return e.jsxs(e.Fragment,{children:[e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"Enable Group Syncing"}),e.jsxs("p",{children:["Enables automatically syncing of users from the"," ",t," provider when a user logs in."]})]}),e.jsx(f,{item:!0,md:6,style:{padding:"20px"},children:e.jsx(re,{control:e.jsx(ge,{onChange:a,value:s.enableGroupSyncing,name:"enableGroupSyncing",checked:s.enableGroupSyncing,disabled:!s.enabled||o}),label:s.enableGroupSyncing?"Enabled":"Disabled"})})]}),e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"Group Field JSON Path"}),e.jsxs("p",{children:["Specifies the path in the ",t," token response from which to read the groups the user belongs to."]})]}),e.jsx(f,{item:!0,md:6,children:e.jsx(X,{onChange:i,label:"Group JSON Path",name:"groupJsonPath",value:s.groupJsonPath,disabled:!s.enableGroupSyncing||o,style:{width:"400px"},variant:"outlined",size:"small",required:!0})})]}),e.jsx(w,{condition:t==="OIDC",show:e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"Request 'groups' Scope"}),e.jsx("p",{children:"When enabled Unleash will also request the 'groups' scope as part of the login request."})]}),e.jsx(f,{item:!0,md:6,style:{padding:"20px"},children:e.jsx(re,{control:e.jsx(ge,{onChange:r,value:s.addGroupsScope,disabled:!s.enableGroupSyncing||o,name:"addGroupsScope",checked:s.addGroupsScope}),label:s.addGroupsScope?"Enabled":"Disabled"})})]})})]})},br={enabled:!1,enableSingleSignOut:!1,addGroupsScope:!1,enableGroupSyncing:!1,autoCreate:!1,unleashHostname:location.hostname,groupJsonPath:"",clientId:"",discoverUrl:"",secret:"",acrValues:"",idTokenSigningAlgorithm:"RS256"},Sr=()=>{const{setToastData:t,setToastApiError:s}=K(),{uiConfig:n}=H(),{oidcConfiguredThroughEnv:o}=n,[a,i]=u.useState(br),{config:r}=Ke("oidc"),{updateSettings:c,errors:l,loading:m}=es("oidc");u.useEffect(()=>{r.discoverUrl&&i(r)},[r]);const p=S=>{j(S.target.name,S.target.value)},d=S=>{j(S.target.name,S.target.value.trim())},g=()=>{i({...a,enabled:!a.enabled})},x=()=>{i({...a,enableSingleSignOut:!a.enableSingleSignOut})},j=(S,k)=>{i({...a,[S]:k})},b=S=>{i({...a,defaultRootRole:void 0,defaultRootRoleId:S==null?void 0:S.id})},y=async S=>{S.preventDefault();try{await c(_s(a)),t({text:"Settings stored",type:"success"})}catch(k){s(V(k))}};return e.jsxs(e.Fragment,{children:[e.jsx(f,{container:!0,sx:{mb:3},children:e.jsxs(f,{item:!0,md:12,children:[e.jsx(w,{condition:!!o,show:e.jsxs(J,{sx:{mb:2},severity:"warning",children:["OIDC is currently configured via environment variables. Please refer to the"," ",e.jsx("a",{href:"https://www.unleash-hosted.com/docs/enterprise-authentication",target:"_blank",rel:"noreferrer",children:"documentation"})," ","for detailed instructions on how to set up OIDC using these variables."]})}),e.jsxs(J,{severity:"info",children:["Please read the"," ",e.jsx("a",{href:"https://www.unleash-hosted.com/docs/enterprise-authentication",target:"_blank",rel:"noreferrer",children:"documentation"})," ","to learn how to integrate with specific OpenID Connect providers (such as Okta and Keycloak). ",e.jsx("br",{}),"Callback URL:"," ",e.jsxs("code",{children:[n.unleashUrl,"/auth/oidc/callback"]})]})]})}),e.jsxs("form",{onSubmit:y,children:[e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"Enable"}),e.jsx("p",{children:"Enable Open Id Connect Authentication."})]}),e.jsx(f,{item:!0,md:6,style:{padding:"20px"},children:e.jsx(re,{control:e.jsx(ge,{onChange:g,value:a.enabled,name:"enabled",checked:a.enabled}),label:a.enabled?"Enabled":"Disabled",disabled:o})})]}),e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"Discover URL"}),e.jsx("p",{children:"(Required) Issuer discover metadata URL"})]}),e.jsx(f,{item:!0,md:6,children:e.jsx(X,{onChange:d,label:"Discover URL",name:"discoverUrl",value:a.discoverUrl,disabled:!a.enabled||o,style:{width:"400px"},variant:"outlined",size:"small"})})]}),e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"Client ID"}),e.jsx("p",{children:"(Required) Client ID of your OpenID application"})]}),e.jsx(f,{item:!0,md:6,children:e.jsx(X,{onChange:d,label:"Client ID",name:"clientId",value:a.clientId,disabled:!a.enabled||o,style:{width:"400px"},variant:"outlined",size:"small",required:!0})})]}),e.jsxs(f,{container:!0,spacing:3,mb:4,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"Client secret"}),e.jsxs("p",{children:["(Required) Client secret of your OpenID application."," "]})]}),e.jsx(f,{item:!0,md:6,children:e.jsx(X,{onChange:d,label:"Client Secret",name:"secret",value:a.secret,disabled:!a.enabled||o,style:{width:"400px"},variant:"outlined",size:"small",required:!0})})]}),e.jsx("h3",{children:"Optional Configuration"}),e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"Enable Single Sign-Out"}),e.jsx("p",{children:"If you enable Single Sign-Out Unleash will redirect the user to the IDP as part of the Sign-out process."})]}),e.jsx(f,{item:!0,md:6,style:{padding:"20px"},children:e.jsx(re,{control:e.jsx(ge,{onChange:x,value:a.enableSingleSignOut,disabled:!a.enabled||o,name:"enableSingleSignOut",checked:a.enableSingleSignOut}),label:a.enableSingleSignOut?"Enabled":"Disabled"})})]}),e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"ACR Values"}),e.jsx("p",{children:'Requested Authentication Context Class Reference values. If multiple values are specified they should be "space" separated. Will be sent as "acr_values" as part of the authentication request. Unleash will validate the acr value in the id token claims against the list of acr values.'})]}),e.jsx(f,{item:!0,md:6,children:e.jsx(X,{onChange:p,label:"ACR Values",name:"acrValues",value:a.acrValues,disabled:!a.enabled||o,style:{width:"400px"},variant:"outlined",size:"small"})})]}),e.jsx(_o,{ssoType:"OIDC",data:a,setValue:j,disabled:o}),e.jsx($o,{data:a,setValue:j,onUpdateRole:b,disabled:o}),e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"ID Signing algorithm"}),e.jsxs("p",{children:["Which signing algorithm to use. ",e.jsx("br",{}),' Leave this alone unless you see errors that look like "unexpected JWT alg received, expected RS256, got: RS512" in your logs.']})]}),e.jsx(f,{item:!0,md:6,children:e.jsxs(Nt,{style:{minWidth:"200px"},children:[e.jsx(Ra,{id:"defaultRootRole-label",children:"Signing algorithm"}),e.jsxs(Da,{label:"Signing algorithm",labelId:"idTokenSigningAlgorithm-label",id:"idTokenSigningAlgorithm",name:"idTokenSigningAlgorithm",value:a.idTokenSigningAlgorithm||"RS256",onChange:S=>j("idTokenSigningAlgorithm",S.target.value),disabled:o,children:[e.jsx(Ge,{value:"RS256",children:"RS256"}),e.jsx(Ge,{value:"RS384",children:"RS384"}),e.jsx(Ge,{value:"RS512",children:"RS512"})]})]})})]}),e.jsx(f,{container:!0,spacing:3,children:e.jsxs(f,{item:!0,md:12,children:[e.jsx(q,{variant:"contained",color:"primary",type:"submit",disabled:m||o,children:"Save"})," ",e.jsx("p",{children:e.jsx("small",{style:{color:"red"},children:l==null?void 0:l.message})})]})})]})]})},vr={enabled:!1,autoCreate:!1,enableGroupSyncing:!1,addGroupsScope:!1,unleashHostname:location.hostname,entityId:"",signOnUrl:"",certificate:"",signOutUrl:"",spCertificate:"",groupJsonPath:""},Cr=()=>{const{setToastData:t,setToastApiError:s}=K(),{uiConfig:n}=H(),{samlConfiguredThroughEnv:o}=n,[a,i]=u.useState(vr),{config:r}=Ke("saml"),{updateSettings:c,errors:l,loading:m}=es("saml");u.useEffect(()=>{r.entityId&&i(r)},[r]);const p=y=>{x(y.target.name,y.target.value)},d=y=>{x(y.target.name,y.target.value.trim())},g=()=>{i({...a,enabled:!a.enabled})},x=(y,S)=>{i({...a,[y]:S})},j=y=>{i({...a,defaultRootRole:void 0,defaultRootRoleId:y==null?void 0:y.id})},b=async y=>{y.preventDefault();try{await c(_s(a)),t({text:"Settings stored",type:"success"})}catch(S){s(V(S))}};return e.jsxs(e.Fragment,{children:[e.jsx(f,{container:!0,sx:{mb:3},children:e.jsxs(f,{item:!0,md:12,children:[e.jsx(w,{condition:!!o,show:e.jsxs(J,{sx:{mb:2},severity:"warning",children:["SAML is currently configured via environment variables. Please refer to the"," ",e.jsx("a",{href:"https://www.unleash-hosted.com/docs/enterprise-authentication",target:"_blank",rel:"noreferrer",children:"documentation"})," ","for detailed instructions on how to set up SAML using these variables."]})}),e.jsxs(J,{severity:"info",children:["Please read the"," ",e.jsx("a",{href:"https://www.unleash-hosted.com/docs/enterprise-authentication",target:"_blank",rel:"noreferrer",children:"documentation"})," ","to learn how to integrate with specific SAML 2.0 providers (such as Okta, Keycloak, and Microsoft Entra ID). ",e.jsx("br",{}),"Callback URL:"," ",e.jsxs("code",{children:[n.unleashUrl,"/auth/saml/callback"]})]})]})}),e.jsxs("form",{onSubmit:b,children:[e.jsxs(f,{container:!0,spacing:3,children:[e.jsxs(f,{item:!0,md:5,mb:2,children:[e.jsx("strong",{children:"Enable"}),e.jsx("p",{children:"Enable SAML 2.0 Authentication."})]}),e.jsx(f,{item:!0,md:6,children:e.jsx(re,{control:e.jsx(ge,{onChange:g,value:a.enabled,name:"enabled",checked:a.enabled,disabled:o}),label:a.enabled?"Enabled":"Disabled"})})]}),e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"Entity ID"}),e.jsx("p",{children:"(Required) The Entity Identity provider issuer."})]}),e.jsx(f,{item:!0,md:6,children:e.jsx(X,{onChange:d,label:"Entity ID",name:"entityId",value:a.entityId,disabled:!a.enabled||o,style:{width:"400px"},variant:"outlined",size:"small",required:!0})})]}),e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"Single Sign-On URL"}),e.jsx("p",{children:"(Required) The url to redirect the user to for signing in."})]}),e.jsx(f,{item:!0,md:6,children:e.jsx(X,{onChange:d,label:"Single Sign-On URL",name:"signOnUrl",value:a.signOnUrl,disabled:!a.enabled||o,style:{width:"400px"},variant:"outlined",size:"small",required:!0})})]}),e.jsxs(f,{container:!0,spacing:3,mb:4,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"X.509 Certificate"}),e.jsx("p",{children:"(Required) The certificate used to sign the SAML 2.0 request."})]}),e.jsx(f,{item:!0,md:7,children:e.jsx(X,{onChange:p,label:"X.509 Certificate",name:"certificate",value:a.certificate,disabled:!a.enabled||o,style:{width:"100%"},InputProps:{style:{fontSize:"0.6em",fontFamily:"monospace"}},multiline:!0,rows:14,maxRows:14,variant:"outlined",size:"small",required:!0})})]}),e.jsx("h3",{children:"Optional Configuration"}),e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"Single Sign-out URL"}),e.jsx("p",{children:"(Optional) The url to redirect the user to for signing out of the IDP."})]}),e.jsx(f,{item:!0,md:6,children:e.jsx(X,{onChange:d,label:"Single Sign-out URL",name:"signOutUrl",value:a.signOutUrl,disabled:!a.enabled||o,style:{width:"400px"},variant:"outlined",size:"small"})})]}),e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"Service Provider X.509 Certificate"}),e.jsx("p",{children:"(Optional) The private certificate used by the Service Provider used to sign the SAML 2.0 request towards the IDP. E.g. used to sign single logout requests (SLO)."})]}),e.jsx(f,{item:!0,md:7,children:e.jsx(X,{onChange:p,label:"X.509 Certificate",name:"spCertificate",value:a.spCertificate,disabled:!a.enabled||o,style:{width:"100%"},InputProps:{style:{fontSize:"0.6em",fontFamily:"monospace"}},multiline:!0,rows:14,maxRows:14,variant:"outlined",size:"small"})})]}),e.jsx(_o,{ssoType:"SAML",data:a,setValue:x,disabled:o}),e.jsx($o,{data:a,setValue:x,onUpdateRole:j,disabled:o}),e.jsx(f,{container:!0,spacing:3,children:e.jsxs(f,{item:!0,md:5,children:[e.jsx(q,{variant:"contained",color:"primary",type:"submit",disabled:m||o,children:"Save"})," ",e.jsx("p",{children:e.jsx("small",{style:{color:"red"},children:l==null?void 0:l.message})})]})})]})]})},wr=h(J)(({theme:t})=>({marginBottom:t.spacing(3)})),Tr=({open:t,setOpen:s,onConfirm:n})=>e.jsx(Q,{open:t,secondaryButtonText:"Close",onClose:(o,a)=>{a||s(!1)},primaryButtonText:"Generate new token",onClick:n,title:"Generate new SCIM API token?",children:e.jsxs(wr,{severity:"error",children:["Generating a new token will ",e.jsx("strong",{children:"immediately revoke"})," the current one, which may break any existing provision integrations currently using it."]})}),kr=h(J)(({theme:t})=>({marginBottom:t.spacing(3)})),Er=({open:t,setOpen:s,token:n})=>e.jsxs(Q,{open:t,secondaryButtonText:"Close",onClose:(o,a)=>{a||s(!1)},title:"SCIM API token created",children:[e.jsx(kr,{severity:"info",children:"Make sure to copy your SCIM API token now. You won't be able to see it again!"}),e.jsx(D,{variant:"body1",children:"Your token:"}),e.jsx(Zn,{token:n||""})]}),rn="api/admin/scim-settings",Rr=()=>{const{loading:t,makeRequest:s,createRequest:n,errors:o}=xe({propagateErrors:!0});return{saveSettings:async r=>{const l=n(rn,{method:"POST",body:JSON.stringify(r)},"saveSettings");await s(l.caller,l.id)},generateNewToken:async()=>{const c=n(`${rn}/generate-new-token`,{method:"POST"},"generateNewToken"),l=await s(c.caller,c.id),{token:m}=await l.json();return m},errors:o,loading:t}},Dr="api/admin/scim-settings",ln={enabled:!1,hasToken:!1},wt=()=>{const{isEnterprise:t}=H(),{data:s,error:n,mutate:o}=_t(t(),ln,ne(Dr),Ar);return u.useMemo(()=>({settings:s??ln,loading:!n&&!s,refetch:()=>o(),error:n}),[s,n,o])},Ar=t=>fetch(t).then(ue("SCIM settings")).then(s=>s.json());h(J)(({theme:t})=>({marginBottom:t.spacing(3)}));const cn=({open:t,closeDialog:s,deleteEntities:n,entityType:o})=>e.jsx(Q,{open:t,primaryButtonText:`Delete SCIM ${o}`,secondaryButtonText:"Cancel",title:`Do you really want to delete ALL SCIM ${o}?`,onClose:s,onClick:n,children:e.jsxs(D,{variant:"body1",children:["This will delete all ",o.toLocaleLowerCase()," created or managed by SCIM."]})}),Ut="removeUser",He=()=>{const{loading:t,makeRequest:s,createRequest:n,errors:o}=xe({propagateErrors:!0});return{addUser:async d=>{const x=n("api/admin/user-admin",{method:"POST",body:JSON.stringify(d)},"addUser");return s(x.caller,x.id)},updateUser:async d=>{const x=n(`api/admin/user-admin/${d.id}`,{method:"PUT",body:JSON.stringify(d)},"updateUser");return s(x.caller,x.id)},removeUser:async d=>{const x=n(`api/admin/user-admin/${d}`,{method:"DELETE"},"removeUser");return s(x.caller,x.id)},changePassword:async(d,g)=>{const j=n(`api/admin/user-admin/${d}/change-password`,{method:"POST",body:JSON.stringify({password:g})},"changePassword");return s(j.caller,j.id)},validatePassword:async d=>{const x=n("api/admin/user-admin/validate-password",{method:"POST",body:JSON.stringify({password:d})},"validatePassword");return s(x.caller,x.id)},resetPassword:async d=>{const x=n("api/admin/user-admin/reset-password",{method:"POST",body:JSON.stringify({id:d})},"resetPassword");return s(x.caller,x.id)},deleteScimUsers:async()=>{const g=n("api/admin/user-admin/scim-users",{method:"DELETE"},"deleteScimUsers");return s(g.caller,g.id)},userApiErrors:o,userLoading:t}},st=()=>{const{makeRequest:t,createRequest:s,errors:n,loading:o}=xe({propagateErrors:!0});return{createGroup:async l=>{const p=s("api/admin/groups",{method:"POST",body:JSON.stringify(l)});return(await t(p.caller,p.id)).json()},updateGroup:async(l,m)=>{const p=`api/admin/groups/${l}`,d=s(p,{method:"PUT",body:JSON.stringify(m)});await t(d.caller,d.id)},removeGroup:async l=>{const m=`api/admin/groups/${l}`,p=s(m,{method:"DELETE"});await t(p.caller,p.id)},deleteScimGroups:async()=>{const m=s("api/admin/groups/scim-groups",{method:"DELETE"});await t(m.caller,m.id)},errors:n,loading:o}},Ir=h("div")(({theme:t})=>({padding:t.spacing(3),border:`1px solid ${t.palette.divider}`,borderRadius:t.shape.borderRadiusLarge})),us=h("div")(({theme:t})=>({marginBottom:t.spacing(1)})),Pr=()=>{const{uiConfig:t}=H(),{setToastData:s,setToastApiError:n}=K(),[o,a]=u.useState(""),[i,r]=u.useState(!1),[c,l]=u.useState(!1),[m,p]=u.useState(!1),[d,g]=u.useState(!1),{settings:x,refetch:j}=wt(),{deleteScimUsers:b}=He(),{deleteScimGroups:y}=st(),[S,k]=u.useState(x.enabled??!0);u.useEffect(()=>{k(x.enabled??!1)},[x]);const{saveSettings:E,generateNewToken:A,errors:v,loading:B}=Rr(),L=async()=>{r(!0)},C=async()=>{try{await y(),s({text:"Scim Groups have been deleted",type:"success"}),l(!1),j()}catch(T){n(V(T))}},W=async()=>{try{await b(),s({text:"Scim Users have been deleted",type:"success"}),p(!1),j()}catch(T){n(V(T))}},P=async()=>{r(!1);const T=await A();a(T),g(!0)},O=async T=>{try{if(k(T),await E({enabled:T}),T&&!x.hasToken){const R=await A();a(R),g(!0)}s({text:"Settings stored",type:"success"}),await j()}catch(R){n(V(R))}};return e.jsxs(e.Fragment,{children:[e.jsx(f,{container:!0,sx:{mb:3},children:e.jsx(f,{item:!0,md:12,children:e.jsxs(J,{severity:"info",children:["Please read the"," ",e.jsx("a",{href:"https://docs.getunleash.io/reference/scim",target:"_blank",rel:"noreferrer",children:"documentation"})," ","to learn how to integrate with specific SCIM clients (Microsoft Entra, Okta, etc). ",e.jsx("br",{}),"SCIM API URL: ",e.jsxs("code",{children:[t.unleashUrl,"/scim"]})]})})}),e.jsxs(Ir,{children:[e.jsxs(f,{container:!0,spacing:3,children:[e.jsxs(f,{item:!0,md:10.5,mb:2,children:[e.jsx(us,{children:e.jsx("strong",{children:"SCIM provisioning"})}),e.jsx("p",{children:"Enables SCIM provisioning. If SCIM provisioning has not previously been enabled here this will also set up a new auth token to use with your SCIM client, and display it to the user. After the dialog has been closed, this token will not be displayed again. If you need a new token you can click the Generate new token button below which will replace the old token with a new token, and similarly display the new token one time to the user."})]}),e.jsx(f,{item:!0,md:1.5,children:e.jsx(re,{control:e.jsx(ge,{onChange:(T,R)=>{O(R)},value:S,name:"enabled",checked:S}),label:S?"Enabled":"Disabled"})})]}),e.jsx(f,{container:!0,spacing:3,children:e.jsx(f,{item:!0,md:5,mb:2,children:e.jsx(w,{condition:!!x.hasToken,show:e.jsx(q,{variant:"outlined",color:"error",disabled:B,onClick:L,children:"Generate new token"})})})}),e.jsxs(f,{container:!0,spacing:3,children:[e.jsxs(f,{item:!0,md:10.5,mb:2,children:[e.jsx(us,{children:e.jsx("strong",{children:"Delete SCIM Users"})}),e.jsx("p",{children:"This will remove all SCIM users from the Unleash database. This action cannot be undone through Unleash but the upstream SCIM provider may re sync these users."})]}),e.jsx(f,{item:!0,md:1.5,children:e.jsx(q,{variant:"outlined",color:"error",disabled:B,onClick:()=>{p(!0)},children:"Delete Users"})}),e.jsxs(f,{item:!0,md:10.5,mb:2,children:[e.jsx(us,{children:e.jsx("strong",{children:"Delete SCIM Groups"})}),e.jsx("p",{children:"This will remove all SCIM groups from the Unleash database. This action cannot be undone through Unleash but the upstream SCIM provider may re sync these groups. Note that this may affect the permissions of users present in those groups."})]}),e.jsx(f,{item:!0,md:1.5,children:e.jsx(q,{variant:"outlined",color:"error",disabled:B,onClick:()=>{l(!0)},children:"Delete Groups"})})]}),e.jsx(Tr,{open:i,setOpen:r,onConfirm:P}),e.jsx(Er,{open:d,setOpen:g,token:o}),e.jsx(cn,{open:m,closeDialog:()=>p(!1),deleteEntities:W,entityType:"Users"}),e.jsx(cn,{open:c,closeDialog:()=>l(!1),deleteEntities:C,entityType:"Groups"})]})]})},Br=()=>{const{data:t,error:s,mutate:n}=Ee(ne("api/admin/user-admin/admin-count"),Lr);return{data:t,loading:!s&&!t,refetch:()=>n(),error:s}},Lr=t=>fetch(t).then(ue("Admin count")).then(s=>s.json()),Ur=({open:t,setOpen:s,onClick:n,adminCount:o,tokens:a})=>e.jsxs(Q,{open:t,onClose:()=>{s(!1)},onClick:n,title:"Disable password based login?",primaryButtonText:"Disable password based login",secondaryButtonText:"Cancel",children:[e.jsxs(J,{severity:"warning",children:[e.jsx("strong",{children:"Warning!"})," Disabling password based login may lock you out of the system permanently if you do not have any alternative admin credentials (such as an admin SSO account or admin API token) secured beforehand.",e.jsx("br",{}),e.jsx("br",{}),e.jsx("strong",{children:"Password based administrators: "})," ",o==null?void 0:o.password,e.jsx("br",{}),e.jsx("strong",{children:"Other administrators: "})," ",o==null?void 0:o.noPassword,e.jsx("br",{}),e.jsx("strong",{children:"Admin service accounts: "})," ",o==null?void 0:o.service,e.jsx("br",{}),e.jsx("strong",{children:"Admin API tokens: "})," ",a.filter(({type:i})=>i==="admin").length]}),e.jsx(D,{sx:{mt:3},children:"You are about to disable password based login. Are you sure you want to proceed?"})]}),Or=()=>{const{setToastData:t,setToastApiError:s}=K(),{config:n,refetch:o}=Ke("simple"),[a,i]=u.useState(!1),{updateSettings:r,errors:c,loading:l}=es("simple"),[m,p]=u.useState(!1),{data:d}=Br(),{tokens:g}=Qt();u.useEffect(()=>{i(!!n.disabled)},[n.disabled]);const x=()=>{i(!a)},j=async y=>{y.preventDefault(),!n.disabled&&a?p(!0):b()},b=async()=>{try{await r({disabled:a}),o(),t({text:"Password authentication settings stored",autoHideDuration:4e3,type:"success",show:!0})}catch(y){s(V(y)),i(n.disabled)}};return e.jsx(e.Fragment,{children:e.jsxs("form",{onSubmit:j,children:[e.jsxs(J,{severity:"info",sx:{mb:3},children:["Overview of administrators on your Unleash instance:",e.jsx("br",{}),e.jsx("br",{}),e.jsx("strong",{children:"Password based administrators: "})," ",e.jsx(ae,{to:"/admin/users",children:d==null?void 0:d.password}),e.jsx("br",{}),e.jsx("strong",{children:"Other administrators: "})," ",e.jsx(ae,{to:"/admin/users",children:d==null?void 0:d.noPassword}),e.jsx("br",{}),e.jsx("strong",{children:"Admin service accounts: "})," ",e.jsx(ae,{to:"/admin/service-accounts",children:d==null?void 0:d.service}),e.jsx("br",{}),e.jsx("strong",{children:"Admin API tokens: "})," ",e.jsx(ae,{to:"/admin/api",children:g.filter(({type:y})=>y==="admin").length})]}),e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"Password based login"}),e.jsx("p",{children:"Allow users to login with username & password"})]}),e.jsx(f,{item:!0,md:6,style:{padding:"20px"},children:e.jsx(re,{control:e.jsx(ge,{onChange:x,value:!a,name:"disabled",checked:!a}),label:a?"Disabled":"Enabled"})})]}),e.jsx(f,{container:!0,spacing:3,children:e.jsxs(f,{item:!0,md:12,children:[e.jsx(q,{variant:"contained",color:"primary",type:"submit",disabled:l,children:"Save"})," ",e.jsx("p",{children:e.jsx("small",{style:{color:"red"},children:c==null?void 0:c.message})})]})}),e.jsx(Ur,{open:m,setOpen:p,onClick:()=>{p(!1),b()},adminCount:d,tokens:g})]})})},$r={enabled:!1,autoCreate:!1,unleashHostname:location.hostname,clientId:"",clientSecret:"",emailDomains:""},_r=()=>{const{setToastData:t,setToastApiError:s}=K(),{uiConfig:n}=H(),[o,a]=u.useState($r),{config:i}=Ke("google"),{updateSettings:r,errors:c,loading:l}=es("google");u.useEffect(()=>{i.clientId&&a(i)},[i]);const m=x=>{a({...o,[x.target.name]:x.target.value})},p=()=>{a({...o,enabled:!o.enabled})},d=()=>{a({...o,autoCreate:!o.autoCreate})},g=async x=>{x.preventDefault();try{await r(_s(o)),t({text:"Settings stored",type:"success"})}catch(j){s(V(j))}};return e.jsxs(e.Fragment,{children:[e.jsxs(F,{children:[e.jsxs(J,{severity:"error",sx:{mb:2},children:["This integration is deprecated and will be removed in next major version. Please use ",e.jsx("strong",{children:"OpenID Connect"})," to enable Google SSO."]}),e.jsxs(J,{severity:"info",sx:{mb:3},children:["Read the"," ",e.jsx("a",{href:"https://www.unleash-hosted.com/docs/enterprise-authentication/google",target:"_blank",rel:"noreferrer",children:"documentation"})," ","to learn how to integrate with Google OAuth 2.0. ",e.jsx("br",{}),"Callback URL:"," ",e.jsxs("code",{children:[n.unleashUrl,"/auth/google/callback"]})]})]}),e.jsxs("form",{onSubmit:g,children:[e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,xs:5,children:[e.jsx("strong",{children:"Enable"}),e.jsx("p",{children:"Enable Google users to login. Value is ignored if Client ID and Client Secret are not defined."})]}),e.jsx(f,{item:!0,xs:6,style:{padding:"20px"},children:e.jsx(re,{control:e.jsx(ge,{onChange:p,value:o.enabled,name:"enabled",checked:o.enabled}),label:o.enabled?"Enabled":"Disabled"})})]}),e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,xs:5,children:[e.jsx("strong",{children:"Client ID"}),e.jsx("p",{children:"(Required) The Client ID provided by Google when registering the application."})]}),e.jsx(f,{item:!0,xs:6,children:e.jsx(X,{onChange:m,label:"Client ID",name:"clientId",placeholder:"",value:o.clientId,style:{width:"400px"},variant:"outlined",size:"small",required:!0})})]}),e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"Client Secret"}),e.jsx("p",{children:"(Required) Client Secret provided by Google when registering the application."})]}),e.jsx(f,{item:!0,md:6,children:e.jsx(X,{onChange:m,label:"Client Secret",name:"clientSecret",value:o.clientSecret,placeholder:"",style:{width:"400px"},variant:"outlined",size:"small",required:!0})})]}),e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"Unleash hostname"}),e.jsxs("p",{children:["(Required) The hostname you are running Unleash on that Google should send the user back to. The final callback URL will be"," ",e.jsx("small",{children:e.jsx("code",{children:"https://[unleash.hostname.com]/auth/google/callback"})})]})]}),e.jsx(f,{item:!0,md:6,children:e.jsx(X,{onChange:m,label:"Unleash Hostname",name:"unleashHostname",placeholder:"",value:o.unleashHostname||"",style:{width:"400px"},variant:"outlined",size:"small"})})]}),e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"Auto-create users"}),e.jsx("p",{children:"Enable automatic creation of new users when signing in with Google."})]}),e.jsx(f,{item:!0,md:6,style:{padding:"20px"},children:e.jsx(ge,{onChange:d,name:"enabled",checked:o.autoCreate})})]}),e.jsxs(f,{container:!0,spacing:3,mb:2,children:[e.jsxs(f,{item:!0,md:5,children:[e.jsx("strong",{children:"Email domains"}),e.jsx("p",{children:"(Optional) Comma separated list of email domains that should be allowed to sign in."})]}),e.jsx(f,{item:!0,md:6,children:e.jsx(X,{onChange:m,label:"Email domains",name:"emailDomains",value:o.emailDomains,placeholder:"@company.com, @anotherCompany.com",style:{width:"400px"},rows:2,multiline:!0,variant:"outlined",size:"small"})})]}),e.jsx(f,{container:!0,spacing:3,children:e.jsxs(f,{item:!0,md:5,children:[e.jsx(q,{variant:"contained",color:"primary",type:"submit",disabled:l,children:"Save"})," ",e.jsx("p",{children:e.jsx("small",{style:{color:"error.dark"},children:c==null?void 0:c.message})})]})})]})]})},Nr=()=>{var i;const{isEnterprise:t}=H(),s=xt("googleAuthEnabled"),n=[{label:"Single sign-on: OpenID Connect",path:"/admin/auth/oidc"},{label:"Single sign-on: SAML 2.0",path:"/admin/auth/saml"},{label:"Password login",path:"/admin/auth/password"},{label:"Single sign-on: Google",path:"/admin/auth/google"},{label:"Single sign-on: SCIM",path:"/admin/auth/scim"}],{pathname:o}=Es(),a=((i=n.find(r=>o===r.path))==null?void 0:i.label)||"Single sign-on: OpenID Connect";return $t(a),t()?e.jsx("div",{children:e.jsx(ve,{permissions:[Ae,Aa],children:e.jsx(te,{header:a,children:e.jsxs(Qe,{children:[e.jsx(N,{path:"/",index:!0,element:e.jsx(Qn,{to:"/admin/auth/oidc"})}),e.jsx(N,{path:"/oidc",index:!0,element:e.jsx(Sr,{})}),e.jsx(N,{path:"/saml",element:e.jsx(Cr,{})}),e.jsx(N,{path:"/password",element:e.jsx(Or,{})}),s&&e.jsx(N,{path:"/google",element:e.jsx(_r,{})}),e.jsx(N,{path:"/scim",element:e.jsx(Pr,{})})]})})})}):e.jsx(Ze,{feature:"sso",page:!0})},Mr=ne("api/admin/invoices"),Fr=h(q)(({theme:t})=>({width:"100%",marginBottom:t.spacing(1.5)})),Gr=({update:t})=>e.jsx(Fr,{href:`${Mr}/${t?"portal":"checkout"}`,variant:t?"outlined":"contained",children:t?"Update billing information":"Add billing information"}),dn=h("aside")(({theme:t})=>({padding:t.spacing(4),height:"100%",borderRadius:t.shape.borderRadiusLarge,backgroundColor:t.palette.background.elevation2})),Wr=h(D)(({theme:t})=>({marginBottom:t.spacing(4)})),zr=h(J)(({theme:t})=>({marginBottom:t.spacing(4)})),hs=h(D)(({theme:t})=>({fontSize:t.fontSizes.smallBody,color:t.palette.text.secondary})),qr=h(Mt)(({theme:t})=>({margin:`${t.spacing(2.5)} 0`,borderColor:t.palette.divider})),Hr=()=>{const{instanceStatus:t}=Xe(),{uiConfig:{billing:s}}=H(),n=s==="pay-as-you-go";if(!t)return e.jsx(f,{item:!0,xs:12,md:5,children:e.jsx(dn,{"data-loading":!0,sx:{flex:1,height:"400px"}})});const o=`${t.plan}${n?" Pay-as-You-Go":""}`,a=t.state!==Xn.ACTIVE,{isCustomBilling:i}=t;return e.jsx(f,{item:!0,xs:12,md:5,children:e.jsxs(dn,{children:[e.jsx(Wr,{variant:"body1",children:"Billing information"}),e.jsx(w,{condition:!!i,show:e.jsx(hs,{children:"Your billing is managed by Unleash"}),elseShow:e.jsxs(e.Fragment,{children:[e.jsx(w,{condition:a,show:e.jsxs(zr,{severity:"warning",children:["In order to"," ",e.jsx("strong",{children:"Upgrade trial"})," you need to provide us your billing information."]})}),e.jsx(Gr,{update:!a}),e.jsx(hs,{children:a?"Once we have received your billing information we will upgrade your trial within 1 business day":"Update your credit card and business information and change which email address we send invoices to"})]})}),e.jsx(qr,{}),e.jsxs(hs,{children:[e.jsx("a",{href:`mailto:support@getunleash.io?subject=${o} plan clarifications`,children:"Get in touch with us"})," ","for any clarification"]})]})})},Vr=h(f)(({theme:t})=>({flexWrap:"nowrap",gap:t.spacing(1)})),Te=({sx:t,children:s})=>e.jsx(Vr,{container:!0,item:!0,justifyContent:"space-between",alignItems:"center",sx:t,children:s}),ie=({children:t,vertical:s=!1})=>e.jsx(f,{container:s,item:!0,display:"flex",alignItems:s?"start":"center",direction:s?"column":void 0,children:t}),Yr=h("span")(({theme:t})=>({fontSize:t.fontSizes.smallBody,marginLeft:t.spacing(1)})),pt=({children:t})=>e.jsxs(Yr,{children:["(",t,")"]}),be=()=>{const{data:t,error:s,mutate:n}=Ee(ne("api/admin/user-admin"),Jr);return u.useMemo(()=>({users:(t==null?void 0:t.users)??[],roles:(t==null?void 0:t.rootRoles)??[],loading:!s&&!t,refetch:()=>n(),error:s}),[t,s,n])},Jr=t=>fetch(t).then(ue("Users")).then(s=>s.json()),No=new Date,am=ft(No,"yyyy-MM");eo(No);const im=t=>ft(t,"yyyy-MM"),rm=t=>ft(t,"yyyy-MM-dd"),lm=t=>to(t,"yyyy-MM",new Date),Kr=t=>to(t,"yyyy-MM-dd",new Date),Ns=5,Ms=1e6,Zr=Kr("2024-05-01"),Qr=["/api/admin","/api/frontend","/api/client"],Xr=t=>{const{apiData:s,...n}=t;return{apiData:s.filter(a=>Qr.includes(a.apiPath)).map(a=>(a.dataPoints=a.dataPoints.filter(({period:i})=>new Date(i)>=Zr),a)),...n}},el=(t,s)=>t.reduce((n,o)=>{const a=o.dataPoints.find(({period:r})=>r===s),i=(a==null?void 0:a.trafficTypes.reduce((r,c)=>r+c.count,0))??0;return n+i},0),Mo=t=>t.flatMap(s=>s.dataPoints.flatMap(n=>n.trafficTypes.map(o=>o.count))).reduce((s,n)=>s+n,0),tl=t=>{const{grouping:s,apiData:n}=t;if(s==="monthly"){const o=ft(new Date(t.dateRange.to),"yyyy-MM");return el(n,o)}else return Mo(n)},sl=(t,s=Ns,n=Ms)=>Math.ceil(t/n)*s,Fo=(t,s,n=Ns,o=Ms)=>{if(t===0)return 0;const a=Math.floor((t-s)/o)*o;return a>0?sl(a,n,o):0},nl=({dayOfMonth:t,daysInMonth:s,trafficData:n})=>{if(t<5)return 0;const o=n.map(i=>({...i,dataPoints:i.dataPoints.filter(r=>Number(r.period.slice(-2))<t)}));return Mo(o)/(t-1)*s},cm=(t,s,n,o=Ns,a=Ms)=>{if(!t)return 0;const i=n.getDate(),r=eo(n),c=nl({dayOfMonth:i,daysInMonth:r,trafficData:t});return Fo(c,s,o,a)},ol=(t,{from:s,to:n})=>{const o=`api/admin/metrics/traffic?grouping=${t}&from=${s}&to=${n}`,{data:a,error:i,mutate:r}=Ee(ne(o),al);return u.useMemo(()=>{const c=a?{state:"success",data:Xr(a)}:i?{state:"error",error:i}:{state:"loading"};return{refetch:()=>r(),result:c}},[a,i,r])},al=t=>fetch(t).then(ue("Instance Metrics")).then(s=>s.json()),Go=t=>{var m,p;const s=new Date,n=d=>ft(d,"yyyy-MM-dd"),o=n(Ia(s)),a=n(Pa(s)),{instanceStatus:i}=Xe(),r=((p=(m=i==null?void 0:i.prices)==null?void 0:m[(i==null?void 0:i.billing)==="pay-as-you-go"?"payg":"pro"])==null?void 0:p.traffic)??Fs,{result:c}=ol("daily",{from:o,to:a});return u.useMemo(()=>{if(c.state!=="success")return 0;const d=tl(c.data);return Fo(d,t,r)},[t,JSON.stringify(c),r])},ps=h(D)(({theme:t})=>({fontSize:t.fontSizes.smallBody,color:t.palette.text.secondary})),il=h(Rs)(({theme:t})=>({fontSize:"1rem",marginRight:t.spacing(1)})),rl=h(Mt)(({theme:t})=>({margin:`${t.spacing(3)} 0`})),ll=({instanceStatus:t})=>{var x,j,b,y,S,k;const{users:s,loading:n}=be(),o=s.filter(E=>E.email),a=((j=(x=t.prices)==null?void 0:x.pro)==null?void 0:j.base)??Wo,i=((y=(b=t.prices)==null?void 0:b.pro)==null?void 0:y.seat)??zo,r=((k=(S=t.prices)==null?void 0:S.pro)==null?void 0:k.traffic)??Fs,c=qo,l=Math.min(o.length,c),m=o.length-l,p=i*m,d=Go(Ho),g=a+p+d;return n?null:e.jsxs(e.Fragment,{children:[e.jsxs(f,{container:!0,children:[e.jsxs(Te,{sx:E=>({marginBottom:E.spacing(1.5)}),children:[e.jsxs(ie,{vertical:!0,children:[e.jsxs(D,{children:[e.jsx("strong",{children:"Included members"}),e.jsx(pt,{children:e.jsxs(ae,{to:"/admin/users",children:[l," of ",c," assigned"]})})]}),e.jsxs(ps,{children:["You have ",c," team members included in your PRO plan"]})]}),e.jsxs(ie,{children:[e.jsx(il,{}),e.jsx(D,{variant:"body2",children:"included"})]})]}),e.jsxs(Te,{sx:E=>({marginBottom:E.spacing(1.5)}),children:[e.jsxs(ie,{vertical:!0,children:[e.jsxs(D,{children:[e.jsx("strong",{children:"Paid members"}),e.jsx(pt,{children:e.jsxs(ae,{to:"/admin/users",children:[m," assigned"]})})]}),e.jsxs(ps,{children:["$",i,"/month per paid member"]})]}),e.jsx(ie,{children:e.jsxs(D,{sx:E=>({fontSize:E.fontSizes.mainHeader}),children:["$",p.toFixed(2)]})})]}),e.jsx(w,{condition:d>0,show:e.jsxs(Te,{children:[e.jsxs(ie,{vertical:!0,children:[e.jsxs(D,{children:[e.jsx("strong",{children:"Accrued traffic charges"}),e.jsx(pt,{children:e.jsx(ae,{to:"/admin/network/data-usage",children:"view details"})})]}),e.jsxs(ps,{children:["$",r," per 1 million started above included data"]})]}),e.jsx(ie,{children:e.jsxs(D,{sx:E=>({fontSize:E.fontSizes.mainHeader}),children:["$",d.toFixed(2)]})})]})})]}),e.jsx(rl,{}),e.jsx(f,{container:!0,children:e.jsxs(Te,{children:[e.jsx(ie,{children:e.jsx(D,{sx:E=>({fontWeight:E.fontWeight.bold,fontSize:E.fontSizes.mainHeader}),children:"Total"})}),e.jsx(ie,{children:e.jsxs(D,{sx:E=>({fontWeight:E.fontWeight.bold,fontSize:"2rem"}),children:["$",g.toFixed(2)]})})]})})]})},un=h(D)(({theme:t})=>({fontSize:t.fontSizes.smallBody,color:t.palette.text.secondary})),cl=h(Mt)(({theme:t})=>({margin:`${t.spacing(3)} 0`})),dl=({instanceStatus:t})=>{var d,g,x,j;const{users:s,loading:n}=be(),o=s.filter(b=>b.email),a=((g=(d=t.prices)==null?void 0:d.payg)==null?void 0:g.seat)??ml,i=((j=(x=t.prices)==null?void 0:x.payg)==null?void 0:j.traffic)??Fs,r=t.minSeats??xl,c=Math.max(o.length,r),l=a*c,m=Go(Ho),p=l+m;return n?null:e.jsxs(e.Fragment,{children:[e.jsxs(f,{container:!0,children:[e.jsxs(Te,{sx:b=>({marginBottom:b.spacing(1.5)}),children:[e.jsxs(ie,{vertical:!0,children:[e.jsxs(D,{children:[e.jsx("strong",{children:"Paid members"}),e.jsx(pt,{children:e.jsxs(ae,{to:"/admin/users",children:[o.length," assigned of"," ",r," minimum"]})})]}),e.jsxs(un,{children:["$",a,"/month per paid member"]})]}),e.jsx(ie,{children:e.jsxs(D,{sx:b=>({fontSize:b.fontSizes.mainHeader}),children:["$",l.toFixed(2)]})})]}),e.jsx(w,{condition:m>0,show:e.jsxs(Te,{children:[e.jsxs(ie,{vertical:!0,children:[e.jsxs(D,{children:[e.jsx("strong",{children:"Accrued traffic charges"}),e.jsx(pt,{children:e.jsx(ae,{to:"/admin/network/data-usage",children:"view details"})})]}),e.jsxs(un,{children:["$",i," per 1 million started above included data"]})]}),e.jsx(ie,{children:e.jsxs(D,{sx:b=>({fontSize:b.fontSizes.mainHeader}),children:["$",m.toFixed(2)]})})]})})]}),e.jsx(cl,{}),e.jsx(f,{container:!0,children:e.jsxs(Te,{children:[e.jsx(ie,{children:e.jsx(D,{sx:b=>({fontWeight:b.fontWeight.bold,fontSize:b.fontSizes.mainHeader}),children:"Total"})}),e.jsx(ie,{children:e.jsxs(D,{sx:b=>({fontWeight:b.fontWeight.bold,fontSize:"2rem"}),children:["$",p.toFixed(2)]})})]})})]})};h(D)(({theme:t})=>({fontSize:t.fontSizes.smallerBody,color:t.palette.text.secondary}));const ul=h(q)(({theme:t})=>({marginTop:t.spacing(1),display:"inline-flex",alignItems:"center"})),hl=()=>{const t=ne("api/admin/invoices/portal");return e.jsx(e.Fragment,{children:e.jsx(f,{container:!0,children:e.jsx(Te,{sx:s=>({marginBottom:s.spacing(3)}),children:e.jsx(ie,{vertical:!0,children:e.jsx(ul,{href:t,variant:"outlined",endIcon:e.jsx(Ba,{}),children:"View usage charges"})})})})})},pl=({instanceStatus:t,isPAYG:s,isEnterpriseConsumption:n})=>s?e.jsx(dl,{instanceStatus:t}):t.plan===Ds.PRO?e.jsx(ll,{instanceStatus:t}):n?e.jsx(hl,{}):null,Wo=80,zo=15,ml=75,Fs=5,xl=5,qo=5,Ho=53e6,hn=h("aside")(({theme:t})=>({padding:t.spacing(2.5),height:"100%",borderRadius:t.shape.borderRadiusLarge,boxShadow:t.boxShadows.elevated,[t.breakpoints.up("md")]:{padding:t.spacing(6.5)}})),gl=h("span")(({theme:t})=>({fontSize:"3.25rem",lineHeight:1,color:t.palette.primary.main,fontWeight:800,marginRight:t.spacing(1.5)})),jl=h("span")(({theme:t})=>({fontWeight:t.fontWeight.bold})),fl=h("span")(({theme:t})=>({fontWeight:t.fontWeight.bold})),yl=h("span")(({theme:t})=>({color:t.palette.primary.main,fontSize:t.fontSizes.mainHeader,fontWeight:t.fontWeight.bold})),bl=h(J)(({theme:t})=>({fontSize:t.fontSizes.smallerBody,marginBottom:t.spacing(3),marginTop:t.spacing(-1.5),[t.breakpoints.up("md")]:{marginTop:t.spacing(-4.5)}})),Sl=()=>{var m,p;const{uiConfig:{billing:t}}=H(),{instanceStatus:s}=Xe(),n=(s==null?void 0:s.plan)&&(s==null?void 0:s.plan)===Ds.PRO,o=t==="pay-as-you-go",a=t==="enterprise-consumption";if(!s)return e.jsx(f,{item:!0,xs:12,md:7,children:e.jsx(hn,{"data-loading":!0,sx:{flex:1,height:"400px"}})});const i=La(s),r=((p=(m=s.prices)==null?void 0:m.pro)==null?void 0:p.base)??Wo,c=`${s.plan}${o?" Pay-as-You-Go":""}`,l=s.state!==Xn.ACTIVE;return e.jsx(f,{item:!0,xs:12,md:7,children:e.jsxs(hn,{children:[e.jsx(w,{condition:l,show:e.jsxs(bl,{severity:"info",children:["After you have sent your billing information, your instance will be upgraded - you don't have to do anything."," ",e.jsx("a",{href:`mailto:support@getunleash.io?subject=${c} plan clarifications`,children:"Get in touch with us"})," ","for any clarification"]})}),e.jsx(gt,{color:"success",children:"Current plan"}),e.jsxs(f,{container:!0,sx:d=>({marginBottom:d.spacing(3)}),children:[e.jsxs(Te,{children:[e.jsxs(ie,{children:[e.jsx(gl,{children:s.plan}),e.jsx(w,{condition:Ua(s),show:e.jsx(fl,{sx:d=>({color:i?d.palette.error.dark:d.palette.warning.dark}),children:i?"Trial expired":s.trialExtended?"Extended Trial":"Trial"})})]}),e.jsx(ie,{children:e.jsx(w,{condition:!!n,show:e.jsxs(yl,{children:["$",r.toFixed(2)]})})})]}),e.jsx(Te,{children:e.jsx(w,{condition:o||a,show:e.jsxs(jl,{children:["Pay-as-You-Go"," ",a?"Consumption":""]})})})]}),e.jsx(pl,{instanceStatus:s,isPAYG:o,isEnterpriseConsumption:a})]})})},vl=()=>e.jsxs(f,{container:!0,spacing:4,children:[e.jsx(Hr,{}),e.jsx(Sl,{})]}),Cl=h(D)(({theme:t})=>({marginTop:t.spacing(6),marginBottom:t.spacing(2.5),fontSize:t.fontSizes.mainHeader})),wl=[{Header:"Amount",accessor:"amountFormatted"},{Header:"Status",accessor:"status",disableGlobalFilter:!0},{Header:"Created date",accessor:"created",Cell:je,disableGlobalFilter:!0},{Header:"Due date",accessor:"dueDate",Cell:je,disableGlobalFilter:!0},{Header:"Download",accessor:"invoicePDF",align:"center",Cell:({value:t})=>e.jsx(F,{sx:{display:"flex",justifyContent:"center"},"data-loading":!0,children:e.jsx(Oe,{href:t,children:e.jsx(Na,{})})}),width:100,disableGlobalFilter:!0,disableSortBy:!0}],Tl=({data:t,isLoading:s=!1})=>{const n=u.useMemo(()=>({sortBy:[{id:"created",desc:!0}]}),[]),{getTableProps:o,getTableBodyProps:a,headerGroups:i,rows:r,prepareRow:c}=G.useTable({columns:wl,data:t,initialState:n,sortTypes:fe,autoResetGlobalFilter:!1,disableSortRemove:!0,defaultColumn:{Cell:oe}},G.useGlobalFilter,G.useSortBy);return e.jsxs(te,{isLoading:s,disablePadding:!0,children:[e.jsx(Cl,{children:"Payment history"}),e.jsxs(Oa,{...o(),children:[e.jsx($a,{headerGroups:i}),e.jsx(As,{...a(),children:r.map(l=>{c(l);const{key:m,...p}=l.getRowProps();return e.jsx(jt,{hover