@ionite/core 0.0.24-beta.20261003.17 → 0.0.24-beta.20261006.21

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/dist/server.js CHANGED
@@ -1 +1 @@
1
- import{A as Ce,B as Mt,C as ur,D as dr,Da as Qt,E as lr,Ea as is,F as zo,H as wn,Ha as Cs,Ja as pr,Ka as en,L as Ar,M as Ir,N as Cn,O as Tr,Oa as Bo,Pa as Ko,Qa as Me,R as Xe,Ra as mt,S as bn,Sa as ft,U as vn,V as Rn,Va as os,W as $t,Wa as as,X as An,Y as hn,a as wr,c as Qe,ca as tn,d as Kt,da as Jr,e as Gt,ea as Hr,f as Jt,fa as qt,g as we,ga as Ae,i as ht,ia as zt,k as ns,l as pt,la as Ee,m as L,ma as ss,n as er,pa as ge,qa as Dt,ra as dt,u as ir,v as or,va as Er,wa as Te,x as ar,xa as lt,y as rs,ya as Z,z as cr,za as vs}from"./shared/core-njzaahvy.js";var Ts="Ionite instance is required. Create one with ionite(source, config) and pass it to this function.",Sr=["user","customer","workload"],xs={user:async(e,t)=>t.sso?.getUser(e),customer:async(e,t)=>t.ciam?.getCustomer(e),workload:async(e,t)=>{let n=await t.workload?.getWorkloadIdentity?.(e);if(!n)return;let r=n.clientId??n.workloadId??n.claims.sub;return r?{...n,id:r}:void 0}};function Ps(e){if(e==="any")return Sr;let t=Array.isArray(e)?e:[e];return Sr.filter((n)=>t.includes(n))}function Us(e){let t=e.headers.get("cookie");if(!t)return[];return t.split(";").map((n)=>n.slice(0,n.indexOf("=")===-1?n.length:n.indexOf("=")).trim()).filter(Boolean)}function Es(e,t){let n=e.headers.get("authorization")?.toLowerCase().startsWith("bearer ")??!1,r=Us(e),s=new Set;for(let a of r){if(a.startsWith("ion.sso"))s.add("user");if(a.startsWith("ion.ciam"))s.add("customer")}let o=r.length>0&&!s.has("user")&&!s.has("customer");return t.filter((a)=>{if(a==="workload")return n;if(r.length===0)return!1;return s.has(a)||o})}function ie(e){return typeof e==="string"?e:e.id}function Cr(e){let{subject:t,subjectType:n}=e,r;if(n==="user")r=t.sso?.scope;else if(n==="customer")r=t.ciam?.scope;else if(n==="workload")r=t.scope;return new Set((r??"").split(/\s+/).filter(Boolean))}function mn(e,t,n){let r=Cr(e),s=t.filter((a)=>r.has(a));return{allow:n==="any"?s.length>0:t.length>0&&s.length===t.length,metadata:{reason:"scope",wantedScopes:t,matchedScopes:s}}}function ct(e,t){return(n)=>{if(e.length===0)return;let r=Cr(n),s=e.filter((a)=>r.has(a));return(t==="any"?s.length>0:s.length===e.length)?s:void 0}}function jt(e,t,n){return(r)=>{if(t.length===0||r.subjectType!=="workload")return;let s=wr(e.config?.authz,r.subject);if(!s)return;let o=t.filter((u)=>s.has(u));return(n==="any"?o.length>0:o.length===t.length)?o:void 0}}function Ms(e,t){if(e.subjectType==="workload"){let n=e.subject.scopesAsEntitlements;if(typeof n==="boolean")return n}return t.config?.authz?.scopesAsEntitlements===!0}function pn(e,t,n,r,s){return{allow:n==="ok",subject:t?.subject,subjectType:t?.subjectType,reason:n,decision:r,response(){if(n==="ok")return new Response(null,{status:204});if(n==="unauthenticated")return e.log.warn("authz.denied",{reason:n,...s()}),Response.json({error:"Unauthorized"},{status:401});if(n==="not_configured")return e.log.warn("authz.denied",{reason:n,subject:t?.subject?.id,subjectType:t?.subjectType,...s()}),Response.json({error:"not_configured"},{status:503});return e.log.warn("authz.denied",{reason:n,subject:t?.subject?.id,subjectType:t?.subjectType,...s()}),Response.json({error:"Forbidden"},{status:403})}}}function Ds(e,t,n){return new Promise((r)=>{let s=[],o=e.length,a=!1,u=()=>{if(o-=1,o===0&&!a)a=!0,r({outcomes:s})};for(let d of e)t(d).then((c)=>{if(s.push({principal:d,decision:c}),!a&&c.allow){a=!0,r({matched:{principal:d,decision:c},outcomes:s});return}u()},(c)=>{n?.(d,c),s.push({principal:d,decision:{allow:!1,metadata:{reason:"error"}}}),u()})})}async function Ne(e,t,n,r,s,o,a){Z(t,Ts);let u=Es(e,Ps(n)),c=(await Promise.all(u.map(async(I)=>{let Y=await xs[I](e,t);return Y?.id?{subject:Y,subjectType:I,subjectId:Y.id}:void 0}))).filter((I)=>I!==void 0);if(c.length===0)return pn(t,void 0,"unauthenticated",void 0,s);let E=async(I)=>{let Y=t.authz.accessIndex;if(!Y?.isSubjectDisabled)return!1;return Y.isSubjectDisabled(I.subjectId,I.subjectType)},B=async(I)=>{if(a){let Y=a(I);if(Y&&Y.length>0){if(await E(I))return{allow:!1,metadata:{reason:"subject_disabled"}};return{allow:!0,metadata:{reason:"trusted-client",matchedPermissions:Y}}}}if(o&&Ms(I,t)){let Y=o(I);if(Y&&Y.length>0){if(await E(I))return{allow:!1,metadata:{reason:"subject_disabled"}};return{allow:!0,metadata:{reason:"scope",matchedScopes:Y}}}}return r(I)},{matched:J,outcomes:X}=await Ds(c,B,(I,Y)=>{t.log.warn("authz.check_error",{"ion.operation":"authz.check","ion.outcome":"error",subject:I.subjectId,subjectType:I.subjectType,error:Y instanceof Error?Y.message:String(Y),...s()})});if(J){if(J.decision.metadata?.reason==="scope")t.log.info("authz.scope_honor",{"ion.operation":"authz.scope_honor","ion.outcome":"allow",subject:J.principal.subjectId,subjectType:J.principal.subjectType,matchedScopes:J.decision.metadata.matchedScopes,...s()});return pn(t,J.principal,"ok",J.decision,s)}let Q=X.length>0&&X.every((I)=>{let Y=I.decision.metadata?.reason;return Y==="access_index_not_configured"||Y==="error"}),C=X[0],q=Q?"not_configured":"forbidden";return pn(t,C?.principal,q,C?.decision,s)}async function Os(e,t,n,r,s,o="any"){return Ne(e,t,o,(a)=>t.authz.has(a.subjectId,n,r,s,a.subjectType),()=>({targetType:n,target:ie(r),resource:s?ie(s):void 0}),s?void 0:ct([ie(r)],"any"),n==="permission"&&!s?jt(t,[ie(r)],"any"):void 0)}async function _s(e,t,n,r,s="any"){return Ne(e,t,s,(o)=>t.authz.hasPermission(o.subjectId,n,r,o.subjectType),()=>({targetType:"permission",target:ie(n),resource:r?ie(r):void 0}),r?void 0:ct([ie(n)],"any"),r?void 0:jt(t,[ie(n)],"any"))}async function js(e,t,n,r,s="any"){return Ne(e,t,s,(o)=>t.authz.hasRole(o.subjectId,n,r,o.subjectType),()=>({targetType:"role",target:ie(n),resource:r?ie(r):void 0}),r?void 0:ct([ie(n)],"any"))}async function Ls(e,t,n,r,s="any"){return Ne(e,t,s,(o)=>t.authz.hasGroup(o.subjectId,n,r,o.subjectType),()=>({targetType:"group",target:ie(n),resource:r?ie(r):void 0}),r?void 0:ct([ie(n)],"any"))}async function Ns(e,t,n,r="any"){let s=n.filter((a)=>!a.resource).map((a)=>ie(a.target)),o=n.filter((a)=>!a.resource&&a.targetType==="permission").map((a)=>ie(a.target));return Ne(e,t,r,(a)=>t.authz.hasAny(a.subjectId,n,a.subjectType),()=>({targets:n.map((a)=>`${a.targetType}:${ie(a.target)}`)}),s.length>0?ct(s,"any"):void 0,o.length>0?jt(t,o,"any"):void 0)}async function $s(e,t,n,r="any"){let s=n.length>0&&n.every((u)=>!u.resource),o=n.length>0&&n.every((u)=>!u.resource&&u.targetType==="permission"),a=n.map((u)=>ie(u.target));return Ne(e,t,r,(u)=>t.authz.hasAll(u.subjectId,n,u.subjectType),()=>({targets:n.map((u)=>`${u.targetType}:${ie(u.target)}`)}),s?ct(a,"all"):void 0,o?jt(t,a,"all"):void 0)}async function Ws(e,t,n,r="any"){return Ne(e,t,r,(s)=>Promise.resolve(mn(s,[n],"any")),()=>({scope:n}))}async function Vs(e,t,n,r="any"){return Ne(e,t,r,(s)=>Promise.resolve(mn(s,n,"any")),()=>({scopes:n}))}async function qs(e,t,n,r="any"){return Ne(e,t,r,(s)=>Promise.resolve(mn(s,n,"all")),()=>({scopes:n}))}function le(e){return typeof e==="string"&&e.length>0?e:void 0}function br(e){let t=le(e.email);return{sub:String(e.sub??""),email:t,name:le(e.name),userName:le(e.preferred_username)??t,avatar:le(e.picture)}}var vr={oidc:{flow:"id_token",scope:"openid profile email",branding:{displayName:"Single sign-on"},mapClaims:br},google:{flow:"id_token",authorizationUrl:"https://accounts.google.com/o/oauth2/v2/auth",tokenUrl:"https://oauth2.googleapis.com/token",jwksUri:"https://www.googleapis.com/oauth2/v3/certs",scope:"openid email profile",branding:{displayName:"Google",iconUrl:"https://www.gstatic.com/firebasejs/ui/2.0.0/images/auth/google.svg",colors:{light:"#ffffff",dark:"#131314",secondary:"#4285F4"},url:"https://accounts.google.com"},mapClaims:br},microsoft:{flow:"id_token",authorizationUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/authorize",tokenUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/token",jwksUri:"https://login.microsoftonline.com/common/discovery/v2.0/keys",scope:"openid email profile",branding:{displayName:"Microsoft",colors:{light:"#ffffff",dark:"#2f2f2f",secondary:"#0067b8"},url:"https://login.microsoftonline.com"},mapClaims:(e)=>{let t=le(e.email)??le(e.preferred_username);return{sub:String(e.sub??e.oid??""),email:t,name:le(e.name),userName:le(e.preferred_username)??t,avatar:le(e.picture)}}},apple:{flow:"id_token",authorizationUrl:"https://appleid.apple.com/auth/authorize",tokenUrl:"https://appleid.apple.com/auth/token",jwksUri:"https://appleid.apple.com/auth/keys",scope:"openid email name",extraAuthParams:{response_mode:"form_post"},branding:{displayName:"Apple",colors:{light:"#000000",dark:"#ffffff"},url:"https://appleid.apple.com"},mapClaims:(e)=>{let t=le(e.email);return{sub:String(e.sub??""),email:t,name:le(e.name),userName:t}}},github:{flow:"userinfo",authorizationUrl:"https://github.com/login/oauth/authorize",tokenUrl:"https://github.com/login/oauth/access_token",userInfoUrl:"https://api.github.com/user",scope:"read:user user:email",branding:{displayName:"GitHub",colors:{light:"#24292f",dark:"#ffffff"},url:"https://github.com"},mapClaims:(e)=>({sub:String(e.id??e.node_id??""),email:le(e.email),name:le(e.name)??le(e.login),userName:le(e.login),avatar:le(e.avatar_url)})}};function fn(e){if(e==="magic-link")return;return vr[e]}function Lt(e,t){if(t.type==="magic-link")return;let n=fn(t.type);if(!n)return;return{name:e,type:t.type,flow:n.flow,authorizationUrl:t.authorizationUrl??n.authorizationUrl,tokenUrl:t.tokenUrl??n.tokenUrl,jwksUri:t.jwksUri??n.jwksUri,userInfoUrl:t.userInfoUrl??n.userInfoUrl,scope:t.scope??n.scope,clientId:t.clientId,clientSecret:t.clientSecret,extraAuthParams:n.extraAuthParams,branding:{...n.branding,...t.branding},mapClaims:n.mapClaims,config:t}}function gn(e){return{...fn(e.type)?.branding??{displayName:e.type},...e.branding}}function yn(e){if(!e)return[];return Object.entries(e).filter(([,t])=>t.enabled!==!1).map(([t,n],r)=>({name:t,config:n,index:r})).sort((t,n)=>{let r=t.config.order??Number.MAX_SAFE_INTEGER,s=n.config.order??Number.MAX_SAFE_INTEGER;if(r!==s)return r-s;return t.index-n.index}).map(({name:t,config:n})=>({name:t,config:n}))}var zs=/^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;function Nt(e){if(e===void 0)return;let t=e.trim().toLowerCase();if(!zs.test(t))throw Error(`Invalid cookiesDomain "${e}": expected a hostname such as "app.example.com" without a scheme, port, path, or leading dot.`);return t}function Ke(e){return e?` Domain=${e};`:""}var Rr=4000;function Bs(e){return`Expires=${e.toUTCString()}`}function xr(e){return`Path=${e.path};${Ke(e.domain)}${e.secure?" Secure;":""} SameSite=${e.sameSite};`}function In(e,t,n,r){if(t.length>Rr)throw Error(`Display cookie ${e} value is ${t.length} bytes; the limit is ${Rr}.`);return`${e}=${t}; ${Bs(n)}; ${xr(r)}`}function $e(e,t){return`${e}=; Max-Age=0; ${xr(t)}`}function kn(e){if(!e)return;let t=e instanceof Date?e:new Date(e);return Number.isNaN(t.getTime())?void 0:t}function Sn(e){return!e||e.getTime()>Date.now()}async function Ks(e,t,n){let r=e.envelope.kind??"session";if(r==="discovered"){let u=kn(e.envelope.expiresAt);return{...e,kind:r,live:Boolean(u&&Sn(u))}}let s=t[`${e.prefix}.session`];if(!s)return{...e,kind:r,live:!1};let o=await n.get(s);if(!o||o.authType!=="sso"&&o.authType!=="ciam")return{...e,kind:r,live:!1};let a=kn(o.expiresAt);return{...e,kind:r,live:Sn(a),...a?{sessionExpiresAt:a}:{}}}function ut(e,t,n){let r=An(t);return e?.includes(`${r}=`)?[$e(r,n)]:[]}function Pr(e,t,n,r,s){let o=[...e.filter((E)=>E.kind==="session").slice(0,n),...e.filter((E)=>E.kind==="discovered").slice(0,r)],a=s?s(e,{max:n,maxDiscovered:r}):o,u=[...a.filter((E)=>E.kind==="session").slice(0,n),...a.filter((E)=>E.kind==="discovered").slice(0,r)];if(u.some((E)=>E.name===t))return u;let d=e.find((E)=>E.name===t);if(!d)return u;return[...[d,...u.filter((E)=>E.kind==="session")].slice(0,n),...u.filter((E)=>E.kind==="discovered")]}async function Ct(e){let t=An(e.cookiesPrefix),n=e.attr;if(e.displayCookie?.enabled!==!0)return ut(e.cookieHeader,e.cookiesPrefix,n);if(!e.sessionStore)return[];let r=Xe(e.user,e.projector),s={v:wn,...e.tenantId?{tenantId:e.tenantId}:{},authType:e.authType,expiresAt:e.expiresAt.toISOString(),user:r},o={name:t,prefix:e.cookiesPrefix,envelope:s,kind:"session",sessionExpiresAt:e.expiresAt,live:!0},a=vn(e.cookieHeader),u=e.sessionStore,d=await Promise.all(Rn(e.cookieHeader).filter((q)=>q.name!==t).map((q)=>Ks(q,a,u))),c=[o,...d.filter((q)=>q.live&&q.kind==="session")].sort((q,I)=>$t(q.sessionExpiresAt?.toISOString()??q.envelope.expiresAt,I.sessionExpiresAt?.toISOString()??I.envelope.expiresAt)),E=e.displayCookie.discovered?.enabled===!0?d.filter((q)=>q.live&&q.kind==="discovered"&&(!e.tenantId||q.envelope.tenantId!==e.tenantId)).sort((q,I)=>$t(q.envelope.expiresAt,I.envelope.expiresAt)):[],B=[...c,...E],J=Ir(e.displayCookie?.max),X=Cn(e.displayCookie.discovered?.max),Q=new Set(Pr(B,t,J,X,e.trim).map((q)=>q.name)),C=[In(t,bn(s),e.expiresAt,n)];for(let q of d)if(!Q.has(q.name))C.push($e(q.name,n));return C}function Gs(e){let t=vn(e.cookieHeader),n=Object.keys(t).filter((C)=>C.startsWith(`${Ar}.`)&&C.endsWith(".profile"));if(!(e.displayCookie?.enabled===!0&&e.displayCookie.discovered?.enabled===!0))return n.map((C)=>$e(C,e.attr));let s=e.now??new Date,o=Tr(e.displayCookie?.discovered?.ttlSeconds),a=new Date(s.getTime()+o*1000),u=Cn(e.displayCookie?.discovered?.max),d=Rn(e.cookieHeader),c=new Set(d.filter((C)=>(C.envelope.kind??"session")==="session").flatMap((C)=>C.envelope.tenantId?[C.envelope.tenantId]:[])),E=new Map;for(let C of d){if(C.envelope.kind!=="discovered"||!C.envelope.tenantId)continue;let q=kn(C.envelope.expiresAt);if(q&&Sn(q)&&!c.has(C.envelope.tenantId))E.set(C.envelope.tenantId,C.envelope)}let B=Xe(e.user,e.projector);for(let C of e.tenants){let q=C.tenantId.trim();if(!q||c.has(q))continue;E.set(q,{v:wn,kind:"discovered",tenantId:q,authType:e.authType,expiresAt:a.toISOString(),user:B,...C.tenantName?{tenantName:C.tenantName}:{}})}let J=[...E.values()].sort((C,q)=>$t(C.expiresAt,q.expiresAt)).slice(0,u),X=new Set(J.map((C)=>hn(C.tenantId??""))),Q=J.map((C)=>In(hn(C.tenantId??""),bn(C),new Date(C.expiresAt),e.attr));for(let C of n)if(!X.has(C))Q.push($e(C,e.attr));return Q}var En=60000,Mr=86400000,Dr=600000,xn=256,ke=new Map;function Js(e){if(typeof e?.ttlMs==="number"&&Number.isFinite(e.ttlMs))Dr=Math.min(Math.max(e.ttlMs,En),Mr);if(typeof e?.maxEntries==="number"&&Number.isFinite(e.maxEntries)){xn=Math.max(1,Math.floor(e.maxEntries));while(ke.size>xn){let t=ke.keys().next().value;if(t===void 0)break;ke.delete(t)}}}function Ur(e,t){ke.delete(e),ke.set(e,t);while(ke.size>xn){let n=ke.keys().next().value;if(n===void 0)break;ke.delete(n)}}var bt=new Map,Pn=()=>Date.now();function Hs(e){Pn=e??(()=>Date.now())}var Un={};function Fs(e){Un=e??{}}function Ys(e){if(!e)return;if(/\bno-store\b/i.test(e))return En;let t=/max-age\s*=\s*(\d+)/i.exec(e);if(!t)return;let n=Number(t[1]);return Number.isFinite(n)?n*1000:void 0}function Xs(e){let n=Ys(e)??Dr;return Math.min(Math.max(n,En),Mr)}async function Mn(e,t=3,n=1000,r=30000,s){let o=Error("Placeholder Error");for(let a=0;a<=t;a++)try{return await e()}catch(u){if(o=u instanceof Error?u:Error(String(u)),u instanceof Error&&u.message.includes("400"))throw u;if(a===t)throw o;let d=Math.min(n*2**a,r),c=Math.random()*0.1*d;await new Promise((E)=>setTimeout(E,d+c)),s?.warn(`Retry attempt ${a+1} after ${d+c}ms delay`)}throw o}async function vt(e,t,n){let r=ke.get(e);if(!n?.forceRefresh&&r&&r.expiresAt>Pn())return Ur(e,r),r.jwks;let s=bt.get(e);if(s)return s;let o=(async()=>{try{return await Mn(async()=>{let a=await fetch(e,{headers:Ee});if(!a.ok){let c=await Er(a);throw t?.warn("JWKS endpoint returned an error",{"ion.operation":"jwks.fetch","ion.outcome":"degraded",reason:"upstream_error",status:a.status,contentType:c.contentType,excerpt:c.excerpt}),Error(`Failed to fetch JWKS (${a.status})`)}let u=await Te(a,{log:t,operation:"jwks.fetch"}),d=Xs(a.headers.get("cache-control"));return Ur(e,{jwks:u,expiresAt:Pn()+d,importedKeys:new Map}),u},Un.maxRetries,Un.baseDelayMs,void 0,t)}catch(a){let u=ke.get(e);if(u)return t?.warn("JWKS refresh failed; serving last-known-good keys",{"ion.operation":"jwks.refresh","ion.outcome":"degraded"}),u.jwks;throw a}finally{bt.delete(e)}})();return bt.set(e,o),o}function Zs(e){if(e){ke.delete(e),bt.delete(e);return}ke.clear(),bt.clear()}async function Qs(e,t,n){return(await Or(e,t,n)).jwk}async function Or(e,t,n){if(!t?.trim())throw Error("JWT header missing kid");await vt(e,n);let r=ke.get(e),s=r?.jwks.keys.find((o)=>o.kid===t);if(!s)await vt(e,n,{forceRefresh:!0}),r=ke.get(e),s=r?.jwks.keys.find((o)=>o.kid===t);if(!r||!s)throw Error("Public key not found");return{jwk:s,entry:r}}async function Dn(e,t,n,r,s){let{jwk:o,entry:a}=await Or(e,t,s),u=`${t}\x00${n}`,d=a.importedKeys.get(u);if(d)return d;let c=r(o);return c.catch(()=>{if(a.importedKeys.get(u)===c)a.importedKeys.delete(u)}),a.importedKeys.set(u,c),c}async function ei(e,t){let n=e.keys.find((r)=>r.kid===t);if(!n)throw Error("Public key not found");return _r(n)}function _r(e){return crypto.subtle.importKey("jwk",{kty:e.kty,n:e.n,e:e.e},{name:"RSASSA-PKCS1-v1_5",hash:"SHA-256"},!1,["verify"])}async function ti(e,t,n){return Dn(e,t,"rs256",_r,n)}var Tn={RS256:{kty:"RSA",importParams:{name:"RSASSA-PKCS1-v1_5",hash:"SHA-256"},verifyParams:{name:"RSASSA-PKCS1-v1_5"}},ES256:{kty:"EC",crv:"P-256",importParams:{name:"ECDSA",namedCurve:"P-256"},verifyParams:{name:"ECDSA",hash:"SHA-256"}}};async function On(e,t,n,r){if(typeof n!=="string"||!(n in Tn))throw Error(`Unsupported JWT alg "${String(n)}" (allowed: ${Object.keys(Tn).join(", ")})`);let s=Tn[n];return{key:await Dn(e,t,`oidc:${n}`,(a)=>{if(a.kty!==s.kty)throw Error(`JWK type "${a.kty}" does not match token alg "${n}"`);if(s.kty==="EC"){let u=a;if(u.crv!==s.crv)throw Error(`JWK curve "${String(u.crv)}" does not match token alg "${n}"`);return crypto.subtle.importKey("jwk",{kty:"EC",crv:u.crv,x:u.x,y:u.y},s.importParams,!1,["verify"])}return crypto.subtle.importKey("jwk",{kty:a.kty,n:a.n,e:a.e},s.importParams,!1,["verify"])},r),algorithm:s.verifyParams}}function xe(e=32){let t=new Uint8Array(e);return crypto.getRandomValues(t),Array.from(t,(n)=>n.toString(16).padStart(2,"0")).join("").substring(0,e)}function Wt(e){let t="";return e.forEach((n)=>{t+=String.fromCharCode(n)}),btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function Nr(e){let t=e.replace(/-/g,"+").replace(/_/g,"/"),n=t.padEnd(t.length+(4-t.length%4)%4,"="),r=atob(n),s=new Uint8Array(r.length);for(let o=0;o<r.length;o++)s[o]=r.charCodeAt(o);return s}function jr(e){let t=new TextDecoder().decode(Nr(e));return JSON.parse(t)}async function It(e){let t=new TextEncoder().encode(e),n=await crypto.subtle.digest("SHA-256",t);return Wt(new Uint8Array(n))}function jn(e){let t=new URL(e.authorizationUrl);if(t.searchParams.set("client_id",e.clientId),t.searchParams.set("redirect_uri",e.redirectUri),t.searchParams.set("response_type","code"),t.searchParams.set("scope",e.scope),t.searchParams.set("state",e.state),e.codeChallenge)t.searchParams.set("code_challenge",e.codeChallenge),t.searchParams.set("code_challenge_method","S256");if(e.nonce)t.searchParams.set("nonce",e.nonce);for(let[n,r]of Object.entries(e.extraParams??{}))t.searchParams.set(n,r);return t.toString()}async function Ln(e){let t=new URLSearchParams;if(t.append("grant_type","authorization_code"),t.append("code",e.code),t.append("redirect_uri",e.redirectUri),t.append("client_id",e.clientId),e.clientSecret)t.append("client_secret",e.clientSecret);if(e.codeVerifier)t.append("code_verifier",e.codeVerifier);let n=await fetch(e.tokenUrl,{method:"POST",headers:{...dt,...Ee},body:t.toString()}),r=await Te(n,{log:e.log,operation:"oidc.token.exchange"});if(!n.ok){let s=r,o=s.error==="invalid_client"&&!e.clientSecret;throw e.log?.error(o?"OIDC authorization-code exchange failed: no client_secret was configured; the provider may require a confidential client":"OIDC authorization-code exchange failed",{"ion.operation":"token.exchange","ion.outcome":"failure","http.status_code":n.status,oidc_error:s.error,...o?{client_auth:"none"}:{}}),Error(`Token exchange failed: ${s.error||n.statusText} - ${s.error_description||""}`.trim())}if(typeof r.access_token!=="string")throw Error("Token exchange response missing access_token");return r}var $r=60;function At(e){return e.trim().replace(/\/$/,"")}function Wr(e){let{claims:t,audience:n}=e,r=At(e.issuer),s=e.nowSec??Math.floor(Date.now()/1000),o=e.clockSkewSec??$r,a=t.iss;if(typeof a!=="string"||At(a)!==r)throw Error("ID token issuer mismatch");let u=t.aud,d=Array.isArray(u)?u.includes(n):typeof u==="string"&&u===n,c=typeof t.azp==="string"&&t.azp===n;if(!d&&!c)throw Error("ID token audience mismatch");if(typeof t.exp!=="number")throw Error("ID token missing exp");if(t.exp<s-o)throw Error("ID token expired");if(e.expectedNonce!==void 0){if(t.nonce!==e.expectedNonce)throw Error("ID token nonce mismatch")}}async function Vr(e,t,n){let r=e.split(".");if(r.length!==3)throw Error("Invalid JWT");let s=jr(r[0]),o=jr(r[1]),a=Nr(r[2]),{key:u,algorithm:d}=await On(t,s.kid,s.alg,n),c=new TextEncoder().encode(`${r[0]}.${r[1]}`);if(!await crypto.subtle.verify(d,u,a,c))throw Error("Invalid JWT signature");return{header:s,payload:o}}async function Ge(e){let{payload:t}=await Vr(e.idToken,e.jwksUri,e.log);return Wr({claims:t,issuer:e.issuer,audience:e.audience,clockSkewSec:e.clockSkewSec,expectedNonce:e.expectedNonce}),t}var ni="http://schemas.openid.net/event/backchannel-logout";async function Nn(e){let{payload:t}=await Vr(e.logoutToken,e.jwksUri,e.log),n=At(e.issuer),r=t.iss;if(typeof r!=="string"||At(r)!==n)throw Error("Logout token issuer mismatch");let s=t.aud,o=Array.isArray(s)?s.includes(e.audience):typeof s==="string"&&s===e.audience,a=typeof t.azp==="string"&&t.azp===e.audience;if(!o&&!a)throw Error("Logout token audience mismatch");if(t.nonce!=null)throw Error("Logout token must not contain a nonce");let u=t.events;if(!(typeof u==="object"&&u!==null&&!Array.isArray(u)&&Object.hasOwn(u,ni)))throw Error("Logout token missing back-channel logout event");let c=typeof t.sid==="string"&&t.sid.length>0,E=typeof t.sub==="string"&&t.sub.length>0;if(!c&&!E)throw Error("Logout token missing sid and sub");if(typeof t.exp==="number"){let B=Math.floor(Date.now()/1000),J=e.clockSkewSec??$r;if(t.exp<B-J)throw Error("Logout token expired")}return t}var ri=3600000,si=60000,ii=86400000,oi=256,We=new Map,Rt=new Map;function Lr(e,t){We.delete(e),We.set(e,t);while(We.size>oi){let n=We.keys().next().value;if(n===void 0)break;We.delete(n)}}var _n=()=>Date.now();function ai(e){_n=e??(()=>Date.now())}function ci(e){if(e){We.delete(e),Rt.delete(e);return}We.clear(),Rt.clear()}function ui(e){let t=e?/max-age\s*=\s*(\d+)/i.exec(e):null,n=t?Number(t[1]):Number.NaN,r=Number.isFinite(n)?n*1000:ri;return Math.min(Math.max(r,si),ii)}async function $n(e){let t=We.get(e);if(t&&t.expiresAt>_n())return Lr(e,t),t.endpoints;let n=Rt.get(e);if(n)return n;let r=(async()=>{try{let s=e.replace(/\/$/,""),o=await fetch(`${s}/.well-known/openid-configuration`,{headers:Ee});if(!o.ok)throw Error(`OIDC discovery failed for ${e} with status ${o.status}`);let a=await Te(o),u={authorizationUrl:typeof a.authorization_endpoint==="string"?a.authorization_endpoint:void 0,tokenUrl:typeof a.token_endpoint==="string"?a.token_endpoint:void 0,jwksUri:typeof a.jwks_uri==="string"?a.jwks_uri:void 0,userInfoUrl:typeof a.userinfo_endpoint==="string"?a.userinfo_endpoint:void 0};return Lr(e,{endpoints:u,expiresAt:_n()+ui(o.headers.get("cache-control"))}),u}catch(s){let o=We.get(e);if(o)return o.endpoints;throw s}finally{Rt.delete(e)}})();return Rt.set(e,r),r}async function Wn(e,t){let n=await fetch(e,{headers:{Authorization:`Bearer ${t}`,...Ee,"User-Agent":"ionite-ciam"}});if(!n.ok)throw Error(`UserInfo request failed with status ${n.status}`);return await Te(n)}function di(e){let t=e.replace(/-----BEGIN [^-]+-----/g,"").replace(/-----END [^-]+-----/g,"").replace(/\s+/g,""),n=atob(t),r=new Uint8Array(n.length);for(let s=0;s<n.length;s++)r[s]=n.charCodeAt(s);return r}async function Vn(e){let t=Math.floor(Date.now()/1000),n={alg:"ES256",kid:e.keyId,typ:"JWT"},r={iss:e.teamId,iat:t,exp:t+(e.expiresInSeconds??3600),aud:"https://appleid.apple.com",sub:e.clientId},s=Wt(new TextEncoder().encode(JSON.stringify(n))),o=Wt(new TextEncoder().encode(JSON.stringify(r))),a=`${s}.${o}`,u=await crypto.subtle.importKey("pkcs8",di(e.privateKey),{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),d=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},u,new TextEncoder().encode(a));return`${a}.${Wt(new Uint8Array(d))}`}function li(e){for(let t=0;t<e.length;t++){let n=e.charCodeAt(t);if(n<=31||n===127)return!0}return!1}function pi(e,t){let n=null;try{n=new URL(e,t)}catch{n=null}let r="";try{r=new URL(t).origin}catch{r=""}return{candidate:e,url:n,requestOrigin:r}}function qr(e,t,n){let r=pi(e,n),s=!1;for(let o of t){let a=o(r);if(a==="deny")return!1;if(a==="allow")s=!0}return s}function zr(){return({candidate:e,url:t})=>{if(li(e))return"deny";if(e.includes("\\"))return"deny";if(e.startsWith("//"))return"deny";if(!t)return"deny";if(t.protocol!=="http:"&&t.protocol!=="https:")return"deny";if(t.username||t.password)return"deny";return"abstain"}}function Br(){return({candidate:e})=>e.startsWith("/")&&!e.startsWith("//")&&!e.startsWith("/\\")?"allow":"abstain"}function Kr(){return({url:e,requestOrigin:t})=>e&&t&&e.origin===t?"allow":"abstain"}function mi(...e){let t=new Set(e.map((n)=>{try{return new URL(n).origin}catch{return n}}));return({url:n})=>n&&t.has(n.origin)?"allow":"abstain"}function fi(...e){let t=e.map((n)=>n.toLowerCase());return({url:n})=>{if(!n)return"abstain";let r=n.hostname.toLowerCase();for(let s of t)if(s.startsWith(".")){if(r===s.slice(1)||r.endsWith(s))return"allow"}else if(r===s)return"allow";return"abstain"}}function qn(){return[zr(),Br(),Kr()]}function Gr(e,t,n){if(!e)return!1;return qr(e,t,n)}function zn(e,t){if(!e)return t.fallback;return qr(e,t.rules,t.requestUrl)?e:t.fallback}var gi={rules:qn(),fallback:"/"};function yi(e,t,n="redirect"){let r=new URL(e.url).searchParams.get(n)??void 0;return Gr(r,t.rules,e.url)?{redirect:r}:void 0}function hi(e,t){let n=e.context;return zn(n?.redirect,{rules:t.rules,fallback:t.fallback,requestUrl:e.request.url})}function Je(e,t,n){if(e instanceof Response)return{response:e};if(typeof e==="string")return{location:zn(e,{rules:qn(),fallback:t,requestUrl:n})};return{location:t}}function Ze(e,t){if(t.length===0)return e;let n=new Headers(e.headers);for(let r of t)n.append("Set-Cookie",r);return new Response(e.body,{status:e.status,statusText:e.statusText,headers:n})}var Vt="ciam",ki="id_token",Si="access_token";function wi(e,t,n,r,s,o){if(!n&&!r)return;let a=new WeakMap,u={...n,...r},d={...u,magicLinkTtl:u.magicLinkTtl??3600,sessionTtl:u.sessionTtl??86400,cookiesSecure:u.cookiesSecure!==void 0?u.cookiesSecure:!0,cookiesSameSite:u.cookiesSameSite!==void 0?u.cookiesSameSite:"Strict",cookiesPrefix:u.cookiesPrefix??(u.ciamId?`ion.ciam.${u.ciamId}`:"ion.ciam"),cookiesPath:u.cookiesPath??"/",cookiesDomain:Nt(u.cookiesDomain)};function c(){if(!d.sessionStore)throw Error("Missing CIAM configuration field: sessionStore. CIAM sessionStore is required for server-side session tracking and first-party logout.");return d.sessionStore}function E(){c()}let B=e.callbackParams??lt(Jr("ionite.ciam")),J=e.idTokenClaims??lt(qt("ionite.ciam")),X=e.tokenResponse??lt(Hr("ionite.ciam"));function Q(i=32){let m=new Uint8Array(i);return crypto.getRandomValues(m),Array.from(m,(p)=>p.toString(16).padStart(2,"0")).join("").substring(0,i)}function C(i,m,p,g=d.cookiesSameSite??"Strict"){if(!d)throw Error("ionite CIAM Manager not initialized");if(i=`${d.cookiesPrefix}.${i}`,typeof m!=="string")m=btoa(JSON.stringify(m));let b;if(p instanceof Date)b=`Expires=${p.toUTCString()}`;else if(typeof p==="number")b=`Max-Age=${p}`;else throw Error("Invalid expires type",p);if(m.length>4000)throw Error(`Error setting cookie: ${i}. Cookie length is: ${m.length}`);return`${i}=${m}; ${b}; Path=${d.cookiesPath};${Ke(d.cookiesDomain)} HttpOnly;${d.cookiesSecure?" Secure;":""} SameSite=${g};`}function q(i){if(!d)throw Error("ionite CIAM Manager not initialized");return`${d.cookiesPrefix}.${i}=; Max-Age=0; Path=${d.cookiesPath};${Ke(d.cookiesDomain)} HttpOnly;${d.cookiesSecure?" Secure;":""} SameSite=${d.cookiesSameSite};`}function I(i,m,p=!1){if(!d)throw Error("ionite CIAM Manager not initialized");let g=m.headers.get("cookie");if(!g)return null;let b=`${d.cookiesPrefix}.${i}`,T=g.split(";").find((v)=>v.trim().startsWith(`${b}=`));if(!T)return null;let P=T.indexOf("="),x=T.substring(P+1).trim();if(!p)return x;try{let v=atob(x);return JSON.parse(v)}catch(v){return t.error("[CIAM] Failed to parse cookie",{"ion.operation":"cookie.parse","ion.outcome":"failure",cookieName:b},v),null}}function Y(i){return`cstate_${i}`}async function ee(i,m,p,g){let b=await d.afterLogin?.({...m,request:i,context:p,displayCookie:d.displayCookie,displayCookieAttributes:me()}),T=Je(b,"/",i.url);if(T.response)return Ze(T.response,g.map(([,P])=>P));return new Response(m.ok?"Authentication successful, redirecting":"Authentication failed, redirecting",{status:302,headers:[["Location",T.location],...g]})}function re(i,m){return["Set-Cookie",C("session",i,m)]}function me(){return{path:d.cookiesPath??"/",domain:d.cookiesDomain,secure:d.cookiesSecure!==!1,sameSite:d.cookiesSameSite??"Strict"}}function oe(){return[["Set-Cookie",q("session")],["Set-Cookie",$e(`${d.cookiesPrefix}.profile`,me())]]}function ue(i){if(d.displayCookie?.enabled===!0)return[];return ut(i.headers.get("cookie"),d.cookiesPrefix??"ion.ciam",me()).map((m)=>["Set-Cookie",m])}async function fe(i,m,p){return(await Ct({cookieHeader:i.headers.get("cookie"),sessionStore:d.sessionStore,cookiesPrefix:d.cookiesPrefix??"ion.ciam",authType:"ciam",tenantId:d.tenantId,expiresAt:p,user:m,projector:d.displayUser,displayCookie:d.displayCookie,trim:d.trimDisplayCookies,attr:me()})).map((b)=>["Set-Cookie",b])}function rt(i){if(!i)return;if(i instanceof Date)return i;let m=new Date(i);return Number.isNaN(m.getTime())?void 0:m}async function st(i){let m=I("session",i);if(!m)return;let p=await c().get(m);if(p&&d.tenantId&&p.tenantId&&p.tenantId!==d.tenantId)return;if(p?.authType!=="ciam")return;let g=rt(p.expiresAt);if(g&&Date.now()>g.getTime()){await c().delete(m);return}return p}async function Ye(i){if(!d)throw Error("ionite CIAM Manager not initialized");E();let m=a.get(i);if(m)return m;let p=St(i);return a.set(i,p),p}async function St(i){try{let m=await st(i);if(!m?.claims?.sub)return{status:"unauthenticated"};return{status:"authenticated",value:ze(m.claims)}}catch(m){return t.error("CIAM session resolution failed",{"ion.operation":"ciam.session","ion.outcome":"degraded"},m),{status:"degraded",error:m instanceof Error?m:void 0}}}async function it(i){let m=await Ye(i);return m.status==="authenticated"?m.value:void 0}async function _e(i){if(!d)throw Error("ionite CIAM Manager not initialized");E();let m;try{m=await it(i)}catch{m=void 0}let p=await d.beforeLogout?.({request:i,user:m});try{let N=I("session",i);if(N)await c().delete(N)}catch(N){t.warn("Failed to delete CIAM session",{"ion.operation":"session.delete","ion.outcome":"degraded"},N)}let g=oe(),b=await d.afterLogout?.({request:i,context:p}),T=Je(b,"/",i.url);if(T.response)return Ze(T.response,g.map(([,N])=>N));let P=T.location??"/",x=i.headers.get("accept");if(x?.includes(Ae)||x?.includes("text/javascript"))return new Response(JSON.stringify({success:!0,message:"Logged out",redirect:P}),{status:200,headers:[["Content-Type",Ae],...g]});return new Response("Logged out",{status:302,headers:[["Location",P],...g]})}function qe(i){return i.id||i.email||`ciam-${i.userName}`}function je(i,m,p){return{sub:qe(i),iss:Vt,aud:Vt,typ:ki,exp:Math.floor(p.getTime()/1000),iat:Math.floor(Date.now()/1000),email:i.email,name:i.name,preferred_username:i.userName,picture:i.avatar,sid:m}}function ot(i,m,p){return{sub:i,iss:Vt,aud:Vt,typ:Si,exp:Math.floor(p.getTime()/1000),iat:Math.floor(Date.now()/1000),sid:m,scope:"openid profile email"}}function ze(i){let m=i.exp?new Date(i.exp*1000):new Date;return{id:i.sub,userName:i.preferred_username??"",name:i.name??"",email:i.email??"",avatar:i.picture,userType:"customer",ciam:{profile:i,scope:"openid profile email",tokenType:"Bearer",expires:m}}}async function Be(i){if(!d)throw Error("ionite CIAM Manager not initialized");if(!s)return new Response(JSON.stringify({error:"Workload authentication required"}),{status:401,headers:ge});if(!await s.getWorkloadIdentity(i))return new Response(JSON.stringify({error:"Unauthorized: Valid workload token required"}),{status:401,headers:ge});let p,g;try{if(!i.headers.get("content-type")?.includes(Ae))return new Response(JSON.stringify({error:"Content-Type must be application/json"}),{status:400,headers:ge});let S=await i.text(),k=JSON.parse(S);g=typeof k?.redirect==="string"&&k.redirect.length>0?k.redirect:void 0;let R={userName:k.userName,name:k.name,email:k.email,avatar:k.avatar},D=await e.customer.validate(R);if(D.issues)return new Response(JSON.stringify({error:"Missing required fields: userName, name, email"}),{status:400,headers:ge});p=D.value}catch(h){return new Response(JSON.stringify({error:"Invalid JSON in request body"}),{status:400,headers:ge})}let T=new URL(i.url).searchParams.get("ttl"),P=T?parseInt(T,10):d.magicLinkTtl??3600;if(Number.isNaN(P)||P<=0)return new Response(JSON.stringify({error:"Invalid TTL parameter"}),{status:400,headers:ge});let x=Q(32),v=new Date(Date.now()+P*1000);if(!d.magicLinkStore)return new Response(JSON.stringify({error:"Magic link store not configured"}),{status:501,headers:ge});try{await d.magicLinkStore.create(x,p,v)}catch(h){return t.error("Error creating magic link",{"ion.operation":"magic_link.create","ion.outcome":"failure"},h),new Response(JSON.stringify({error:"Failed to create magic link"}),{status:500,headers:ge})}let N=new URL(i.url),y=d.magicLinkLoginUrl||"/magic-link/login",l=new URL(y,N.origin);if(l.searchParams.set("token",x),g)l.searchParams.set("redirect",g);return new Response(JSON.stringify({magicLink:l.toString(),expiresAt:v.toISOString()}),{status:200,headers:ge})}async function Se(i){if(!d)throw Error("ionite CIAM Manager not initialized");E();let p=new URL(i.url).searchParams.get("token");if(!p)return ee(i,{ok:!1,error:Error("Missing magic-link token")},void 0,[]);if(!d.magicLinkStore)return ee(i,{ok:!1,error:Error("Magic link store not configured")},void 0,[]);let g=await d.magicLinkStore.getAndDelete(p);if(!g)return ee(i,{ok:!1,error:Error("Magic link invalid, expired, or already used")},void 0,[]);let b=new Date(Date.now()+(d.sessionTtl??86400)*1000),T=Q(32),P=qe(g.customer),x=je(g.customer,T,b),v=ot(P,T,b),N=ze(x),y;try{let h={sid:T,sub:P,authType:"ciam",tenantId:d.tenantId,expiresAt:b,claims:x,accessClaims:v,createdAt:new Date};await c().create(h),y=h}catch(h){throw t.warn("Failed to create session",{"ion.operation":"session.create","ion.outcome":"degraded"},h),h}if(d.customerStore)try{let h=N.id;if(h){let S=new Date,k=await d.customerStore.get(h);if(k||d.enableJitUserProvisioning){let R={...k??{},...N,id:h,tenantId:k?.tenantId,createdAt:k?.createdAt??S,updatedAt:S,userType:k?.userType??"customer"};await d.customerStore.upsert(R)}}}catch(h){t.warn("Failed to store customer",{"ion.operation":"customer.store","ion.outcome":"degraded"},h)}let l=[re(T,b),...await fe(i,N,b)];return ee(i,{ok:!0,user:N,session:y},void 0,l)}function be(i,m=200,p=[]){return new Response(JSON.stringify(i),{status:m,headers:[["Content-Type",Ae],...p]})}function Ie(i,m){try{return new URL(i).toString()}catch{let p=new URL(m).origin,g=d.cookiesSecure?p.replace(/^http:\/\//,"https://"):p;return new URL(i,g).toString()}}function Le(){let i=d.customerLoginUrl||"/auth/customer/login",m=i.includes("?")?"&":"?";return yn(d.providers).map(({name:p,config:g})=>{let b=gn(g);return{name:p,type:g.type,displayName:b.displayName,loginUrl:`${i}${m}provider=${encodeURIComponent(p)}`,iconUrl:b.iconUrl,colors:b.colors,url:b.url}})}async function Ue(i){if(!i)return{};let{authorizationUrl:m,tokenUrl:p,jwksUri:g,userInfoUrl:b}=i,T=i.config.authority;if(T&&(!m||!p||i.flow==="id_token"&&!g))try{let x=await $n(T);m=m??x.authorizationUrl,p=p??x.tokenUrl,g=g??x.jwksUri,b=b??x.userInfoUrl}catch(x){t.error("CIAM provider OIDC discovery failed",{"ion.operation":"ciam.oidc.discovery","ion.outcome":"failure"},x)}return{authorizationUrl:m,tokenUrl:p,jwksUri:g,userInfoUrl:b}}async function M(i){if(i.type==="apple"){let{teamId:m,keyId:p,privateKey:g,clientId:b}=i.config;if(m&&p&&g&&b)return Vn({teamId:m,keyId:p,privateKey:g,clientId:b})}return i.clientSecret}async function W(i){c();let p=new URL(i.url).searchParams.get("provider");if(!p)return be({error:"Missing required query parameter: provider"},400);let g=d.providers?.[p];if(!g||g.enabled===!1||g.type==="magic-link")return be({error:`Unknown or disabled CIAM provider: ${p}`},404);let b=Lt(p,g);if(!b?.clientId)return be({error:`CIAM provider ${p} is not fully configured`},500);let T=await Ue(b);if(!T.authorizationUrl)return be({error:`CIAM provider ${p} is missing an authorization endpoint`},500);let P=d.customerCallbackUrl||"/auth/customer/callback",x=Ie(P,i.url),v=xe(),N=xe(64),y=xe(),l=b.flow==="id_token",h=l?await It(N):void 0,S=await d.beforeLogin?.({request:i}),k=jn({authorizationUrl:T.authorizationUrl,clientId:b.clientId,redirectUri:x,scope:b.scope,state:v,codeChallenge:h,nonce:y,extraParams:b.extraAuthParams}),R={provider:p,state:v,codeVerifier:l?N:void 0,nonce:y,redirectUri:x,...S===void 0?{}:{context:S}};return new Response("Redirecting to CIAM provider",{status:302,headers:[["Location",k],["Set-Cookie",C(Y(v),R,d.loginStateTtl??600,"Lax")]]})}async function U(i){if(i.method==="POST"){if((i.headers.get("content-type")??"").includes(zt)){let p=await i.text();return Object.fromEntries(new URLSearchParams(p).entries())}}return Object.fromEntries(new URL(i.url).searchParams.entries())}async function K(i,m){let p=i.mapClaims(m);if(!p.sub)return{ok:!1};let g=`${i.name}:${p.sub}`,b={id:g,userName:p.userName||p.email||g,name:p.name||"",email:p.email||"",avatar:p.avatar,userType:"customer"},T=g;if(d.customerStore){let l=await d.customerStore.lookup(b)??await d.customerStore.get(g);if(T=l?.id??g,!l&&!d.enableJitUserProvisioning)return t.warn("CIAM JIT customer provisioning disabled: unknown customer rejected",{"ion.operation":"customer.store","ion.outcome":"skipped"}),{ok:!1};let h=new Date,S={...l??{},...b,id:T,tenantId:l?.tenantId,createdAt:l?.createdAt??h,updatedAt:h,userType:l?.userType??"customer"};await d.customerStore.upsert(S)}let P=new Date(Date.now()+(d.sessionTtl??86400)*1000),x=xe(32),v={sub:T,iss:i.name,aud:i.clientId,exp:Math.floor(P.getTime()/1000),iat:Math.floor(Date.now()/1000),email:p.email,name:p.name,preferred_username:p.userName??p.email,picture:p.avatar,sid:x},N={sid:x,sub:T,authType:"ciam",tenantId:d.tenantId,expiresAt:P,claims:v,accessClaims:{sub:T,sid:x,scope:i.scope},createdAt:new Date},y=c();try{await y.create(N)}catch(l){if(!await y.get(x))throw l;await y.update(x,N)}return{ok:!0,claims:v,sid:x,expires:P}}async function _(i){c();let m,p,g=(b)=>{let T=m?[["Set-Cookie",q(m)]]:[];return ee(i,{ok:!1,error:b},p,T)};try{let b=await U(i),T=await B.validate(b);if(T.issues||!T.value)return g(Error("Invalid CIAM callback parameters"));let{code:P,state:x}=T.value;if(!x)return g(Error("Missing CIAM callback state"));m=Y(x);let v=I(m,i,!0);if(p=v?.context,!v?.provider||!v.state||v.state!==x)return t.warn("CIAM callback state verification failed",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),g(Error("CIAM callback state verification failed"));let N=d.providers?.[v.provider];if(!N)return g(Error("Unknown CIAM provider"));let y=Lt(v.provider,N);if(!y?.clientId)return g(Error("CIAM provider not configured"));let l=await Ue(y);if(!l.tokenUrl)return g(Error("CIAM provider missing token endpoint"));let h=await M(y),S=await Ln({tokenUrl:l.tokenUrl,clientId:y.clientId,clientSecret:h,redirectUri:v.redirectUri||Ie(d.customerCallbackUrl||"/auth/customer/callback",i.url),code:P,codeVerifier:y.flow==="id_token"?v.codeVerifier:void 0,log:t}),k;if(y.flow==="id_token"){let O=y.config.authority;if(!S.id_token||!l.jwksUri||!O)return g(Error("CIAM id_token flow misconfigured"));if(!v.nonce)return g(Error("CIAM callback state cookie missing nonce"));if((await X.validate(S)).issues)return t.warn("CIAM token response validation failed",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),g(Error("CIAM token response validation failed"));k=await Ge({idToken:S.id_token,jwksUri:l.jwksUri,issuer:O,audience:y.clientId,expectedNonce:v.nonce,log:t});let G=await J.validate(k);if(!G.issues)k=G.value}else{if(!l.userInfoUrl)return g(Error("CIAM provider missing userinfo endpoint"));k=await Wn(l.userInfoUrl,S.access_token);let O=y.config.authority;if(S.id_token&&l.jwksUri&&O){let z=await Ge({idToken:S.id_token,jwksUri:l.jwksUri,issuer:O,audience:y.clientId,expectedNonce:v.nonce||void 0,log:t}),G=typeof z.sub==="string"?z.sub:"";if(G){if(typeof k.sub==="string"&&k.sub.length>0&&k.sub!==G)return t.warn("CIAM UserInfo sub does not match verified id_token sub",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),g(Error("CIAM UserInfo sub mismatch"));k.sub=G}}if(typeof k.sub!=="string"||k.sub.length===0)return t.warn("CIAM UserInfo response missing sub",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),g(Error("CIAM UserInfo response missing sub"))}let R=await K(y,k);if(!R.ok)return g(Error("Failed to persist CIAM customer"));let D=ze(R.claims);t.info("CIAM third-party sign-in succeeded",{"ion.operation":"ciam.oidc.callback","ion.outcome":"success",provider:y.name});let A=[["Set-Cookie",q(m)],re(R.sid,R.expires),...await fe(i,D,R.expires)];return ee(i,{ok:!0,user:D,session:void 0},p,A)}catch(b){return t.error("Error during CIAM third-party sign-in callback",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"},b),g(b)}}async function j(i){if(!d)throw Error("ionite CIAM Manager not initialized");E();let m=d.magicLinkUrl||"/magic-link",p=d.magicLinkLoginUrl||"/magic-link/login",g=d.logoutUrl||"/auth/customer/logout",b=d.customerLoginUrl||"/auth/customer/login",T=d.customerCallbackUrl||"/auth/customer/callback",P=d.customerProvidersUrl||"/auth/customer/providers",x=new URL(i.url).pathname,v=(R)=>{if(!R)return;try{return new URL(R).pathname}catch{return R.startsWith("/")?R:`/${R}`}};if(v(m)===x&&i.method==="POST")return Be(i);if(v(p)===x&&i.method==="GET")return Se(i);if(v(g)===x&&i.method==="GET")return _e(i);if(v(P)===x&&i.method==="GET")return be({providers:Le()});if(v(b)===x&&i.method==="GET")return W(i);if(v(T)===x&&(i.method==="GET"||i.method==="POST"))return _(i);return new Response("Not Found",{status:404})}async function f(i){if((d.userEndpoint??"full")==="off")return new Response("Not Found",{status:404,headers:ue(i)});let m=await Ye(i);if(m.status==="degraded")return new Response(JSON.stringify({error:"auth_unavailable"}),{status:503,headers:ge});if(m.status==="unauthenticated")return new Response(JSON.stringify({error:"Unauthorized"}),{status:401,headers:ge});let p=rt(m.value.ciam?.expires),g=d.displayCookie?.enabled===!0?p&&!I("profile",i)?await fe(i,m.value,p):[]:ue(i),b=d.userEndpoint==="display"?Xe(m.value,d.displayUser):m.value;return new Response(JSON.stringify(b),{headers:[["Content-Type",Ae],...g]})}return{...d,getCustomer:it,resolveCustomer:Ye,logout:_e,handler:j,customerHandler:f,listCustomerProviders:Le}}async function Ci(e,t){return Z(t,"Ionite instance is required. Create one with ionite(source, config) and pass it to this function."),t.ciam?.getCustomer(e)}async function Bt(e,t){return Z(t,"Ionite instance is required. Create one with ionite(source, config) and pass it to this function."),await t.ciam?.resolveCustomer(e)??{status:"unauthenticated"}}var bi="urn:ietf:params:scim:schemas:core:2.0:User",Fr="urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",vi="urn:ietf:params:scim:schemas:core:2.0:Group";function Bn(e,t,n){let s=(t==="group"?e.resources:void 0)?.map((o)=>typeof o==="string"?o:o.id).filter(Boolean);return{schemas:[vi,L],id:e.id,externalId:e.providerId,displayName:e.displayName??e.name,members:n,[L]:{type:t,requestable:e.requestable,riskLevel:e.riskLevel??pt,providerId:e.providerId,requestUrl:e.requestUrl,source:e.source,deprecated:e.deprecated,description:e.description,resources:s&&s.length>0?s:void 0,assignableSubjectTypes:e.assignableSubjectTypes,recommendedSubjectTypes:e.recommendedSubjectTypes,attributes:we(e,Qe)}}}function Ri(e){if(e.scimName)return e.scimName;if(!e.name)return;let[t,...n]=e.name.split(" ");return{givenName:t,familyName:n.join(" ")||void 0}}function Ai(e){let t={attributes:we(e,Kt)};if(e.ecid!==void 0)t.ecid=e.ecid;if(e.accountClass!==void 0)t.accountClass=e.accountClass;return t.ecid!==void 0||t.accountClass!==void 0||t.attributes!==void 0?t:void 0}function Ii(e){return Object.keys(e.scimSchemaExtensions??{}).filter((t)=>t.startsWith("urn:")&&e.scimSchemaExtensions?.[t]!==void 0)}function Kn(e){let t=e.userName||e.email||e.id||"",n=e.emails??(e.email?[{value:e.email,primary:!0}]:[]),r=new Set([bi]);if(e.scimEnterprise!==void 0)r.add(Fr);let s=Ai(e);if(s!==void 0)r.add(Me);for(let a of Ii(e))r.add(a);let o={};if(e.scimEnterprise!==void 0)o[Fr]=e.scimEnterprise;if(s!==void 0)o[Me]=s;for(let[a,u]of Object.entries(e.scimSchemaExtensions??{}))if(a.startsWith("urn:")&&a!==Me&&u!==void 0)o[a]=u;return{schemas:Array.from(r),id:e.id,externalId:e.externalId,userName:t,displayName:e.displayName??e.name??t,name:Ri(e),nickName:e.nickName,profileUrl:e.avatar,title:e.title,userType:e.userType,preferredLanguage:e.preferredLanguage,locale:e.locale,timezone:e.timezone,active:e.active??!0,emails:n,phoneNumbers:e.phoneNumbers,ims:e.ims,photos:e.photos,addresses:e.addresses,groups:e.groups,entitlements:e.entitlements,roles:e.roles,x509Certificates:e.x509Certificates,meta:{resourceType:"User",created:(e.createdAt??e.updatedAt??new Date).toISOString(),lastModified:(e.updatedAt??e.createdAt??new Date).toISOString()},...o}}function Gn(e){return{schemas:[mt],id:e.id,externalId:e.externalId,userName:e.clientId??e.id,displayName:e.displayName??e.clientId??e.id,description:e.description,active:e.active??!0,ecid:e.ecid,providerId:e.providerId,requestUrl:e.requestUrl,attributes:we(e,Jt),meta:{resourceType:"Workload",created:(e.createdAt??e.updatedAt??new Date).toISOString(),lastModified:(e.updatedAt??e.createdAt??new Date).toISOString()}}}function Jn(e){return{schemas:[ft],id:e.id,externalId:e.externalId??e.id,userName:e.userName??e.email??e.id,displayName:e.displayName??e.name??e.userName??e.id,active:e.active??!0,emails:e.emails??(e.email?[{value:e.email,primary:!0}]:void 0),providerId:e.providerId,requestUrl:e.requestUrl,attributes:we(e,Gt),meta:{resourceType:"Customer",created:(e.createdAt??e.updatedAt??new Date).toISOString(),lastModified:(e.updatedAt??e.createdAt??new Date).toISOString()}}}function Hn(e){return{enabled:e?.enabled!==!1,assignment:e?.assignment??"app",delta:e?.delta}}var Ti="urn:ietf:params:scim:api:messages:2.0:ListResponse",tr="urn:ietf:params:scim:api:messages:2.0:Error",nr="urn:ietf:params:scim:schemas:core:2.0:User",Ut="urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",rr="urn:ietf:params:scim:schemas:core:2.0:Group",xi="urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig",Ht="urn:ietf:params:scim:schemas:core:2.0:ResourceType",et="urn:ietf:params:scim:schemas:core:2.0:Schema",Pi="00000000000000000000000000000000";function Ui(e){let t={timestamp:new Date().toISOString()};if(e)t.actor=e;try{let s=globalThis[Symbol.for("opentelemetry.js.api.1")]?.trace?.getActiveSpan?.()?.spanContext?.(),o=s?.traceId;if(o&&o!==Pi){if(t.traceId=o,s?.spanId)t.spanId=s.spanId}}catch{}return t}class Et extends Error{constructor(e){super(e);this.name="SubjectTypeNotAssignableError",Object.setPrototypeOf(this,Et.prototype)}}async function cs(e,t,n,r){let s=n.subjectType;if(!er.includes(s))throw new Et(`Cannot grant ${n.targetType} "${Ce(n.target)}" to a "${s}" principal: only [${er.join(", ")}] principals are assignable on this platform.`);let o=cr(t,e);if(!o&&!r)return;let a=Ce(n.target),u;if(r)u=await r.getNode(n.targetType,a);else if(o)u=await(n.targetType==="group"?o.groups:n.targetType==="role"?o.roles:o.permissions).get(a);if(!u)return;let d=u.assignableSubjectTypes;if(!d||d.length===0||!d.includes(s))throw new Et(`Cannot grant ${n.targetType} "${a}" to a "${s}" principal: this entitlement restricts assignment to [${(d??[]).join(", ")||"none"}].`)}async function Ei(e,t){let n=ir(e.codeCatalog,Ce(t.target));if(!n)return;if(n.kind!==t.targetType)throw Error(`Cannot grant ${t.targetType} "${n.entity.id}": code declares that id as ${n.kind}.`);if(!e.catalogStore)throw Error(`Cannot grant code entitlement "${n.entity.id}": no AccessCatalogStore is wired for materialization.`);await ar(n.kind,n.entity,or(e.catalogStore,n.kind))}async function Mi(e,t,n,r){await Ei(e,t),await cs(e.catalogStore,e.codeCatalog,t,r);let s={...t,status:t.status??"active",provenance:t.provenance??Ui()};if(s.id=Mt(s),await e.accessStore?.grant(s),e.accessIndex&&(e.catalogStore||e.codeCatalog)){let o=await dr(s,{catalog:e.catalogStore,code:e.codeCatalog,resources:e.resources,cache:r});await e.accessIndex.materialize(s.id,o)}return n?.push({op:"add",change:s}),s}async function xt(e,t,n){let r=t.id??Mt(t);await e.accessStore?.revoke(t),await e.accessIndex?.removeByRoot(r),n?.push({op:"delete",change:{...t,id:r}})}async function Xt(e,t){let n=await Di(e,t),r=await _i(e,t);return{oaa:n,delta:r}}async function Di(e,t){if(t.length===0||!e.authz.oaa.isReady())return{status:"skipped"};return Fe(e,"authz.oaa.push","OAA incremental access push failed after SCIM mutation; full sync will reconcile",()=>e.authz.oaa.pushAccessChanges(t),{count:t.length})}async function Fe(e,t,n,r,s){try{return await r(),{status:"ok"}}catch(o){return e.log?.warn(n,{"ion.operation":t,"ion.outcome":"degraded",...s,error:Oe(o)}),{status:"degraded",reason:Oe(o)}}}var Oi=6;async function _i(e,t){let n=e.iamDelta;if(!n?.isReady()||t.length===0)return{status:"skipped"};let r=new Map;for(let d of t){let c=`${d.change.subjectType}:${Ce(d.change.subject)}\x00${d.change.targetType}:${Ce(d.change.target)}`;r.set(c,d)}let s=[...r.values()],o=s.map(({op:d,change:c})=>()=>d==="add"?n.onGrant(c):n.onRevoke(c)),u=(await ji(o,Oi)).filter((d)=>d.status==="rejected");if(u.length>0)return e.log?.warn("IAM delta egress degraded after SCIM mutation; IAM server reconcile/aggregation will recover",{"ion.operation":"iam.delta.egress","ion.outcome":"degraded",failed:u.length,total:s.length,error:Oe(u[0]?.reason)}),{status:"degraded",reason:Oe(u[0]?.reason)};return{status:"ok"}}async function ji(e,t){let n=Array(e.length),r=0,s=async()=>{while(!0){let a=r++;if(a>=e.length)return;let u=e[a];if(!u)continue;try{n[a]={status:"fulfilled",value:await u()}}catch(d){n[a]={status:"rejected",reason:d}}}},o=Array.from({length:Math.min(t,e.length)},s);return await Promise.all(o),n}class nn extends Error{constructor(e){super(e);this.name="DerivedRevokeError",Object.setPrototypeOf(this,nn.prototype)}}class kt extends Error{constructor(e,t,n=!1){super(e);this.name="ScimMutationError",this.summary=t,this.clientError=n,Object.setPrototypeOf(this,kt.prototype)}}function V(e,t,n){return new Response(JSON.stringify({schemas:[tr],status:String(e),scimType:n,detail:t}),{status:e,headers:Dt})}function Ve(e,t){let n=t?.totalResults??e.length,r=t?.startIndex??1,s=t?.itemsPerPage??e.length;return new Response(JSON.stringify({schemas:[Ti],totalResults:n,startIndex:r,itemsPerPage:s,Resources:e}),{status:200,headers:Dt})}function ye(e,t=200,n){let r=new Headers(Dt);if(n)r.set("Location",n);return new Response(JSON.stringify(e),{status:t,headers:r})}function Yr(e){return V(e.clientError?409:500,`${e.message}; authz mutation summary: ${JSON.stringify(e.summary)}`,e.clientError?"mutability":"invalidValue")}function Pt(e){return Mt(e)}function Fn(e,t){return Zt(Xr(e),Xr(t))}function Xr(e){let t=new Map;if(!e?.id)return t;for(let n of e.groups??[]){let r={subject:e.id,subjectType:"user",targetType:"group",target:n.value,metadata:n.display||n.type?{display:n.display,type:n.type}:void 0};t.set(Pt(r),r)}for(let n of e.roles??[]){let r={subject:e.id,subjectType:"user",targetType:"role",target:n.value,metadata:n.display||n.type?{display:n.display,type:n.type,primary:n.primary}:void 0};t.set(Pt(r),r)}for(let n of e.entitlements??[]){let r={subject:e.id,subjectType:"user",targetType:"permission",target:n.value,metadata:n.display||n.type?{display:n.display,type:n.type,primary:n.primary}:void 0};t.set(Pt(r),r)}return t}class rn extends Error{constructor(e){super(e);this.name="AmbiguousMemberSubjectTypeError",Object.setPrototypeOf(this,rn.prototype)}}function Li(e,t,n){if(e.type==="Group")return;if(e.type==="Workload")return"workload";if(e.type==="User")return"user";if(e.type==="Customer")return"customer";let r=t??[];if(r.length===1)return r[0];throw new rn(`SCIM Group member "${e.value}" of entitlement "${n}" omits type, and the entitlement is assignable to more than one principal kind [${r.join(", ")||"none"}]. Set members[].type to User, Workload, or Customer.`)}function Ft(e,t,n,r,s){let o=new Map,a=r&&r.length>0?r:void 0;for(let u of e??[]){let d=Li(u,s,n);if(!d)continue;let c={subject:u.value,subjectType:d,targetType:t,target:n,resources:a,metadata:u.display||u.type?{display:u.display,type:u.type}:void 0};o.set(Pt(c),c)}return o}function Yn(e){let t=e[L]?.resources;return t&&t.length>0?t:void 0}function Ni(e,t){let n=(s,o)=>[...s??[]].sort().join(",")===[...o??[]].sort().join(","),r=e[L];if(r?.type!==void 0&&r.type!==t.kind)return!0;if(r?.requestable!==void 0&&r.requestable!==t.entity.requestable)return!0;if(r?.resources!==void 0&&!n(r.resources,sr(t.entity)))return!0;if(r?.assignableSubjectTypes!==void 0&&!n(r.assignableSubjectTypes,t.entity.assignableSubjectTypes))return!0;if(r?.recommendedSubjectTypes!==void 0&&!n(r.recommendedSubjectTypes,t.entity.recommendedSubjectTypes))return!0;return!1}function $i(e,t){let n=(o,a)=>[...o??[]].sort().join(",")===[...a??[]].sort().join(","),r=e[L],s=t[L];if(r?.type!==void 0&&r.type!==s?.type)return!0;if(r?.requestable!==void 0&&r.requestable!==s?.requestable)return!0;if(r?.resources!==void 0&&!n(r.resources,s?.resources))return!0;if(r?.assignableSubjectTypes!==void 0&&!n(r.assignableSubjectTypes,s?.assignableSubjectTypes))return!0;if(r?.recommendedSubjectTypes!==void 0&&!n(r.recommendedSubjectTypes,s?.recommendedSubjectTypes))return!0;return!1}function Wi(e){let t=new Map;for(let n of e)t.set(Pt(n),n);return t}async function tt(e,t,n,r,s,o){let a=[],u=new Set,d=(E,B)=>`${B}\x00${E}`,c=o?o.get(`${n}:${r}`)??[]:t?(await t.listByTarget(n,r)).items:[];for(let E of c){let B=Ce(E.subject),J=E.metadata,X=E.subjectType==="workload"?"Workload":E.subjectType==="customer"?"Customer":J?.type??"User",Q=d(B,X);if(u.has(Q))continue;u.add(Q),a.push({value:B,...J?.display?{display:J.display}:{},type:X})}for(let E of s??[]){if(E.targetType!==n||Ce(E.target)!==r)continue;let B=Ce(E.subject),J=d(B,"Workload");if(u.has(J))continue;u.add(J),a.push({value:B,type:"Workload"})}if(n==="group"){let E=await e.groups.get(r);for(let B of E?.groups??[]){let J=Ce(B),X=d(J,"Group");if(!J||u.has(X))continue;u.add(X),a.push({value:J,type:"Group"})}}return a.length>0?a:void 0}function Zt(e,t){let n=[];for(let[r,s]of t)if(!e.has(r))n.push({action:"grant",change:s});for(let[r,s]of e)if(!t.has(r))n.push({action:"revoke",change:s});return n}async function Xn(e,t){if(e.oaa.isReady())await e.oaa.pushUser(t)}async function Zr(e,t,n){if(t?.externalId&&t.externalId!==n.externalId)await e?.onUserDelete(t.externalId);await e?.onUserUpsert(n)}async function gt(e,t,n,r){let s={metadataApplied:!1,access:[]},o={status:"skipped"},a=[],u=new ur(e.catalogStore,e.resources,e.codeCatalog);try{try{await t(),s.metadataApplied=!0}catch(d){for(let c of n)s.access.push({change:c.change,status:"rolled_back"});throw s.metadataApplied=!1,new kt(`SCIM metadata write failed: ${Oe(d)}`,s,!1)}if(r?.oaa)await Fe(e,"authz.oaa.metadata","OAA metadata projection failed after SCIM write; full sync will reconcile",r.oaa);if(r?.delta&&e.iamDelta?.isReady())o=await Fe(e,"iam.delta.egress","IAM delta metadata projection failed after SCIM write; full aggregation will reconcile",r.delta);for(let d=0;d<n.length;d++){let c=n[d];try{if(c.action==="grant")await Mi(e,c.change,a,u);else await Ki(e,c.change,a);s.access.push({change:c.change,status:"applied"})}catch(E){s.access.push({change:c.change,status:"failed",error:E});for(let J=d+1;J<n.length;J++)s.access.push({change:n[J].change,status:"rolled_back"});let B=E instanceof nn||E instanceof Et;if(!B)await zi(e,c.change,u);throw new kt(B?Oe(E):`SCIM access mutation failed: ${Oe(E)}`,s,B)}}return s}finally{await qi(e),s.egress=await Xt(e,a),s.egress.delta=Vi(o,s.egress.delta),Bi(e,s)}}function Vi(e,t){if(e.status==="degraded")return e;if(t.status==="degraded")return t;return e.status==="ok"||t.status==="ok"?{status:"ok"}:{status:"skipped"}}function Oe(e){return e instanceof Error?e.message:String(e)}async function qi(e){try{await e.settleAuthz?.()}catch{}}async function zi(e,t,n){if(!e.accessIndex||!e.catalogStore&&!e.codeCatalog||!e.accessStore)return;let r=Ce(t.subject);if(!r)return;let s=t.subjectType;try{await lr(r,s,{accessStore:e.accessStore,accessIndex:e.accessIndex,catalogStore:e.catalogStore,code:e.codeCatalog,resources:e.resources},n)}catch(o){e.log?.warn("Per-subject reconcile after failed SCIM access mutation failed",{"ion.operation":"authz.reconcile.subject.repair","ion.outcome":"degraded",subject:r,subjectType:s,error:Oe(o)})}}function Bi(e,t){if(!e.onAccessMutation)return;try{e.onAccessMutation(t)}catch{}}async function Ki(e,t,n){if(e.accessStore){let r=t.id??Mt(t);if(!await e.accessStore.get(r)){if((e.accessIndex?await e.accessIndex.has(t.subject,t.targetType,t.target,t.resources?.[0],t.subjectType):{allow:!1}).allow)throw new nn(`Cannot revoke ${t.targetType} "${Ce(t.target)}" for "${Ce(t.subject)}": it is not a directly granted root (it is derived from group/role membership). Remove the granting group/role instead.`);await xt(e,t,n);return}}await xt(e,t,n)}function yt(e){let t=e[L]?.type??"group";if(t==="group"||t==="role"||t==="permission")return t;throw Error(`Unsupported ionite SCIM Group authz type "${String(t)}"`)}async function Zn(e,t,n){if(!e.oaa.isReady())return;if(n==="role"){await e.oaa.pushRole(t);return}if(n==="permission"){await e.oaa.pushPermission(t);return}await e.oaa.pushGroup(t)}function sr(e){let t=e.resources;if(!t||t.length===0)return;let n=t.map((r)=>typeof r==="string"?r:r.id).filter(Boolean);return n.length>0?n:void 0}function nt(e,t,n){return Bn(e,t,n)}function Gi(e,t){let n=e[L],s={...we(n?.attributes??{},Qe),id:t,name:e.displayName,displayName:e.displayName,description:n?.description??e.displayName,requestable:n?.requestable,riskLevel:n?.riskLevel??pt,providerId:n?.providerId??e.externalId,requestUrl:n?.requestUrl,assignableSubjectTypes:["user"]};if(n?.resources!==void 0)s.resources=n.resources;return s}function Ji(e){if(!e)return;let t=e.trim().match(/^requestable\s+eq\s+(true|false)$/i);if(!t)return;return{requestable:t[1]?.toLowerCase()==="true"}}function Qr(e){if(!e)return;let t=e.trim().match(/^externalId\s+eq\s+"([^"]*)"$/i);return t?t[1]:void 0}function Hi(e){if(!e)return;let t=e.trim(),n=t.match(/^userName\s+eq\s+"([^"]*)"$/i);if(n)return{userName:n[1]};let r=t.match(/^externalId\s+eq\s+"([^"]*)"$/i);if(r)return{externalId:r[1]};let s=t.match(/^meta\.lastModified\s+gt\s+"([^"]*)"$/i);if(s)return{updatedAfter:s[1]};return}function Fi(e,t,n){let r=new Set(["id","schemas"]),s={...e};if(t){let o=new Set(t.split(",").map((a)=>a.trim()).filter(Boolean));for(let a of Object.keys(s))if(!r.has(a)&&!o.has(a))delete s[a]}if(n){for(let o of n.split(",").map((a)=>a.trim()).filter(Boolean))if(!r.has(o))delete s[o]}return s}function es(e,t){let n=async(o,a,u)=>{let d=await e.toScim(o),c=o.id;return{...d,id:c,meta:{...d.meta??{},resourceType:e.resourceType,location:c?de(a,`${u}/${encodeURIComponent(c)}`):void 0}}},r=(o,a)=>{let u=a.op.toLowerCase();if(!a.path){if(u!=="remove"&&a.value&&typeof a.value==="object"&&!Array.isArray(a.value))Object.assign(o,a.value);return}if(u==="remove"){delete o[a.path];return}o[a.path]=a.value};return{handler:async(o,a)=>{if(!await t.validateAuth(o))return V(401,"Authorization required");let u=new URL(o.url),d=a?.basePath??`/${e.resourceType}s`,c=u.pathname;if(c.startsWith(d))c=c.substring(d.length);let E=c.match(/^\/([^/]+)$/),B=E?.[1]?decodeURIComponent(E[1]):void 0,J=u.searchParams.get("attributes"),X=u.searchParams.get("excludedAttributes"),Q=(C)=>Fi(C,J,X);try{if(B){if(o.method==="GET"){let C=await e.store.get(B);if(!C)return V(404,`${e.resourceType} not found`);return ye(Q(await n(C,o,d)))}if(o.method==="PUT"||o.method==="PATCH"){let C=await e.store.get(B);if(!C)return V(404,`${e.resourceType} not found`);let q=await o.json(),I=q;if(o.method==="PATCH"){let oe=q.Operations;if(!Array.isArray(oe))return V(400,"PATCH requires Operations","invalidSyntax");let ue=await e.toScim(C);for(let fe of oe)r(ue,fe);I=ue}let Y=await He(e.validator,I);if(Y.issues)return V(400,Y.issues.map((oe)=>oe.message).join("; "),"invalidValue");let ee=o.method==="PATCH"?"patch":"replace",re=await e.store.upsert({...await e.fromScim(Y.value,{existing:C,mode:ee}),id:C.id??B});if(C.active!==re.active)await t.accessIndex?.setSubjectDisabled?.(re.id,e.subjectType,re.active===!1);let me=re.id?de(o,`${d}/${encodeURIComponent(re.id)}`):void 0;for(let oe of e.projections??[])await Fe(t,`${oe.channel}.${e.subjectType}.upsert`,`${e.resourceType} projection degraded after SCIM upsert; aggregation will reconcile`,()=>oe.upsert(re,C));return ye(Q(await n(re,o,d)),200,me)}if(o.method==="DELETE"){let C=await e.store.get(B);if(!C)return V(404,`${e.resourceType} not found`);if(t.revokeSubjectAccess)await t.revokeSubjectAccess(B,e.subjectType);await e.store.delete(B),await t.accessIndex?.setSubjectDisabled?.(B,e.subjectType,!1);for(let q of e.projections??[])await Fe(t,`${q.channel}.${e.subjectType}.delete`,`${e.resourceType} projection degraded after SCIM delete; aggregation will reconcile`,()=>q.delete(C));return new Response(null,{status:204})}return V(405,"Method not allowed")}if(o.method==="GET"){let C=parseInt(u.searchParams.get("startIndex")??"",10),q=parseInt(u.searchParams.get("count")??"",10),I=C!=null&&!Number.isNaN(C)?Math.max(0,C-1):0,Y=q!=null&&!Number.isNaN(q)?q:void 0,ee=Hi(u.searchParams.get("filter"));if(ee?.externalId!==void 0){let oe=e.store.getByExternalId?await e.store.getByExternalId(ee.externalId):await e.store.lookup({externalId:ee.externalId}),ue=oe?[Q(await n(oe,o,d))]:[];return Ve(ue,{totalResults:ue.length,startIndex:1,itemsPerPage:ue.length})}let re=await e.store.list({start:I,limit:Y,filter:ee}),me=await Promise.all(re.items.map(async(oe)=>Q(await n(oe,o,d))));return Ve(me,{totalResults:re.total,startIndex:I+1,itemsPerPage:re.count})}if(o.method==="POST"){let C=await o.json(),q=await He(e.validator,C);if(q.issues)return V(400,q.issues.map((ee)=>ee.message).join("; "),"invalidValue");let I=await e.store.upsert(await e.fromScim(q.value,{mode:"create"}));if(I.active===!1)await t.accessIndex?.setSubjectDisabled?.(I.id,e.subjectType,!0);for(let ee of e.projections??[])await Fe(t,`${ee.channel}.${e.subjectType}.upsert`,`${e.resourceType} projection degraded after SCIM create; aggregation will reconcile`,()=>ee.upsert(I,void 0));let Y=I.id?de(o,`${d}/${encodeURIComponent(I.id)}`):void 0;return ye(Q(await n(I,o,d)),201,Y)}return V(405,"Method not allowed")}catch(C){if(en(C))return V(409,C.message,"uniqueness");return V(500,C instanceof Error?C.message:"Internal error")}}}}async function Yi(e,t,n,r){let s=[],o=[["group",e.groups],["role",e.roles],["permission",e.permissions]];for(let[u,d]of o)for await(let c of ht((E,B)=>d.list({start:E,limit:B,filter:{requestable:!0}})))if(c.providerId===n)s.push({entity:c,type:u});if(s.length>1)throw new pr(`Ambiguous providerId "${n}": ${s.length} entitlements share it (${s.map((u)=>`${u.type}:${u.entity.id}`).join(", ")})`,"unique_violation","providerId");let a=s[0];if(a?.entity.requestable!==!0)return;return nt(a.entity,a.type,await tt(e,t,a.type,a.entity.id,r))}async function Xi(e,t,n,r){let s=Math.max(0,n.start),o=n.limit!=null?s+n.limit:void 0,a={start:0,limit:o,filter:n.filter},[u,d,c]=await Promise.all([e.groups.list(a),e.roles.list(a),e.permissions.list(a)]),E=[...u.items.map((C)=>({entity:C,type:"group"})),...d.items.map((C)=>({entity:C,type:"role"})),...c.items.map((C)=>({entity:C,type:"permission"}))],B=u.total+d.total+c.total,J=E.slice(s,o),X=t?.listByTargets?await t.listByTargets(J.map(({entity:C,type:q})=>({targetType:q,target:C.id}))):void 0,Q=await Promise.all(J.map(async({entity:C,type:q})=>nt(C,q,await tt(e,t,q,C.id,r,X))));return{resources:Q,total:B,count:Q.length}}async function Tt(e,t,n,r){let[s,o,a]=await Promise.all([e.groups.get(n),e.roles.get(n),e.permissions.get(n)]);if(s)return nt(s,"group",await tt(e,t,"group",n,r));if(o)return nt(o,"role",await tt(e,t,"role",n,r));if(a)return nt(a,"permission",await tt(e,t,"permission",n,r));return}async function Qn(e,t,n,r){let s=yt(t),o=s==="role"?await e.roles.get(n):s==="permission"?await e.permissions.get(n):await e.groups.get(n),a=Gi(t,n),u=o?.assignableSubjectTypes&&o.assignableSubjectTypes.length>0?o.assignableSubjectTypes:["user"],d={...o??{},...a,source:o?.source??"scim",assignableSubjectTypes:u},c=r?r.displayName??r.name:o?.name;if(a.displayName===c)delete d.displayName;if(a.riskLevel===(r?.riskLevel??pt))delete d.riskLevel;let E=we(a,Qe),B=r?we(r,Qe):void 0;if(t[L]?.attributes!==void 0){for(let X of Object.keys(we(o??{},Qe)??{}))if(!(X in(E??{})))delete d[X]}for(let[X,Q]of Object.entries(E??{}))if(is(Q,B?.[X]))delete d[X];if(r)d.name=r.name;let J=s==="role"?e.roles.set(d):s==="permission"?e.permissions.set(d):e.groups.set(d);return await J.ready(),J}async function Zi(e,t){await Promise.all([e.groups.delete(t),e.roles.delete(t),e.permissions.delete(t)])}function Yt(){return crypto.randomUUID()}function He(e,t){let n=e;if(typeof n.validate==="function")return n.validate(t);return Promise.resolve(e["~standard"].validate(t))}function Qi(e){if(!e)return;try{return new URL(e).pathname}catch{return e.startsWith("/")?e:`/${e}`}}function De(e){let t=Qi(e);return t?Qt(t):void 0}function ts(...e){for(let t of e){let n=De(t);if(!n)continue;for(let r of["/Users","/Groups","/Workloads","/Customers"])if(n.endsWith(r))return n.slice(0,-r.length)}return}function de(e,t){return new URL(t,e.url).toString()}function w(e,t,n,r){let{multiValued:s=!1,...o}=r??{};return{name:e,type:t,description:n,multiValued:s,...o}}function eo(e,t){return{schemas:[xi],documentationUri:t?.documentationUri,patch:{supported:!0},bulk:{supported:!1},filter:{supported:!0,maxResults:1000},changePassword:{supported:!1},sort:{supported:!1},etag:{supported:!1},authenticationSchemes:[{type:"oauthbearertoken",name:"OAuth Bearer Token",description:"Use an ionite workload bearer token for IAM discovery and provisioning requests.",primary:!0}],meta:{resourceType:"ServiceProviderConfig",location:de(e.request,`${e.basePath}/ServiceProviderConfig`)}}}function to(e){let t=[];if(e.supportsUsers)t.push({schemas:[Ht],id:"User",name:"User",description:"User Account",endpoint:e.usersUrl,schema:nr,schemaExtensions:[{schema:Ut,required:!1},{schema:Me,required:!1}],meta:{resourceType:"ResourceType",location:de(e.request,`${e.basePath}/ResourceTypes/User`)}});if(e.supportsGroups)t.push({schemas:[Ht],id:"Group",name:"Group",description:"Group",endpoint:e.groupsUrl,schema:rr,schemaExtensions:[{schema:L,required:!1}],meta:{resourceType:"ResourceType",location:de(e.request,`${e.basePath}/ResourceTypes/Group`)}});if(e.supportsWorkloads)t.push({schemas:[Ht],id:"Workload",name:"Workload",description:"Workload (machine) principal",endpoint:e.workloadsUrl,schema:mt,meta:{resourceType:"ResourceType",location:de(e.request,`${e.basePath}/ResourceTypes/Workload`)}});if(e.supportsCustomers)t.push({schemas:[Ht],id:"Customer",name:"Customer",description:"Customer (CIAM) principal",endpoint:e.customersUrl,schema:ft,meta:{resourceType:"ResourceType",location:de(e.request,`${e.basePath}/ResourceTypes/Customer`)}});return t}function no(e){let t=[];if(e.supportsUsers)t.push({schemas:[et],id:nr,name:"User",description:"User Account",meta:{resourceType:"Schema",location:de(e.request,`${e.basePath}/Schemas/${encodeURIComponent(nr)}`)},attributes:[w("id","string","Unique identifier for the User.",{multiValued:!1,required:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),w("externalId","string","External identifier from the provisioning client.",{multiValued:!1,required:!1,mutability:"readWrite",returned:"default",uniqueness:"none"}),w("userName","string","Unique identifier typically used for login.",{multiValued:!1,required:!0,caseExact:!1,mutability:"readWrite",returned:"default",uniqueness:"server"}),w("name","complex","The components of the user name.",{multiValued:!1,required:!1,mutability:"readWrite",returned:"default",subAttributes:[w("formatted","string","The full name, including titles and suffixes.",{multiValued:!1}),w("familyName","string","The family name of the User.",{multiValued:!1}),w("givenName","string","The given name of the User.",{multiValued:!1}),w("middleName","string","The middle name(s) of the User.",{multiValued:!1}),w("honorificPrefix","string","The honorific prefix(es) of the User.",{multiValued:!1}),w("honorificSuffix","string","The honorific suffix(es) of the User.",{multiValued:!1})]}),w("displayName","string","The name of the User, suitable for display.",{multiValued:!1}),w("nickName","string","The casual way to address the user.",{multiValued:!1}),w("profileUrl","reference","A URL pointing to the User profile.",{multiValued:!1,referenceTypes:["external"]}),w("title","string","The user title, such as Vice President.",{multiValued:!1}),w("userType","string","The relationship between the organization and the User.",{multiValued:!1}),w("preferredLanguage","string","Preferred written or spoken language.",{multiValued:!1}),w("locale","string","Default location for localizing values.",{multiValued:!1}),w("timezone","string","The User time zone.",{multiValued:!1}),w("active","boolean","The User administrative status.",{multiValued:!1}),w("emails","complex","Email addresses for the User.",{multiValued:!0,subAttributes:[w("value","string","Email address value.",{multiValued:!1,required:!0}),w("display","string","Display label for the email.",{multiValued:!1}),w("type","string","Email type such as work or home.",{multiValued:!1}),w("primary","boolean","Primary email indicator.",{multiValued:!1})]}),w("phoneNumbers","complex","Phone numbers for the User.",{multiValued:!0,subAttributes:[w("value","string","Phone number value.",{multiValued:!1,required:!0}),w("display","string","Display label for the phone number.",{multiValued:!1}),w("type","string","Phone number type.",{multiValued:!1}),w("primary","boolean","Primary phone number indicator.",{multiValued:!1})]}),w("photos","complex","Photo URLs for the User.",{multiValued:!0,subAttributes:[w("value","reference","Photo URL.",{multiValued:!1,required:!0,referenceTypes:["external"]}),w("display","string","Display label for the photo.",{multiValued:!1}),w("type","string","Photo type.",{multiValued:!1}),w("primary","boolean","Primary photo indicator.",{multiValued:!1})]}),w("addresses","complex","Physical mailing addresses for the User.",{multiValued:!0,subAttributes:[w("formatted","string","Formatted mailing address.",{multiValued:!1}),w("streetAddress","string","Full street address component.",{multiValued:!1}),w("locality","string","City or locality.",{multiValued:!1}),w("region","string","State or region.",{multiValued:!1}),w("postalCode","string","Postal code.",{multiValued:!1}),w("country","string","Country.",{multiValued:!1}),w("type","string","Address type.",{multiValued:!1}),w("primary","boolean","Primary address indicator.",{multiValued:!1})]}),w("groups","complex","Groups to which the User belongs.",{multiValued:!0,mutability:"readOnly",subAttributes:[w("value","string","Group identifier.",{multiValued:!1,required:!0}),w("$ref","reference","Reference to the Group resource.",{multiValued:!1,referenceTypes:["Group"]}),w("display","string","Display name of the group.",{multiValued:!1}),w("type","string","Relationship type.",{multiValued:!1})]}),w("entitlements","complex","Entitlements for the User.",{multiValued:!0,subAttributes:[w("value","string","Entitlement value.",{multiValued:!1,required:!0}),w("display","string","Display value.",{multiValued:!1}),w("type","string","Entitlement type.",{multiValued:!1}),w("primary","boolean","Primary entitlement indicator.",{multiValued:!1})]}),w("roles","complex","Roles for the User.",{multiValued:!0,subAttributes:[w("value","string","Role value.",{multiValued:!1,required:!0}),w("display","string","Display value.",{multiValued:!1}),w("type","string","Role type.",{multiValued:!1}),w("primary","boolean","Primary role indicator.",{multiValued:!1})]}),w("x509Certificates","complex","Certificates issued to the User.",{multiValued:!0,subAttributes:[w("value","string","Certificate value.",{multiValued:!1,required:!0}),w("display","string","Display value.",{multiValued:!1}),w("type","string","Certificate type.",{multiValued:!1}),w("primary","boolean","Primary certificate indicator.",{multiValued:!1})]})]}),t.push({schemas:[et],id:Ut,name:"EnterpriseUser",description:"Enterprise User extension",meta:{resourceType:"Schema",location:de(e.request,`${e.basePath}/Schemas/${encodeURIComponent(Ut)}`)},attributes:[w("employeeNumber","string","Numeric or alphanumeric identifier assigned to a person.",{multiValued:!1}),w("costCenter","string","Name of a cost center.",{multiValued:!1}),w("organization","string","Name of an organization.",{multiValued:!1}),w("division","string","Name of a division.",{multiValued:!1}),w("department","string","Name of a department.",{multiValued:!1}),w("manager","complex","The User manager.",{multiValued:!1,subAttributes:[w("value","string","Identifier of the manager User resource.",{multiValued:!1}),w("$ref","reference","Reference to the manager User resource.",{multiValued:!1,referenceTypes:["User"]}),w("displayName","string","Display name of the manager.",{multiValued:!1})]})]}),t.push({schemas:[et],id:Me,name:"IoniteUser",description:"ionite User extension carrying ECID, account purpose, and AppDev custom attributes. See https://ionite.com/docs/llms-ecid.txt.",meta:{resourceType:"Schema",location:de(e.request,`${e.basePath}/Schemas/${encodeURIComponent(Me)}`)},attributes:[w("ecid","string","Enterprise Controlled ID formatted as 'ecid:<realm>:<opaque>' (realm = the minting authority's id). Correlates multiple accounts to one identity.",{multiValued:!1,caseExact:!0}),w("accountClass","string","Account purpose (distinct from userType persona). Open value set: 'daily', 'privileged', 'break_glass', 'service'.",{multiValued:!1}),w("attributes","complex","AppDev custom attributes. IAM may override seeded values.",{multiValued:!1,required:!1,mutability:"readWrite"})]});if(e.supportsGroups)t.push({schemas:[et],id:L,name:"IoniteAuthzGroup",description:"ionite authorization metadata for SCIM Group resources.",meta:{resourceType:"Schema",location:de(e.request,`${e.basePath}/Schemas/${encodeURIComponent(L)}`)},attributes:[w("type","string","Authorization entity kind: group, role, or permission.",{multiValued:!1,required:!1}),w("requestable","boolean","Whether this catalog entry is exposed as assignable access to IAM tooling. Only true entries are served.",{multiValued:!1,required:!1}),w("riskLevel","string",`Advisory access-risk classification. Unset values project as ${pt}; canonical values are suggestions, not a closed enum.`,{multiValued:!1,required:!1,mutability:"readWrite",canonicalValues:[...ns]}),w("providerId","string","IAM service-provider id captured when this entitlement is materialized at the destination.",{multiValued:!1,required:!1,mutability:"readWrite"}),w("requestUrl","reference","IAM-owned deep link where a principal can request this entitlement.",{multiValued:!1,required:!1,mutability:"readWrite",referenceTypes:["external"]}),w("source","string","Provenance of the catalog row.",{multiValued:!1,required:!1,mutability:"readOnly",canonicalValues:["code","app","scim"]}),w("deprecated","boolean","Whether this retired entitlement may be deleted.",{multiValued:!1,required:!1,mutability:"readOnly"}),w("description","string","Human-readable authorization entity description.",{multiValued:!1,required:!1}),w("resources","string","Resource ids this entitlement is scoped to.",{multiValued:!0,required:!1}),w("assignableSubjectTypes","string","AppDev-owned required audience of principal kinds (user, workload, customer) that may hold this entitlement. Read-only to IAM tooling.",{multiValued:!0,required:!1,mutability:"readOnly",canonicalValues:["user","customer","workload"]}),w("recommendedSubjectTypes","string","AppDev advisory default principal kinds (subset of assignableSubjectTypes). Read-only to IAM tooling.",{multiValued:!0,required:!1,mutability:"readOnly",canonicalValues:["user","customer","workload"]}),w("attributes","complex","AppDev custom attributes. IAM may override seeded values.",{multiValued:!1,required:!1,mutability:"readWrite"})]});if(e.supportsGroups)t.push({schemas:[et],id:rr,name:"Group",description:"Group",meta:{resourceType:"Schema",location:de(e.request,`${e.basePath}/Schemas/${encodeURIComponent(rr)}`)},attributes:[w("id","string","Unique identifier for the Group.",{multiValued:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),w("externalId","string","External identifier from the provisioning client.",{multiValued:!1,uniqueness:"none"}),w("displayName","string","Human-readable name for the Group.",{multiValued:!1,required:!0,uniqueness:"none"}),w("members","complex","Members of the Group.",{multiValued:!0,subAttributes:[w("value","string","Identifier of the member resource.",{multiValued:!1,required:!0}),w("$ref","reference","Reference to the member resource.",{multiValued:!1,referenceTypes:["User","Group","Workload","Customer"]}),w("display","string","Display name of the member.",{multiValued:!1}),w("type","string","Member type.",{multiValued:!1})]})]});if(e.supportsWorkloads)t.push({schemas:[et],id:mt,name:"Workload",description:"Workload (machine) principal",meta:{resourceType:"Schema",location:de(e.request,`${e.basePath}/Schemas/${encodeURIComponent(mt)}`)},attributes:[w("id","string","Unique identifier for the Workload.",{multiValued:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),w("externalId","string","External identifier from the provisioning client.",{multiValued:!1}),w("userName","string","Login identifier, typically the OAuth clientId.",{multiValued:!1}),w("displayName","string","Human-readable name for the Workload.",{multiValued:!1}),w("description","string","Free-form description of the Workload.",{multiValued:!1}),w("active","boolean","Administrative status of the Workload.",{multiValued:!1}),w("attributes","complex","AppDev custom attributes.",{multiValued:!1,required:!1,mutability:"readWrite"})]});if(e.supportsCustomers)t.push({schemas:[et],id:ft,name:"Customer",description:"Customer (CIAM) principal",meta:{resourceType:"Schema",location:de(e.request,`${e.basePath}/Schemas/${encodeURIComponent(ft)}`)},attributes:[w("id","string","Unique identifier for the Customer.",{multiValued:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),w("externalId","string","External identifier from the provisioning client.",{multiValued:!1}),w("userName","string","Unique identifier typically used for login.",{multiValued:!1}),w("displayName","string","Human-readable name for the Customer.",{multiValued:!1}),w("active","boolean","Administrative status of the Customer.",{multiValued:!1}),w("emails","complex","Email addresses for the Customer.",{multiValued:!0,subAttributes:[w("value","string","Email address.",{multiValued:!1,required:!0}),w("primary","boolean","Whether this is the primary email.",{multiValued:!1})]}),w("attributes","complex","AppDev custom attributes.",{multiValued:!1,required:!1,mutability:"readWrite"})]});return t}function ro(e,t,n,r,s,o,a,u,d,c,E,B,J,X,Q){let C={authz:r,settleAuthz:Q,accessStore:s,accessIndex:o,catalogStore:a,codeCatalog:u,resources:d,log:t,iamDelta:B,onAccessMutation:J};if(!c&&!E)return;let I={...c,...E},Y=I.users?.enabled!==!1,ee=I.groups?.enabled!==!1,re=I.workloads?.enabled!==!1,me=I.customers?.enabled!==!1;if(Boolean(I.url||I.userStore||a||u)&&!n)t.error("IAM requires workload identity for SCIM push/pull operations",{"ion.operation":"workload.require","ion.outcome":"failure"});function ue(){if(!n)throw t.error("IAM requires workload identity for SCIM push/pull operations",{"ion.operation":"workload.require","ion.outcome":"failure"}),Error("IAM requires workload identity for SCIM push/pull operations");return n}async function fe(M){let W=ue(),U=M.headers.get("Authorization");if(!U?.startsWith("Bearer "))return!1;try{let K=U.substring(7);return(await W.validateToken(K)).valid}catch{return!1}}async function rt(){let M=ue(),W=typeof M.getServerToken==="function"?await M.getServerToken():await M.getToken();return new Headers({...Dt,...ss,Authorization:`Bearer ${W}`})}async function st(M,W,U,K){if(!I.url)throw Error("IAM URL not configured for outgoing requests");let _=`${I.url}${W}`;try{let j=await rt(),f=await fetch(_,{method:M,headers:j,body:U?JSON.stringify(U):void 0}),i=await Te(f,{log:t,operation:"scim.request"});if(!f.ok)return{success:!1,error:i,status:f.status};let m=await K["~standard"].validate(i);if(m.issues)return t.error("SCIM response validation failed",{"ion.operation":"scim.response.validate","ion.outcome":"failure",validationIssues:m.issues}),{success:!1,error:{schemas:[tr],status:"400",scimType:"invalidValue",detail:`Response validation failed: ${m.issues.map((p)=>p.message).join("; ")}`},status:400};return{success:!0,data:m.value,status:f.status}}catch(j){return{success:!1,error:{schemas:[tr],status:"500",detail:j instanceof Error?j.message:"Unknown error occurred"},status:500}}}function Ye(){return I.url}function St(M,W){let U=De(W?.usersUrl??I.usersUrl??"/api/iam/Users")??"/api/iam/Users",K=De(W?.groupsUrl??I.groupsUrl??"/api/iam/Groups")??"/api/iam/Groups",_=De(W?.workloadsUrl??I.workloadsUrl??"/api/iam/Workloads")??"/api/iam/Workloads",j=De(W?.customersUrl??I.customersUrl??"/api/iam/Customers")??"/api/iam/Customers",f=De(W?.discovery?.basePath??I.discovery?.basePath)??ts(U,K,_,j);if(!f)return;return{request:M,basePath:f,usersUrl:U,groupsUrl:K,workloadsUrl:_,customersUrl:j,supportsUsers:Y&&Boolean(I.userStore),supportsGroups:ee&&Boolean(a||u),supportsWorkloads:re&&Boolean(I.workloadIdentityStore),supportsCustomers:me&&Boolean(I.customerStore)}}async function it(M){let W=eo(M,I.discovery);return await I.discovery?.buildServiceProviderConfig?.(M,W)??W}async function _e(M){let W=to(M);return await I.discovery?.buildResourceTypes?.(M,W)??W}async function qe(M){let W=no(M);return await I.discovery?.buildSchemas?.(M,W)??W}async function je(M,W){let U=St(M,W);if(!U)return;let K=Qt(new URL(M.url).pathname),{basePath:_}=U;if(K!==_&&!K.startsWith(`${_}/`))return;let j=Qt(K.slice(_.length)||"/");if(!(j==="/ServiceProviderConfig"||j==="/ResourceTypes"||j.startsWith("/ResourceTypes/")||j==="/Schemas"||j.startsWith("/Schemas/")))return;if(M.method!=="GET")return V(405,"Method not allowed");if(!await fe(M))return V(401,"Authorization required");if(j==="/ServiceProviderConfig")return ye(await it(U));if(j==="/ResourceTypes")return Ve(await _e(U));if(j.startsWith("/ResourceTypes/")){let m=decodeURIComponent(j.slice(15)),p=(await _e(U)).find((g)=>g.id===m||g.name===m);return p?ye(p):V(404,"Resource not found")}if(j==="/Schemas")return Ve(await qe(U));if(j.startsWith("/Schemas/")){let m=decodeURIComponent(j.slice(9)),p=(await qe(U)).find((g)=>g.id===m);return p?ye(p):V(404,"Resource not found")}return}let ot,ze;if(I.url)ze=async(W,U)=>{let K={...W,schemas:W.schemas??["urn:ietf:params:scim:schemas:core:2.0:User","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"]};return st("POST","/Users",K,e.user)},ot={createGroup:async(W,U)=>{let K={schemas:["urn:ietf:params:scim:schemas:core:2.0:Group"],displayName:W,externalId:U?.id,members:U?.members};return st("POST","/Groups",K,e.group)}};let Be;if(a||u){let M=cr(u,a),W=(y,l,h)=>{let S=y[L]??{},k=yt(y),R=y.id,D=R?de(l,`${h}/${encodeURIComponent(R)}`):void 0,A={id:R??y.externalId??y.displayName,name:y.displayName,displayName:y.displayName,description:S.description??y.displayName,requestable:S.requestable,providerId:S.providerId??y.externalId,requestUrl:S.requestUrl,source:S.source,deprecated:S.deprecated,riskLevel:S.riskLevel,assignableSubjectTypes:S.assignableSubjectTypes,recommendedSubjectTypes:S.recommendedSubjectTypes},O=S.requestUrl??I.entitlementRequestUrl?.(A,k,{request:l});return{...y,meta:{...y.meta,resourceType:"Group",location:D},[L]:{...S,requestUrl:O}}},U=(y)=>ir(u,y),K=async(y,l)=>{if(!a){if(l)throw Error(`Cannot persist access for code entitlement "${y.entity.id}": no AccessCatalogStore is wired.`);return y.entity}try{return await ar(y.kind,y.entity,or(a,y.kind))}catch(h){if(l)throw h;return t.warn("Code entitlement discovery materialization failed; serving the code template",{"ion.operation":"iam.catalog.materialize","ion.outcome":"degraded",entitlementId:y.entity.id,entitlementType:y.kind,error:Oe(h)}),y.entity}},_=async(y)=>{if(!a)return;try{await rs(u,a,y)}catch(l){t.warn("Retired code entitlement deprecation failed; serving the last durable row",{"ion.operation":"iam.catalog.deprecate","ion.outcome":"degraded",entitlementId:y,error:Oe(l)})}},j=(y,l)=>V(403,`Entitlement "${y}" is declared in application code; its structural definition cannot be ${l} through SCIM. IAM may change presentation and receipts, while code continues to own structure.`,"mutability"),f=(y)=>y.path==="members"||Boolean(y.path?.startsWith("members[")),i=(y)=>f(y)||y.path==="displayName"||y.path===`${L}.description`||y.path===`${L}.riskLevel`||y.path===`${L}.providerId`||y.path===`${L}.requestUrl`||y.path===`${L}.attributes`||Boolean(y.path?.startsWith(`${L}.attributes.`)),m=(y)=>y?.[L]?.requestable===!0,p=(y)=>V(404,`Requestable Group ${y} not found`,"invalidValue"),g=async(y,l)=>{if(!await fe(y))return V(401,"Authorization required");let S=new URL(y.url),k=l?.basePath??"/Groups",R=S.pathname;if(R.startsWith(k))R=R.substring(k.length);let A=R.match(/^\/([^/]+)$/)?.[1],O=y.method;try{if(A)switch(O){case"GET":return await T(y,k,A);case"PUT":return await x(y,k,A);case"PATCH":return await v(y,k,A);case"DELETE":return await N(A);default:return V(405,"Method not allowed")}else if(R===""||R==="/")switch(O){case"GET":return await b(y,k);case"POST":return await P(y,k);default:return V(405,"Method not allowed")}return V(404,"Resource not found")}catch(z){if(z instanceof kt)return Yr(z);if(z instanceof rn)return V(400,z.message,"invalidValue");if(en(z))return V(409,z.message,"uniqueness");return t.error("Groups inbound handler error",{"ion.operation":"scim.groups.handler","ion.outcome":"failure"},z),V(500,z instanceof Error?z.message:"Internal server error")}},b=async(y,l)=>{let h=new URL(y.url),S=h.searchParams.get("startIndex"),k=h.searchParams.get("count"),R=S!=null?parseInt(S,10):void 0,D=k!=null?parseInt(k,10):void 0,A=R!=null&&!Number.isNaN(R)?Math.max(0,R-1):0,O=D!=null&&!Number.isNaN(D)?D:void 0,z=h.searchParams.get("filter"),G=Qr(z);if(G!==void 0){await _();let F=await Yi(M,s,G,X),he=F?[W(F,y,l)]:[];return Ve(he,{totalResults:he.length,startIndex:1,itemsPerPage:he.length})}if(Ji(z)?.requestable===!1)return Ve([],{totalResults:0,startIndex:1,itemsPerPage:0});let ne={requestable:!0};if(u)await Promise.all([...u.groups.list().filter((F)=>F.requestable===!0).map((F)=>({entity:F,kind:"group"})),...u.roles.list().filter((F)=>F.requestable===!0).map((F)=>({entity:F,kind:"role"})),...u.permissions.list().filter((F)=>F.requestable===!0).map((F)=>({entity:F,kind:"permission"}))].map((F)=>K(F,!1)));await _();let te=await Xi(M,s,{start:A,limit:O,filter:ne},X);return Ve(te.resources.map((F)=>W(F,y,l)),{totalResults:te.total,startIndex:A+1,itemsPerPage:te.count})},T=async(y,l,h)=>{let S=U(h);if(S&&S.entity.requestable!==!0)return p(h);if(S)await K(S,!1);await _(h);let k=await Tt(M,s,h,X);if(!m(k))return p(h);return ye(W(k,y,l))},P=async(y,l)=>{let h=await y.json(),S=await He(e.group,h);if(S.issues)return t.error("Group creation validation failed",{"ion.operation":"scim.group.create","ion.outcome":"failure",validationIssues:S.issues}),V(400,`Request validation failed: ${S.issues.map((te)=>te.message).join("; ")}`,"invalidValue");let k=S.value;if(!k.displayName)return V(400,"displayName is required","invalidValue");if(k[L]?.requestable===!1)return V(400,"SCIM may create only requestable entitlements; non-requestable definitions are App-owned.","invalidValue");if(k[L]={...k[L],requestable:!0},!a)return V(501,"Group creation is not supported: this application declares its catalog in code (authz.catalog) and wires no AccessCatalogStore for SCIM-authored definitions.","invalidValue");let D=yt(k),A=Yt();if(U(A))throw new pr(`id "${A}" is reserved by the code catalog`,"unique_violation","id");let O=Yn(k),z=Zt(new Map,Ft(k.members,D,A,O,k[L]?.assignableSubjectTypes)),G;await gt(C,async()=>{G=await Qn(M,k,A)},z,{oaa:()=>Zn(r,G,D)});let se=await tt(M,s,D,A),ne=W(nt(G,D,se),y,l);return ye(ne,201,ne.meta?.location)},x=async(y,l,h)=>{let S=await y.json(),k=await He(e.group,S);if(k.issues)return t.error("Group replacement validation failed",{"ion.operation":"scim.group.replace","ion.outcome":"failure",validationIssues:k.issues}),V(400,`Request validation failed: ${k.issues.map((he)=>he.message).join("; ")}`,"invalidValue");let R=k.value,D=yt(R),A=U(h);if(A&&A.entity.requestable!==!0)return p(h);if(A){if(await K(A,!0),Ni(R,A))return j(h,"replaced")}let O=await Tt(M,s,h);if(!m(O))return p(h);if(!A&&O[L]?.source==="code"&&$i(R,O))return j(h,"replaced");let z=A?.kind??D,G=A?sr(A.entity):Yn(R),se=s?(await s.listByTarget(z,h)).items:[],ne=Zt(Wi(se),Ft(R.members,z,h,G,A?.entity.assignableSubjectTypes??O[L]?.assignableSubjectTypes??R[L]?.assignableSubjectTypes)),te;await gt(C,async()=>{te=await Qn(M,R,h,A?.entity)},ne,{oaa:()=>Zn(r,te,z)});let F=await tt(M,s,z,h);return ye(W(nt(te,z,F),y,l))},v=async(y,l,h)=>{let S=U(h);if(S&&S.entity.requestable!==!0)return p(h);if(S)await K(S,!0);let k=await Tt(M,s,h);if(!m(k))return p(h);let R=await y.json();if((S!==void 0||k[L]?.source==="code")&&(R.Operations??[]).some((H)=>!i(H)))return j(h,"patched");let A={...k};for(let H of R.Operations??[])if(H.op==="replace"&&H.path&&H.value!==void 0){if(H.path==="displayName")A.displayName=H.value;else if(H.path===`${L}.requestable`)A[L]={...A[L],requestable:Boolean(H.value)};else if(H.path===`${L}.description`)A[L]={...A[L],description:String(H.value)};else if(H.path===`${L}.riskLevel`)A[L]={...A[L],riskLevel:String(H.value)};else if(H.path===`${L}.providerId`)A[L]={...A[L],providerId:String(H.value)};else if(H.path===`${L}.requestUrl`)A[L]={...A[L],requestUrl:String(H.value)};else if(H.path===`${L}.attributes`&&typeof H.value==="object"&&H.value!==null&&!Array.isArray(H.value))A[L]={...A[L],attributes:H.value};else if(H.path.startsWith(`${L}.attributes.`)){let ve=H.path.slice(`${L}.attributes.`.length);A[L]={...A[L],attributes:{...A[L]?.attributes,[ve]:H.value}}}}else if(H.op==="add"&&H.path==="members"&&H.value!==void 0){let ve=H.value;A.members=[...A.members??[],...ve]}else if(H.op==="remove"&&H.path?.startsWith("members[")){let ve=H.path.match(/members\[value eq "([^"]+)"\]/);if(ve)A.members=(A.members??[]).filter((ae)=>ae.value!==ve[1])}else if(H.op==="remove"&&H.path?.startsWith(`${L}.attributes.`)){let ve=H.path.slice(`${L}.attributes.`.length),ae={...A[L]?.attributes};delete ae[ve],A[L]={...A[L],attributes:ae}}let O=await He(e.group,A);if(O.issues)return t.error("Group patch validation failed",{"ion.operation":"scim.group.patch","ion.outcome":"failure",validationIssues:O.issues}),V(400,`Request validation failed: ${O.issues.map((H)=>H.message).join("; ")}`,"invalidValue");let z=S?.kind??yt(A),G=S?sr(S.entity):Yn(A),se=S?.entity.assignableSubjectTypes??k[L]?.assignableSubjectTypes??A[L]?.assignableSubjectTypes,ne=Zt(Ft(k.members,z,h,G,se),Ft(A.members,z,h,G,se)),te,F=!S||(R.Operations??[]).some((H)=>!f(H));await gt(C,async()=>{if(F)te=await Qn(M,A,h,S?.entity)},ne,F?{oaa:()=>Zn(r,te,z)}:void 0);let he=await Tt(M,s,h);return ye(W(he,y,l))},N=async(y)=>{let l=U(y);if(l&&l.entity.requestable!==!0)return p(y);if(l)await K(l,!0);let h=await Tt(M,s,y);if(!m(h))return p(y);let S=h[L];if((l||S?.source==="code")&&S?.deprecated!==!0)return V(403,`Code-owned entitlement "${y}" can be deleted only after it is marked deprecated.`,"mutability");let k=yt(h);if(s){let R=await s.listByTarget(k,y),D=[];for(let A of R.items)await xt(C,A,D);await Xt(C,D)}return await Zi(M,y),new Response(null,{status:204})};Be={handler:g}}let Se,be,Ie;if(I.userStore){let{userStore:M,inboundUsers:W}=I,U=(l)=>l?.find((h)=>h.primary)?.value||l?.[0]?.value,K=async(l)=>{if(W?.mapBaseUserToScim)return await W.mapBaseUserToScim(l);return Kn(l)},_=async(l,h,S)=>{let k=await K(l),R=k.id??l.id;return{...k,id:R,meta:{...k.meta,resourceType:"User",location:R?de(h,`${S}/${encodeURIComponent(R)}`):void 0}}},j=async(l,h)=>{if(W?.mapValidatedScimToBaseUser)return await W.mapValidatedScimToBaseUser(l,h);let S=new Date,k=U(l.emails),R=l.name?.formatted||[l.name?.givenName,l.name?.middleName,l.name?.familyName].filter(Boolean).join(" ").trim()||l.displayName,D=l.id||h.existing?.id||Yt(),A=l.userName||k||h.existing?.userName||D,O=R||l.displayName||h.existing?.name||A,z=Object.fromEntries(Object.entries(l).filter(([he,H])=>he.startsWith("urn:")&&he!==Ut&&he!==Me&&H!==void 0)),G=l[Me],se=we(G?.attributes??{},Kt),ne=G?.ecid!==void 0&&G.ecid!==null?tn(G.ecid):h.existing?.ecid,te=G?.accountClass??h.existing?.accountClass,F=h.existing?.sso;return{...h.existing??{},id:D,userName:A,name:O,email:k||h.existing?.email||A,avatar:l.profileUrl,sso:{...F??{},profile:{...F?.profile??{},sub:D,iss:F?.profile.iss??"iam-provisioned",aud:F?.profile.aud??"iam-provisioned",exp:F?.profile.exp??Math.floor(Date.now()/1000)+3600,iat:F?.profile.iat??Math.floor(Date.now()/1000),email:k||h.existing?.email||A,email_verified:!0,name:O,preferred_username:A},tenant:F?.tenant??{id:"iam-provisioned",name:"IAM Provisioned"},scope:F?.scope??"openid profile email",tokenType:F?.tokenType??"Bearer",expires:F?.expires??new Date(Date.now()+3600000)},externalId:l.externalId,ecid:ne,accountClass:te,displayName:l.displayName,scimName:l.name,emails:l.emails,nickName:l.nickName,title:l.title,preferredLanguage:l.preferredLanguage,locale:l.locale,timezone:l.timezone,active:l.active,phoneNumbers:l.phoneNumbers,ims:l.ims,photos:l.photos,addresses:l.addresses,groups:l.groups,entitlements:l.entitlements,roles:l.roles,x509Certificates:l.x509Certificates,scimEnterprise:l[Ut],scimSchemaExtensions:Object.keys(z).length>0?z:void 0,createdAt:h.existing?.createdAt??(l.meta?.created?new Date(l.meta.created):S),updatedAt:l.meta?.lastModified?new Date(l.meta.lastModified):S,userType:l.userType,...se}},f=(l,h,S)=>{l[h]=S},i=(l,h,S)=>{let k=l[h];if(Array.isArray(k)){l[h]=[...k,...Array.isArray(S)?S:[S]];return}if(k&&typeof k==="object"&&!Array.isArray(k)&&S&&typeof S==="object"&&!Array.isArray(S)){l[h]={...k,...S};return}l[h]=S},m=(l,h,S)=>{let k=h.match(/^(urn:.*:(?:User|Group))(?::(.+))?$/),R=k?[k[1],...k[2]?.split(":")??[]]:h.split("."),D=l;for(let O of R.slice(0,-1)){let z=D[O];if(z===void 0){if(!S)return null;D[O]={}}else if(z===null||typeof z!=="object"||Array.isArray(z)){if(!S)return null;D[O]={}}D=D[O]}let A=R.at(-1);if(!A)return null;return{parent:D,key:A}},p=(l,h)=>{let S=h.op.toLowerCase();if(!h.path){if(S!=="remove"&&h.value&&typeof h.value==="object"&&!Array.isArray(h.value))Object.assign(l,h.value);return}let k=h.path.match(/^([A-Za-z0-9]+)\[value eq "([^"]+)"\]$/);if(k&&S==="remove"){let[,D,A]=k,O=l[D];if(Array.isArray(O))l[D]=O.filter((z)=>!(z&&typeof z==="object"&&("value"in z)&&z.value===A));return}let R=m(l,h.path,S!=="remove");if(!R)return;if(S==="remove"){delete R.parent[R.key];return}if(S==="add"){i(R.parent,R.key,h.value);return}f(R.parent,R.key,h.value)},g=async(l,h)=>{if(!await fe(l))return V(401,"Authorization required");let k=new URL(l.url),R=h?.basePath??"/Users",D=k.pathname;if(D.startsWith(R))D=D.substring(R.length);let O=D.match(/^\/([^/]+)$/)?.[1],z=l.method;try{if(O)switch(z){case"GET":return await T(l,R,O);case"PUT":return await v(l,R,O);case"PATCH":return await N(l,R,O);case"DELETE":return await y(O);default:return V(405,"Method not allowed")}else if(D===""||D==="/")switch(z){case"GET":return await b(l,R);case"POST":return await x(l,R);default:return V(405,"Method not allowed")}return V(404,"Resource not found")}catch(G){if(G instanceof kt)return Yr(G);if(en(G))return V(409,G.message,"uniqueness");return t.error("Users inbound handler error",{"ion.operation":"scim.users.handler","ion.outcome":"failure"},G),V(500,G instanceof Error?G.message:"Internal server error")}},b=async(l,h)=>{let S=new URL(l.url),k=S.searchParams.get("startIndex"),R=S.searchParams.get("count"),D=k!=null?parseInt(k,10):void 0,A=R!=null?parseInt(R,10):void 0,O=D!=null&&!Number.isNaN(D)?Math.max(0,D-1):0,z=A!=null&&!Number.isNaN(A)?A:void 0,G=Qr(S.searchParams.get("filter"));if(G!==void 0){let te=await M.lookup({externalId:G}),F=te?[await _(te,l,h)]:[];return Ve(F,{totalResults:F.length,startIndex:1,itemsPerPage:F.length})}let se=await M.list({start:O,limit:z}),ne=await Promise.all(se.items.map((te)=>_(te,l,h)));return Ve(ne,{totalResults:se.total,startIndex:O+1,itemsPerPage:se.count})},T=async(l,h,S)=>{let k=await M.get(S);if(!k)return V(404,`User ${S} not found`,"invalidValue");return ye(await _(k,l,h))},P=async(l,h)=>{let S=C.accessIndex;if(!S?.setSubjectDisabled||!h.id)return;let k=l?l.active??!0:!0,R=h.active??!0;if(l&&k===R)return;if(!l&&R)return;await S.setSubjectDisabled(h.id,"user",!R)},x=async(l,h)=>{let S=await l.json(),k=await He(e.user,S);if(k.issues)return t.error("User creation validation failed",{"ion.operation":"scim.user.create","ion.outcome":"failure",validationIssues:k.issues}),V(400,`Request validation failed: ${k.issues.map((O)=>O.message).join("; ")}`,"invalidValue");let R=k.value;if(!R.userName&&!R.emails?.[0]?.value)return V(400,"userName or email is required","invalidValue");let D=await j(R,{mode:"create"});await gt(C,async()=>{await M.upsert(D),await P(void 0,D)},Fn(void 0,D),{oaa:async()=>{await Xn(r,D)},delta:async()=>{await C.iamDelta?.onUserUpsert(D)}});let A=await _(D,l,h);return ye(A,201,A.meta?.location)},v=async(l,h,S)=>{let k=await M.get(S);if(!k)return V(404,`User ${S} not found`,"invalidValue");let R=await l.json(),D=await He(e.user,R);if(D.issues)return t.error("User replacement validation failed",{"ion.operation":"scim.user.replace","ion.outcome":"failure",validationIssues:D.issues}),V(400,`Request validation failed: ${D.issues.map((z)=>z.message).join("; ")}`,"invalidValue");let A=D.value,O=await j({...A,id:S},{existing:k,mode:"replace"});return O.createdAt=k.createdAt,O.updatedAt=new Date,await gt(C,async()=>{await M.upsert(O),await P(k,O)},Fn(k,O),{oaa:async()=>{await Xn(r,O)},delta:async()=>{await Zr(C.iamDelta,k,O)}}),ye(await _(O,l,h))},N=async(l,h,S)=>{let k=await M.get(S);if(!k)return V(404,`User ${S} not found`,"invalidValue");let D=(await l.json()).Operations??[],O={...await K(k)};for(let se of D)p(O,se);let z=await He(e.user,O);if(z.issues)return t.error("User patch validation failed",{"ion.operation":"scim.user.patch","ion.outcome":"failure",validationIssues:z.issues}),V(400,`Request validation failed: ${z.issues.map((se)=>se.message).join("; ")}`,"invalidValue");let G=await j(z.value,{existing:k,mode:"patch"});return G.updatedAt=new Date,await gt(C,async()=>{await M.upsert(G),await P(k,G)},Fn(k,G),{oaa:async()=>{await Xn(r,G)},delta:async()=>{await Zr(C.iamDelta,k,G)}}),ye(await _(G,l,h))},y=async(l)=>{let h=await M.get(l);if(!h)return V(404,`User ${l} not found`,"invalidValue");if(s){let S=[];for await(let k of ht((R,D)=>s.listBySubject(l,"user",{start:R,limit:D})))await xt(C,k,S);await Xt(C,S)}if(await M.delete(l),await C.accessIndex?.setSubjectDisabled?.(l,"user",!1),h.externalId&&C.iamDelta?.isReady())await Fe(C,"iam.delta.egress","IAM delta user delete failed after SCIM write; full aggregation will reconcile",()=>C.iamDelta?.onUserDelete(h.externalId)??Promise.resolve(),{id:l,kind:"user"});else if(C.iamDelta?.isReady())C.log?.warn("IAM delta: deleted User has no externalId; destination delete skipped",{"ion.operation":"iam.delta.delete","ion.outcome":"skipped",id:l,kind:"user"});if(C.authz.oaa.isReady())await Fe(C,"authz.oaa.delete","OAA incremental user delete failed; full sync will reconcile",()=>C.authz.oaa.deleteUser(l),{id:l,kind:"user"});return new Response(null,{status:204})};Se={handler:g}}let Le=async(M,W)=>{if(!s)return;let U=[];for await(let K of ht((_,j)=>s.listBySubject(M,W,{start:_,limit:j})))await xt(C,K,U);await Xt(C,U)};if(I.workloadIdentityStore){let{workloadIdentityStore:M,inboundWorkloads:W}=I;be=es({resourceType:"Workload",subjectType:"workload",store:M,validator:e.workload??os,toScim:async(U)=>await(W?.mapBaseWorkloadToScim?.(U)??Gn(U)),fromScim:async(U,K)=>{if(W?.mapValidatedScimToBaseWorkload)return W.mapValidatedScimToBaseWorkload(U,K);let _=K.existing,j=U,f=j.id?.trim()||_?.id||Yt(),i=we(j.attributes??{},Jt);return{..._??{},id:f,externalId:j.externalId??_?.externalId,clientId:j.userName??_?.clientId??f,displayName:j.displayName??_?.displayName,description:j.description??_?.description,active:j.active??_?.active??!0,providerId:_?.providerId,requestUrl:_?.requestUrl,...i}},projections:[{channel:"oaa",upsert:async(U)=>{if(r.oaa.isReady())await r.oaa.pushWorkload(U)},delete:async(U)=>{if(r.oaa.isReady())await r.oaa.deleteWorkload(U.id)}},{channel:"delta",upsert:async(U,K)=>{let _=K?.externalId??K?.id,j=U.externalId??U.id;if(_&&_!==j)await B?.onWorkloadDelete(_);await B?.onWorkloadUpsert(U)},delete:async(U)=>{await B?.onWorkloadDelete(U.externalId??U.id)}}]},{validateAuth:fe,accessStore:s,accessIndex:o,revokeSubjectAccess:Le,log:t})}if(I.customerStore){let{customerStore:M,inboundCustomers:W}=I;Ie=es({resourceType:"Customer",subjectType:"customer",store:M,validator:e.customer??as,toScim:async(U)=>await(W?.mapBaseCustomerToScim?.(U)??Jn(U)),fromScim:async(U,K)=>{if(W?.mapValidatedScimToBaseCustomer)return W.mapValidatedScimToBaseCustomer(U,K);let _=K.existing,j=U,f=j.id?.trim()||_?.id||Yt(),i=we(j.attributes??{},Gt),m=j.emails?.find((p)=>p.primary)?.value??j.emails?.[0]?.value;return{..._??{},id:f,externalId:j.externalId??_?.externalId??f,userName:j.userName??_?.userName??f,name:j.displayName??_?.name??j.userName??f,email:m??_?.email??"",displayName:j.displayName??_?.displayName,emails:j.emails??_?.emails,active:j.active??_?.active??!0,providerId:_?.providerId,requestUrl:_?.requestUrl,...i}},projections:[{channel:"oaa",upsert:async(U)=>{if(r.oaa.isReady())await r.oaa.pushCustomer(U)},delete:async(U)=>{if(r.oaa.isReady()&&U.id)await r.oaa.deleteCustomer(U.id)}},{channel:"delta",upsert:async(U,K)=>{let _=K?.externalId??K?.id,j=U.externalId??U.id;if(_&&_!==j)await B?.onCustomerDelete(_);await B?.onCustomerUpsert(U)},delete:async(U)=>{let K=U.externalId??U.id;if(K)await B?.onCustomerDelete(K)}}]},{validateAuth:fe,accessStore:s,accessIndex:o,revokeSubjectAccess:Le,log:t})}async function Ue(M,W){ue();let U=new URL(M.url).pathname,K=De(W?.usersUrl??I.usersUrl??"/api/iam/Users")??"/api/iam/Users",_=De(W?.groupsUrl??I.groupsUrl??"/api/iam/Groups")??"/api/iam/Groups",j=De(W?.workloadsUrl??I.workloadsUrl??"/api/iam/Workloads")??"/api/iam/Workloads",f=De(W?.customersUrl??I.customersUrl??"/api/iam/Customers")??"/api/iam/Customers",i=`${ts(K,_,j,f)??"/api/iam"}/AccessRequests`,m=await je(M,W);if(m)return m;let p=(g)=>U===g||U.startsWith(`${g}/`);if(p(K)){if(!Y)return V(404,"SCIM Users endpoint is disabled by RemoteConfig");if(!Se)return V(501,"SCIM Users endpoint is enabled by RemoteConfig but no user store capability is wired by the application.");return Se.handler(M,{basePath:K})}if(p(_)){if(!ee)return V(404,"SCIM Groups endpoint is disabled by RemoteConfig");if(!Be)return V(501,"SCIM Groups endpoint is enabled by RemoteConfig but no AccessCatalogStore capability is wired by the application.");return Be.handler(M,{basePath:_})}if(p(j)){if(!re)return V(404,"SCIM Workloads endpoint is disabled by RemoteConfig");if(!be)return V(501,"SCIM Workloads endpoint is enabled by RemoteConfig but no workload identity store capability is wired by the application.");return be.handler(M,{basePath:j})}if(p(f)){if(!me)return V(404,"SCIM Customers endpoint is disabled by RemoteConfig");if(!Ie)return V(501,"SCIM Customers endpoint is enabled by RemoteConfig but no customer store capability is wired by the application.");return Ie.handler(M,{basePath:f})}if(p(i)){if(!I.accessRequests)return V(404,"AccessRequests endpoint is not configured");if(M.method!=="POST")return V(405,"Method not allowed");if(!await fe(M))return V(401,"Authorization required");let g;try{g=await M.json()}catch{return V(400,"Request body must be valid JSON","invalidSyntax")}if(typeof g.subject!=="string"||!g.subject||typeof g.target!=="string"||!g.target||g.subjectType!=="user"&&g.subjectType!=="workload"&&g.subjectType!=="customer"||g.targetType!=="group"&&g.targetType!=="role"&&g.targetType!=="permission"||g.operation!=="grant"&&g.operation!=="revoke")return V(400,"subject, subjectType, targetType, target, and operation are required","invalidValue");let b=await I.accessRequests.create({subject:g.subject,subjectType:g.subjectType,targetType:g.targetType,target:g.target,operation:g.operation,justification:typeof g.justification==="string"?g.justification:void 0});return ye(b.request,b.created?201:200,b.request.trackingUrl)}return V(404,"Resource not found")}return{...I,users:Hn(I.users),workloads:Hn(I.workloads),customers:Hn(I.customers),groups:{enabled:ee},createUser:ze,getBaseUrl:Ye,groups_outbound:ot,groups_inbound:Be,users_inbound:Se,workloads_inbound:be,customers_inbound:Ie,handler:Ue,delta:B}}function mr(e,t){let n=new TextEncoder().encode(e),r=typeof t==="string"?new TextEncoder().encode(t):t,s=new Uint8Array(n.length+1+r.length);return s.set(n,0),s[n.length]=46,s.set(r,n.length+1),s}function so(e){let t=e.replace(/-/g,"+").replace(/_/g,"/"),n=t.length%4===0?"":"=".repeat(4-t.length%4),r=atob(t+n),s=new Uint8Array(r.length);for(let o=0;o<r.length;o++)s[o]=r.charCodeAt(o);return s}function io(e){let t="";for(let n of e)t+=String.fromCharCode(n);return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function us(e){let t=JSON.parse(e);if(!t||typeof t!=="object"||!Array.isArray(t.keys))throw Error("Invalid JWKS: expected { keys: [...] }");return t}function oo(e){return JSON.stringify(e)}async function ao(e){return crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:e.x},{name:"Ed25519"},!0,["verify"])}async function co(e){return crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:e.x,d:e.d},{name:"Ed25519"},!0,["sign"])}async function uo(e){let n=(typeof e.jwks==="string"?us(e.jwks):e.jwks).keys.find((r)=>r.kid===e.kid&&r.kty==="OKP"&&r.crv==="Ed25519");if(!n?.x)return!1;try{let r=await ao(n),s=mr(e.requestId,e.rawBody),o=so(e.signatureB64Url);return crypto.subtle.verify({name:"Ed25519"},r,o,s)}catch{return!1}}async function lo(e){let t=await co(e.privateKeyJwk),n=mr(e.requestId,e.rawBody),r=await crypto.subtle.sign({name:"Ed25519"},t,n);return io(new Uint8Array(r))}async function po(e){let t=await crypto.subtle.generateKey({name:"Ed25519"},!0,["sign","verify"]),n=await crypto.subtle.exportKey("jwk",t.privateKey),s=(await crypto.subtle.exportKey("jwk",t.publicKey)).x,o=n.d;if(!s||!o)throw Error("Failed to export Ed25519 key material (missing x/d)");return{privateJwk:{kty:"OKP",crv:"Ed25519",x:s,d:o,kid:e,alg:"EdDSA",use:"sig"},publicJwks:{keys:[{kty:"OKP",crv:"Ed25519",x:s,kid:e,alg:"EdDSA",use:"sig"}]}}}var Ot={jwksTtlSeconds:{min:60,max:86400,default:600},jwksMaxEntries:{min:16,max:4096,default:256},sessionReadTtlSeconds:{min:1,max:300,default:30},sessionReadMaxEntries:{min:16,max:65536,default:1024}};function sn(e,t){if(typeof e!=="number"||!Number.isFinite(e))return t.default;let n=Math.floor(e);if(n<t.min)return t.min;if(n>t.max)return t.max;return n}function ds(e){return{ttlMs:sn(e?.ttlSeconds,Ot.jwksTtlSeconds)*1000,maxEntries:sn(e?.maxEntries,Ot.jwksMaxEntries)}}function ls(e){let t=e?.read;return{read:{enabled:t?.enabled===!0,ttlMs:sn(t?.ttlSeconds,Ot.sessionReadTtlSeconds)*1000,maxEntries:sn(t?.maxEntries,Ot.sessionReadMaxEntries)}}}function mo(e){return{jwks:ds(e?.jwks),session:ls(e?.session)}}var on=new TextEncoder,fo=new TextDecoder;function fs(e){let t="";for(let n of e)t+=String.fromCharCode(n);return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function ps(e){return fs(on.encode(JSON.stringify(e)))}function gs(e){if(!/^[A-Za-z0-9_-]+$/.test(e))return;let t=e.replace(/-/g,"+").replace(/_/g,"/").padEnd(Math.ceil(e.length/4)*4,"=");try{return Uint8Array.from(atob(t),(n)=>n.charCodeAt(0))}catch{return}}function ms(e){let t=gs(e);if(!t)return;try{let n=JSON.parse(fo.decode(t));return n!==null&&typeof n==="object"&&!Array.isArray(n)?n:void 0}catch{return}}function go(e){return on.encode(e)}function ys(e){let t=new Uint8Array(e.byteLength);return t.set(e),t.buffer}async function hs(e){return crypto.subtle.importKey("raw",ys(go(e)),{name:"HMAC",hash:"SHA-256"},!1,["sign","verify"])}function yo(e){let t=e.active.trim(),n=new Map(Object.entries(e.keys).map(([s,o])=>[s.trim(),{kid:s.trim(),secret:o}])),r=n.get(t);if(!t||!r?.secret)throw Error("Signing key ring must name a non-empty active key.");for(let s of n.values())if(!s.kid||!s.secret)throw Error("Signing key ring ids and secrets must be non-empty.");return{current:()=>r,find:(s)=>n.get(s)}}async function ho(e,t,n){let r=Math.floor(n.ttlSeconds);if(!Number.isFinite(r)||r<1)throw Error("Compact JWT ttlSeconds must be a positive integer.");let s=t.current();if(!s.kid||!s.secret)throw Error("Signing key ring returned an invalid active key.");let o=Math.floor(Date.now()/1000),a=ps({alg:"HS256",kid:s.kid,typ:"JWT"}),u=ps({...e,iat:o,exp:o+r}),d=`${a}.${u}`,c=await crypto.subtle.sign("HMAC",await hs(s.secret),on.encode(d));return`${d}.${fs(new Uint8Array(c))}`}async function ko(e,t){let n=e.split(".");if(n.length!==3)return null;let[r,s,o]=n;if(!r||!s||!o)return null;let a=ms(r);if(a?.alg!=="HS256"||a.typ!=="JWT"||typeof a.kid!=="string")return null;let u=t.find(a.kid);if(!u?.secret)return null;let d=gs(o);if(!d)return null;if(!await crypto.subtle.verify("HMAC",await hs(u.secret),ys(d),on.encode(`${r}.${s}`)))return null;let E=ms(s);if(!E)return null;let{iat:B,exp:J}=E;if(typeof B!=="number"||typeof J!=="number"||!Number.isSafeInteger(B)||!Number.isSafeInteger(J))return null;let X=Math.floor(Date.now()/1000);if(B>X+60||J+60<=X)return null;return E}function So(e){let t={};if(!e)return t;let n=e.split(";");for(let r of n){let s=r.trim();if(!s)continue;let o=s.indexOf("=");if(o===-1)continue;t[s.slice(0,o).trim()]=s.slice(o+1).trim()}return t}function ks(e){if(!e.expiresAt)return!1;let t=e.expiresAt instanceof Date?e.expiresAt:new Date(e.expiresAt);return!Number.isNaN(t.getTime())&&Date.now()>t.getTime()}function wo(e){if(!e||typeof e!=="object"||Array.isArray(e))return;let{access_token:t,id_token:n,refresh_token:r,tokens:s,...o}=e;return o}function Pe(e,t){let n=e[t];return typeof n==="string"?n:""}function Co(e,t){let n=e.exp;if(typeof n==="number")return new Date(n*1000);if(typeof n==="string"&&n.trim()){let r=Number(n);if(!Number.isNaN(r))return new Date(r*1000)}if(t instanceof Date)return t;if(t){let r=new Date(t);if(!Number.isNaN(r.getTime()))return r}return new Date}function bo(e){let t=e.claims;if(!t?.sub||typeof t.sub!=="string")return;let n=Co(t,e.expiresAt);if(e.authType==="sso")return{id:t.sub,userName:Pe(t,"preferred_username"),name:Pe(t,"name"),email:Pe(t,"email"),avatar:Pe(t,"picture")||void 0,sso:{profile:t,tenant:{id:Pe(t,"idp")||Pe(t,"iss"),name:Pe(t,"iss")},tokenType:"Bearer",expires:n}};return{id:t.sub,userName:Pe(t,"preferred_username"),name:Pe(t,"name"),email:Pe(t,"email"),avatar:Pe(t,"picture")||void 0,userType:"customer",ciam:{profile:t,scope:"openid profile email",tokenType:"Bearer",expires:n}}}function vo(e){if(e.authType!=="sso"&&e.authType!=="ciam")return;if(ks(e))return;return{sid:e.sid,authType:e.authType,tenantId:typeof e.tenantId==="string"?e.tenantId:void 0,sub:e.sub,expiresAt:e.expiresAt,createdAt:e.createdAt,claims:wo(e.claims)}}function Ro(e,t){if(!e.endsWith(".session"))return!1;if(!t||t.length===0)return!0;return t.some((n)=>e===`${n}.session`)}function Ao(e){if(e===void 0)return;let t=(Array.isArray(e)?e:[e]).map((n)=>n.trim()).filter((n)=>n.length>0);return t.length>0?t:void 0}async function Ss(e,t,n){return(await ws(e,t,n)).map(vo).filter((s)=>Boolean(s))}async function ws(e,t,n){let r=So(e.headers.get("cookie")),s=Ao(n?.cookiesPrefix),o=[],a=new Set;for(let[u,d]of Object.entries(r)){if(!Ro(u,s)||!d)continue;if(a.has(d))continue;a.add(d);let c=await t.get(d);if(!c)continue;if(c.authType!=="sso"&&c.authType!=="ciam")continue;if(ks(c))continue;o.push(c)}return o}async function Io(e,t,n){return(await Ss(e,t,n)).map(bo).filter((s)=>Boolean(s))}var To="@ionite/core",xo=lt(qt(To));async function Po(e,t){let n=await Ge({idToken:e,jwksUri:t.jwksUri,issuer:t.issuer,audience:t.audience}),r=await xo.validate(n);if(r.issues)throw Error(`ID token claims validation failed: ${r.issues.map((a)=>a.message).join("; ")}`);let s=r.value;if(s===void 0)throw Error("ID token claims missing");return Cs(s)}function pe(e){return Date.now()-e}function fr(e){if(e instanceof Error)return{"error.name":e.name,"error.message":e.message};return{"error.name":typeof e,"error.message":String(e)}}function an(e,t){if(!e)return{};try{let n=new URL(e);return{[`${t}.origin`]:n.origin,[`${t}.path`]:n.pathname}}catch{return{[`${t}.path`]:e.startsWith("/")?e:`/${e}`}}}function cn(e,t=5){if(!Array.isArray(e))return[String(e)];return e.slice(0,t).map((n)=>{if(!n||typeof n!=="object")return String(n);let r=n,s=Array.isArray(r.path)?r.path.join("."):String(r.path??""),o=typeof r.message==="string"?r.message:String(r.message??"validation failed");return s?`${s}: ${o}`:o})}function Uo(e){if(!e||typeof e!=="object")return{};let t=e;return{oidc_error:typeof t.error==="string"?t.error:void 0,oidc_error_description:typeof t.error_description==="string"?t.error_description:void 0,oidc_error_uri:typeof t.error_uri==="string"?t.error_uri:void 0}}function Eo(e,t={}){let n=typeof e==="string"?e:e?.headers.get("cookie")??void 0;if(!n)return[];let s=`${t.cookiePrefix??"ion.sso"}.`,o=new Set;for(let a of Object.keys(Do(n))){if(!a.startsWith(s))continue;let u=a.slice(s.length),d=u.lastIndexOf(".");if(d<=0)continue;let c=u.slice(0,d).trim();if(c)o.add(c)}return Array.from(o)}function Mo(e,t,n,r,s){if(!n&&!r)return;let o=new WeakMap,a=new Map,u={...n,...r},d=!!(u.authority&&u.tokenUrl&&u.authorizationUrl&&u.clientId&&u.redirectUri&&u.scope),c={...u,authority:d?Z(u.authority,"Missing 'authority' from SSO Config"):u.authority,tokenUrl:d?Z(u.tokenUrl,"Missing 'tokenUrl' from SSO Config"):u.tokenUrl,authorizationUrl:d?Z(u.authorizationUrl,"Missing 'authorizationUrl' from SSO Config"):u.authorizationUrl,clientId:d?Z(u.clientId,"Missing 'clientId' from SSO Config"):u.clientId,redirectUri:d?Z(u.redirectUri,"Missing 'redirectUri' from SSO Config"):u.redirectUri,scope:d?Z(u.scope,"Missing 'scope' from SSO Config"):u.scope,responseType:u.responseType??"code",cookiesSecure:u.cookiesSecure!==void 0?u.cookiesSecure:!0,cookiesSameSite:u.cookiesSameSite!==void 0?u.cookiesSameSite:"Strict",cookiesPrefix:u.cookiesPrefix??(u.clientId?`ion.sso.${u.clientId}`:"ion.sso"),cookiesPath:u.cookiesPath??"/",cookiesDomain:Nt(u.cookiesDomain)},E=Math.min(600,Math.max(0,Math.floor(Number(c.rotationGraceSeconds??60))||0))*1000,B=Math.floor(Number(c.sessionWindowSeconds??86400)),J=Number.isFinite(B)&&B>=1?B:86400;function X(){let f=[];if(!c.authority)f.push("authority");if(!c.tokenUrl)f.push("tokenUrl");if(!c.authorizationUrl)f.push("authorizationUrl");if(!c.clientId)f.push("clientId");if(!c.redirectUri)f.push("redirectUri");if(!c.scope)f.push("scope");if(f.length>0)throw Error(`Missing OIDC configuration fields: ${f.join(", ")}. OIDC configuration is required for SSO operations. Please provide these fields either in your vault configuration or in the SSO config when initializing ionite.`)}async function Q(f){if(!c)throw Error("ionite SSO Manager not initialized");let i=o.get(f);if(i)return i;let m=C(f);return o.set(f,m),m}async function C(f){try{let{tokens:i,session:m,refreshedUser:p}=await Se(f);if(!i)return{status:"unauthenticated"};if(p)return{status:"authenticated",value:p};if(m?.claims)return{status:"authenticated",value:ue(m.claims,i,je(m.expiresAt))};return{status:"unauthenticated"}}catch(i){if(bs(i))return{status:"unauthenticated"};return t.error("Error parsing user from cookies",{"ion.operation":"cookie.parse","ion.outcome":"degraded"},i),{status:"degraded",error:i instanceof Error?i:void 0}}}async function q(f){let i=await Q(f);return i.status==="authenticated"?i.value:void 0}async function I(f){if(!c)throw Error("ionite SSO Manager not initialized");X();let i=Z(c.redirectUri,"Missing 'redirectUri' from SSO Config"),m=Z(c.authorizationUrl,"Missing 'authorizationUrl' from SSO Config"),p=Z(c.clientId,"Missing 'clientId' from SSO Config"),g=Z(c.scope,"Missing 'scope' from SSO Config"),b=c.cookiesSecure?f.url.replace(/^http:\/\//,"https://"):f.url,T=xe(),P=xe(64),x=xe(),v=i;try{new URL(v)}catch{if(b)try{let S=new URL(b),k=v.startsWith("//")?v.slice(1):v.startsWith("/")?v:`/${v}`;v=new URL(k,S.origin).toString()}catch{try{let S=new URL(m),k=v.startsWith("//")?v.slice(1):v.startsWith("/")?v:`/${v}`;v=new URL(k,S.origin).toString()}catch{throw Error(`Invalid redirectUri: "${i}". It must be a valid absolute URL.`)}}}let N=new URL(m);N.searchParams.append("client_id",p),N.searchParams.append("redirect_uri",v),N.searchParams.append("response_type","code"),N.searchParams.append("scope",g),N.searchParams.append("state",T),N.searchParams.append("nonce",x);let y=await It(P);N.searchParams.append("code_challenge",y),N.searchParams.append("code_challenge_method","S256");let l=await c.beforeLogin?.({request:f}),h=l===void 0?{state:T,codeVerifier:P,nonce:x}:{state:T,codeVerifier:P,nonce:x,context:l};return new Response("Redirecting to SSO Provider",{status:302,headers:{Location:N.toString(),"Set-Cookie":Ie(_(T),h,c.loginStateTtl??600,"Lax")}})}async function Y(f){if(!c)throw Error("ionite SSO Manager not initialized");let i;try{i=await q(f)}catch{i=void 0}let m=await c.beforeLogout?.({request:f,user:i}),p=K("session",f),g;try{g=await Se(f);let y=g.tokens?.refresh_token??K("refresh",f);if(y)await Ye(y)}catch(y){t.warn("Failed to revoke token",{"ion.operation":"token.revoke","ion.outcome":"degraded"},y)}if(c.sessionStore)try{let y=g?.sid??p;if(y)await c.sessionStore.delete(y)}catch(y){t.warn("Failed to delete session",{"ion.operation":"session.delete","ion.outcome":"degraded"},y)}let b=M(),T=await c.afterLogout?.({request:f,context:m}),P=Je(T,"/",f.url);if(P.response){let y=new Headers(P.response.headers);for(let[,l]of b)y.append("Set-Cookie",l);return new Response(P.response.body,{status:P.response.status,statusText:P.response.statusText,headers:y})}let x=P.location??"/",v=f.headers.get("accept");if(v?.includes(Ae)||v?.includes("text/javascript"))return new Response(JSON.stringify({success:!0,message:"Logged out",redirect:x}),{status:200,headers:[["Content-Type",Ae],...b]});return new Response("Logged out",{status:302,headers:[["Location",x],...b]})}async function ee(f){if(!c)throw Error("ionite SSO Manager not initialized");if(!c.sessionStore)throw Error("Back-Channel Logout requires sessionStore configuration");try{if(!f.headers.get("content-type")?.includes(zt))return new Response("Invalid Content-Type, expected application/x-www-form-urlencoded",{status:400});let m=await f.text(),g=new URLSearchParams(m).get("logout_token");if(!g)return new Response("Missing logout_token parameter",{status:400});let b=Z(c.authority,"Missing 'authority' from SSO Config. OIDC configuration is required to verify logout tokens."),T=Z(c.clientId,"Missing 'clientId' from SSO Config. OIDC configuration is required to verify logout tokens."),P=c.jwksUri||`${b}/protocol/openid-connect/certs`,x=await Nn({logoutToken:g,jwksUri:P,issuer:b,audience:T,log:t}),v=typeof x.sid==="string"?x.sid:void 0;if(!v)return t.warn("Back-Channel Logout: logout_token missing sid claim",{"ion.operation":"backchannel_logout","ion.outcome":"failure"}),new Response("Invalid logout_token: missing sid claim",{status:400});return await c.sessionStore.delete(v),t.info("Back-Channel Logout: successfully deleted session",{"ion.module":"sso",sid:v}),new Response("OK",{status:200})}catch(i){return t.error("Error during back-channel logout",{"ion.operation":"backchannel_logout","ion.outcome":"failure"},i),new Response("Internal Server Error",{status:500})}}async function re(f){if(!c)throw Error("ionite SSO Manager not initialized");let i=Date.now(),m=new URL(f.url),p=new URLSearchParams(m.search);t.debug("SSO callback received",{"ion.event":"ion.sso.callback.received","ion.module":"sso","ion.operation":"sign_in.callback","http.method":f.method,"url.path":m.pathname,hasCode:p.has("code"),hasState:p.has("state"),hasError:p.has("error"),...an(p.get("iss")??void 0,"oidc.issuer")});let g=Object.fromEntries(p.entries()),b=await e.callbackParams.validate(g);if(b.issues)return t.warn("SSO callback parameter validation failed",{"ion.event":"ion.sso.callback.validation_failed","ion.operation":"sign_in.callback","ion.outcome":"failure","validation.issues":cn(b.issues)}),vs(b.issues,"OIDC callback parameters validation failed");let{code:T,state:P}=b.value,x;try{let v=Z(P,'OIDC "state" was not present in the callback parameters'),N=K(_(v),f,!0),{codeVerifier:y,state:l,nonce:h,context:S}=N??{};x=S,t.debug("SSO callback state cookie read",{"ion.event":"ion.sso.callback.state_cookie_read","ion.module":"sso","ion.operation":"sign_in.callback",hasStateCookie:Boolean(N),hasCodeVerifier:Boolean(y),hasStateVerifier:Boolean(l),hasNonce:Boolean(h),hasContext:S!==void 0});let k=Z(y,'OIDC "codeVerifier" was not present in cookies, ensure that the SSO login was initiated correctly');Z(l,'OIDC "stateVerifier" was not present in cookies, ensure that the SSO login was initiated correctly');let R=Z(h,'OIDC "nonce" was not present in cookies, ensure that the SSO login was initiated correctly'),D=Z(T,'OIDC "code" was not present in the callback parameters');if(P!==l)throw t.warn("SSO callback state verification failed",{"ion.event":"ion.sso.callback.state_verification_failed","ion.operation":"sign_in.callback","ion.outcome":"failure"}),Error('SSO State Verifier failed, the "state" request parameter does not equal the "state" in the SSO cookie');t.debug("SSO callback state verified",{"ion.event":"ion.sso.callback.state_verified","ion.module":"sso","ion.operation":"sign_in.callback"});let A=c.cookiesSecure?f.url.replace(/^http:\/\//,"https://"):f.url,O=await rt(D,k,A),{tokenExpiresAt:z,sessionExpiresAt:G}=me(O);O.expires=z.toISOString();let se=Date.now();t.debug("SSO ID token parsing started",{"ion.event":"ion.sso.id_token.parse_started","ion.module":"sso","ion.operation":"id_token.parse"});let ne=await oe(O,R,G);t.debug("SSO ID token parsing completed",{"ion.event":"ion.sso.id_token.parse_completed","ion.module":"sso","ion.operation":"id_token.parse","duration.ms":pe(se),"user.id":ne.id});let te,F;{let ae=_e("SSO requires sessionStore configuration for opaque session cookies."),at=typeof ne.sso.profile.sid==="string"?ne.sso.profile.sid:void 0,wt=at||xe(32),Re=ne.id;if(t.debug("SSO session creation evaluated",{"ion.event":"ion.sso.session.create_evaluated","ion.module":"sso","ion.operation":"session.create",hasSid:Boolean(wt),hasIdpSid:Boolean(at),hasSub:Boolean(Re),"user.id":Re}),!Re)throw Error("Session creation failed: missing sub in ID token claims");let ln=Date.now(),_t={sid:wt,sub:Re,idpSid:at,authType:"sso",tenantId:c.tenantId,tokens:O,claims:ne.sso.profile,expiresAt:G,createdAt:new Date};await qe(ae,_t),F=_t,te=["Set-Cookie",Ie("session",wt,G)],t.info("SSO session created",{"ion.event":"ion.sso.session.created","ion.operation":"session.create","ion.outcome":"success","duration.ms":pe(ln),"user.id":Re})}if(c.userStore)try{let ae=ne.id;if(ae){let at=new Date,wt=Date.now();t.debug("SSO user store lookup started",{"ion.event":"ion.sso.user.lookup_started","ion.module":"sso","ion.operation":"user.lookup","user.id":ae});let Re=await c.userStore.get(ae);if(t.debug("SSO user store lookup completed",{"ion.event":"ion.sso.user.lookup_completed","ion.module":"sso","ion.operation":"user.lookup","duration.ms":pe(wt),"user.id":ae,found:Boolean(Re)}),Re||c.enableJitUserProvisioning){let ln=Date.now(),_t={...Re??{},...ne,id:ae,tenantId:Re?.tenantId,createdAt:Re?.createdAt??at,updatedAt:at};await c.userStore.upsert(_t),t.info("SSO user stored",{"ion.event":"ion.sso.user.stored","ion.operation":"user.store","ion.outcome":"success","duration.ms":pe(ln),"user.id":ae,existing:Boolean(Re),jitProvisioning:Boolean(c.enableJitUserProvisioning)})}else t.warn("JIT user provisioning disabled: user not found in store and will not be created",{"ion.event":"ion.sso.user.skipped","ion.operation":"user.store","ion.outcome":"skipped","user.id":ae})}else t.warn("User storage skipped: missing sub in ID token claims",{"ion.event":"ion.sso.user.skipped","ion.operation":"user.store","ion.outcome":"skipped"})}catch(ae){t.warn("Failed to store user",{"ion.event":"ion.sso.user.store_failed","ion.operation":"user.store","ion.outcome":"degraded",...fr(ae)})}t.info("SSO sign-in succeeded",{"ion.event":"ion.sso.sign_in.succeeded","ion.operation":"sign_in.callback","ion.outcome":"success","duration.ms":pe(i),"user.id":ne.id});let he=[["Set-Cookie",Le(_(v))],...te?[te]:[],...te?await U(f,await fe(ne),G):[]],H=await c.afterLogin?.({ok:!0,request:f,user:ne,session:F,context:x,displayCookie:c.displayCookie,displayCookieAttributes:Ue()}),ve=Je(H,"/",f.url);if(ve.response)return Ze(ve.response,he.map(([,ae])=>ae));return new Response("Authentication successful, redirecting",{status:302,headers:[["Location",ve.location],...he]})}catch(v){t.error("Error during sign-in callback",{"ion.event":"ion.sso.sign_in.callback_failed","ion.operation":"sign_in.callback","ion.outcome":"failure","duration.ms":pe(i),...fr(v)});let N=P?[["Set-Cookie",Le(_(P))]]:[],y=await c.afterLogin?.({ok:!1,request:f,error:v,context:x,displayCookie:c.displayCookie,displayCookieAttributes:Ue()}),l=Je(y,"/",f.url);if(l.response)return Ze(l.response,N.map(([,h])=>h));return new Response("Authentication failed, redirecting",{status:302,headers:[["Location",l.location],...N]})}}function me(f){let i=Date.now(),m=Number(f.expires_in??3600)||3600,p=new Date(i+m*1000),g;if(f.refresh_expires_in!=null&&Number.isFinite(Number(f.refresh_expires_in)))g=Number(f.refresh_expires_in);else if(f.refresh_token)g=J;else g=m;return{tokenExpiresAt:p,sessionExpiresAt:new Date(i+g*1000)}}async function oe(f,i,m){if(!c)throw Error("ionite SSO Manager not initialized");let p=Date.now(),g=await it(f.id_token,i);return t.debug("SSO user parsed from ID token",{"ion.event":"ion.sso.user.parse_completed","ion.module":"sso","ion.operation":"id_token.parse","duration.ms":pe(p),"user.id":g.sub,hasEmail:Boolean(g.email),hasName:Boolean(g.name)}),ue(g,f,m)}function ue(f,i,m){let p=m??me(i).sessionExpiresAt,g=f.ecid!==void 0&&f.ecid!==null?tn(f.ecid):void 0;return{id:f.sub,userName:f.preferred_username||"",name:f.name||"",email:f.email||"",emails:[{value:f.email||"",primary:!0}],...g?{ecid:g}:{},avatar:f.picture,sso:{profile:{...f},tenant:{id:f.idp||f.iss||"",name:f.iss||""},scope:i.scope,tokenType:i.token_type,sessionState:i.session_state,expires:p}}}async function fe(f){if(!c.userStore)return f;let i=await c.userStore.lookup(f);if(!i)return f;return{...f,...i,id:f.id,sso:f.sso}}async function rt(f,i,m){if(!c)throw Error("ionite SSO Manager not initialized");X();let p=Z(c.tokenUrl,"Missing 'tokenUrl' from SSO Config"),g=Z(c.redirectUri,"Missing 'redirectUri' from SSO Config"),b=Z(c.clientId,"Missing 'clientId' from SSO Config"),T=g;try{new URL(T)}catch{if(m)try{let x=new URL(m),v=T.startsWith("//")?T.slice(1):T.startsWith("/")?T:`/${T}`;T=new URL(v,x.origin).toString()}catch{try{let x=new URL(p),v=T.startsWith("//")?T.slice(1):T.startsWith("/")?T:`/${T}`;T=new URL(v,x.origin).toString()}catch{throw Error(`Invalid redirectUri: "${g}". It must be a valid absolute URL.`)}}}let P=new URLSearchParams;if(P.append("grant_type","authorization_code"),P.append("code",f),P.append("redirect_uri",T),P.append("client_id",b),c.clientSecret)P.append("client_secret",c.clientSecret);P.append("code_verifier",i);try{let x=Date.now();t.debug("SSO token exchange started",{"ion.event":"ion.sso.token.exchange_started","ion.module":"sso","ion.operation":"token.exchange",...an(p,"oidc.token_url"),...an(T,"oidc.redirect_uri"),hasClientSecret:Boolean(c.clientSecret)});let v=await fetch(p,{method:"POST",headers:{...dt,...Ee},body:P.toString()});t.debug("SSO token exchange response received",{"ion.event":"ion.sso.token.response_received","ion.module":"sso","ion.operation":"token.exchange","http.status_code":v.status,"duration.ms":pe(x)}),t.debug("SSO token exchange response body read started",{"ion.event":"ion.sso.token.response_body_read_started","ion.module":"sso","ion.operation":"token.exchange"});let N=await Te(v,{log:t,operation:"token.exchange"});if(t.debug("SSO token exchange response body read completed",{"ion.event":"ion.sso.token.response_body_read_completed","ion.module":"sso","ion.operation":"token.exchange","duration.ms":pe(x)}),!v.ok){t.error("Token exchange error",{"ion.event":"ion.sso.token.exchange_failed","ion.operation":"token.exchange","ion.outcome":"failure","http.status_code":v.status,"duration.ms":pe(x),...Uo(N)});let l=N;throw Error(`Token exchange failed: ${l.error||v.statusText} - ${l.error_description||""}`.trim())}let y=await e.tokenResponse.validate(N);if(y.issues)throw t.error("Token response validation failed",{"ion.event":"ion.sso.token.response_validation_failed","ion.operation":"token.exchange","ion.outcome":"failure","duration.ms":pe(x),"validation.issues":cn(y.issues)}),Error(`Token response validation failed: ${y.issues}`);return t.debug("SSO token exchange completed",{"ion.event":"ion.sso.token.exchange_completed","ion.module":"sso","ion.operation":"token.exchange","ion.outcome":"success","duration.ms":pe(x),tokenType:y.value.token_type,hasAccessToken:Boolean(y.value.access_token),hasIdToken:Boolean(y.value.id_token),hasRefreshToken:Boolean(y.value.refresh_token),expiresIn:y.value.expires_in}),y.value}catch(x){throw t.error("Error during token exchange",{"ion.event":"ion.sso.token.exchange_failed","ion.operation":"token.exchange","ion.outcome":"failure",...fr(x)}),x}}async function st(f){return Mn(async()=>{if(!c)throw Error("ionite SSO Manager not initialized");X();let i=Z(c.tokenUrl,"Missing 'tokenUrl' from SSO Config"),m=Z(c.clientId,"Missing 'clientId' from SSO Config"),p=new URLSearchParams;if(p.append("grant_type","refresh_token"),p.append("refresh_token",f),p.append("client_id",m),c.clientSecret)p.append("client_secret",c.clientSecret);let g=await fetch(i,{method:"POST",headers:{...dt,...Ee},body:p.toString()}),b=await Te(g,{log:t,operation:"token.refresh"});if(!g.ok){t.error("Token refresh error",{"ion.operation":"token.refresh","ion.outcome":"failure",response:b});let P=b;throw Error(`Token refresh failed: ${P.error||g.statusText} - ${P.error_description||""}`.trim())}let T=await e.tokenResponse.validate(b);if(T.issues)throw t.error("Token refresh response validation failed",{"ion.event":"ion.sso.token.refresh_validation_failed","ion.operation":"token.refresh","ion.outcome":"failure","validation.issues":cn(T.issues)}),Error(`Token refresh response validation failed: ${T.issues}`);return T.value},void 0,void 0,void 0,t)}async function Ye(f){try{if(!c)throw Error("ionite SSO Manager not initialized");if(!c.revocationEndpoint)return;let i=Z(c.clientId,"Missing 'clientId' from SSO Config"),m=new URLSearchParams;if(m.append("token",f),m.append("token_type_hint","refresh_token"),m.append("client_id",i),c.clientSecret)m.append("client_secret",c.clientSecret);let p=await fetch(c.revocationEndpoint,{method:"POST",headers:{...Ee,...dt},body:m.toString()});if(!p.ok)t.warn("Token revocation failed",{"ion.operation":"token.revoke","ion.outcome":"degraded",status:p.status,statusText:p.statusText});else t.info("Token revoked successfully",{"ion.module":"sso"})}catch(i){t.warn("Error revoking token",{"ion.operation":"token.revoke","ion.outcome":"degraded"},i)}}async function St(){if(!c)throw Error("ionite SSO Manager not initialized");let f=c.authority;if(!c.jwksUri&&!f)throw Error("Missing 'jwksUri' or 'authority' from SSO Config. OIDC configuration is required for this operation.");let i=c.jwksUri||`${f}/protocol/openid-connect/certs`;return vt(i,t)}async function it(f,i){let m=Date.now(),p=Z(c.authority,"Missing 'authority' from SSO Config. OIDC configuration is required to verify ID tokens."),g=Z(c.clientId,"Missing 'clientId' from SSO Config. OIDC configuration is required to verify ID tokens."),b=c.jwksUri||`${p}/protocol/openid-connect/certs`;t.debug("SSO ID token verification started",{"ion.event":"ion.sso.id_token.verify_started","ion.module":"sso","ion.operation":"id_token.verify",...an(b,"oidc.jwks_uri")});let T;try{T=await Ge({idToken:f,jwksUri:b,issuer:p,audience:g,expectedNonce:i,log:t})}catch(x){throw t.error("SSO ID token verification failed",{"ion.event":"ion.sso.id_token.verify_failed","ion.module":"sso","ion.operation":"id_token.verify","ion.outcome":"failure","duration.ms":pe(m)},x),x}t.debug("SSO ID token signature verified",{"ion.event":"ion.sso.id_token.signature_verified","ion.module":"sso","ion.operation":"id_token.verify","duration.ms":pe(m)});let P=await e.idTokenClaims.validate(T);if(P.issues)throw t.error("ID token claims validation failed",{"ion.event":"ion.sso.id_token.validation_failed","ion.operation":"id_token.validate","ion.outcome":"failure","duration.ms":pe(m),"validation.issues":cn(P.issues)}),Error(`ID token claims validation failed: ${P.issues}`);return t.debug("SSO ID token claims validated",{"ion.event":"ion.sso.id_token.claims_validated","ion.module":"sso","ion.operation":"id_token.validate","ion.outcome":"success","duration.ms":pe(m),"user.id":P.value.sub,hasIssuer:Boolean(P.value.iss),hasAudience:Boolean(P.value.aud)}),P.value}function _e(f="SSO sessionStore is required for opaque session cookies."){if(!c.sessionStore)throw Error(f);return c.sessionStore}async function qe(f,i){try{await f.create(i)}catch(m){if(!await f.get(i.sid))throw m;await f.update(i.sid,i)}}function je(f){if(!f)return;if(f instanceof Date)return f;let i=new Date(f);return Number.isNaN(i.getTime())?void 0:i}function ot(f){let i=f.tokens;if(!i?.access_token||!i.id_token||!i.token_type)return;return i}async function ze(f,i=!1){let m=_e(),p=K("session",f);if(!p)return{tokens:void 0,refreshHeaders:[]};let g=await m.get(p);if(g&&c.tenantId&&g.tenantId&&g.tenantId!==c.tenantId)return{tokens:void 0,refreshHeaders:M(),sid:p};if(g?.authType!=="sso")return{tokens:void 0,refreshHeaders:M(),sid:p};let b=ot(g);if(!b)return{tokens:void 0,refreshHeaders:M(),sid:p};let T=je(g.expiresAt);if(T?Date.now()>T.getTime():!1)return await m.delete(p),{tokens:void 0,sid:p,refreshHeaders:M()};let x=je(b.expires),v=x?Date.now()>x.getTime():!0;if((i||v)&&b.refresh_token)return Be(f,p,g,b);return{tokens:b,sid:p,session:g,refreshHeaders:W(f)}}function Be(f,i,m,p){let g=a.get(i);if(g)return g;let b=_e(),T=(async()=>{let P=await st(p.refresh_token),{tokenExpiresAt:x,sessionExpiresAt:v}=me(P);P.expires=x.toISOString();let N=await oe(P,void 0,v),y=N.sso.profile,l=xe(32),h={...m,sid:l,tokens:P,claims:y,expiresAt:v,createdAt:new Date};await qe(b,h);try{if(E<=0)await b.delete(i);else{let{refresh_token:S,...k}=p;await b.update(i,{tokens:k,expiresAt:new Date(Date.now()+E)})}}catch(S){t.warn("Failed to retire rotated SSO session record",{"ion.operation":"session.rotate","ion.outcome":"degraded"},S)}return{tokens:P,sid:l,session:h,refreshedUser:N,refreshHeaders:[["Set-Cookie",Ie("session",l,v)],...await U(f,N,v)]}})();return a.set(i,T),T.finally(()=>{a.delete(i)})}async function Se(f,i=!1){return ze(f,i)}async function be(f){let{tokens:i}=await Se(f);if(!i)return;return i.access_token}function Ie(f,i,m,p=c.cookiesSameSite??"Strict"){if(!c)throw Error("ionite SSO Manager not initialized");if(f=`${c.cookiesPrefix}.${f}`,typeof i!=="string")i=btoa(JSON.stringify(i));let g;if(m instanceof Date)g=`Expires=${m.toUTCString()}`;else if(typeof m==="number")g=`Max-Age=${m}`;else throw Error("Invalid expires type",m);if(i.length>4000)throw Error(`Error setting cookie: ${f}. Cookie length is: ${i.length}`);return`${f}=${i}; ${g}; Path=${c.cookiesPath};${Ke(c.cookiesDomain)} HttpOnly;${c.cookiesSecure?" Secure;":""} SameSite=${p};`}function Le(f){if(!c)throw Error("ionite SSO Manager not initialized");return`${c.cookiesPrefix}.${f}=; Max-Age=0; Path=${c.cookiesPath};${Ke(c.cookiesDomain)} HttpOnly;${c.cookiesSecure?" Secure;":""} SameSite=${c.cookiesSameSite};`}function Ue(){return{path:c.cookiesPath??"/",domain:c.cookiesDomain,secure:c.cookiesSecure!==!1,sameSite:c.cookiesSameSite??"Strict"}}function M(){return[["Set-Cookie",Le("session")],["Set-Cookie",$e(`${c.cookiesPrefix}.profile`,Ue())]]}function W(f){if(c.displayCookie?.enabled===!0)return[];return ut(f.headers.get("cookie"),c.cookiesPrefix??"ion.sso",Ue()).map((i)=>["Set-Cookie",i])}async function U(f,i,m){return(await Ct({cookieHeader:f.headers.get("cookie"),sessionStore:c.sessionStore,cookiesPrefix:c.cookiesPrefix??"ion.sso",authType:"sso",tenantId:c.tenantId,expiresAt:m,user:i,projector:c.displayUser,displayCookie:c.displayCookie,trim:c.trimDisplayCookies,attr:Ue()})).map((g)=>["Set-Cookie",g])}function K(f,i,m=!1){if(!c)throw Error("ionite SSO Manager not initialized");let p=i.headers.get("cookie");if(!p)return null;let g=`${c.cookiesPrefix}.${f}`,b=p.split(";").find((v)=>v.trim().startsWith(`${g}=`));if(!b)return null;let T=b.indexOf("="),P=b.slice(T+1).trim();if(!m)return P;let x=atob(P);return JSON.parse(x)}function _(f){return`state_${f}`}async function j(f,i){if(!c)throw Error("ionite SSO Manager not initialized");let{loginUrl:m,userUrl:p,tokenUrl:g,refreshUrl:b,logoutUrl:T,logoutBackChannelUrl:P,jwksUrl:x,redirectUri:v}={...c,...i},N=new URL(f.url).pathname;if(v){let y;try{y=new URL(v).pathname}catch{try{let l=new URL(f.url),h=v.startsWith("//")?v.slice(1):v;y=new URL(h,l.origin).pathname}catch{y=v.startsWith("/")?v:`/${v}`}}if(y===N)return re(f)}if(m===N)return I(f);if(p===N){if((c.userEndpoint??"full")==="off")return new Response("Not Found",{status:404,headers:W(f)});try{let{tokens:y,session:l,refreshedUser:h,refreshHeaders:S}=await Se(f);if(!y)return new Response("User not logged in",{status:401,headers:S});let k=h??(l?.claims?ue(l.claims,y,je(l.expiresAt)):void 0);if(!k)return new Response("User not logged in",{status:401,headers:S});let R=await fe(k),D=`${c.cookiesPrefix}.profile`,A=je(l?.expiresAt),O=c.displayCookie?.enabled===!0&&A&&!K("profile",f)&&!S.some(([,G])=>G.startsWith(`${D}=`))?await U(f,R,A):[],z=c.userEndpoint==="display"?Xe(R,c.displayUser):R;return new Response(JSON.stringify(z),{headers:[["Content-Type",Ae],...S,...O]})}catch(y){if(bs(y))return new Response("User not logged in",{status:401});return t.error("Error resolving SSO user",{"ion.operation":"sso.user","ion.outcome":"degraded"},y),new Response(JSON.stringify({error:"auth_unavailable"}),{status:503,headers:ge})}}if(g===N){let{tokens:y,refreshHeaders:l}=await Se(f);if(!y)return new Response("User not logged in",{status:401,headers:l});return new Response(JSON.stringify({token:y.access_token,expires:y.expires}),{headers:[["Content-Type",Ae],...l]})}if(b===N){let{tokens:y,refreshHeaders:l}=await Se(f,!0);if(!y)return new Response("User not logged in",{status:401});return new Response("Refresh Complete",{status:200,headers:l})}if(T===N)return Y(f);if(P===N)return ee(f);if(x===N){let y=await St();return new Response(JSON.stringify(y),{headers:[["Content-Type",Ae]]})}return new Response("Not Found",{status:404})}return{...c,getUser:q,resolveUser:Q,getJwt:be,initiateLogin:I,logout:Y,logoutBackChannel:ee,callbackHandler:re,handler:j}}function Do(e){let t={},n=e.split(";");for(let r of n){let s=r.trim();if(!s)continue;let o=s.indexOf("=");if(o===-1)continue;let a=s.slice(0,o).trim(),u=s.slice(o+1).trim();t[a]=u}return t}function bs(e){if(!(e instanceof Error))return!1;return["Public key not found","Invalid JWT","Invalid JWT signature","ID token expired","ID token issuer mismatch","ID token audience mismatch","ID token nonce mismatch","ID token missing exp","invalid_grant"].some((t)=>e.message.includes(t))}function Rs(e){return e=e??"SSO Unavailable",new Response(JSON.stringify({error:e}),{status:503,statusText:e,headers:ge})}var un="Ionite instance is required. Create one with ionite(source, config) and pass it to this function.";async function Oo(e,t){return Z(t,un),t.sso?.getUser(e)}async function gr(e,t){return Z(t,un),await t.sso?.resolveUser(e)??{status:"unauthenticated"}}async function _o(e,t){Z(t,un);let n=t.sso;if(!n)return Rs();return n.initiateLogin(e)}async function jo(e,t){Z(t,un);let n=t.sso;if(!n)return Rs();return n.callbackHandler(e)}var hr="tenant.owner",yr="tenant.owner.",Lo="tenant:";function No(e){return{id:hr,name:"Tenant owner",description:"Administer one tenant resource",requestable:!1,permissionTypes:["Admin"],resourceTypes:["tenant"],assignableSubjectTypes:["customer"],...e}}function kr(e){let t=e.trim();if(!t)throw Error("tenantId is required");return`${Lo}${t}`}function $o(e){let t=e.trim();if(!t)throw Error("tenantId is required");return`${yr}${t}`}function ce(e){return{allow:!1,reason:e,response(){if(e==="not_found")return Response.json({error:"Not Found"},{status:404});if(e==="forbidden")return Response.json({error:"Forbidden"},{status:403});if(e==="unavailable")return Response.json({error:"Tenant runtime unavailable"},{status:503});return Response.json({error:"Unauthorized"},{status:401})}}}function dn(e,t){if(!e.id)return ce("unavailable");return{allow:!0,session:{id:e.id,email:e.email,name:e.name,kind:t}}}function As(e){return e==="access_index_not_configured"||e==="error"}async function Is(e,t){let n;try{n=await Bt(e,t.rootIon)}catch{return ce("unavailable")}if(n.status==="degraded")return ce("unavailable");if(n.status==="unauthenticated")return ce("unauthenticated");if(!n.value.id)return ce("unavailable");try{let r=await t.rootIon.authz.hasPermission(n.value.id,t.ownerPermission??hr,kr(t.tenantId),"customer");if(r.allow)return dn(n.value,"owner");return ce(As(r.metadata?.reason)?"unavailable":"forbidden")}catch{return ce("unavailable")}}async function Wo(e,t){let{tenantIon:n}=t;if(!n)return ce("not_found");if(n.isReady()){let s;try{s=await gr(e,n)}catch{return ce("unavailable")}if(s.status==="degraded")return ce("unavailable");if(s.status==="authenticated"){if(!s.value.id)return ce("unavailable");if(!t.permission)return dn(s.value,"sso");try{let o=await n.authz.hasPermission(s.value.id,t.permission,void 0,"user");if(o.allow)return dn(s.value,"sso");return ce(As(o.metadata?.reason)?"unavailable":"forbidden")}catch{return ce("unavailable")}}if(t.allowTenantCustomer){let o;try{o=await Bt(e,n)}catch{return ce("unavailable")}if(o.status==="degraded")return ce("unavailable");if(o.status==="authenticated"){if(!o.value.id)return ce("unavailable");return dn(o.value,"customer")}}}let r=await Is(e,t);if(r.allow||r.reason==="unavailable")return r;if(!n.isReady())return ce("unavailable");return ce("unauthenticated")}async function Vo(e,t){let n=e.authz.accessStore;if(!n)throw Error("Cannot list owned tenants: no AccessAssignmentStore is wired.");let r=new Set;for await(let s of ht((o,a)=>n.listBySubject(t,"customer",{start:o,limit:a}))){let o=typeof s.target==="string"?s.target:s.target.id;if(s.targetType!=="group"||!o.startsWith(yr))continue;let a=o.slice(yr.length);if(!a||!s.resources?.includes(kr(a)))continue;r.add(a)}return[...r].sort()}function qo(e,t){let n=t.redirectTo.trim()||"/",r=t.tenantIon?.sso?.isReady?.()===!0?`${t.tenantIonBasePath?.(e)??`/api/${encodeURIComponent(e)}/ionite`}/auth/login`:t.fallbackPath,s=new URL(r,"http://localhost");return s.searchParams.set("redirect",n),`${s.pathname}${s.search}`}export{Ot as CACHE_BOUNDS,vr as CIAM_PROVIDER_PRESETS,ur as CatalogAdjacencyCache,Bo as InMemoryTenantStore,hr as TENANT_OWNER_PERMISSION,fi as allowHosts,mi as allowOrigins,Br as allowRelativePaths,Kr as allowSameOrigin,cs as assertSubjectTypeAssignable,Wr as assertTrustedIdTokenClaims,Jn as baseCustomerToScim,Kn as baseUserToScimUser,Gn as baseWorkloadToScim,zr as blockDangerousUrls,jn as buildAuthorizationUrl,mr as buildLfvSigningInput,jo as callback,yi as captureRedirect,wi as ciam,ci as clearDiscoveryCache,Zs as clearJwksCache,zo as collectReferencedDefinitions,Js as configureJwksCache,gi as defaultRedirectPolicies,$n as discoverOidcEndpoints,ws as discoverSessionRecords,Ss as discoverSessions,Bn as entitlementToScimGroup,Ln as exchangeAuthorizationCode,dr as expandRoot,Wn as fetchUserInfo,$e as formatDisplayClearCookie,In as formatDisplaySetCookie,Vn as generateAppleClientSecret,po as generateLfvEd25519KeyPair,Dn as getCachedVerificationKey,Ci as getCustomer,Io as getDiscoveredSessionUsers,vt as getJwks,Vo as getOwnedTenantIds,fn as getProviderPreset,ti as getPublicKeyForKid,ei as getPublicKeyFromJwks,Oo as getUser,On as getVerificationKeyForKid,Os as has,$s as hasAll,qs as hasAllScope,Ns as hasAny,Vs as hasAnyScope,Ls as hasGroup,_s as hasPermission,js as hasRole,Ws as hasScope,ro as iam,_o as initiateLogin,Gr as isRedirectAllowed,Eo as listSsoClientIdsFromCookies,At as normalizeOidcIssuer,yn as orderedEnabledProviders,us as parseLfvJwks,It as pkceChallengeFromVerifier,Gs as planDiscoveredTenantCookies,ut as planDisplayCookieClear,Ct as planDisplayCookieHeaders,lr as reconcileSubjectAccess,Je as resolveAfterRedirect,mo as resolveCacheConfig,hi as resolveCapturedRedirect,Lt as resolveCiamProvider,Bt as resolveCustomer,Qs as resolveJwkForKid,ds as resolveJwksCacheConfig,gn as resolveProviderBranding,zn as resolveRedirect,ls as resolveSessionCacheConfig,Is as resolveTenantOwner,Wo as resolveTenantSession,gr as resolveUser,qn as sameOriginRedirectRules,Pr as selectDisplayCookies,Ko as sendTenantWebhook,ai as setDiscoveryClock,Hs as setJwksClock,Fs as setJwksRetry,ho as signCompactJwt,lo as signLfvPayload,Mo as sso,yo as staticSigningKeyRing,oo as stringifyLfvJwks,qo as tenantAccessLoginUrl,$o as tenantOwnerEntitlementId,No as tenantOwnerPermission,kr as tenantResourceId,ko as verifyCompactJwt,Ge as verifyIdToken,uo as verifyLfvSignature,Nn as verifyLogoutToken,Po as verifyUser,Ze as withSetCookies};
1
+ import{J,d,A,I,v,o,c,Y,f,e,g,x,N,L,K,Z,q,n,p,Q,E,pe,$e,W,ee,te,V,ne,m,z,re,B,P,U,G,O,se,oe,ie,y,s,D,i,ae,r,w,h,F,a,l,t,ce,R,S,H,k,M,Me,ot,u,b,C,ue,de}from"./shared/core-knezf9yx.js";var Vs=new Set(se.map((T)=>T.id));async function bn(T){let _=qs(T.block);if(_.length===0||!T.subjectId)return[];let j=zs(T.claims,T.accessClaims,T.scope),X=T.block.expand===!0,le=X&&T.block.resources===!0,ge=[],he=new Set,ke=(ye)=>{let fe=`${ye.targetType}:${ye.target}:${ye.resource??""}`;if(he.has(fe))return;he.add(fe),ge.push(ye)};for(let ye of _){let fe=Bs(j,ye);for(let ze of fe){let Ye=await Ks(T.catalog,ze);if(!Ye){T.log?.debug("claims entitlement dropped: value is not a catalog id",{"ion.event":"ion.authz.claims.unmatched","ion.module":"authz",claim:ye,value:ze});continue}if(!X||!T.catalog){ke({targetType:Ye,target:ze,claim:ye});continue}let Qe={subject:T.subjectId,subjectType:T.subjectType,targetType:Ye,target:ze,...le?Fs(await Hs(T.catalog,Ye,ze)):{applyToApplication:!0}},ct=await E(Qe,T.catalog),st=Qe.id;for(let _e of ct){if(_e.resource&&!le)continue;ke({targetType:_e.targetType,target:_e.target,..._e.resource?{resource:_e.resource}:{},claim:ye,root:st??_e.rootId})}}}return ge}function Cn(T){if(!T)return;let _=T.split(".");if(_.length!==3||!_[1])return;try{let j=_[1].replace(/-/g,"+").replace(/_/g,"/"),X=j.padEnd(j.length+(4-j.length%4)%4,"="),le=JSON.parse(atob(X));return le&&typeof le==="object"&&!Array.isArray(le)?le:void 0}catch{return}}var tr=new WeakMap;function vn(T,_,j){let X=tr.get(T)??{};X[_]=j??[],tr.set(T,X)}function nr(T,_){return tr.get(T)?.[_]}function qs(T){return T.claims.filter((_)=>typeof _==="string"&&_.length>0)}function zs(T,_,j){let X={...T};if(_){for(let[le,ge]of Object.entries(_))if(X[le]===void 0)X[le]=ge}if(X.scope===void 0&&j)X.scope=j;return X}function Bs(T,_){let j=Gs(T,_);if(typeof j==="string")return _==="scope"||_.endsWith(".scope")?j.split(/\s+/).filter(Boolean):j.length>0?[j]:[];if(Array.isArray(j))return j.filter((X)=>typeof X==="string"&&X.length>0);return[]}function Gs(T,_){let j=T;for(let X of _.split(".")){if(!j||typeof j!=="object"||Array.isArray(j))return;j=j[X]}return j}async function Ks(T,_){if(Vs.has(_))return"permission";if(!T)return;for(let j of["permission","role","group"])if(await Js(T,j,_))return j;return}async function Js(T,_,j){if(Kr(T,_,j))return!0;let le=_==="permission"?T.catalog?.permissions:_==="role"?T.catalog?.roles:T.catalog?.groups;if(!le)return!1;return await le.get(j)!==void 0}function Kr(T,_,j){if(!T.code)return;if(_==="permission")return T.code.permissions.get(j);if(_==="role")return T.code.roles.get(j);return T.code.groups.get(j)}async function Hs(T,_,j){let X=Kr(T,_,j),le=_==="permission"?T.catalog?.permissions:_==="role"?T.catalog?.roles:T.catalog?.groups,ke=((le?await le.get(j):void 0)?.resources??X?.resources??[]).map((ye)=>ye.trim()).filter(Boolean);return ke.length>0?ke:void 0}function Fs(T){if(!T||T.length===0)return{applyToApplication:!0};return{resources:T}}var Ys="Ionite instance is required. Create one with ionite(source, config) and pass it to this function.",Jr=["user","customer","workload"],Xs={user:async(T,_)=>_.sso?.getUser(T),customer:async(T,_)=>_.ciam?.getCustomer(T),workload:async(T,_)=>{let j=await _.workload?.getWorkloadIdentity?.(T);if(!j)return;let X=j.clientId??j.workloadId??j.claims.sub;return X?{...j,id:X}:void 0}};function Zs(T){if(T==="any")return Jr;let _=Array.isArray(T)?T:[T];return Jr.filter((j)=>_.includes(j))}function Qs(T){let _=T.headers.get("cookie");if(!_)return[];return _.split(";").map((j)=>j.slice(0,j.indexOf("=")===-1?j.length:j.indexOf("=")).trim()).filter(Boolean)}function ei(T,_){let j=T.headers.get("authorization")?.toLowerCase().startsWith("bearer ")??!1,X=Qs(T),le=new Set;for(let he of X){if(he.startsWith("ion.sso"))le.add("user");if(he.startsWith("ion.ciam"))le.add("customer")}let ge=X.length>0&&!le.has("user")&&!le.has("customer");return _.filter((he)=>{if(he==="workload")return j;if(X.length===0)return!1;return le.has(he)||ge})}function lt(T){return typeof T==="string"?T:T.id}function ti(T){let{subject:_,subjectType:j}=T,X;if(j==="user")X=_.sso?.scope;else if(j==="customer")X=_.ciam?.scope;else if(j==="workload")X=_.scope;return new Set((X??"").split(/\s+/).filter(Boolean))}function sr(T,_,j){let X=ti(T),le=_.filter((he)=>X.has(he));return{allow:j==="any"?le.length>0:_.length>0&&le.length===_.length,metadata:{reason:"scope",wantedScopes:_,matchedScopes:le}}}function Hr(T,_){if(T.targetType!==_.targetType||T.target!==_.id)return!1;return _.resource?T.resource===_.resource:T.resource===void 0}function pn(T,_){return(j)=>{if(T.length===0)return;let X=j.derivedEntitlements??[];if(X.length===0)return;let le=T.filter((he)=>X.some((ke)=>Hr(ke,he)));if(!(_==="any"?le.length>0:le.length===T.length))return;return X.filter((he)=>le.some((ke)=>Hr(he,ke)))}}function jn(T,_,j){return(X)=>{if(_.length===0||X.subjectType!=="workload")return;let le=J(T.config?.authz,X.subject);if(!le)return;let ge=_.filter((ke)=>le.has(ke));return(j==="any"?ge.length>0:ge.length===_.length)?ge:void 0}}function rr(T,_,j,X,le){return{allow:j==="ok",subject:_?.subject,subjectType:_?.subjectType,reason:j,decision:X,response(){if(j==="ok")return new Response(null,{status:204});if(j==="unauthenticated")return T.log.warn("authz.denied",{reason:j,...le()}),Response.json({error:"Unauthorized"},{status:401});if(j==="not_configured")return T.log.warn("authz.denied",{reason:j,subject:_?.subject?.id,subjectType:_?.subjectType,...le()}),Response.json({error:"not_configured"},{status:503});return T.log.warn("authz.denied",{reason:j,subject:_?.subject?.id,subjectType:_?.subjectType,...le()}),Response.json({error:"Forbidden"},{status:403})}}}function ni(T,_,j){return new Promise((X)=>{let le=[],ge=T.length,he=!1,ke=()=>{if(ge-=1,ge===0&&!he)he=!0,X({outcomes:le})};for(let ye of T)_(ye).then((fe)=>{if(le.push({principal:ye,decision:fe}),!he&&fe.allow){he=!0,X({matched:{principal:ye,decision:fe},outcomes:le});return}ke()},(fe)=>{j?.(ye,fe),le.push({principal:ye,decision:{allow:!1,metadata:{reason:"error"}}}),ke()})})}async function zt(T,_,j,X,le,ge,he){t(_,Ys);let ke=ei(T,Zs(j)),fe=(await Promise.all(ke.map(async(et)=>{let De=await Xs[et](T,_);if(!De?.id)return;let it=et==="workload"?De.derivedEntitlements:et==="user"||et==="customer"?nr(T,et):void 0;return{subject:De,subjectType:et,subjectId:De.id,derivedEntitlements:it}}))).filter((et)=>et!==void 0);if(fe.length===0)return rr(_,void 0,"unauthenticated",void 0,le);let ze=async(et)=>{let De=_.authz.accessIndex;if(!De?.isSubjectDisabled)return!1;return De.isSubjectDisabled(et.subjectId,et.subjectType)},Ye=async(et)=>{if(he){let De=he(et);if(De&&De.length>0){if(await ze(et))return{allow:!1,metadata:{reason:"subject_disabled"}};return{allow:!0,metadata:{reason:"trusted-client",matchedPermissions:De}}}}if(ge){let De=ge(et);if(De&&De.length>0){if(await ze(et))return{allow:!1,metadata:{reason:"subject_disabled"}};return{allow:!0,metadata:{reason:"claims",matchedIds:De.map((it)=>it.target),matchedClaims:[...new Set(De.map((it)=>it.claim))],roots:[...new Set(De.map((it)=>it.root).filter((it)=>Boolean(it)))]}}}}return X(et)},{matched:Qe,outcomes:ct}=await ni(fe,Ye,(et,De)=>{_.log.warn("authz.check_error",{"ion.operation":"authz.check","ion.outcome":"error",subject:et.subjectId,subjectType:et.subjectType,error:De instanceof Error?De.message:String(De),...le()})});if(Qe){if(Qe.decision.metadata?.reason==="claims")_.log.info("authz.claims_honor",{"ion.operation":"authz.claims_honor","ion.outcome":"allow",subject:Qe.principal.subjectId,subjectType:Qe.principal.subjectType,matchedIds:Qe.decision.metadata.matchedIds,matchedClaims:Qe.decision.metadata.matchedClaims,roots:Qe.decision.metadata.roots,...le()});return rr(_,Qe.principal,"ok",Qe.decision,le)}let st=ct.length>0&&ct.every((et)=>{let De=et.decision.metadata?.reason;return De==="access_index_not_configured"||De==="error"}),_e=ct[0],Le=st?"not_configured":"forbidden";return rr(_,_e?.principal,Le,_e?.decision,le)}async function ri(T,_,j,X,le,ge="any"){return zt(T,_,ge,(he)=>_.authz.has(he.subjectId,j,X,le,he.subjectType),()=>({targetType:j,target:lt(X),resource:le?lt(le):void 0}),pn([{targetType:j,id:lt(X),resource:le?lt(le):void 0}],"any"),j==="permission"&&!le?jn(_,[lt(X)],"any"):void 0)}async function si(T,_,j,X,le="any"){return zt(T,_,le,(ge)=>_.authz.hasPermission(ge.subjectId,j,X,ge.subjectType),()=>({targetType:"permission",target:lt(j),resource:X?lt(X):void 0}),pn([{targetType:"permission",id:lt(j),resource:X?lt(X):void 0}],"any"),X?void 0:jn(_,[lt(j)],"any"))}async function ii(T,_,j,X,le="any"){return zt(T,_,le,(ge)=>_.authz.hasRole(ge.subjectId,j,X,ge.subjectType),()=>({targetType:"role",target:lt(j),resource:X?lt(X):void 0}),pn([{targetType:"role",id:lt(j),resource:X?lt(X):void 0}],"any"))}async function oi(T,_,j,X,le="any"){return zt(T,_,le,(ge)=>_.authz.hasGroup(ge.subjectId,j,X,ge.subjectType),()=>({targetType:"group",target:lt(j),resource:X?lt(X):void 0}),pn([{targetType:"group",id:lt(j),resource:X?lt(X):void 0}],"any"))}async function ai(T,_,j,X="any"){let le=j.map((he)=>({targetType:he.targetType,id:lt(he.target),resource:he.resource?lt(he.resource):void 0})),ge=j.filter((he)=>!he.resource&&he.targetType==="permission").map((he)=>lt(he.target));return zt(T,_,X,(he)=>_.authz.hasAny(he.subjectId,j,he.subjectType),()=>({targets:j.map((he)=>`${he.targetType}:${lt(he.target)}`)}),le.length>0?pn(le,"any"):void 0,ge.length>0?jn(_,ge,"any"):void 0)}async function ci(T,_,j,X="any"){let le=j.map((ke)=>({targetType:ke.targetType,id:lt(ke.target),resource:ke.resource?lt(ke.resource):void 0})),ge=j.length>0&&j.every((ke)=>!ke.resource&&ke.targetType==="permission"),he=j.map((ke)=>lt(ke.target));return zt(T,_,X,(ke)=>_.authz.hasAll(ke.subjectId,j,ke.subjectType),()=>({targets:j.map((ke)=>`${ke.targetType}:${lt(ke.target)}`)}),le.length>0?pn(le,"all"):void 0,ge?jn(_,he,"all"):void 0)}async function ui(T,_,j,X="any"){return zt(T,_,X,(le)=>Promise.resolve(sr(le,[j],"any")),()=>({scope:j}))}async function di(T,_,j,X="any"){return zt(T,_,X,(le)=>Promise.resolve(sr(le,j,"any")),()=>({scopes:j}))}async function li(T,_,j,X="any"){return zt(T,_,X,(le)=>Promise.resolve(sr(le,j,"all")),()=>({scopes:j}))}function kt(T){return typeof T==="string"&&T.length>0?T:void 0}function Fr(T){let _=kt(T.email);return{sub:String(T.sub??""),email:_,name:kt(T.name),userName:kt(T.preferred_username)??_,avatar:kt(T.picture)}}var Yr={oidc:{flow:"id_token",scope:"openid profile email",branding:{displayName:"Single sign-on"},mapClaims:Fr},google:{flow:"id_token",authorizationUrl:"https://accounts.google.com/o/oauth2/v2/auth",tokenUrl:"https://oauth2.googleapis.com/token",jwksUri:"https://www.googleapis.com/oauth2/v3/certs",scope:"openid email profile",branding:{displayName:"Google",iconUrl:"https://www.gstatic.com/firebasejs/ui/2.0.0/images/auth/google.svg",colors:{light:"#ffffff",dark:"#131314",secondary:"#4285F4"},url:"https://accounts.google.com"},mapClaims:Fr},microsoft:{flow:"id_token",authorizationUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/authorize",tokenUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/token",jwksUri:"https://login.microsoftonline.com/common/discovery/v2.0/keys",scope:"openid email profile",branding:{displayName:"Microsoft",colors:{light:"#ffffff",dark:"#2f2f2f",secondary:"#0067b8"},url:"https://login.microsoftonline.com"},mapClaims:(T)=>{let _=kt(T.email)??kt(T.preferred_username);return{sub:String(T.sub??T.oid??""),email:_,name:kt(T.name),userName:kt(T.preferred_username)??_,avatar:kt(T.picture)}}},apple:{flow:"id_token",authorizationUrl:"https://appleid.apple.com/auth/authorize",tokenUrl:"https://appleid.apple.com/auth/token",jwksUri:"https://appleid.apple.com/auth/keys",scope:"openid email name",extraAuthParams:{response_mode:"form_post"},branding:{displayName:"Apple",colors:{light:"#000000",dark:"#ffffff"},url:"https://appleid.apple.com"},mapClaims:(T)=>{let _=kt(T.email);return{sub:String(T.sub??""),email:_,name:kt(T.name),userName:_}}},github:{flow:"userinfo",authorizationUrl:"https://github.com/login/oauth/authorize",tokenUrl:"https://github.com/login/oauth/access_token",userInfoUrl:"https://api.github.com/user",scope:"read:user user:email",branding:{displayName:"GitHub",colors:{light:"#24292f",dark:"#ffffff"},url:"https://github.com"},mapClaims:(T)=>({sub:String(T.id??T.node_id??""),email:kt(T.email),name:kt(T.name)??kt(T.login),userName:kt(T.login),avatar:kt(T.avatar_url)})}};function ir(T){if(T==="magic-link")return;return Yr[T]}function Ln(T,_){if(_.type==="magic-link")return;let j=ir(_.type);if(!j)return;return{name:T,type:_.type,flow:j.flow,authorizationUrl:_.authorizationUrl??j.authorizationUrl,tokenUrl:_.tokenUrl??j.tokenUrl,jwksUri:_.jwksUri??j.jwksUri,userInfoUrl:_.userInfoUrl??j.userInfoUrl,scope:_.scope??j.scope,clientId:_.clientId,clientSecret:_.clientSecret,extraAuthParams:j.extraAuthParams,branding:{...j.branding,..._.branding},mapClaims:j.mapClaims,config:_}}function or(T){return{...ir(T.type)?.branding??{displayName:T.type},...T.branding}}function ar(T){if(!T)return[];return Object.entries(T).filter(([,_])=>_.enabled!==!1).map(([_,j],X)=>({name:_,config:j,index:X})).sort((_,j)=>{let X=_.config.order??Number.MAX_SAFE_INTEGER,le=j.config.order??Number.MAX_SAFE_INTEGER;if(X!==le)return X-le;return _.index-j.index}).map(({name:_,config:j})=>({name:_,config:j}))}var pi=/^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;function Nn(T){if(T===void 0)return;let _=T.trim().toLowerCase();if(!pi.test(_))throw Error(`Invalid cookiesDomain "${T}": expected a hostname such as "app.example.com" without a scheme, port, path, or leading dot.`);return _}function Xt(T){return T?` Domain=${T};`:""}var Xr=4000;function mi(T){return`Expires=${T.toUTCString()}`}function Zr(T){return`Path=${T.path};${Xt(T.domain)}${T.secure?" Secure;":""} SameSite=${T.sameSite};`}function dr(T,_,j,X){if(_.length>Xr)throw Error(`Display cookie ${T} value is ${_.length} bytes; the limit is ${Xr}.`);return`${T}=${_}; ${mi(j)}; ${Zr(X)}`}function Bt(T,_){return`${T}=; Max-Age=0; ${Zr(_)}`}function cr(T){if(!T)return;let _=T instanceof Date?T:new Date(T);return Number.isNaN(_.getTime())?void 0:_}function ur(T){return!T||T.getTime()>Date.now()}async function fi(T,_,j){let X=T.envelope.kind??"session";if(X==="discovered"){let ke=cr(T.envelope.expiresAt);return{...T,kind:X,live:Boolean(ke&&ur(ke))}}let le=_[`${T.prefix}.session`];if(!le)return{...T,kind:X,live:!1};let ge=await j.get(le);if(!ge||ge.authType!=="sso"&&ge.authType!=="ciam")return{...T,kind:X,live:!1};let he=cr(ge.expiresAt);return{...T,kind:X,live:ur(he),...he?{sessionExpiresAt:he}:{}}}function mn(T,_,j){let X=U(_);return T?.includes(`${X}=`)?[Bt(X,j)]:[]}function Qr(T,_,j,X,le){let ge=[...T.filter((ze)=>ze.kind==="session").slice(0,j),...T.filter((ze)=>ze.kind==="discovered").slice(0,X)],he=le?le(T,{max:j,maxDiscovered:X}):ge,ke=[...he.filter((ze)=>ze.kind==="session").slice(0,j),...he.filter((ze)=>ze.kind==="discovered").slice(0,X)];if(ke.some((ze)=>ze.name===_))return ke;let ye=T.find((ze)=>ze.name===_);if(!ye)return ke;return[...[ye,...ke.filter((ze)=>ze.kind==="session")].slice(0,j),...ke.filter((ze)=>ze.kind==="discovered")]}async function Rn(T){let _=U(T.cookiesPrefix),j=T.attr;if(T.displayCookie?.enabled!==!0)return mn(T.cookieHeader,T.cookiesPrefix,j);if(!T.sessionStore)return[];let X=m(T.user,T.projector),le={v:W,...T.tenantId?{tenantId:T.tenantId}:{},authType:T.authType,expiresAt:T.expiresAt.toISOString(),user:X},ge={name:_,prefix:T.cookiesPrefix,envelope:le,kind:"session",sessionExpiresAt:T.expiresAt,live:!0},he=re(T.cookieHeader),ke=T.sessionStore,ye=await Promise.all(B(T.cookieHeader).filter((Le)=>Le.name!==_).map((Le)=>fi(Le,he,ke))),fe=[ge,...ye.filter((Le)=>Le.live&&Le.kind==="session")].sort((Le,et)=>P(Le.sessionExpiresAt?.toISOString()??Le.envelope.expiresAt,et.sessionExpiresAt?.toISOString()??et.envelope.expiresAt)),ze=T.displayCookie.discovered?.enabled===!0?ye.filter((Le)=>Le.live&&Le.kind==="discovered"&&(!T.tenantId||Le.envelope.tenantId!==T.tenantId)).sort((Le,et)=>P(Le.envelope.expiresAt,et.envelope.expiresAt)):[],Ye=[...fe,...ze],Qe=te(T.displayCookie?.max),ct=V(T.displayCookie.discovered?.max),st=new Set(Qr(Ye,_,Qe,ct,T.trim).map((Le)=>Le.name)),_e=[dr(_,z(le),T.expiresAt,j)];for(let Le of ye)if(!st.has(Le.name))_e.push(Bt(Le.name,j));return _e}function gi(T){let _=re(T.cookieHeader),j=Object.keys(_).filter((_e)=>_e.startsWith(`${ee}.`)&&_e.endsWith(".profile"));if(!(T.displayCookie?.enabled===!0&&T.displayCookie.discovered?.enabled===!0))return j.map((_e)=>Bt(_e,T.attr));let le=T.now??new Date,ge=ne(T.displayCookie?.discovered?.ttlSeconds),he=new Date(le.getTime()+ge*1000),ke=V(T.displayCookie?.discovered?.max),ye=B(T.cookieHeader),fe=new Set(ye.filter((_e)=>(_e.envelope.kind??"session")==="session").flatMap((_e)=>_e.envelope.tenantId?[_e.envelope.tenantId]:[])),ze=new Map;for(let _e of ye){if(_e.envelope.kind!=="discovered"||!_e.envelope.tenantId)continue;let Le=cr(_e.envelope.expiresAt);if(Le&&ur(Le)&&!fe.has(_e.envelope.tenantId))ze.set(_e.envelope.tenantId,_e.envelope)}let Ye=m(T.user,T.projector);for(let _e of T.tenants){let Le=_e.tenantId.trim();if(!Le||fe.has(Le))continue;ze.set(Le,{v:W,kind:"discovered",tenantId:Le,authType:T.authType,expiresAt:he.toISOString(),user:Ye,..._e.tenantName?{tenantName:_e.tenantName}:{}})}let Qe=[...ze.values()].sort((_e,Le)=>P(_e.expiresAt,Le.expiresAt)).slice(0,ke),ct=new Set(Qe.map((_e)=>G(_e.tenantId??""))),st=Qe.map((_e)=>dr(G(_e.tenantId??""),z(_e),new Date(_e.expiresAt),T.attr));for(let _e of j)if(!ct.has(_e))st.push(Bt(_e,T.attr));return st}var gr=60000,ts=86400000,ns=600000,pr=256,It=new Map;function yi(T){if(typeof T?.ttlMs==="number"&&Number.isFinite(T.ttlMs))ns=Math.min(Math.max(T.ttlMs,gr),ts);if(typeof T?.maxEntries==="number"&&Number.isFinite(T.maxEntries)){pr=Math.max(1,Math.floor(T.maxEntries));while(It.size>pr){let _=It.keys().next().value;if(_===void 0)break;It.delete(_)}}}function es(T,_){It.delete(T),It.set(T,_);while(It.size>pr){let j=It.keys().next().value;if(j===void 0)break;It.delete(j)}}var An=new Map,mr=()=>Date.now();function hi(T){mr=T??(()=>Date.now())}var fr={};function ki(T){fr=T??{}}function Si(T){if(!T)return;if(/\bno-store\b/i.test(T))return gr;let _=/max-age\s*=\s*(\d+)/i.exec(T);if(!_)return;let j=Number(_[1]);return Number.isFinite(j)?j*1000:void 0}function wi(T){let j=Si(T)??ns;return Math.min(Math.max(j,gr),ts)}async function yr(T,_=3,j=1000,X=30000,le){let ge=Error("Placeholder Error");for(let he=0;he<=_;he++)try{return await T()}catch(ke){if(ge=ke instanceof Error?ke:Error(String(ke)),ke instanceof Error&&ke.message.includes("400"))throw ke;if(he===_)throw ge;let ye=Math.min(j*2**he,X),fe=Math.random()*0.1*ye;await new Promise((ze)=>setTimeout(ze,ye+fe)),le?.warn(`Retry attempt ${he+1} after ${ye+fe}ms delay`)}throw ge}async function In(T,_,j){let X=It.get(T);if(!j?.forceRefresh&&X&&X.expiresAt>mr())return es(T,X),X.jwks;let le=An.get(T);if(le)return le;let ge=(async()=>{try{return await yr(async()=>{let he=await fetch(T,{headers:i});if(!he.ok){let fe=await F(he);throw _?.warn("JWKS endpoint returned an error",{"ion.operation":"jwks.fetch","ion.outcome":"degraded",reason:"upstream_error",status:he.status,contentType:fe.contentType,excerpt:fe.excerpt}),Error(`Failed to fetch JWKS (${he.status})`)}let ke=await a(he,{log:_,operation:"jwks.fetch"}),ye=wi(he.headers.get("cache-control"));return es(T,{jwks:ke,expiresAt:mr()+ye,importedKeys:new Map}),ke},fr.maxRetries,fr.baseDelayMs,void 0,_)}catch(he){let ke=It.get(T);if(ke)return _?.warn("JWKS refresh failed; serving last-known-good keys",{"ion.operation":"jwks.refresh","ion.outcome":"degraded"}),ke.jwks;throw he}finally{An.delete(T)}})();return An.set(T,ge),ge}function bi(T){if(T){It.delete(T),An.delete(T);return}It.clear(),An.clear()}async function Ci(T,_,j){return(await rs(T,_,j)).jwk}async function rs(T,_,j){if(!_?.trim())throw Error("JWT header missing kid");await In(T,j);let X=It.get(T),le=X?.jwks.keys.find((ge)=>ge.kid===_);if(!le)await In(T,j,{forceRefresh:!0}),X=It.get(T),le=X?.jwks.keys.find((ge)=>ge.kid===_);if(!X||!le)throw Error("Public key not found");return{jwk:le,entry:X}}async function hr(T,_,j,X,le){let{jwk:ge,entry:he}=await rs(T,_,le),ke=`${_}\x00${j}`,ye=he.importedKeys.get(ke);if(ye)return ye;let fe=X(ge);return fe.catch(()=>{if(he.importedKeys.get(ke)===fe)he.importedKeys.delete(ke)}),he.importedKeys.set(ke,fe),fe}async function vi(T,_){let j=T.keys.find((X)=>X.kid===_);if(!j)throw Error("Public key not found");return ss(j)}function ss(T){return crypto.subtle.importKey("jwk",{kty:T.kty,n:T.n,e:T.e},{name:"RSASSA-PKCS1-v1_5",hash:"SHA-256"},!1,["verify"])}async function Ri(T,_,j){return hr(T,_,"rs256",ss,j)}var lr={RS256:{kty:"RSA",importParams:{name:"RSASSA-PKCS1-v1_5",hash:"SHA-256"},verifyParams:{name:"RSASSA-PKCS1-v1_5"}},ES256:{kty:"EC",crv:"P-256",importParams:{name:"ECDSA",namedCurve:"P-256"},verifyParams:{name:"ECDSA",hash:"SHA-256"}}};async function kr(T,_,j,X){if(typeof j!=="string"||!(j in lr))throw Error(`Unsupported JWT alg "${String(j)}" (allowed: ${Object.keys(lr).join(", ")})`);let le=lr[j];return{key:await hr(T,_,`oidc:${j}`,(he)=>{if(he.kty!==le.kty)throw Error(`JWK type "${he.kty}" does not match token alg "${j}"`);if(le.kty==="EC"){let ke=he;if(ke.crv!==le.crv)throw Error(`JWK curve "${String(ke.crv)}" does not match token alg "${j}"`);return crypto.subtle.importKey("jwk",{kty:"EC",crv:ke.crv,x:ke.x,y:ke.y},le.importParams,!1,["verify"])}return crypto.subtle.importKey("jwk",{kty:he.kty,n:he.n,e:he.e},le.importParams,!1,["verify"])},X),algorithm:le.verifyParams}}function _t(T=32){let _=new Uint8Array(T);return crypto.getRandomValues(_),Array.from(_,(j)=>j.toString(16).padStart(2,"0")).join("").substring(0,T)}function $n(T){let _="";return T.forEach((j)=>{_+=String.fromCharCode(j)}),btoa(_).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function as(T){let _=T.replace(/-/g,"+").replace(/_/g,"/"),j=_.padEnd(_.length+(4-_.length%4)%4,"="),X=atob(j),le=new Uint8Array(X.length);for(let ge=0;ge<X.length;ge++)le[ge]=X.charCodeAt(ge);return le}function is(T){let _=new TextDecoder().decode(as(T));return JSON.parse(_)}async function Pn(T){let _=new TextEncoder().encode(T),j=await crypto.subtle.digest("SHA-256",_);return $n(new Uint8Array(j))}function wr(T){let _=new URL(T.authorizationUrl);if(_.searchParams.set("client_id",T.clientId),_.searchParams.set("redirect_uri",T.redirectUri),_.searchParams.set("response_type","code"),_.searchParams.set("scope",T.scope),_.searchParams.set("state",T.state),T.codeChallenge)_.searchParams.set("code_challenge",T.codeChallenge),_.searchParams.set("code_challenge_method","S256");if(T.nonce)_.searchParams.set("nonce",T.nonce);for(let[j,X]of Object.entries(T.extraParams??{}))_.searchParams.set(j,X);return _.toString()}async function br(T){let _=new URLSearchParams;if(_.append("grant_type","authorization_code"),_.append("code",T.code),_.append("redirect_uri",T.redirectUri),_.append("client_id",T.clientId),T.clientSecret)_.append("client_secret",T.clientSecret);if(T.codeVerifier)_.append("code_verifier",T.codeVerifier);let j=await fetch(T.tokenUrl,{method:"POST",headers:{...h,...i},body:_.toString()}),X=await a(j,{log:T.log,operation:"oidc.token.exchange"});if(!j.ok){let le=X,ge=le.error==="invalid_client"&&!T.clientSecret;throw T.log?.error(ge?"OIDC authorization-code exchange failed: no client_secret was configured; the provider may require a confidential client":"OIDC authorization-code exchange failed",{"ion.operation":"token.exchange","ion.outcome":"failure","http.status_code":j.status,oidc_error:le.error,...ge?{client_auth:"none"}:{}}),Error(`Token exchange failed: ${le.error||j.statusText} - ${le.error_description||""}`.trim())}if(typeof X.access_token!=="string")throw Error("Token exchange response missing access_token");return X}var cs=60;function xn(T){return T.trim().replace(/\/$/,"")}function us(T){let{claims:_,audience:j}=T,X=xn(T.issuer),le=T.nowSec??Math.floor(Date.now()/1000),ge=T.clockSkewSec??cs,he=_.iss;if(typeof he!=="string"||xn(he)!==X)throw Error("ID token issuer mismatch");let ke=_.aud,ye=Array.isArray(ke)?ke.includes(j):typeof ke==="string"&&ke===j,fe=typeof _.azp==="string"&&_.azp===j;if(!ye&&!fe)throw Error("ID token audience mismatch");if(typeof _.exp!=="number")throw Error("ID token missing exp");if(_.exp<le-ge)throw Error("ID token expired");if(T.expectedNonce!==void 0){if(_.nonce!==T.expectedNonce)throw Error("ID token nonce mismatch")}}async function ds(T,_,j){let X=T.split(".");if(X.length!==3)throw Error("Invalid JWT");let le=is(X[0]),ge=is(X[1]),he=as(X[2]),{key:ke,algorithm:ye}=await kr(_,le.kid,le.alg,j),fe=new TextEncoder().encode(`${X[0]}.${X[1]}`);if(!await crypto.subtle.verify(ye,ke,he,fe))throw Error("Invalid JWT signature");return{header:le,payload:ge}}async function Zt(T){let{payload:_}=await ds(T.idToken,T.jwksUri,T.log);return us({claims:_,issuer:T.issuer,audience:T.audience,clockSkewSec:T.clockSkewSec,expectedNonce:T.expectedNonce}),_}var Ai="http://schemas.openid.net/event/backchannel-logout";async function Cr(T){let{payload:_}=await ds(T.logoutToken,T.jwksUri,T.log),j=xn(T.issuer),X=_.iss;if(typeof X!=="string"||xn(X)!==j)throw Error("Logout token issuer mismatch");let le=_.aud,ge=Array.isArray(le)?le.includes(T.audience):typeof le==="string"&&le===T.audience,he=typeof _.azp==="string"&&_.azp===T.audience;if(!ge&&!he)throw Error("Logout token audience mismatch");if(_.nonce!=null)throw Error("Logout token must not contain a nonce");let ke=_.events;if(!(typeof ke==="object"&&ke!==null&&!Array.isArray(ke)&&Object.hasOwn(ke,Ai)))throw Error("Logout token missing back-channel logout event");let fe=typeof _.sid==="string"&&_.sid.length>0,ze=typeof _.sub==="string"&&_.sub.length>0;if(!fe&&!ze)throw Error("Logout token missing sid and sub");if(typeof _.exp==="number"){let Ye=Math.floor(Date.now()/1000),Qe=T.clockSkewSec??cs;if(_.exp<Ye-Qe)throw Error("Logout token expired")}return _}var Ii=3600000,Ti=60000,xi=86400000,Pi=256,Gt=new Map,Tn=new Map;function os(T,_){Gt.delete(T),Gt.set(T,_);while(Gt.size>Pi){let j=Gt.keys().next().value;if(j===void 0)break;Gt.delete(j)}}var Sr=()=>Date.now();function Ui(T){Sr=T??(()=>Date.now())}function Ei(T){if(T){Gt.delete(T),Tn.delete(T);return}Gt.clear(),Tn.clear()}function Di(T){let _=T?/max-age\s*=\s*(\d+)/i.exec(T):null,j=_?Number(_[1]):Number.NaN,X=Number.isFinite(j)?j*1000:Ii;return Math.min(Math.max(X,Ti),xi)}async function vr(T){let _=Gt.get(T);if(_&&_.expiresAt>Sr())return os(T,_),_.endpoints;let j=Tn.get(T);if(j)return j;let X=(async()=>{try{let le=T.replace(/\/$/,""),ge=await fetch(`${le}/.well-known/openid-configuration`,{headers:i});if(!ge.ok)throw Error(`OIDC discovery failed for ${T} with status ${ge.status}`);let he=await a(ge),ke={authorizationUrl:typeof he.authorization_endpoint==="string"?he.authorization_endpoint:void 0,tokenUrl:typeof he.token_endpoint==="string"?he.token_endpoint:void 0,jwksUri:typeof he.jwks_uri==="string"?he.jwks_uri:void 0,userInfoUrl:typeof he.userinfo_endpoint==="string"?he.userinfo_endpoint:void 0};return os(T,{endpoints:ke,expiresAt:Sr()+Di(ge.headers.get("cache-control"))}),ke}catch(le){let ge=Gt.get(T);if(ge)return ge.endpoints;throw le}finally{Tn.delete(T)}})();return Tn.set(T,X),X}async function Rr(T,_){let j=await fetch(T,{headers:{Authorization:`Bearer ${_}`,...i,"User-Agent":"ionite-ciam"}});if(!j.ok)throw Error(`UserInfo request failed with status ${j.status}`);return await a(j)}function Mi(T){let _=T.replace(/-----BEGIN [^-]+-----/g,"").replace(/-----END [^-]+-----/g,"").replace(/\s+/g,""),j=atob(_),X=new Uint8Array(j.length);for(let le=0;le<j.length;le++)X[le]=j.charCodeAt(le);return X}async function Ar(T){let _=Math.floor(Date.now()/1000),j={alg:"ES256",kid:T.keyId,typ:"JWT"},X={iss:T.teamId,iat:_,exp:_+(T.expiresInSeconds??3600),aud:"https://appleid.apple.com",sub:T.clientId},le=$n(new TextEncoder().encode(JSON.stringify(j))),ge=$n(new TextEncoder().encode(JSON.stringify(X))),he=`${le}.${ge}`,ke=await crypto.subtle.importKey("pkcs8",Mi(T.privateKey),{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),ye=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},ke,new TextEncoder().encode(he));return`${he}.${$n(new Uint8Array(ye))}`}function Oi(T){for(let _=0;_<T.length;_++){let j=T.charCodeAt(_);if(j<=31||j===127)return!0}return!1}function _i(T,_){let j=null;try{j=new URL(T,_)}catch{j=null}let X="";try{X=new URL(_).origin}catch{X=""}return{candidate:T,url:j,requestOrigin:X}}function ls(T,_,j){let X=_i(T,j),le=!1;for(let ge of _){let he=ge(X);if(he==="deny")return!1;if(he==="allow")le=!0}return le}function ps(){return({candidate:T,url:_})=>{if(Oi(T))return"deny";if(T.includes("\\"))return"deny";if(T.startsWith("//"))return"deny";if(!_)return"deny";if(_.protocol!=="http:"&&_.protocol!=="https:")return"deny";if(_.username||_.password)return"deny";return"abstain"}}function ms(){return({candidate:T})=>T.startsWith("/")&&!T.startsWith("//")&&!T.startsWith("/\\")?"allow":"abstain"}function fs(){return({url:T,requestOrigin:_})=>T&&_&&T.origin===_?"allow":"abstain"}function ji(...T){let _=new Set(T.map((j)=>{try{return new URL(j).origin}catch{return j}}));return({url:j})=>j&&_.has(j.origin)?"allow":"abstain"}function Li(...T){let _=T.map((j)=>j.toLowerCase());return({url:j})=>{if(!j)return"abstain";let X=j.hostname.toLowerCase();for(let le of _)if(le.startsWith(".")){if(X===le.slice(1)||X.endsWith(le))return"allow"}else if(X===le)return"allow";return"abstain"}}function Ir(){return[ps(),ms(),fs()]}function gs(T,_,j){if(!T)return!1;return ls(T,_,j)}function Tr(T,_){if(!T)return _.fallback;return ls(T,_.rules,_.requestUrl)?T:_.fallback}var Ni={rules:Ir(),fallback:"/"};function $i(T,_,j="redirect"){let X=new URL(T.url).searchParams.get(j)??void 0;return gs(X,_.rules,T.url)?{redirect:X}:void 0}function Wi(T,_){let j=T.context;return Tr(j?.redirect,{rules:_.rules,fallback:_.fallback,requestUrl:T.request.url})}function Qt(T,_,j){if(T instanceof Response)return{response:T};if(typeof T==="string")return{location:Tr(T,{rules:Ir(),fallback:_,requestUrl:j})};return{location:_}}function sn(T,_){if(_.length===0)return T;let j=new Headers(T.headers);for(let X of _)j.append("Set-Cookie",X);return new Response(T.body,{status:T.status,statusText:T.statusText,headers:j})}var Wn="ciam",Vi="id_token",qi="access_token";function zi(T,_,j,X,le,ge){if(!j&&!X)return;let he=new WeakMap,ke={...j,...X},ye={...ke,magicLinkTtl:ke.magicLinkTtl??3600,sessionTtl:ke.sessionTtl??86400,cookiesSecure:ke.cookiesSecure!==void 0?ke.cookiesSecure:!0,cookiesSameSite:ke.cookiesSameSite!==void 0?ke.cookiesSameSite:"Strict",cookiesPrefix:ke.cookiesPrefix??(ke.ciamId?`ion.ciam.${ke.ciamId}`:"ion.ciam"),cookiesPath:ke.cookiesPath??"/",cookiesDomain:Nn(ke.cookiesDomain)};function fe(){if(!ye.sessionStore)throw Error("Missing CIAM configuration field: sessionStore. CIAM sessionStore is required for server-side session tracking and first-party logout.");return ye.sessionStore}function ze(){fe()}let Ye=T.callbackParams??l(oe("ionite.ciam")),Qe=T.idTokenClaims??l(y("ionite.ciam")),ct=T.tokenResponse??l(ie("ionite.ciam"));function st(me=32){let we=new Uint8Array(me);return crypto.getRandomValues(we),Array.from(we,(be)=>be.toString(16).padStart(2,"0")).join("").substring(0,me)}function _e(me,we,be,Re=ye.cookiesSameSite??"Strict"){if(!ye)throw Error("ionite CIAM Manager not initialized");if(me=`${ye.cookiesPrefix}.${me}`,typeof we!=="string")we=btoa(JSON.stringify(we));let Ue;if(be instanceof Date)Ue=`Expires=${be.toUTCString()}`;else if(typeof be==="number")Ue=`Max-Age=${be}`;else throw Error("Invalid expires type",be);if(we.length>4000)throw Error(`Error setting cookie: ${me}. Cookie length is: ${we.length}`);return`${me}=${we}; ${Ue}; Path=${ye.cookiesPath};${Xt(ye.cookiesDomain)} HttpOnly;${ye.cookiesSecure?" Secure;":""} SameSite=${Re};`}function Le(me){if(!ye)throw Error("ionite CIAM Manager not initialized");return`${ye.cookiesPrefix}.${me}=; Max-Age=0; Path=${ye.cookiesPath};${Xt(ye.cookiesDomain)} HttpOnly;${ye.cookiesSecure?" Secure;":""} SameSite=${ye.cookiesSameSite};`}function et(me,we,be=!1){if(!ye)throw Error("ionite CIAM Manager not initialized");let Re=we.headers.get("cookie");if(!Re)return null;let Ue=`${ye.cookiesPrefix}.${me}`,je=Re.split(";").find((Ee)=>Ee.trim().startsWith(`${Ue}=`));if(!je)return null;let We=je.indexOf("="),qe=je.substring(We+1).trim();if(!be)return qe;try{let Ee=atob(qe);return JSON.parse(Ee)}catch(Ee){return _.error("[CIAM] Failed to parse cookie",{"ion.operation":"cookie.parse","ion.outcome":"failure",cookieName:Ue},Ee),null}}function De(me){return`cstate_${me}`}async function it(me,we,be,Re){let Ue=await ye.afterLogin?.({...we,request:me,context:be,displayCookie:ye.displayCookie,displayCookieAttributes:bt()}),je=Qt(Ue,"/",me.url);if(je.response)return sn(je.response,Re.map(([,We])=>We));return new Response(we.ok?"Authentication successful, redirecting":"Authentication failed, redirecting",{status:302,headers:[["Location",je.location],...Re]})}function pt(me,we){return["Set-Cookie",_e("session",me,we)]}function bt(){return{path:ye.cookiesPath??"/",domain:ye.cookiesDomain,secure:ye.cookiesSecure!==!1,sameSite:ye.cookiesSameSite??"Strict"}}function mt(){return[["Set-Cookie",Le("session")],["Set-Cookie",Bt(`${ye.cookiesPrefix}.profile`,bt())]]}function Rt(me){if(ye.displayCookie?.enabled===!0)return[];return mn(me.headers.get("cookie"),ye.cookiesPrefix??"ion.ciam",bt()).map((we)=>["Set-Cookie",we])}async function Tt(me,we,be){return(await Rn({cookieHeader:me.headers.get("cookie"),sessionStore:ye.sessionStore,cookiesPrefix:ye.cookiesPrefix??"ion.ciam",authType:"ciam",tenantId:ye.tenantId,expiresAt:be,user:we,projector:ye.displayUser,displayCookie:ye.displayCookie,trim:ye.trimDisplayCookies,attr:bt()})).map((Ue)=>["Set-Cookie",Ue])}function Mt(me){if(!me)return;if(me instanceof Date)return me;let we=new Date(me);return Number.isNaN(we.getTime())?void 0:we}async function kn(me){let we=et("session",me);if(!we)return;let be=await fe().get(we);if(be&&ye.tenantId&&be.tenantId&&be.tenantId!==ye.tenantId)return;if(be?.authType!=="ciam")return;let Re=Mt(be.expiresAt);if(Re&&Date.now()>Re.getTime()){await fe().delete(we);return}return be}async function Jt(me){if(!ye)throw Error("ionite CIAM Manager not initialized");ze();let we=he.get(me);if(we)return we;let be=Sn(me);return he.set(me,be),be}async function Sn(me){try{let we=await kn(me);if(!we?.claims?.sub)return{status:"unauthenticated"};return vn(me,"customer",we.entitlements),{status:"authenticated",value:xt(we.claims)}}catch(we){return _.error("CIAM session resolution failed",{"ion.operation":"ciam.session","ion.outcome":"degraded"},we),{status:"degraded",error:we instanceof Error?we:void 0}}}async function un(me){let we=await Jt(me);return we.status==="authenticated"?we.value:void 0}async function Ht(me){if(!ye)throw Error("ionite CIAM Manager not initialized");ze();let we;try{we=await un(me)}catch{we=void 0}let be=await ye.beforeLogout?.({request:me,user:we});try{let Ae=et("session",me);if(Ae)await fe().delete(Ae)}catch(Ae){_.warn("Failed to delete CIAM session",{"ion.operation":"session.delete","ion.outcome":"degraded"},Ae)}let Re=mt(),Ue=await ye.afterLogout?.({request:me,context:be}),je=Qt(Ue,"/",me.url);if(je.response)return sn(je.response,Re.map(([,Ae])=>Ae));let We=je.location??"/",qe=me.headers.get("accept");if(qe?.includes(s)||qe?.includes("text/javascript"))return new Response(JSON.stringify({success:!0,message:"Logged out",redirect:We}),{status:200,headers:[["Content-Type",s],...Re]});return new Response("Logged out",{status:302,headers:[["Location",We],...Re]})}function Ft(me){return me.id||me.email||`ciam-${me.userName}`}function nn(me,we,be){return{sub:Ft(me),iss:Wn,aud:Wn,typ:Vi,exp:Math.floor(be.getTime()/1000),iat:Math.floor(Date.now()/1000),email:me.email,name:me.name,preferred_username:me.userName,picture:me.avatar,sid:we}}function dn(me,we,be){return{sub:me,iss:Wn,aud:Wn,typ:qi,exp:Math.floor(be.getTime()/1000),iat:Math.floor(Date.now()/1000),sid:we,scope:"openid profile email"}}function xt(me){let we=me.exp?new Date(me.exp*1000):new Date;return{id:me.sub,userName:me.preferred_username??"",name:me.name??"",email:me.email??"",avatar:me.picture,userType:"customer",ciam:{profile:me,scope:"openid profile email",tokenType:"Bearer",expires:we}}}async function ln(me){if(!ye)throw Error("ionite CIAM Manager not initialized");if(!le)return new Response(JSON.stringify({error:"Workload authentication required"}),{status:401,headers:r});if(!await le.getWorkloadIdentity(me))return new Response(JSON.stringify({error:"Unauthorized: Valid workload token required"}),{status:401,headers:r});let be,Re;try{if(!me.headers.get("content-type")?.includes(s))return new Response(JSON.stringify({error:"Content-Type must be application/json"}),{status:400,headers:r});let Te=await me.text(),xe=JSON.parse(Te);Re=typeof xe?.redirect==="string"&&xe.redirect.length>0?xe.redirect:void 0;let Ne={userName:xe.userName,name:xe.name,email:xe.email,avatar:xe.avatar},Oe=await T.customer.validate(Ne);if(Oe.issues)return new Response(JSON.stringify({error:"Missing required fields: userName, name, email"}),{status:400,headers:r});be=Oe.value}catch(Ie){return new Response(JSON.stringify({error:"Invalid JSON in request body"}),{status:400,headers:r})}let je=new URL(me.url).searchParams.get("ttl"),We=je?parseInt(je,10):ye.magicLinkTtl??3600;if(Number.isNaN(We)||We<=0)return new Response(JSON.stringify({error:"Invalid TTL parameter"}),{status:400,headers:r});let qe=st(32),Ee=new Date(Date.now()+We*1000);if(!ye.magicLinkStore)return new Response(JSON.stringify({error:"Magic link store not configured"}),{status:501,headers:r});try{await ye.magicLinkStore.create(qe,be,Ee)}catch(Ie){return _.error("Error creating magic link",{"ion.operation":"magic_link.create","ion.outcome":"failure"},Ie),new Response(JSON.stringify({error:"Failed to create magic link"}),{status:500,headers:r})}let Ae=new URL(me.url),Se=ye.magicLinkLoginUrl||"/magic-link/login",ve=new URL(Se,Ae.origin);if(ve.searchParams.set("token",qe),Re)ve.searchParams.set("redirect",Re);return new Response(JSON.stringify({magicLink:ve.toString(),expiresAt:Ee.toISOString()}),{status:200,headers:r})}async function Yt(me){if(!ye)throw Error("ionite CIAM Manager not initialized");ze();let be=new URL(me.url).searchParams.get("token");if(!be)return it(me,{ok:!1,error:Error("Missing magic-link token")},void 0,[]);if(!ye.magicLinkStore)return it(me,{ok:!1,error:Error("Magic link store not configured")},void 0,[]);let Re=await ye.magicLinkStore.getAndDelete(be);if(!Re)return it(me,{ok:!1,error:Error("Magic link invalid, expired, or already used")},void 0,[]);let Ue=new Date(Date.now()+(ye.sessionTtl??86400)*1000),je=st(32),We=Ft(Re.customer),qe=nn(Re.customer,je,Ue),Ee=dn(We,je,Ue),Ae=xt(qe),Se;try{let Ie={sid:je,sub:We,authType:"ciam",tenantId:ye.tenantId,expiresAt:Ue,claims:qe,accessClaims:Ee,createdAt:new Date};await fe().create(Ie),Se=Ie}catch(Ie){throw _.warn("Failed to create session",{"ion.operation":"session.create","ion.outcome":"degraded"},Ie),Ie}if(ye.customerStore)try{let Ie=Ae.id;if(Ie){let Te=new Date,xe=await ye.customerStore.get(Ie);if(xe||ye.enableJitUserProvisioning){let Ne={...xe??{},...Ae,id:Ie,tenantId:xe?.tenantId,createdAt:xe?.createdAt??Te,updatedAt:Te,userType:xe?.userType??"customer"};await ye.customerStore.upsert(Ne)}}}catch(Ie){_.warn("Failed to store customer",{"ion.operation":"customer.store","ion.outcome":"degraded"},Ie)}let ve=[pt(je,Ue),...await Tt(me,Ae,Ue)];return it(me,{ok:!0,user:Ae,session:Se},void 0,ve)}function Pt(me,we=200,be=[]){return new Response(JSON.stringify(me),{status:we,headers:[["Content-Type",s],...be]})}function At(me,we){try{return new URL(me).toString()}catch{let be=new URL(we).origin,Re=ye.cookiesSecure?be.replace(/^http:\/\//,"https://"):be;return new URL(me,Re).toString()}}function $t(){let me=ye.customerLoginUrl||"/auth/customer/login",we=me.includes("?")?"&":"?";return ar(ye.providers).map(({name:be,config:Re})=>{let Ue=or(Re);return{name:be,type:Re.type,displayName:Ue.displayName,loginUrl:`${me}${we}provider=${encodeURIComponent(be)}`,iconUrl:Ue.iconUrl,colors:Ue.colors,url:Ue.url}})}async function Wt(me){if(!me)return{};let{authorizationUrl:we,tokenUrl:be,jwksUri:Re,userInfoUrl:Ue}=me,je=me.config.authority;if(je&&(!we||!be||me.flow==="id_token"&&!Re))try{let qe=await vr(je);we=we??qe.authorizationUrl,be=be??qe.tokenUrl,Re=Re??qe.jwksUri,Ue=Ue??qe.userInfoUrl}catch(qe){_.error("CIAM provider OIDC discovery failed",{"ion.operation":"ciam.oidc.discovery","ion.outcome":"failure"},qe)}return{authorizationUrl:we,tokenUrl:be,jwksUri:Re,userInfoUrl:Ue}}async function rn(me){if(me.type==="apple"){let{teamId:we,keyId:be,privateKey:Re,clientId:Ue}=me.config;if(we&&be&&Re&&Ue)return Ar({teamId:we,keyId:be,privateKey:Re,clientId:Ue})}return me.clientSecret}async function Ot(me){fe();let be=new URL(me.url).searchParams.get("provider");if(!be)return Pt({error:"Missing required query parameter: provider"},400);let Re=ye.providers?.[be];if(!Re||Re.enabled===!1||Re.type==="magic-link")return Pt({error:`Unknown or disabled CIAM provider: ${be}`},404);let Ue=Ln(be,Re);if(!Ue?.clientId)return Pt({error:`CIAM provider ${be} is not fully configured`},500);let je=await Wt(Ue);if(!je.authorizationUrl)return Pt({error:`CIAM provider ${be} is missing an authorization endpoint`},500);let We=ye.customerCallbackUrl||"/auth/customer/callback",qe=At(We,me.url),Ee=_t(),Ae=_t(64),Se=_t(),ve=Ue.flow==="id_token",Ie=ve?await Pn(Ae):void 0,Te=await ye.beforeLogin?.({request:me}),xe=wr({authorizationUrl:je.authorizationUrl,clientId:Ue.clientId,redirectUri:qe,scope:Ue.scope,state:Ee,codeChallenge:Ie,nonce:Se,extraParams:Ue.extraAuthParams}),Ne={provider:be,state:Ee,codeVerifier:ve?Ae:void 0,nonce:Se,redirectUri:qe,...Te===void 0?{}:{context:Te}};return new Response("Redirecting to CIAM provider",{status:302,headers:[["Location",xe],["Set-Cookie",_e(De(Ee),Ne,ye.loginStateTtl??600,"Lax")]]})}async function Ve(me){if(me.method==="POST"){if((me.headers.get("content-type")??"").includes(D)){let be=await me.text();return Object.fromEntries(new URLSearchParams(be).entries())}}return Object.fromEntries(new URL(me.url).searchParams.entries())}let Xe=!1;async function Be(me,we,be,Re){let Ue=me.config.claimsAsEntitlements;if(!Ue?.claims?.length||me.type==="magic-link")return;if(ye.sessionStore?.capabilities?.derivedEntitlements!==!0){if(!Xe)Xe=!0,_.warn("CIAM claims entitlements are configured but the session store does not persist them",{"ion.event":"ion.ciam.claims.incapable","ion.module":"ciam","ion.outcome":"degraded"});return}return bn({block:Ue,claims:we,accessClaims:Cn(Re),subjectType:"customer",subjectId:be,catalog:ge?.catalogView?.(),log:_})}async function Ze(me,we,be){let Re=me.mapClaims(we);if(!Re.sub)return{ok:!1};let Ue=`${me.name}:${Re.sub}`,je={id:Ue,userName:Re.userName||Re.email||Ue,name:Re.name||"",email:Re.email||"",avatar:Re.avatar,userType:"customer"},We=Ue;if(ye.customerStore){let Ie=await ye.customerStore.lookup(je)??await ye.customerStore.get(Ue);if(We=Ie?.id??Ue,!Ie&&!ye.enableJitUserProvisioning)return _.warn("CIAM JIT customer provisioning disabled: unknown customer rejected",{"ion.operation":"customer.store","ion.outcome":"skipped"}),{ok:!1};let Te=new Date,xe={...Ie??{},...je,id:We,tenantId:Ie?.tenantId,createdAt:Ie?.createdAt??Te,updatedAt:Te,userType:Ie?.userType??"customer"};await ye.customerStore.upsert(xe)}let qe=new Date(Date.now()+(ye.sessionTtl??86400)*1000),Ee=_t(32),Ae={sub:We,iss:me.name,aud:me.clientId,exp:Math.floor(qe.getTime()/1000),iat:Math.floor(Date.now()/1000),email:Re.email,name:Re.name,preferred_username:Re.userName??Re.email,picture:Re.avatar,sid:Ee},Se={sid:Ee,sub:We,authType:"ciam",tenantId:ye.tenantId,expiresAt:qe,claims:Ae,accessClaims:{sub:We,sid:Ee,scope:me.scope},entitlements:await Be(me,we,We,be),createdAt:new Date},ve=fe();try{await ve.create(Se)}catch(Ie){if(!await ve.get(Ee))throw Ie;await ve.update(Ee,Se)}return{ok:!0,claims:Ae,sid:Ee,expires:qe}}async function Je(me){fe();let we,be,Re=(Ue)=>{let je=we?[["Set-Cookie",Le(we)]]:[];return it(me,{ok:!1,error:Ue},be,je)};try{let Ue=await Ve(me),je=await Ye.validate(Ue);if(je.issues||!je.value)return Re(Error("Invalid CIAM callback parameters"));let{code:We,state:qe}=je.value;if(!qe)return Re(Error("Missing CIAM callback state"));we=De(qe);let Ee=et(we,me,!0);if(be=Ee?.context,!Ee?.provider||!Ee.state||Ee.state!==qe)return _.warn("CIAM callback state verification failed",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),Re(Error("CIAM callback state verification failed"));let Ae=ye.providers?.[Ee.provider];if(!Ae)return Re(Error("Unknown CIAM provider"));let Se=Ln(Ee.provider,Ae);if(!Se?.clientId)return Re(Error("CIAM provider not configured"));let ve=await Wt(Se);if(!ve.tokenUrl)return Re(Error("CIAM provider missing token endpoint"));let Ie=await rn(Se),Te=await br({tokenUrl:ve.tokenUrl,clientId:Se.clientId,clientSecret:Ie,redirectUri:Ee.redirectUri||At(ye.customerCallbackUrl||"/auth/customer/callback",me.url),code:We,codeVerifier:Se.flow==="id_token"?Ee.codeVerifier:void 0,log:_}),xe;if(Se.flow==="id_token"){let Fe=Se.config.authority;if(!Te.id_token||!ve.jwksUri||!Fe)return Re(Error("CIAM id_token flow misconfigured"));if(!Ee.nonce)return Re(Error("CIAM callback state cookie missing nonce"));if((await ct.validate(Te)).issues)return _.warn("CIAM token response validation failed",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),Re(Error("CIAM token response validation failed"));xe=await Zt({idToken:Te.id_token,jwksUri:ve.jwksUri,issuer:Fe,audience:Se.clientId,expectedNonce:Ee.nonce,log:_});let at=await Qe.validate(xe);if(!at.issues)xe=at.value}else{if(!ve.userInfoUrl)return Re(Error("CIAM provider missing userinfo endpoint"));xe=await Rr(ve.userInfoUrl,Te.access_token);let Fe=Se.config.authority;if(Te.id_token&&ve.jwksUri&&Fe){let rt=await Zt({idToken:Te.id_token,jwksUri:ve.jwksUri,issuer:Fe,audience:Se.clientId,expectedNonce:Ee.nonce||void 0,log:_}),at=typeof rt.sub==="string"?rt.sub:"";if(at){if(typeof xe.sub==="string"&&xe.sub.length>0&&xe.sub!==at)return _.warn("CIAM UserInfo sub does not match verified id_token sub",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),Re(Error("CIAM UserInfo sub mismatch"));xe.sub=at}}if(typeof xe.sub!=="string"||xe.sub.length===0)return _.warn("CIAM UserInfo response missing sub",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),Re(Error("CIAM UserInfo response missing sub"))}let Ne=await Ze(Se,xe,Te.access_token);if(!Ne.ok)return Re(Error("Failed to persist CIAM customer"));let Oe=xt(Ne.claims);_.info("CIAM third-party sign-in succeeded",{"ion.operation":"ciam.oidc.callback","ion.outcome":"success",provider:Se.name});let Ge=[["Set-Cookie",Le(we)],pt(Ne.sid,Ne.expires),...await Tt(me,Oe,Ne.expires)];return it(me,{ok:!0,user:Oe,session:void 0},be,Ge)}catch(Ue){return _.error("Error during CIAM third-party sign-in callback",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"},Ue),Re(Ue)}}async function He(me){if(!ye)throw Error("ionite CIAM Manager not initialized");ze();let we=ye.magicLinkUrl||"/magic-link",be=ye.magicLinkLoginUrl||"/magic-link/login",Re=ye.logoutUrl||"/auth/customer/logout",Ue=ye.customerLoginUrl||"/auth/customer/login",je=ye.customerCallbackUrl||"/auth/customer/callback",We=ye.customerProvidersUrl||"/auth/customer/providers",qe=new URL(me.url).pathname,Ee=(Ne)=>{if(!Ne)return;try{return new URL(Ne).pathname}catch{return Ne.startsWith("/")?Ne:`/${Ne}`}};if(Ee(we)===qe&&me.method==="POST")return ln(me);if(Ee(be)===qe&&me.method==="GET")return Yt(me);if(Ee(Re)===qe&&me.method==="GET")return Ht(me);if(Ee(We)===qe&&me.method==="GET")return Pt({providers:$t()});if(Ee(Ue)===qe&&me.method==="GET")return Ot(me);if(Ee(je)===qe&&(me.method==="GET"||me.method==="POST"))return Je(me);return new Response("Not Found",{status:404})}async function ut(me){if((ye.userEndpoint??"full")==="off")return new Response("Not Found",{status:404,headers:Rt(me)});let we=await Jt(me);if(we.status==="degraded")return new Response(JSON.stringify({error:"auth_unavailable"}),{status:503,headers:r});if(we.status==="unauthenticated")return new Response(JSON.stringify({error:"Unauthorized"}),{status:401,headers:r});let be=Mt(we.value.ciam?.expires),Re=ye.displayCookie?.enabled===!0?be&&!et("profile",me)?await Tt(me,we.value,be):[]:Rt(me),Ue=ye.userEndpoint==="display"?m(we.value,ye.displayUser):we.value;return new Response(JSON.stringify(Ue),{headers:[["Content-Type",s],...Re]})}let Ce;return Ce={...ye,describe:()=>({module:"ciam",active:!0,ready:Ce.isReady?.()??!0,magicLinkTtl:ye.magicLinkTtl,loginStateTtl:ye.loginStateTtl,sessionTtl:ye.sessionTtl,cookies:{prefix:ye.cookiesPrefix,path:ye.cookiesPath,secure:ye.cookiesSecure,sameSite:ye.cookiesSameSite,domain:ye.cookiesDomain},displayCookie:ye.displayCookie,jit:{enabled:ye.enableJitUserProvisioning===!0,customerStore:ye.customerStore!==void 0},sessionStore:ye.sessionStore!==void 0,magicLinkStore:ye.magicLinkStore!==void 0,providers:Object.entries(ye.providers??{}).map(([me,we])=>({name:me,type:we.type,enabled:we.enabled!==!1,order:we.order,branding:we.branding,authority:we.authority,authorizationUrl:we.authorizationUrl,tokenUrl:we.tokenUrl,jwksUri:we.jwksUri,userInfoUrl:we.userInfoUrl,clientId:we.clientId,scope:we.scope,...we.claimsAsEntitlements?.claims?.length?{claimsAsEntitlements:{claims:[...we.claimsAsEntitlements.claims],expand:we.claimsAsEntitlements.expand===!0,resources:we.claimsAsEntitlements.expand===!0&&we.claimsAsEntitlements.resources===!0,capable:ye.sessionStore?.capabilities?.derivedEntitlements===!0}}:{},loginUrl:`${ye.customerLoginUrl??""}?provider=${encodeURIComponent(me)}`})),urls:{magicLinkUrl:ye.magicLinkUrl??"",magicLinkLoginUrl:ye.magicLinkLoginUrl??"",customerUrl:ye.customerUrl??"",customerLoginUrl:ye.customerLoginUrl??"",customerCallbackUrl:ye.customerCallbackUrl??"",customerProvidersUrl:ye.customerProvidersUrl??"",logoutUrl:ye.logoutUrl??""}}),getCustomer:un,resolveCustomer:Jt,logout:Ht,handler:He,customerHandler:ut,listCustomerProviders:$t},Ce}async function Bi(T,_){return t(_,"Ionite instance is required. Create one with ionite(source, config) and pass it to this function."),_.ciam?.getCustomer(T)}async function Vn(T,_){return t(_,"Ionite instance is required. Create one with ionite(source, config) and pass it to this function."),await _.ciam?.resolveCustomer(T)??{status:"unauthenticated"}}var Gi="urn:ietf:params:scim:schemas:core:2.0:User",ys="urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",Ki="urn:ietf:params:scim:schemas:core:2.0:Group";function xr(T,_,j){let le=(_==="group"?T.resources:void 0)?.map((ge)=>typeof ge==="string"?ge:ge.id).filter(Boolean);return{schemas:[Ki,e],id:T.id,externalId:T.providerId,displayName:T.displayName??T.name,members:j,[e]:{type:_,requestable:T.requestable,riskLevel:T.riskLevel??f,providerId:T.providerId,requestUrl:T.requestUrl,source:T.source,deprecated:T.deprecated,description:T.description,resources:le&&le.length>0?le:void 0,assignableSubjectTypes:T.assignableSubjectTypes,recommendedSubjectTypes:T.recommendedSubjectTypes,attributes:o(T,d)}}}function Ji(T){if(T.scimName)return T.scimName;if(!T.name)return;let[_,...j]=T.name.split(" ");return{givenName:_,familyName:j.join(" ")||void 0}}function Hi(T){let _={attributes:o(T,A)};if(T.ecid!==void 0)_.ecid=T.ecid;if(T.accountClass!==void 0)_.accountClass=T.accountClass;return _.ecid!==void 0||_.accountClass!==void 0||_.attributes!==void 0?_:void 0}function Fi(T){return Object.keys(T.scimSchemaExtensions??{}).filter((_)=>_.startsWith("urn:")&&T.scimSchemaExtensions?.[_]!==void 0)}function Pr(T){let _=T.userName||T.email||T.id||"",j=T.emails??(T.email?[{value:T.email,primary:!0}]:[]),X=new Set([Gi]);if(T.scimEnterprise!==void 0)X.add(ys);let le=Hi(T);if(le!==void 0)X.add(u);for(let he of Fi(T))X.add(he);let ge={};if(T.scimEnterprise!==void 0)ge[ys]=T.scimEnterprise;if(le!==void 0)ge[u]=le;for(let[he,ke]of Object.entries(T.scimSchemaExtensions??{}))if(he.startsWith("urn:")&&he!==u&&ke!==void 0)ge[he]=ke;return{schemas:Array.from(X),id:T.id,externalId:T.externalId,userName:_,displayName:T.displayName??T.name??_,name:Ji(T),nickName:T.nickName,profileUrl:T.avatar,title:T.title,userType:T.userType,preferredLanguage:T.preferredLanguage,locale:T.locale,timezone:T.timezone,active:T.active??!0,emails:j,phoneNumbers:T.phoneNumbers,ims:T.ims,photos:T.photos,addresses:T.addresses,groups:T.groups,entitlements:T.entitlements,roles:T.roles,x509Certificates:T.x509Certificates,meta:{resourceType:"User",created:(T.createdAt??T.updatedAt??new Date).toISOString(),lastModified:(T.updatedAt??T.createdAt??new Date).toISOString()},...ge}}function Ur(T){return{schemas:[b],id:T.id,externalId:T.externalId,userName:T.clientId??T.id,displayName:T.displayName??T.clientId??T.id,description:T.description,active:T.active??!0,ecid:T.ecid,providerId:T.providerId,requestUrl:T.requestUrl,attributes:o(T,v),meta:{resourceType:"Workload",created:(T.createdAt??T.updatedAt??new Date).toISOString(),lastModified:(T.updatedAt??T.createdAt??new Date).toISOString()}}}function Er(T){return{schemas:[C],id:T.id,externalId:T.externalId??T.id,userName:T.userName??T.email??T.id,displayName:T.displayName??T.name??T.userName??T.id,active:T.active??!0,emails:T.emails??(T.email?[{value:T.email,primary:!0}]:void 0),providerId:T.providerId,requestUrl:T.requestUrl,attributes:o(T,I),meta:{resourceType:"Customer",created:(T.createdAt??T.updatedAt??new Date).toISOString(),lastModified:(T.updatedAt??T.createdAt??new Date).toISOString()}}}function fn(T){return{enabled:T?.enabled!==!1,assignment:T?.assignment??"app",delta:T?.delta}}var Yi="urn:ietf:params:scim:api:messages:2.0:ListResponse",jr="urn:ietf:params:scim:api:messages:2.0:Error",Lr="urn:ietf:params:scim:schemas:core:2.0:User",Mn="urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",Nr="urn:ietf:params:scim:schemas:core:2.0:Group",Xi="urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig",qn="urn:ietf:params:scim:schemas:core:2.0:ResourceType",on="urn:ietf:params:scim:schemas:core:2.0:Schema",Zi="00000000000000000000000000000000";function Qi(T){let _={timestamp:new Date().toISOString()};if(T)_.actor=T;try{let le=globalThis[Symbol.for("opentelemetry.js.api.1")]?.trace?.getActiveSpan?.()?.spanContext?.(),ge=le?.traceId;if(ge&&ge!==Zi){if(_.traceId=ge,le?.spanId)_.spanId=le.spanId}}catch{}return _}class On extends Error{constructor(T){super(T);this.name="SubjectTypeNotAssignableError",Object.setPrototypeOf(this,On.prototype)}}async function Rs(T,_,j,X){let le=j.subjectType;if(!g.includes(le))throw new On(`Cannot grant ${j.targetType} "${n(j.target)}" to a "${le}" principal: only [${g.join(", ")}] principals are assignable on this platform.`);let ge=q(_,T);if(!ge&&!X)return;let he=n(j.target),ke;if(X)ke=await X.getNode(j.targetType,he);else if(ge)ke=await(j.targetType==="group"?ge.groups:j.targetType==="role"?ge.roles:ge.permissions).get(he);if(!ke)return;let ye=ke.assignableSubjectTypes;if(!ye||ye.length===0||!ye.includes(le))throw new On(`Cannot grant ${j.targetType} "${he}" to a "${le}" principal: this entitlement restricts assignment to [${(ye??[]).join(", ")||"none"}].`)}async function eo(T,_){let j=N(T.codeCatalog,n(_.target));if(!j)return;if(j.kind!==_.targetType)throw Error(`Cannot grant ${_.targetType} "${j.entity.id}": code declares that id as ${j.kind}.`);if(!T.catalogStore)throw Error(`Cannot grant code entitlement "${j.entity.id}": no AccessCatalogStore is wired for materialization.`);await K(j.kind,j.entity,L(T.catalogStore,j.kind))}async function to(T,_,j,X){await eo(T,_),await Rs(T.catalogStore,T.codeCatalog,_,X);let le={..._,status:_.status??"active",provenance:_.provenance??Qi()};if(le.id=p(le),await T.accessStore?.grant(le),T.accessIndex&&(T.catalogStore||T.codeCatalog)){let ge=await E(le,{catalog:T.catalogStore,code:T.codeCatalog,resources:T.resources,cache:X});await T.accessIndex.materialize(le.id,ge)}return j?.push({op:"add",change:le}),le}async function En(T,_,j){let X=_.id??p(_);await T.accessStore?.revoke(_),await T.accessIndex?.removeByRoot(X),j?.push({op:"delete",change:{..._,id:X}})}async function Gn(T,_){let j=await no(T,_),X=await so(T,_);return{oaa:j,delta:X}}async function no(T,_){if(_.length===0||!T.authz.oaa.isReady())return{status:"skipped"};return tn(T,"authz.oaa.push","OAA incremental access push failed after SCIM mutation; full sync will reconcile",()=>T.authz.oaa.pushAccessChanges(_),{count:_.length})}async function tn(T,_,j,X,le){try{return await X(),{status:"ok"}}catch(ge){return T.log?.warn(j,{"ion.operation":_,"ion.outcome":"degraded",...le,error:Nt(ge)}),{status:"degraded",reason:Nt(ge)}}}var ro=6;async function so(T,_){let j=T.iamDelta;if(!j?.isReady()||_.length===0)return{status:"skipped"};let X=new Map;for(let ye of _){let fe=`${ye.change.subjectType}:${n(ye.change.subject)}\x00${ye.change.targetType}:${n(ye.change.target)}`;X.set(fe,ye)}let le=[...X.values()],ge=le.map(({op:ye,change:fe})=>()=>ye==="add"?j.onGrant(fe):j.onRevoke(fe)),ke=(await io(ge,ro)).filter((ye)=>ye.status==="rejected");if(ke.length>0)return T.log?.warn("IAM delta egress degraded after SCIM mutation; IAM server reconcile/aggregation will recover",{"ion.operation":"iam.delta.egress","ion.outcome":"degraded",failed:ke.length,total:le.length,error:Nt(ke[0]?.reason)}),{status:"degraded",reason:Nt(ke[0]?.reason)};return{status:"ok"}}async function io(T,_){let j=Array(T.length),X=0,le=async()=>{while(!0){let he=X++;if(he>=T.length)return;let ke=T[he];if(!ke)continue;try{j[he]={status:"fulfilled",value:await ke()}}catch(ye){j[he]={status:"rejected",reason:ye}}}},ge=Array.from({length:Math.min(_,T.length)},le);return await Promise.all(ge),j}class Jn extends Error{constructor(T){super(T);this.name="DerivedRevokeError",Object.setPrototypeOf(this,Jn.prototype)}}class hn extends Error{constructor(T,_,j=!1){super(T);this.name="ScimMutationError",this.summary=_,this.clientError=j,Object.setPrototypeOf(this,hn.prototype)}}function Ke(T,_,j){return new Response(JSON.stringify({schemas:[jr],status:String(T),scimType:j,detail:_}),{status:T,headers:w})}function Kt(T,_){let j=_?.totalResults??T.length,X=_?.startIndex??1,le=_?.itemsPerPage??T.length;return new Response(JSON.stringify({schemas:[Yi],totalResults:j,startIndex:X,itemsPerPage:le,Resources:T}),{status:200,headers:w})}function St(T,_=200,j){let X=new Headers(w);if(j)X.set("Location",j);return new Response(JSON.stringify(T),{status:_,headers:X})}function hs(T){return Ke(T.clientError?409:500,`${T.message}; authz mutation summary: ${JSON.stringify(T.summary)}`,T.clientError?"mutability":"invalidValue")}function Dn(T){return p(T)}function Dr(T,_){return Kn(ks(T),ks(_))}function ks(T){let _=new Map;if(!T?.id)return _;for(let j of T.groups??[]){let X={subject:T.id,subjectType:"user",targetType:"group",target:j.value,metadata:j.display||j.type?{display:j.display,type:j.type}:void 0};_.set(Dn(X),X)}for(let j of T.roles??[]){let X={subject:T.id,subjectType:"user",targetType:"role",target:j.value,metadata:j.display||j.type?{display:j.display,type:j.type,primary:j.primary}:void 0};_.set(Dn(X),X)}for(let j of T.entitlements??[]){let X={subject:T.id,subjectType:"user",targetType:"permission",target:j.value,metadata:j.display||j.type?{display:j.display,type:j.type,primary:j.primary}:void 0};_.set(Dn(X),X)}return _}class Hn extends Error{constructor(T){super(T);this.name="AmbiguousMemberSubjectTypeError",Object.setPrototypeOf(this,Hn.prototype)}}function oo(T,_,j){if(T.type==="Group")return;if(T.type==="Workload")return"workload";if(T.type==="User")return"user";if(T.type==="Customer")return"customer";let X=_??[];if(X.length===1)return X[0];throw new Hn(`SCIM Group member "${T.value}" of entitlement "${j}" omits type, and the entitlement is assignable to more than one principal kind [${X.join(", ")||"none"}]. Set members[].type to User, Workload, or Customer.`)}function zn(T,_,j,X,le){let ge=new Map,he=X&&X.length>0?X:void 0;for(let ke of T??[]){let ye=oo(ke,le,j);if(!ye)continue;let fe={subject:ke.value,subjectType:ye,targetType:_,target:j,resources:he,metadata:ke.display||ke.type?{display:ke.display,type:ke.type}:void 0};ge.set(Dn(fe),fe)}return ge}function Ss(T){let _=T[e]?.resources;return _&&_.length>0?_:void 0}function ao(T,_){let j=(le,ge)=>[...le??[]].sort().join(",")===[...ge??[]].sort().join(","),X=T[e];if(X?.type!==void 0&&X.type!==_.kind)return!0;if(X?.requestable!==void 0&&X.requestable!==_.entity.requestable)return!0;if(X?.resources!==void 0&&!j(X.resources,$r(_.entity)))return!0;if(X?.assignableSubjectTypes!==void 0&&!j(X.assignableSubjectTypes,_.entity.assignableSubjectTypes))return!0;if(X?.recommendedSubjectTypes!==void 0&&!j(X.recommendedSubjectTypes,_.entity.recommendedSubjectTypes))return!0;return!1}function co(T,_){let j=(ge,he)=>[...ge??[]].sort().join(",")===[...he??[]].sort().join(","),X=T[e],le=_[e];if(X?.type!==void 0&&X.type!==le?.type)return!0;if(X?.requestable!==void 0&&X.requestable!==le?.requestable)return!0;if(X?.resources!==void 0&&!j(X.resources,le?.resources))return!0;if(X?.assignableSubjectTypes!==void 0&&!j(X.assignableSubjectTypes,le?.assignableSubjectTypes))return!0;if(X?.recommendedSubjectTypes!==void 0&&!j(X.recommendedSubjectTypes,le?.recommendedSubjectTypes))return!0;return!1}function uo(T){let _=new Map;for(let j of T)_.set(Dn(j),j);return _}async function an(T,_,j,X,le,ge){let he=[],ke=new Set,ye=(ze,Ye)=>`${Ye}\x00${ze}`,fe=ge?ge.get(`${j}:${X}`)??[]:_?(await _.listByTarget(j,X)).items:[];for(let ze of fe){let Ye=n(ze.subject),Qe=ze.metadata,ct=ze.subjectType==="workload"?"Workload":ze.subjectType==="customer"?"Customer":Qe?.type??"User",st=ye(Ye,ct);if(ke.has(st))continue;ke.add(st),he.push({value:Ye,...Qe?.display?{display:Qe.display}:{},type:ct})}for(let ze of le??[]){if(ze.targetType!==j||n(ze.target)!==X)continue;let Ye=n(ze.subject),Qe=ye(Ye,"Workload");if(ke.has(Qe))continue;ke.add(Qe),he.push({value:Ye,type:"Workload"})}if(j==="group"){let ze=await T.groups.get(X);for(let Ye of ze?.groups??[]){let Qe=n(Ye),ct=ye(Qe,"Group");if(!Qe||ke.has(ct))continue;ke.add(ct),he.push({value:Qe,type:"Group"})}}return he.length>0?he:void 0}function Kn(T,_){let j=[];for(let[X,le]of _)if(!T.has(X))j.push({action:"grant",change:le});for(let[X,le]of T)if(!_.has(X))j.push({action:"revoke",change:le});return j}async function Mr(T,_){if(T.oaa.isReady())await T.oaa.pushUser(_)}async function ws(T,_,j){if(_?.externalId&&_.externalId!==j.externalId)await T?.onUserDelete(_.externalId);await T?.onUserUpsert(j)}async function gn(T,_,j,X){let le={metadataApplied:!1,access:[]},ge={status:"skipped"},he=[],ke=new Q(T.catalogStore,T.resources,T.codeCatalog);try{try{await _(),le.metadataApplied=!0}catch(ye){for(let fe of j)le.access.push({change:fe.change,status:"rolled_back"});throw le.metadataApplied=!1,new hn(`SCIM metadata write failed: ${Nt(ye)}`,le,!1)}if(X?.oaa)await tn(T,"authz.oaa.metadata","OAA metadata projection failed after SCIM write; full sync will reconcile",X.oaa);if(X?.delta&&T.iamDelta?.isReady())ge=await tn(T,"iam.delta.egress","IAM delta metadata projection failed after SCIM write; full aggregation will reconcile",X.delta);for(let ye=0;ye<j.length;ye++){let fe=j[ye];try{if(fe.action==="grant")await to(T,fe.change,he,ke);else await go(T,fe.change,he);le.access.push({change:fe.change,status:"applied"})}catch(ze){le.access.push({change:fe.change,status:"failed",error:ze});for(let Qe=ye+1;Qe<j.length;Qe++)le.access.push({change:j[Qe].change,status:"rolled_back"});let Ye=ze instanceof Jn||ze instanceof On;if(!Ye)await mo(T,fe.change,ke);throw new hn(Ye?Nt(ze):`SCIM access mutation failed: ${Nt(ze)}`,le,Ye)}}return le}finally{await po(T),le.egress=await Gn(T,he),le.egress.delta=lo(ge,le.egress.delta),fo(T,le)}}function lo(T,_){if(T.status==="degraded")return T;if(_.status==="degraded")return _;return T.status==="ok"||_.status==="ok"?{status:"ok"}:{status:"skipped"}}function Nt(T){return T instanceof Error?T.message:String(T)}async function po(T){try{await T.settleAuthz?.()}catch{}}async function mo(T,_,j){if(!T.accessIndex||!T.catalogStore&&!T.codeCatalog||!T.accessStore)return;let X=n(_.subject);if(!X)return;let le=_.subjectType;try{await pe(X,le,{accessStore:T.accessStore,accessIndex:T.accessIndex,catalogStore:T.catalogStore,code:T.codeCatalog,resources:T.resources},j)}catch(ge){T.log?.warn("Per-subject reconcile after failed SCIM access mutation failed",{"ion.operation":"authz.reconcile.subject.repair","ion.outcome":"degraded",subject:X,subjectType:le,error:Nt(ge)})}}function fo(T,_){if(!T.onAccessMutation)return;try{T.onAccessMutation(_)}catch{}}async function go(T,_,j){if(T.accessStore){let X=_.id??p(_);if(!await T.accessStore.get(X)){if((T.accessIndex?await T.accessIndex.has(_.subject,_.targetType,_.target,_.resources?.[0],_.subjectType):{allow:!1}).allow)throw new Jn(`Cannot revoke ${_.targetType} "${n(_.target)}" for "${n(_.subject)}": it is not a directly granted root (it is derived from group/role membership). Remove the granting group/role instead.`);await En(T,_,j);return}}await En(T,_,j)}function yn(T){let _=T[e]?.type??"group";if(_==="group"||_==="role"||_==="permission")return _;throw Error(`Unsupported ionite SCIM Group authz type "${String(_)}"`)}async function Or(T,_,j){if(!T.oaa.isReady())return;if(j==="role"){await T.oaa.pushRole(_);return}if(j==="permission"){await T.oaa.pushPermission(_);return}await T.oaa.pushGroup(_)}function $r(T){let _=T.resources;if(!_||_.length===0)return;let j=_.map((X)=>typeof X==="string"?X:X.id).filter(Boolean);return j.length>0?j:void 0}function cn(T,_,j){return xr(T,_,j)}function yo(T,_){let j=T[e],le={...o(j?.attributes??{},d),id:_,name:T.displayName,displayName:T.displayName,description:j?.description??T.displayName,requestable:j?.requestable,riskLevel:j?.riskLevel??f,providerId:j?.providerId??T.externalId,requestUrl:j?.requestUrl,assignableSubjectTypes:["user"]};if(j?.resources!==void 0)le.resources=j.resources;return le}function ho(T){if(!T)return;let _=T.trim().match(/^requestable\s+eq\s+(true|false)$/i);if(!_)return;return{requestable:_[1]?.toLowerCase()==="true"}}function bs(T){if(!T)return;let _=T.trim().match(/^externalId\s+eq\s+"([^"]*)"$/i);return _?_[1]:void 0}function ko(T){if(!T)return;let _=T.trim(),j=_.match(/^userName\s+eq\s+"([^"]*)"$/i);if(j)return{userName:j[1]};let X=_.match(/^externalId\s+eq\s+"([^"]*)"$/i);if(X)return{externalId:X[1]};let le=_.match(/^meta\.lastModified\s+gt\s+"([^"]*)"$/i);if(le)return{updatedAfter:le[1]};return}function So(T,_,j){let X=new Set(["id","schemas"]),le={...T};if(_){let ge=new Set(_.split(",").map((he)=>he.trim()).filter(Boolean));for(let he of Object.keys(le))if(!X.has(he)&&!ge.has(he))delete le[he]}if(j){for(let ge of j.split(",").map((he)=>he.trim()).filter(Boolean))if(!X.has(ge))delete le[ge]}return le}function Cs(T,_){let j=async(ge,he,ke)=>{let ye=await T.toScim(ge),fe=ge.id;return{...ye,id:fe,meta:{...ye.meta??{},resourceType:T.resourceType,location:fe?yt(he,`${ke}/${encodeURIComponent(fe)}`):void 0}}},X=(ge,he)=>{let ke=he.op.toLowerCase();if(!he.path){if(ke!=="remove"&&he.value&&typeof he.value==="object"&&!Array.isArray(he.value))Object.assign(ge,he.value);return}if(ke==="remove"){delete ge[he.path];return}ge[he.path]=he.value};return{handler:async(ge,he)=>{if(!await _.validateAuth(ge))return Ke(401,"Authorization required");let ke=new URL(ge.url),ye=he?.basePath??`/${T.resourceType}s`,fe=ke.pathname;if(fe.startsWith(ye))fe=fe.substring(ye.length);let ze=fe.match(/^\/([^/]+)$/),Ye=ze?.[1]?decodeURIComponent(ze[1]):void 0,Qe=ke.searchParams.get("attributes"),ct=ke.searchParams.get("excludedAttributes"),st=(_e)=>So(_e,Qe,ct);try{if(Ye){if(ge.method==="GET"){let _e=await T.store.get(Ye);if(!_e)return Ke(404,`${T.resourceType} not found`);return St(st(await j(_e,ge,ye)))}if(ge.method==="PUT"||ge.method==="PATCH"){let _e=await T.store.get(Ye);if(!_e)return Ke(404,`${T.resourceType} not found`);let Le=await ge.json(),et=Le;if(ge.method==="PATCH"){let mt=Le.Operations;if(!Array.isArray(mt))return Ke(400,"PATCH requires Operations","invalidSyntax");let Rt=await T.toScim(_e);for(let Tt of mt)X(Rt,Tt);et=Rt}let De=await en(T.validator,et);if(De.issues)return Ke(400,De.issues.map((mt)=>mt.message).join("; "),"invalidValue");let it=ge.method==="PATCH"?"patch":"replace",pt=await T.store.upsert({...await T.fromScim(De.value,{existing:_e,mode:it}),id:_e.id??Ye});if(_e.active!==pt.active)await _.accessIndex?.setSubjectDisabled?.(pt.id,T.subjectType,pt.active===!1);let bt=pt.id?yt(ge,`${ye}/${encodeURIComponent(pt.id)}`):void 0;for(let mt of T.projections??[])await tn(_,`${mt.channel}.${T.subjectType}.upsert`,`${T.resourceType} projection degraded after SCIM upsert; aggregation will reconcile`,()=>mt.upsert(pt,_e));return St(st(await j(pt,ge,ye)),200,bt)}if(ge.method==="DELETE"){let _e=await T.store.get(Ye);if(!_e)return Ke(404,`${T.resourceType} not found`);if(_.revokeSubjectAccess)await _.revokeSubjectAccess(Ye,T.subjectType);await T.store.delete(Ye),await _.accessIndex?.setSubjectDisabled?.(Ye,T.subjectType,!1);for(let Le of T.projections??[])await tn(_,`${Le.channel}.${T.subjectType}.delete`,`${T.resourceType} projection degraded after SCIM delete; aggregation will reconcile`,()=>Le.delete(_e));return new Response(null,{status:204})}return Ke(405,"Method not allowed")}if(ge.method==="GET"){let _e=parseInt(ke.searchParams.get("startIndex")??"",10),Le=parseInt(ke.searchParams.get("count")??"",10),et=_e!=null&&!Number.isNaN(_e)?Math.max(0,_e-1):0,De=Le!=null&&!Number.isNaN(Le)?Le:void 0,it=ko(ke.searchParams.get("filter"));if(it?.externalId!==void 0){let mt=T.store.getByExternalId?await T.store.getByExternalId(it.externalId):await T.store.lookup({externalId:it.externalId}),Rt=mt?[st(await j(mt,ge,ye))]:[];return Kt(Rt,{totalResults:Rt.length,startIndex:1,itemsPerPage:Rt.length})}let pt=await T.store.list({start:et,limit:De,filter:it}),bt=await Promise.all(pt.items.map(async(mt)=>st(await j(mt,ge,ye))));return Kt(bt,{totalResults:pt.total,startIndex:et+1,itemsPerPage:pt.count})}if(ge.method==="POST"){let _e=await ge.json(),Le=await en(T.validator,_e);if(Le.issues)return Ke(400,Le.issues.map((it)=>it.message).join("; "),"invalidValue");let et=await T.store.upsert(await T.fromScim(Le.value,{mode:"create"}));if(et.active===!1)await _.accessIndex?.setSubjectDisabled?.(et.id,T.subjectType,!0);for(let it of T.projections??[])await tn(_,`${it.channel}.${T.subjectType}.upsert`,`${T.resourceType} projection degraded after SCIM create; aggregation will reconcile`,()=>it.upsert(et,void 0));let De=et.id?yt(ge,`${ye}/${encodeURIComponent(et.id)}`):void 0;return St(st(await j(et,ge,ye)),201,De)}return Ke(405,"Method not allowed")}catch(_e){if(M(_e))return Ke(409,_e.message,"uniqueness");return Ke(500,_e instanceof Error?_e.message:"Internal error")}}}}async function wo(T,_,j,X){let le=[],ge=[["group",T.groups],["role",T.roles],["permission",T.permissions]];for(let[ke,ye]of ge)for await(let fe of c((ze,Ye)=>ye.list({start:ze,limit:Ye,filter:{requestable:!0}})))if(fe.providerId===j)le.push({entity:fe,type:ke});if(le.length>1)throw new k(`Ambiguous providerId "${j}": ${le.length} entitlements share it (${le.map((ke)=>`${ke.type}:${ke.entity.id}`).join(", ")})`,"unique_violation","providerId");let he=le[0];if(he?.entity.requestable!==!0)return;return cn(he.entity,he.type,await an(T,_,he.type,he.entity.id,X))}async function bo(T,_,j,X){let le=Math.max(0,j.start),ge=j.limit!=null?le+j.limit:void 0,he={start:0,limit:ge,filter:j.filter},[ke,ye,fe]=await Promise.all([T.groups.list(he),T.roles.list(he),T.permissions.list(he)]),ze=[...ke.items.map((_e)=>({entity:_e,type:"group"})),...ye.items.map((_e)=>({entity:_e,type:"role"})),...fe.items.map((_e)=>({entity:_e,type:"permission"}))],Ye=ke.total+ye.total+fe.total,Qe=ze.slice(le,ge),ct=_?.listByTargets?await _.listByTargets(Qe.map(({entity:_e,type:Le})=>({targetType:Le,target:_e.id}))):void 0,st=await Promise.all(Qe.map(async({entity:_e,type:Le})=>cn(_e,Le,await an(T,_,Le,_e.id,X,ct))));return{resources:st,total:Ye,count:st.length}}async function Un(T,_,j,X){let[le,ge,he]=await Promise.all([T.groups.get(j),T.roles.get(j),T.permissions.get(j)]);if(le)return cn(le,"group",await an(T,_,"group",j,X));if(ge)return cn(ge,"role",await an(T,_,"role",j,X));if(he)return cn(he,"permission",await an(T,_,"permission",j,X));return}async function _r(T,_,j,X,le){let ge=yn(_),he=ge==="role"?await T.roles.get(j):ge==="permission"?await T.permissions.get(j):await T.groups.get(j),ke=yo(_,j),ye=he?.assignableSubjectTypes&&he.assignableSubjectTypes.length>0?he.assignableSubjectTypes:["user"],fe={...he??{},...ke,source:he?.source??"scim",assignableSubjectTypes:le?.assignableSubjectTypes??ye,recommendedSubjectTypes:le?.recommendedSubjectTypes??he?.recommendedSubjectTypes};if(le){if(delete fe.groups,delete fe.roles,delete fe.permissions,delete fe.resources,ge==="group")fe.groups=le.groups,fe.roles=le.roles,fe.permissions=le.permissions,fe.resources=le.resources;else if(ge==="role")fe.permissions=le.permissions}let ze=X?X.displayName??X.name:he?.name;if(ke.displayName===ze)delete fe.displayName;if(ke.riskLevel===(X?.riskLevel??f))delete fe.riskLevel;let Ye=o(ke,d),Qe=X?o(X,d):void 0;if(_[e]?.attributes!==void 0){for(let st of Object.keys(o(he??{},d)??{}))if(!(st in(Ye??{})))delete fe[st]}for(let[st,_e]of Object.entries(Ye??{}))if(S(_e,Qe?.[st]))delete fe[st];if(X)fe.name=X.name;let ct=ge==="role"?T.roles.set(fe):ge==="permission"?T.permissions.set(fe):T.groups.set(fe);return await ct.ready(),ct}async function Co(T,_){await Promise.all([T.groups.delete(_),T.roles.delete(_),T.permissions.delete(_)])}function Bn(){return crypto.randomUUID()}function en(T,_){let j=T;if(typeof j.validate==="function")return j.validate(_);return Promise.resolve(T["~standard"].validate(_))}function vo(T){if(!T)return;try{return new URL(T).pathname}catch{return T.startsWith("/")?T:`/${T}`}}function Lt(T){let _=vo(T);return _?R(_):void 0}function vs(...T){for(let _ of T){let j=Lt(_);if(!j)continue;for(let X of["/Users","/Groups","/Workloads","/Customers"])if(j.endsWith(X))return j.slice(0,-X.length)}return}function yt(T,_){return new URL(_,T.url).toString()}function Pe(T,_,j,X){let{multiValued:le=!1,...ge}=X??{};return{name:T,type:_,description:j,multiValued:le,...ge}}function Ro(T,_){return{schemas:[Xi],documentationUri:_?.documentationUri,patch:{supported:!0},bulk:{supported:!1},filter:{supported:!0,maxResults:1000},changePassword:{supported:!1},sort:{supported:!1},etag:{supported:!1},authenticationSchemes:[{type:"oauthbearertoken",name:"OAuth Bearer Token",description:"Use an ionite workload bearer token for IAM discovery and provisioning requests.",primary:!0}],meta:{resourceType:"ServiceProviderConfig",location:yt(T.request,`${T.basePath}/ServiceProviderConfig`)}}}function Ao(T){let _=[];if(T.supportsUsers)_.push({schemas:[qn],id:"User",name:"User",description:"User Account",endpoint:T.usersUrl,schema:Lr,schemaExtensions:[{schema:Mn,required:!1},{schema:u,required:!1}],meta:{resourceType:"ResourceType",location:yt(T.request,`${T.basePath}/ResourceTypes/User`)}});if(T.supportsGroups)_.push({schemas:[qn],id:"Group",name:"Group",description:"Group",endpoint:T.groupsUrl,schema:Nr,schemaExtensions:[{schema:e,required:!1}],meta:{resourceType:"ResourceType",location:yt(T.request,`${T.basePath}/ResourceTypes/Group`)}});if(T.supportsWorkloads)_.push({schemas:[qn],id:"Workload",name:"Workload",description:"Workload (machine) principal",endpoint:T.workloadsUrl,schema:b,meta:{resourceType:"ResourceType",location:yt(T.request,`${T.basePath}/ResourceTypes/Workload`)}});if(T.supportsCustomers)_.push({schemas:[qn],id:"Customer",name:"Customer",description:"Customer (CIAM) principal",endpoint:T.customersUrl,schema:C,meta:{resourceType:"ResourceType",location:yt(T.request,`${T.basePath}/ResourceTypes/Customer`)}});return _}function Io(T){let _=[];if(T.supportsUsers)_.push({schemas:[on],id:Lr,name:"User",description:"User Account",meta:{resourceType:"Schema",location:yt(T.request,`${T.basePath}/Schemas/${encodeURIComponent(Lr)}`)},attributes:[Pe("id","string","Unique identifier for the User.",{multiValued:!1,required:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),Pe("externalId","string","External identifier from the provisioning client.",{multiValued:!1,required:!1,mutability:"readWrite",returned:"default",uniqueness:"none"}),Pe("userName","string","Unique identifier typically used for login.",{multiValued:!1,required:!0,caseExact:!1,mutability:"readWrite",returned:"default",uniqueness:"server"}),Pe("name","complex","The components of the user name.",{multiValued:!1,required:!1,mutability:"readWrite",returned:"default",subAttributes:[Pe("formatted","string","The full name, including titles and suffixes.",{multiValued:!1}),Pe("familyName","string","The family name of the User.",{multiValued:!1}),Pe("givenName","string","The given name of the User.",{multiValued:!1}),Pe("middleName","string","The middle name(s) of the User.",{multiValued:!1}),Pe("honorificPrefix","string","The honorific prefix(es) of the User.",{multiValued:!1}),Pe("honorificSuffix","string","The honorific suffix(es) of the User.",{multiValued:!1})]}),Pe("displayName","string","The name of the User, suitable for display.",{multiValued:!1}),Pe("nickName","string","The casual way to address the user.",{multiValued:!1}),Pe("profileUrl","reference","A URL pointing to the User profile.",{multiValued:!1,referenceTypes:["external"]}),Pe("title","string","The user title, such as Vice President.",{multiValued:!1}),Pe("userType","string","The relationship between the organization and the User.",{multiValued:!1}),Pe("preferredLanguage","string","Preferred written or spoken language.",{multiValued:!1}),Pe("locale","string","Default location for localizing values.",{multiValued:!1}),Pe("timezone","string","The User time zone.",{multiValued:!1}),Pe("active","boolean","The User administrative status.",{multiValued:!1}),Pe("emails","complex","Email addresses for the User.",{multiValued:!0,subAttributes:[Pe("value","string","Email address value.",{multiValued:!1,required:!0}),Pe("display","string","Display label for the email.",{multiValued:!1}),Pe("type","string","Email type such as work or home.",{multiValued:!1}),Pe("primary","boolean","Primary email indicator.",{multiValued:!1})]}),Pe("phoneNumbers","complex","Phone numbers for the User.",{multiValued:!0,subAttributes:[Pe("value","string","Phone number value.",{multiValued:!1,required:!0}),Pe("display","string","Display label for the phone number.",{multiValued:!1}),Pe("type","string","Phone number type.",{multiValued:!1}),Pe("primary","boolean","Primary phone number indicator.",{multiValued:!1})]}),Pe("photos","complex","Photo URLs for the User.",{multiValued:!0,subAttributes:[Pe("value","reference","Photo URL.",{multiValued:!1,required:!0,referenceTypes:["external"]}),Pe("display","string","Display label for the photo.",{multiValued:!1}),Pe("type","string","Photo type.",{multiValued:!1}),Pe("primary","boolean","Primary photo indicator.",{multiValued:!1})]}),Pe("addresses","complex","Physical mailing addresses for the User.",{multiValued:!0,subAttributes:[Pe("formatted","string","Formatted mailing address.",{multiValued:!1}),Pe("streetAddress","string","Full street address component.",{multiValued:!1}),Pe("locality","string","City or locality.",{multiValued:!1}),Pe("region","string","State or region.",{multiValued:!1}),Pe("postalCode","string","Postal code.",{multiValued:!1}),Pe("country","string","Country.",{multiValued:!1}),Pe("type","string","Address type.",{multiValued:!1}),Pe("primary","boolean","Primary address indicator.",{multiValued:!1})]}),Pe("groups","complex","Groups to which the User belongs.",{multiValued:!0,mutability:"readOnly",subAttributes:[Pe("value","string","Group identifier.",{multiValued:!1,required:!0}),Pe("$ref","reference","Reference to the Group resource.",{multiValued:!1,referenceTypes:["Group"]}),Pe("display","string","Display name of the group.",{multiValued:!1}),Pe("type","string","Relationship type.",{multiValued:!1})]}),Pe("entitlements","complex","Entitlements for the User.",{multiValued:!0,subAttributes:[Pe("value","string","Entitlement value.",{multiValued:!1,required:!0}),Pe("display","string","Display value.",{multiValued:!1}),Pe("type","string","Entitlement type.",{multiValued:!1}),Pe("primary","boolean","Primary entitlement indicator.",{multiValued:!1})]}),Pe("roles","complex","Roles for the User.",{multiValued:!0,subAttributes:[Pe("value","string","Role value.",{multiValued:!1,required:!0}),Pe("display","string","Display value.",{multiValued:!1}),Pe("type","string","Role type.",{multiValued:!1}),Pe("primary","boolean","Primary role indicator.",{multiValued:!1})]}),Pe("x509Certificates","complex","Certificates issued to the User.",{multiValued:!0,subAttributes:[Pe("value","string","Certificate value.",{multiValued:!1,required:!0}),Pe("display","string","Display value.",{multiValued:!1}),Pe("type","string","Certificate type.",{multiValued:!1}),Pe("primary","boolean","Primary certificate indicator.",{multiValued:!1})]})]}),_.push({schemas:[on],id:Mn,name:"EnterpriseUser",description:"Enterprise User extension",meta:{resourceType:"Schema",location:yt(T.request,`${T.basePath}/Schemas/${encodeURIComponent(Mn)}`)},attributes:[Pe("employeeNumber","string","Numeric or alphanumeric identifier assigned to a person.",{multiValued:!1}),Pe("costCenter","string","Name of a cost center.",{multiValued:!1}),Pe("organization","string","Name of an organization.",{multiValued:!1}),Pe("division","string","Name of a division.",{multiValued:!1}),Pe("department","string","Name of a department.",{multiValued:!1}),Pe("manager","complex","The User manager.",{multiValued:!1,subAttributes:[Pe("value","string","Identifier of the manager User resource.",{multiValued:!1}),Pe("$ref","reference","Reference to the manager User resource.",{multiValued:!1,referenceTypes:["User"]}),Pe("displayName","string","Display name of the manager.",{multiValued:!1})]})]}),_.push({schemas:[on],id:u,name:"IoniteUser",description:"ionite User extension carrying ECID, account purpose, and AppDev custom attributes. See https://ionite.com/docs/llms-ecid.txt.",meta:{resourceType:"Schema",location:yt(T.request,`${T.basePath}/Schemas/${encodeURIComponent(u)}`)},attributes:[Pe("ecid","string","Enterprise Controlled ID formatted as 'ecid:<realm>:<opaque>' (realm = the minting authority's id). Correlates multiple accounts to one identity.",{multiValued:!1,caseExact:!0}),Pe("accountClass","string","Account purpose (distinct from userType persona). Open value set: 'daily', 'privileged', 'break_glass', 'service'.",{multiValued:!1}),Pe("attributes","complex","AppDev custom attributes. IAM may override seeded values.",{multiValued:!1,required:!1,mutability:"readWrite"})]});if(T.supportsGroups)_.push({schemas:[on],id:e,name:"IoniteAuthzGroup",description:"ionite authorization metadata for SCIM Group resources.",meta:{resourceType:"Schema",location:yt(T.request,`${T.basePath}/Schemas/${encodeURIComponent(e)}`)},attributes:[Pe("type","string","Authorization entity kind: group, role, or permission.",{multiValued:!1,required:!1}),Pe("requestable","boolean","Whether this catalog entry is exposed as assignable access to IAM tooling. Only true entries are served.",{multiValued:!1,required:!1}),Pe("riskLevel","string",`Advisory access-risk classification. Unset values project as ${f}; canonical values are suggestions, not a closed enum.`,{multiValued:!1,required:!1,mutability:"readWrite",canonicalValues:[...Y]}),Pe("providerId","string","IAM service-provider id captured when this entitlement is materialized at the destination.",{multiValued:!1,required:!1,mutability:"readWrite"}),Pe("requestUrl","reference","IAM-owned deep link where a principal can request this entitlement.",{multiValued:!1,required:!1,mutability:"readWrite",referenceTypes:["external"]}),Pe("source","string","Provenance of the catalog row.",{multiValued:!1,required:!1,mutability:"readOnly",canonicalValues:["code","app","scim"]}),Pe("deprecated","boolean","Whether this retired entitlement may be deleted.",{multiValued:!1,required:!1,mutability:"readOnly"}),Pe("description","string","Human-readable authorization entity description.",{multiValued:!1,required:!1}),Pe("resources","string","Resource ids this entitlement is scoped to.",{multiValued:!0,required:!1}),Pe("assignableSubjectTypes","string","AppDev-owned required audience of principal kinds (user, workload, customer) that may hold this entitlement. Read-only to IAM tooling.",{multiValued:!0,required:!1,mutability:"readOnly",canonicalValues:["user","customer","workload"]}),Pe("recommendedSubjectTypes","string","AppDev advisory default principal kinds (subset of assignableSubjectTypes). Read-only to IAM tooling.",{multiValued:!0,required:!1,mutability:"readOnly",canonicalValues:["user","customer","workload"]}),Pe("attributes","complex","AppDev custom attributes. IAM may override seeded values.",{multiValued:!1,required:!1,mutability:"readWrite"})]});if(T.supportsGroups)_.push({schemas:[on],id:Nr,name:"Group",description:"Group",meta:{resourceType:"Schema",location:yt(T.request,`${T.basePath}/Schemas/${encodeURIComponent(Nr)}`)},attributes:[Pe("id","string","Unique identifier for the Group.",{multiValued:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),Pe("externalId","string","External identifier from the provisioning client.",{multiValued:!1,uniqueness:"none"}),Pe("displayName","string","Human-readable name for the Group.",{multiValued:!1,required:!0,uniqueness:"none"}),Pe("members","complex","Members of the Group.",{multiValued:!0,subAttributes:[Pe("value","string","Identifier of the member resource.",{multiValued:!1,required:!0}),Pe("$ref","reference","Reference to the member resource.",{multiValued:!1,referenceTypes:["User","Group","Workload","Customer"]}),Pe("display","string","Display name of the member.",{multiValued:!1}),Pe("type","string","Member type.",{multiValued:!1})]})]});if(T.supportsWorkloads)_.push({schemas:[on],id:b,name:"Workload",description:"Workload (machine) principal",meta:{resourceType:"Schema",location:yt(T.request,`${T.basePath}/Schemas/${encodeURIComponent(b)}`)},attributes:[Pe("id","string","Unique identifier for the Workload.",{multiValued:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),Pe("externalId","string","External identifier from the provisioning client.",{multiValued:!1}),Pe("userName","string","Login identifier, typically the OAuth clientId.",{multiValued:!1}),Pe("displayName","string","Human-readable name for the Workload.",{multiValued:!1}),Pe("description","string","Free-form description of the Workload.",{multiValued:!1}),Pe("active","boolean","Administrative status of the Workload.",{multiValued:!1}),Pe("attributes","complex","AppDev custom attributes.",{multiValued:!1,required:!1,mutability:"readWrite"})]});if(T.supportsCustomers)_.push({schemas:[on],id:C,name:"Customer",description:"Customer (CIAM) principal",meta:{resourceType:"Schema",location:yt(T.request,`${T.basePath}/Schemas/${encodeURIComponent(C)}`)},attributes:[Pe("id","string","Unique identifier for the Customer.",{multiValued:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),Pe("externalId","string","External identifier from the provisioning client.",{multiValued:!1}),Pe("userName","string","Unique identifier typically used for login.",{multiValued:!1}),Pe("displayName","string","Human-readable name for the Customer.",{multiValued:!1}),Pe("active","boolean","Administrative status of the Customer.",{multiValued:!1}),Pe("emails","complex","Email addresses for the Customer.",{multiValued:!0,subAttributes:[Pe("value","string","Email address.",{multiValued:!1,required:!0}),Pe("primary","boolean","Whether this is the primary email.",{multiValued:!1})]}),Pe("attributes","complex","AppDev custom attributes.",{multiValued:!1,required:!1,mutability:"readWrite"})]});return _}function To(T,_,j,X,le,ge,he,ke,ye,fe,ze,Ye,Qe,ct,st,_e){let Le={authz:X,settleAuthz:_e,accessStore:le,accessIndex:ge,catalogStore:he,codeCatalog:ke,resources:ye,log:_,iamDelta:Ye,onAccessMutation:Qe,onInboundEntitlement:ct};if(!fe&&!ze)return;let De={...fe,...ze},it=De.users?.enabled!==!1,pt=De.groups?.enabled!==!1,bt=De.workloads?.enabled!==!1,mt=De.customers?.enabled!==!1;if(Boolean(De.url||De.userStore||he||ke)&&!j)_.error("IAM requires workload identity for SCIM push/pull operations",{"ion.operation":"workload.require","ion.outcome":"failure"});function Tt(){if(!j)throw _.error("IAM requires workload identity for SCIM push/pull operations",{"ion.operation":"workload.require","ion.outcome":"failure"}),Error("IAM requires workload identity for SCIM push/pull operations");return j}async function Mt(Ve){let Xe=Tt(),Be=Ve.headers.get("Authorization");if(!Be?.startsWith("Bearer "))return!1;try{let Ze=Be.substring(7);return(await Xe.validateToken(Ze)).valid}catch{return!1}}async function kn(){let Ve=Tt(),Xe=typeof Ve.getServerToken==="function"?await Ve.getServerToken():await Ve.getToken();return new Headers({...w,...ae,Authorization:`Bearer ${Xe}`})}async function Jt(Ve,Xe,Be,Ze){if(!De.url)throw Error("IAM URL not configured for outgoing requests");let Je=`${De.url}${Xe}`;try{let He=await kn(),ut=await fetch(Je,{method:Ve,headers:He,body:Be?JSON.stringify(Be):void 0}),Ce=await a(ut,{log:_,operation:"scim.request"});if(!ut.ok)return{success:!1,error:Ce,status:ut.status};let me=await Ze["~standard"].validate(Ce);if(me.issues)return _.error("SCIM response validation failed",{"ion.operation":"scim.response.validate","ion.outcome":"failure",validationIssues:me.issues}),{success:!1,error:{schemas:[jr],status:"400",scimType:"invalidValue",detail:`Response validation failed: ${me.issues.map((we)=>we.message).join("; ")}`},status:400};return{success:!0,data:me.value,status:ut.status}}catch(He){return{success:!1,error:{schemas:[jr],status:"500",detail:He instanceof Error?He.message:"Unknown error occurred"},status:500}}}function Sn(){return De.url}function un(Ve,Xe){let Be=Lt(Xe?.usersUrl??De.usersUrl??"/api/iam/Users")??"/api/iam/Users",Ze=Lt(Xe?.groupsUrl??De.groupsUrl??"/api/iam/Groups")??"/api/iam/Groups",Je=Lt(Xe?.workloadsUrl??De.workloadsUrl??"/api/iam/Workloads")??"/api/iam/Workloads",He=Lt(Xe?.customersUrl??De.customersUrl??"/api/iam/Customers")??"/api/iam/Customers",ut=Lt(Xe?.discovery?.basePath??De.discovery?.basePath)??vs(Be,Ze,Je,He);if(!ut)return;return{request:Ve,basePath:ut,usersUrl:Be,groupsUrl:Ze,workloadsUrl:Je,customersUrl:He,supportsUsers:it&&Boolean(De.userStore),supportsGroups:pt&&Boolean(he||ke),supportsWorkloads:bt&&Boolean(De.workloadIdentityStore),supportsCustomers:mt&&Boolean(De.customerStore)}}async function Ht(Ve){let Xe=Ro(Ve,De.discovery);return await De.discovery?.buildServiceProviderConfig?.(Ve,Xe)??Xe}async function Ft(Ve){let Xe=Ao(Ve);return await De.discovery?.buildResourceTypes?.(Ve,Xe)??Xe}async function nn(Ve){let Xe=Io(Ve);return await De.discovery?.buildSchemas?.(Ve,Xe)??Xe}async function dn(Ve,Xe){let Be=un(Ve,Xe);if(!Be)return;let Ze=R(new URL(Ve.url).pathname),{basePath:Je}=Be;if(Ze!==Je&&!Ze.startsWith(`${Je}/`))return;let He=R(Ze.slice(Je.length)||"/");if(!(He==="/ServiceProviderConfig"||He==="/ResourceTypes"||He.startsWith("/ResourceTypes/")||He==="/Schemas"||He.startsWith("/Schemas/")))return;if(Ve.method!=="GET")return Ke(405,"Method not allowed");if(!await Mt(Ve))return Ke(401,"Authorization required");if(He==="/ServiceProviderConfig")return St(await Ht(Be));if(He==="/ResourceTypes")return Kt(await Ft(Be));if(He.startsWith("/ResourceTypes/")){let me=decodeURIComponent(He.slice(15)),we=(await Ft(Be)).find((be)=>be.id===me||be.name===me);return we?St(we):Ke(404,"Resource not found")}if(He==="/Schemas")return Kt(await nn(Be));if(He.startsWith("/Schemas/")){let me=decodeURIComponent(He.slice(9)),we=(await nn(Be)).find((be)=>be.id===me);return we?St(we):Ke(404,"Resource not found")}return}let xt,ln;if(De.url)ln=async(Xe,Be)=>{let Ze={...Xe,schemas:Xe.schemas??["urn:ietf:params:scim:schemas:core:2.0:User","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"]};return Jt("POST","/Users",Ze,T.user)},xt={createGroup:async(Xe,Be)=>{let Ze={schemas:["urn:ietf:params:scim:schemas:core:2.0:Group"],displayName:Xe,externalId:Be?.id,members:Be?.members};return Jt("POST","/Groups",Ze,T.group)}};let Yt;if(he||ke){let Ve=q(ke,he),Xe=(Ae,Se,ve)=>{let Ie=Ae[e]??{},Te=yn(Ae),xe=Ae.id,Ne=xe?yt(Se,`${ve}/${encodeURIComponent(xe)}`):void 0,Oe={id:xe??Ae.externalId??Ae.displayName,name:Ae.displayName,displayName:Ae.displayName,description:Ie.description??Ae.displayName,requestable:Ie.requestable,providerId:Ie.providerId??Ae.externalId,requestUrl:Ie.requestUrl,source:Ie.source,deprecated:Ie.deprecated,riskLevel:Ie.riskLevel,assignableSubjectTypes:Ie.assignableSubjectTypes,recommendedSubjectTypes:Ie.recommendedSubjectTypes},Ge=Ie.requestUrl??De.entitlementRequestUrl?.(Oe,Te,{request:Se});return{...Ae,meta:{...Ae.meta,resourceType:"Group",location:Ne},[e]:{...Ie,requestUrl:Ge}}},Be=(Ae)=>N(ke,Ae),Ze=async(Ae,Se)=>{if(!he){if(Se)throw Error(`Cannot persist access for code entitlement "${Ae.entity.id}": no AccessCatalogStore is wired.`);return Ae.entity}try{return await K(Ae.kind,Ae.entity,L(he,Ae.kind))}catch(ve){if(Se)throw ve;return _.warn("Code entitlement discovery materialization failed; serving the code template",{"ion.operation":"iam.catalog.materialize","ion.outcome":"degraded",entitlementId:Ae.entity.id,entitlementType:Ae.kind,error:Nt(ve)}),Ae.entity}},Je=async(Ae)=>{if(!he)return;try{await Z(ke,he,Ae)}catch(Se){_.warn("Retired code entitlement deprecation failed; serving the last durable row",{"ion.operation":"iam.catalog.deprecate","ion.outcome":"degraded",entitlementId:Ae,error:Nt(Se)})}},He=(Ae,Se)=>Ke(403,`Entitlement "${Ae}" is declared in application code; its structural definition cannot be ${Se} through SCIM. IAM may change presentation and receipts, while code continues to own structure.`,"mutability"),ut=(Ae)=>Ae.path==="members"||Boolean(Ae.path?.startsWith("members[")),Ce=(Ae)=>ut(Ae)||Ae.path==="displayName"||Ae.path===`${e}.description`||Ae.path===`${e}.riskLevel`||Ae.path===`${e}.providerId`||Ae.path===`${e}.requestUrl`||Ae.path===`${e}.attributes`||Boolean(Ae.path?.startsWith(`${e}.attributes.`)),me=(Ae)=>Ae?.[e]?.requestable===!0,we=(Ae)=>Ke(404,`Requestable Group ${Ae} not found`,"invalidValue"),be=async(Ae,Se)=>{if(!await Mt(Ae))return Ke(401,"Authorization required");let Ie=new URL(Ae.url),Te=Se?.basePath??"/Groups",xe=Ie.pathname;if(xe.startsWith(Te))xe=xe.substring(Te.length);let Oe=xe.match(/^\/([^/]+)$/)?.[1],Ge=Ae.method;try{if(Oe)switch(Ge){case"GET":return await Ue(Ae,Te,Oe);case"PUT":return await We(Ae,Te,Oe);case"PATCH":return await qe(Ae,Te,Oe);case"DELETE":return await Ee(Oe);default:return Ke(405,"Method not allowed")}else if(xe===""||xe==="/")switch(Ge){case"GET":return await Re(Ae,Te);case"POST":return await je(Ae,Te);default:return Ke(405,"Method not allowed")}return Ke(404,"Resource not found")}catch(Fe){if(Fe instanceof hn)return hs(Fe);if(Fe instanceof Hn)return Ke(400,Fe.message,"invalidValue");if(M(Fe))return Ke(409,Fe.message,"uniqueness");return _.error("Groups inbound handler error",{"ion.operation":"scim.groups.handler","ion.outcome":"failure"},Fe),Ke(500,Fe instanceof Error?Fe.message:"Internal server error")}},Re=async(Ae,Se)=>{let ve=new URL(Ae.url),Ie=ve.searchParams.get("startIndex"),Te=ve.searchParams.get("count"),xe=Ie!=null?parseInt(Ie,10):void 0,Ne=Te!=null?parseInt(Te,10):void 0,Oe=xe!=null&&!Number.isNaN(xe)?Math.max(0,xe-1):0,Ge=Ne!=null&&!Number.isNaN(Ne)?Ne:void 0,Fe=ve.searchParams.get("filter"),rt=bs(Fe);if(rt!==void 0){await Je();let nt=await wo(Ve,le,rt,st),ht=nt?[Xe(nt,Ae,Se)]:[];return Kt(ht,{totalResults:ht.length,startIndex:1,itemsPerPage:ht.length})}if(ho(Fe)?.requestable===!1)return Kt([],{totalResults:0,startIndex:1,itemsPerPage:0});let ft={requestable:!0};if(ke)await Promise.all([...ke.groups.list().filter((nt)=>nt.requestable===!0).map((nt)=>({entity:nt,kind:"group"})),...ke.roles.list().filter((nt)=>nt.requestable===!0).map((nt)=>({entity:nt,kind:"role"})),...ke.permissions.list().filter((nt)=>nt.requestable===!0).map((nt)=>({entity:nt,kind:"permission"}))].map((nt)=>Ze(nt,!1)));await Je();let dt=await bo(Ve,le,{start:Oe,limit:Ge,filter:ft},st);return Kt(dt.resources.map((nt)=>Xe(nt,Ae,Se)),{totalResults:dt.total,startIndex:Oe+1,itemsPerPage:dt.count})},Ue=async(Ae,Se,ve)=>{let Ie=Be(ve);if(Ie&&Ie.entity.requestable!==!0)return we(ve);if(Ie)await Ze(Ie,!1);await Je(ve);let Te=await Un(Ve,le,ve,st);if(!me(Te))return we(ve);return St(Xe(Te,Ae,Se))},je=async(Ae,Se)=>{let ve=await Ae.json(),Ie=await en(T.group,ve);if(Ie.issues)return _.error("Group creation validation failed",{"ion.operation":"scim.group.create","ion.outcome":"failure",validationIssues:Ie.issues}),Ke(400,`Request validation failed: ${Ie.issues.map((Dt)=>Dt.message).join("; ")}`,"invalidValue");let Te=Ie.value;if(!Te.displayName)return Ke(400,"displayName is required","invalidValue");if(Te[e]?.requestable===!1)return Ke(400,"SCIM may create only requestable entitlements; non-requestable definitions are App-owned.","invalidValue");if(Te[e]={...Te[e],requestable:!0},!Le.onInboundEntitlement)return Ke(501,"IAM-sourced entitlement creation is not implemented: this application declares no authz.onInboundEntitlement callback.","invalidValue");if(!he)return Ke(501,"Group creation is not supported: this application declares its catalog in code (authz.catalog) and wires no AccessCatalogStore for SCIM-authored definitions.","invalidValue");let Ne=yn(Te),Oe=Te[e],Ge=await Le.onInboundEntitlement({type:Ne,displayName:Te.displayName,description:Oe?.description,externalId:Te.externalId,riskLevel:Oe?.riskLevel,attributes:Oe?.attributes,resources:Oe?.resources,members:Te.members??[],request:Ae});if(!Ge.accept)return Ke(403,Ge.reason??"The application rejected the IAM-sourced entitlement");if((Ne==="role"?[...Ge.groups??[],...Ge.roles??[],...Ge.resources??[]]:Ne==="permission"?[...Ge.groups??[],...Ge.roles??[],...Ge.permissions??[],...Ge.resources??[]]:[]).length>0)throw Error(`onInboundEntitlement returned structure that is invalid for entitlement type "${Ne}".`);let rt=Ge.assignableSubjectTypes??["user"];x({id:Ge.id,assignableSubjectTypes:rt,recommendedSubjectTypes:Ge.recommendedSubjectTypes});let at=async(Dt,vt)=>{await Promise.all((vt??[]).map(async(qt)=>{if(!(Dt==="group"?await Ve.groups.get(qt):Dt==="role"?await Ve.roles.get(qt):Dt==="permission"?await Ve.permissions.get(qt):await ye?.get(qt)))throw Error(`onInboundEntitlement accepted "${Te.displayName}" with unknown ${Dt} binding "${qt}".`)}))};await Promise.all([at("group",Ge.groups),at("role",Ge.roles),at("permission",Ge.permissions),at("resource",Ge.resources)]);let ft=Ge.id??Bn(),[dt,nt,ht]=await Promise.all([Ve.groups.get(ft),Ve.roles.get(ft),Ve.permissions.get(ft)]);if(dt||nt||ht)throw new k(`id "${ft}" already exists in the entitlement catalog`,"unique_violation","id");let tt=Ge.resources,Ut=Kn(new Map,zn(Te.members,Ne,ft,tt,rt)),Et;await gn(Le,async()=>{Et=await _r(Ve,Te,ft,void 0,{...Ge,assignableSubjectTypes:rt})},Ut,{oaa:()=>Or(X,Et,Ne)});let Ct=await an(Ve,le,Ne,ft),Vt=Xe(cn(Et,Ne,Ct),Ae,Se);return St(Vt,201,Vt.meta?.location)},We=async(Ae,Se,ve)=>{let Ie=await Ae.json(),Te=await en(T.group,Ie);if(Te.issues)return _.error("Group replacement validation failed",{"ion.operation":"scim.group.replace","ion.outcome":"failure",validationIssues:Te.issues}),Ke(400,`Request validation failed: ${Te.issues.map((ht)=>ht.message).join("; ")}`,"invalidValue");let xe=Te.value,Ne=yn(xe),Oe=Be(ve);if(Oe&&Oe.entity.requestable!==!0)return we(ve);if(Oe){if(await Ze(Oe,!0),ao(xe,Oe))return He(ve,"replaced")}let Ge=await Un(Ve,le,ve);if(!me(Ge))return we(ve);if(!Oe&&Ge[e]?.source==="code"&&co(xe,Ge))return He(ve,"replaced");let Fe=Oe?.kind??Ne,rt=Oe?$r(Oe.entity):Ss(xe),at=le?(await le.listByTarget(Fe,ve)).items:[],ft=Kn(uo(at),zn(xe.members,Fe,ve,rt,Oe?.entity.assignableSubjectTypes??Ge[e]?.assignableSubjectTypes??xe[e]?.assignableSubjectTypes)),dt;await gn(Le,async()=>{dt=await _r(Ve,xe,ve,Oe?.entity)},ft,{oaa:()=>Or(X,dt,Fe)});let nt=await an(Ve,le,Fe,ve);return St(Xe(cn(dt,Fe,nt),Ae,Se))},qe=async(Ae,Se,ve)=>{let Ie=Be(ve);if(Ie&&Ie.entity.requestable!==!0)return we(ve);if(Ie)await Ze(Ie,!0);let Te=await Un(Ve,le,ve);if(!me(Te))return we(ve);let xe=await Ae.json();if((Ie!==void 0||Te[e]?.source==="code")&&(xe.Operations??[]).some((tt)=>!Ce(tt)))return He(ve,"patched");let Oe={...Te};for(let tt of xe.Operations??[])if(tt.op==="replace"&&tt.path&&tt.value!==void 0){if(tt.path==="displayName")Oe.displayName=tt.value;else if(tt.path===`${e}.requestable`)Oe[e]={...Oe[e],requestable:Boolean(tt.value)};else if(tt.path===`${e}.description`)Oe[e]={...Oe[e],description:String(tt.value)};else if(tt.path===`${e}.riskLevel`)Oe[e]={...Oe[e],riskLevel:String(tt.value)};else if(tt.path===`${e}.providerId`)Oe[e]={...Oe[e],providerId:String(tt.value)};else if(tt.path===`${e}.requestUrl`)Oe[e]={...Oe[e],requestUrl:String(tt.value)};else if(tt.path===`${e}.attributes`&&typeof tt.value==="object"&&tt.value!==null&&!Array.isArray(tt.value))Oe[e]={...Oe[e],attributes:tt.value};else if(tt.path.startsWith(`${e}.attributes.`)){let Ut=tt.path.slice(`${e}.attributes.`.length);Oe[e]={...Oe[e],attributes:{...Oe[e]?.attributes,[Ut]:tt.value}}}}else if(tt.op==="add"&&tt.path==="members"&&tt.value!==void 0){let Ut=tt.value;Oe.members=[...Oe.members??[],...Ut]}else if(tt.op==="remove"&&tt.path?.startsWith("members[")){let Ut=tt.path.match(/members\[value eq "([^"]+)"\]/);if(Ut)Oe.members=(Oe.members??[]).filter((Et)=>Et.value!==Ut[1])}else if(tt.op==="remove"&&tt.path?.startsWith(`${e}.attributes.`)){let Ut=tt.path.slice(`${e}.attributes.`.length),Et={...Oe[e]?.attributes};delete Et[Ut],Oe[e]={...Oe[e],attributes:Et}}let Ge=await en(T.group,Oe);if(Ge.issues)return _.error("Group patch validation failed",{"ion.operation":"scim.group.patch","ion.outcome":"failure",validationIssues:Ge.issues}),Ke(400,`Request validation failed: ${Ge.issues.map((tt)=>tt.message).join("; ")}`,"invalidValue");let Fe=Ie?.kind??yn(Oe),rt=Ie?$r(Ie.entity):Ss(Oe),at=Ie?.entity.assignableSubjectTypes??Te[e]?.assignableSubjectTypes??Oe[e]?.assignableSubjectTypes,ft=Kn(zn(Te.members,Fe,ve,rt,at),zn(Oe.members,Fe,ve,rt,at)),dt,nt=!Ie||(xe.Operations??[]).some((tt)=>!ut(tt));await gn(Le,async()=>{if(nt)dt=await _r(Ve,Oe,ve,Ie?.entity)},ft,nt?{oaa:()=>Or(X,dt,Fe)}:void 0);let ht=await Un(Ve,le,ve);return St(Xe(ht,Ae,Se))},Ee=async(Ae)=>{let Se=Be(Ae);if(Se&&Se.entity.requestable!==!0)return we(Ae);if(Se)await Ze(Se,!0);let ve=await Un(Ve,le,Ae);if(!me(ve))return we(Ae);let Ie=ve[e];if((Se||Ie?.source==="code")&&Ie?.deprecated!==!0)return Ke(403,`Code-owned entitlement "${Ae}" can be deleted only after it is marked deprecated.`,"mutability");let Te=yn(ve);if(le){let xe=await le.listByTarget(Te,Ae),Ne=[];for(let Oe of xe.items)await En(Le,Oe,Ne);await Gn(Le,Ne)}return await Co(Ve,Ae),new Response(null,{status:204})};Yt={handler:be}}let Pt,At,$t;if(De.userStore){let{userStore:Ve,inboundUsers:Xe}=De,Be=(Se)=>Se?.find((ve)=>ve.primary)?.value||Se?.[0]?.value,Ze=async(Se)=>{if(Xe?.mapBaseUserToScim)return await Xe.mapBaseUserToScim(Se);return Pr(Se)},Je=async(Se,ve,Ie)=>{let Te=await Ze(Se),xe=Te.id??Se.id;return{...Te,id:xe,meta:{...Te.meta,resourceType:"User",location:xe?yt(ve,`${Ie}/${encodeURIComponent(xe)}`):void 0}}},He=async(Se,ve)=>{if(Xe?.mapValidatedScimToBaseUser)return await Xe.mapValidatedScimToBaseUser(Se,ve);let Ie=new Date,Te=Be(Se.emails),xe=Se.name?.formatted||[Se.name?.givenName,Se.name?.middleName,Se.name?.familyName].filter(Boolean).join(" ").trim()||Se.displayName,Ne=Se.id||ve.existing?.id||Bn(),Oe=Se.userName||Te||ve.existing?.userName||Ne,Ge=xe||Se.displayName||ve.existing?.name||Oe,Fe=Object.fromEntries(Object.entries(Se).filter(([ht,tt])=>ht.startsWith("urn:")&&ht!==Mn&&ht!==u&&tt!==void 0)),rt=Se[u],at=o(rt?.attributes??{},A),ft=rt?.ecid!==void 0&&rt.ecid!==null?O(rt.ecid):ve.existing?.ecid,dt=rt?.accountClass??ve.existing?.accountClass,nt=ve.existing?.sso;return{...ve.existing??{},id:Ne,userName:Oe,name:Ge,email:Te||ve.existing?.email||Oe,avatar:Se.profileUrl,sso:{...nt??{},profile:{...nt?.profile??{},sub:Ne,iss:nt?.profile.iss??"iam-provisioned",aud:nt?.profile.aud??"iam-provisioned",exp:nt?.profile.exp??Math.floor(Date.now()/1000)+3600,iat:nt?.profile.iat??Math.floor(Date.now()/1000),email:Te||ve.existing?.email||Oe,email_verified:!0,name:Ge,preferred_username:Oe},tenant:nt?.tenant??{id:"iam-provisioned",name:"IAM Provisioned"},scope:nt?.scope??"openid profile email",tokenType:nt?.tokenType??"Bearer",expires:nt?.expires??new Date(Date.now()+3600000)},externalId:Se.externalId,ecid:ft,accountClass:dt,displayName:Se.displayName,scimName:Se.name,emails:Se.emails,nickName:Se.nickName,title:Se.title,preferredLanguage:Se.preferredLanguage,locale:Se.locale,timezone:Se.timezone,active:Se.active,phoneNumbers:Se.phoneNumbers,ims:Se.ims,photos:Se.photos,addresses:Se.addresses,groups:Se.groups,entitlements:Se.entitlements,roles:Se.roles,x509Certificates:Se.x509Certificates,scimEnterprise:Se[Mn],scimSchemaExtensions:Object.keys(Fe).length>0?Fe:void 0,createdAt:ve.existing?.createdAt??(Se.meta?.created?new Date(Se.meta.created):Ie),updatedAt:Se.meta?.lastModified?new Date(Se.meta.lastModified):Ie,userType:Se.userType,...at}},ut=(Se,ve,Ie)=>{Se[ve]=Ie},Ce=(Se,ve,Ie)=>{let Te=Se[ve];if(Array.isArray(Te)){Se[ve]=[...Te,...Array.isArray(Ie)?Ie:[Ie]];return}if(Te&&typeof Te==="object"&&!Array.isArray(Te)&&Ie&&typeof Ie==="object"&&!Array.isArray(Ie)){Se[ve]={...Te,...Ie};return}Se[ve]=Ie},me=(Se,ve,Ie)=>{let Te=ve.match(/^(urn:.*:(?:User|Group))(?::(.+))?$/),xe=Te?[Te[1],...Te[2]?.split(":")??[]]:ve.split("."),Ne=Se;for(let Ge of xe.slice(0,-1)){let Fe=Ne[Ge];if(Fe===void 0){if(!Ie)return null;Ne[Ge]={}}else if(Fe===null||typeof Fe!=="object"||Array.isArray(Fe)){if(!Ie)return null;Ne[Ge]={}}Ne=Ne[Ge]}let Oe=xe.at(-1);if(!Oe)return null;return{parent:Ne,key:Oe}},we=(Se,ve)=>{let Ie=ve.op.toLowerCase();if(!ve.path){if(Ie!=="remove"&&ve.value&&typeof ve.value==="object"&&!Array.isArray(ve.value))Object.assign(Se,ve.value);return}let Te=ve.path.match(/^([A-Za-z0-9]+)\[value eq "([^"]+)"\]$/);if(Te&&Ie==="remove"){let[,Ne,Oe]=Te,Ge=Se[Ne];if(Array.isArray(Ge))Se[Ne]=Ge.filter((Fe)=>!(Fe&&typeof Fe==="object"&&("value"in Fe)&&Fe.value===Oe));return}let xe=me(Se,ve.path,Ie!=="remove");if(!xe)return;if(Ie==="remove"){delete xe.parent[xe.key];return}if(Ie==="add"){Ce(xe.parent,xe.key,ve.value);return}ut(xe.parent,xe.key,ve.value)},be=async(Se,ve)=>{if(!await Mt(Se))return Ke(401,"Authorization required");let Te=new URL(Se.url),xe=ve?.basePath??"/Users",Ne=Te.pathname;if(Ne.startsWith(xe))Ne=Ne.substring(xe.length);let Ge=Ne.match(/^\/([^/]+)$/)?.[1],Fe=Se.method;try{if(Ge)switch(Fe){case"GET":return await Ue(Se,xe,Ge);case"PUT":return await qe(Se,xe,Ge);case"PATCH":return await Ee(Se,xe,Ge);case"DELETE":return await Ae(Ge);default:return Ke(405,"Method not allowed")}else if(Ne===""||Ne==="/")switch(Fe){case"GET":return await Re(Se,xe);case"POST":return await We(Se,xe);default:return Ke(405,"Method not allowed")}return Ke(404,"Resource not found")}catch(rt){if(rt instanceof hn)return hs(rt);if(M(rt))return Ke(409,rt.message,"uniqueness");return _.error("Users inbound handler error",{"ion.operation":"scim.users.handler","ion.outcome":"failure"},rt),Ke(500,rt instanceof Error?rt.message:"Internal server error")}},Re=async(Se,ve)=>{let Ie=new URL(Se.url),Te=Ie.searchParams.get("startIndex"),xe=Ie.searchParams.get("count"),Ne=Te!=null?parseInt(Te,10):void 0,Oe=xe!=null?parseInt(xe,10):void 0,Ge=Ne!=null&&!Number.isNaN(Ne)?Math.max(0,Ne-1):0,Fe=Oe!=null&&!Number.isNaN(Oe)?Oe:void 0,rt=bs(Ie.searchParams.get("filter"));if(rt!==void 0){let dt=await Ve.lookup({externalId:rt}),nt=dt?[await Je(dt,Se,ve)]:[];return Kt(nt,{totalResults:nt.length,startIndex:1,itemsPerPage:nt.length})}let at=await Ve.list({start:Ge,limit:Fe}),ft=await Promise.all(at.items.map((dt)=>Je(dt,Se,ve)));return Kt(ft,{totalResults:at.total,startIndex:Ge+1,itemsPerPage:at.count})},Ue=async(Se,ve,Ie)=>{let Te=await Ve.get(Ie);if(!Te)return Ke(404,`User ${Ie} not found`,"invalidValue");return St(await Je(Te,Se,ve))},je=async(Se,ve)=>{let Ie=Le.accessIndex;if(!Ie?.setSubjectDisabled||!ve.id)return;let Te=Se?Se.active??!0:!0,xe=ve.active??!0;if(Se&&Te===xe)return;if(!Se&&xe)return;await Ie.setSubjectDisabled(ve.id,"user",!xe)},We=async(Se,ve)=>{let Ie=await Se.json(),Te=await en(T.user,Ie);if(Te.issues)return _.error("User creation validation failed",{"ion.operation":"scim.user.create","ion.outcome":"failure",validationIssues:Te.issues}),Ke(400,`Request validation failed: ${Te.issues.map((Ge)=>Ge.message).join("; ")}`,"invalidValue");let xe=Te.value;if(!xe.userName&&!xe.emails?.[0]?.value)return Ke(400,"userName or email is required","invalidValue");let Ne=await He(xe,{mode:"create"});await gn(Le,async()=>{await Ve.upsert(Ne),await je(void 0,Ne)},Dr(void 0,Ne),{oaa:async()=>{await Mr(X,Ne)},delta:async()=>{await Le.iamDelta?.onUserUpsert(Ne)}});let Oe=await Je(Ne,Se,ve);return St(Oe,201,Oe.meta?.location)},qe=async(Se,ve,Ie)=>{let Te=await Ve.get(Ie);if(!Te)return Ke(404,`User ${Ie} not found`,"invalidValue");let xe=await Se.json(),Ne=await en(T.user,xe);if(Ne.issues)return _.error("User replacement validation failed",{"ion.operation":"scim.user.replace","ion.outcome":"failure",validationIssues:Ne.issues}),Ke(400,`Request validation failed: ${Ne.issues.map((Fe)=>Fe.message).join("; ")}`,"invalidValue");let Oe=Ne.value,Ge=await He({...Oe,id:Ie},{existing:Te,mode:"replace"});return Ge.createdAt=Te.createdAt,Ge.updatedAt=new Date,await gn(Le,async()=>{await Ve.upsert(Ge),await je(Te,Ge)},Dr(Te,Ge),{oaa:async()=>{await Mr(X,Ge)},delta:async()=>{await ws(Le.iamDelta,Te,Ge)}}),St(await Je(Ge,Se,ve))},Ee=async(Se,ve,Ie)=>{let Te=await Ve.get(Ie);if(!Te)return Ke(404,`User ${Ie} not found`,"invalidValue");let Ne=(await Se.json()).Operations??[],Ge={...await Ze(Te)};for(let at of Ne)we(Ge,at);let Fe=await en(T.user,Ge);if(Fe.issues)return _.error("User patch validation failed",{"ion.operation":"scim.user.patch","ion.outcome":"failure",validationIssues:Fe.issues}),Ke(400,`Request validation failed: ${Fe.issues.map((at)=>at.message).join("; ")}`,"invalidValue");let rt=await He(Fe.value,{existing:Te,mode:"patch"});return rt.updatedAt=new Date,await gn(Le,async()=>{await Ve.upsert(rt),await je(Te,rt)},Dr(Te,rt),{oaa:async()=>{await Mr(X,rt)},delta:async()=>{await ws(Le.iamDelta,Te,rt)}}),St(await Je(rt,Se,ve))},Ae=async(Se)=>{let ve=await Ve.get(Se);if(!ve)return Ke(404,`User ${Se} not found`,"invalidValue");if(le){let Ie=[];for await(let Te of c((xe,Ne)=>le.listBySubject(Se,"user",{start:xe,limit:Ne})))await En(Le,Te,Ie);await Gn(Le,Ie)}if(await Ve.delete(Se),await Le.accessIndex?.setSubjectDisabled?.(Se,"user",!1),ve.externalId&&Le.iamDelta?.isReady())await tn(Le,"iam.delta.egress","IAM delta user delete failed after SCIM write; full aggregation will reconcile",()=>Le.iamDelta?.onUserDelete(ve.externalId)??Promise.resolve(),{id:Se,kind:"user"});else if(Le.iamDelta?.isReady())Le.log?.warn("IAM delta: deleted User has no externalId; destination delete skipped",{"ion.operation":"iam.delta.delete","ion.outcome":"skipped",id:Se,kind:"user"});if(Le.authz.oaa.isReady())await tn(Le,"authz.oaa.delete","OAA incremental user delete failed; full sync will reconcile",()=>Le.authz.oaa.deleteUser(Se),{id:Se,kind:"user"});return new Response(null,{status:204})};Pt={handler:be}}let Wt=async(Ve,Xe)=>{if(!le)return;let Be=[];for await(let Ze of c((Je,He)=>le.listBySubject(Ve,Xe,{start:Je,limit:He})))await En(Le,Ze,Be);await Gn(Le,Be)};if(De.workloadIdentityStore){let{workloadIdentityStore:Ve,inboundWorkloads:Xe}=De;At=Cs({resourceType:"Workload",subjectType:"workload",store:Ve,validator:T.workload??ue,toScim:async(Be)=>await(Xe?.mapBaseWorkloadToScim?.(Be)??Ur(Be)),fromScim:async(Be,Ze)=>{if(Xe?.mapValidatedScimToBaseWorkload)return Xe.mapValidatedScimToBaseWorkload(Be,Ze);let Je=Ze.existing,He=Be,ut=He.id?.trim()||Je?.id||Bn(),Ce=o(He.attributes??{},v);return{...Je??{},id:ut,externalId:He.externalId??Je?.externalId,clientId:He.userName??Je?.clientId??ut,displayName:He.displayName??Je?.displayName,description:He.description??Je?.description,active:He.active??Je?.active??!0,providerId:Je?.providerId,requestUrl:Je?.requestUrl,...Ce}},projections:[{channel:"oaa",upsert:async(Be)=>{if(X.oaa.isReady())await X.oaa.pushWorkload(Be)},delete:async(Be)=>{if(X.oaa.isReady())await X.oaa.deleteWorkload(Be.id)}},{channel:"delta",upsert:async(Be,Ze)=>{let Je=Ze?.externalId??Ze?.id,He=Be.externalId??Be.id;if(Je&&Je!==He)await Ye?.onWorkloadDelete(Je);await Ye?.onWorkloadUpsert(Be)},delete:async(Be)=>{await Ye?.onWorkloadDelete(Be.externalId??Be.id)}}]},{validateAuth:Mt,accessStore:le,accessIndex:ge,revokeSubjectAccess:Wt,log:_})}if(De.customerStore){let{customerStore:Ve,inboundCustomers:Xe}=De;$t=Cs({resourceType:"Customer",subjectType:"customer",store:Ve,validator:T.customer??de,toScim:async(Be)=>await(Xe?.mapBaseCustomerToScim?.(Be)??Er(Be)),fromScim:async(Be,Ze)=>{if(Xe?.mapValidatedScimToBaseCustomer)return Xe.mapValidatedScimToBaseCustomer(Be,Ze);let Je=Ze.existing,He=Be,ut=He.id?.trim()||Je?.id||Bn(),Ce=o(He.attributes??{},I),me=He.emails?.find((we)=>we.primary)?.value??He.emails?.[0]?.value;return{...Je??{},id:ut,externalId:He.externalId??Je?.externalId??ut,userName:He.userName??Je?.userName??ut,name:He.displayName??Je?.name??He.userName??ut,email:me??Je?.email??"",displayName:He.displayName??Je?.displayName,emails:He.emails??Je?.emails,active:He.active??Je?.active??!0,providerId:Je?.providerId,requestUrl:Je?.requestUrl,...Ce}},projections:[{channel:"oaa",upsert:async(Be)=>{if(X.oaa.isReady())await X.oaa.pushCustomer(Be)},delete:async(Be)=>{if(X.oaa.isReady()&&Be.id)await X.oaa.deleteCustomer(Be.id)}},{channel:"delta",upsert:async(Be,Ze)=>{let Je=Ze?.externalId??Ze?.id,He=Be.externalId??Be.id;if(Je&&Je!==He)await Ye?.onCustomerDelete(Je);await Ye?.onCustomerUpsert(Be)},delete:async(Be)=>{let Ze=Be.externalId??Be.id;if(Ze)await Ye?.onCustomerDelete(Ze)}}]},{validateAuth:Mt,accessStore:le,accessIndex:ge,revokeSubjectAccess:Wt,log:_})}async function rn(Ve,Xe){Tt();let Be=new URL(Ve.url).pathname,Ze=Lt(Xe?.usersUrl??De.usersUrl??"/api/iam/Users")??"/api/iam/Users",Je=Lt(Xe?.groupsUrl??De.groupsUrl??"/api/iam/Groups")??"/api/iam/Groups",He=Lt(Xe?.workloadsUrl??De.workloadsUrl??"/api/iam/Workloads")??"/api/iam/Workloads",ut=Lt(Xe?.customersUrl??De.customersUrl??"/api/iam/Customers")??"/api/iam/Customers",Ce=`${vs(Ze,Je,He,ut)??"/api/iam"}/AccessRequests`,me=await dn(Ve,Xe);if(me)return me;let we=(be)=>Be===be||Be.startsWith(`${be}/`);if(we(Ze)){if(!it)return Ke(404,"SCIM Users endpoint is disabled by RemoteConfig");if(!Pt)return Ke(501,"SCIM Users endpoint is enabled by RemoteConfig but no user store capability is wired by the application.");return Pt.handler(Ve,{basePath:Ze})}if(we(Je)){if(!pt)return Ke(404,"SCIM Groups endpoint is disabled by RemoteConfig");if(!Yt)return Ke(501,"SCIM Groups endpoint is enabled by RemoteConfig but no AccessCatalogStore capability is wired by the application.");return Yt.handler(Ve,{basePath:Je})}if(we(He)){if(!bt)return Ke(404,"SCIM Workloads endpoint is disabled by RemoteConfig");if(!At)return Ke(501,"SCIM Workloads endpoint is enabled by RemoteConfig but no workload identity store capability is wired by the application.");return At.handler(Ve,{basePath:He})}if(we(ut)){if(!mt)return Ke(404,"SCIM Customers endpoint is disabled by RemoteConfig");if(!$t)return Ke(501,"SCIM Customers endpoint is enabled by RemoteConfig but no customer store capability is wired by the application.");return $t.handler(Ve,{basePath:ut})}if(we(Ce)){if(!De.accessRequests)return Ke(404,"AccessRequests endpoint is not configured");if(!await Mt(Ve))return Ke(401,"Authorization required");if(Ve.method==="GET"){if(!De.accessRequests.get)return Ke(404,"AccessRequests read endpoint is not configured");let Ue=Be.startsWith(`${Ce}/`)?Be.slice(Ce.length+1):void 0;if(!Ue||Ue.includes("/"))return Ke(404,"AccessRequest not found");let je;try{je=decodeURIComponent(Ue)}catch{return Ke(400,"AccessRequest id is invalid","invalidValue")}let We=await De.accessRequests.get(je);if(!We)return Ke(404,"AccessRequest not found");return St(We,200,We.trackingUrl)}if(Ve.method!=="POST"||Be!==Ce)return Ke(405,"Method not allowed");let be;try{be=await Ve.json()}catch{return Ke(400,"Request body must be valid JSON","invalidSyntax")}if(typeof be.subject!=="string"||!be.subject||typeof be.target!=="string"||!be.target||be.subjectType!=="user"&&be.subjectType!=="workload"&&be.subjectType!=="customer"||be.targetType!=="group"&&be.targetType!=="role"&&be.targetType!=="permission"||be.operation!=="grant"&&be.operation!=="revoke")return Ke(400,"subject, subjectType, targetType, target, and operation are required","invalidValue");let Re=await De.accessRequests.create({subject:be.subject,subjectType:be.subjectType,targetType:be.targetType,target:be.target,operation:be.operation,justification:typeof be.justification==="string"?be.justification:void 0});return St(Re.request,Re.created?201:200,Re.request.trackingUrl)}return Ke(404,"Resource not found")}let Ot;return Ot={...De,describe:()=>({module:"iam",active:!0,ready:Ot.isReady?.()??!0,url:De.url,deltaAudience:De.deltaAudience,accessRequests:{...De.url?{iam:`${R(De.url)}/AccessRequests`}:{},ciam:{}},users:{...fn(De.users),storeWired:De.userStore!==void 0},workloads:{...fn(De.workloads),storeWired:De.workloadIdentityStore!==void 0},customers:{...fn(De.customers),storeWired:De.customerStore!==void 0},groups:{enabled:pt,catalogWired:he!==void 0},urls:{usersUrl:De.usersUrl??"",groupsUrl:De.groupsUrl??"",workloadsUrl:De.workloadsUrl??"",customersUrl:De.customersUrl??""}}),users:fn(De.users),workloads:fn(De.workloads),customers:fn(De.customers),groups:{enabled:pt},createUser:ln,getBaseUrl:Sn,groups_outbound:xt,groups_inbound:Yt,users_inbound:Pt,workloads_inbound:At,customers_inbound:$t,handler:rn,delta:Ye},Ot}function Wr(T,_){let j=new TextEncoder().encode(T),X=typeof _==="string"?new TextEncoder().encode(_):_,le=new Uint8Array(j.length+1+X.length);return le.set(j,0),le[j.length]=46,le.set(X,j.length+1),le}function xo(T){let _=T.replace(/-/g,"+").replace(/_/g,"/"),j=_.length%4===0?"":"=".repeat(4-_.length%4),X=atob(_+j),le=new Uint8Array(X.length);for(let ge=0;ge<X.length;ge++)le[ge]=X.charCodeAt(ge);return le}function Po(T){let _="";for(let j of T)_+=String.fromCharCode(j);return btoa(_).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function As(T){let _=JSON.parse(T);if(!_||typeof _!=="object"||!Array.isArray(_.keys))throw Error("Invalid JWKS: expected { keys: [...] }");return _}function Uo(T){return JSON.stringify(T)}async function Eo(T){return crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:T.x},{name:"Ed25519"},!0,["verify"])}async function Do(T){return crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:T.x,d:T.d},{name:"Ed25519"},!0,["sign"])}async function Mo(T){let j=(typeof T.jwks==="string"?As(T.jwks):T.jwks).keys.find((X)=>X.kid===T.kid&&X.kty==="OKP"&&X.crv==="Ed25519");if(!j?.x)return!1;try{let X=await Eo(j),le=Wr(T.requestId,T.rawBody),ge=xo(T.signatureB64Url);return crypto.subtle.verify({name:"Ed25519"},X,ge,le)}catch{return!1}}async function Oo(T){let _=await Do(T.privateKeyJwk),j=Wr(T.requestId,T.rawBody),X=await crypto.subtle.sign({name:"Ed25519"},_,j);return Po(new Uint8Array(X))}async function _o(T){let _=await crypto.subtle.generateKey({name:"Ed25519"},!0,["sign","verify"]),j=await crypto.subtle.exportKey("jwk",_.privateKey),le=(await crypto.subtle.exportKey("jwk",_.publicKey)).x,ge=j.d;if(!le||!ge)throw Error("Failed to export Ed25519 key material (missing x/d)");return{privateJwk:{kty:"OKP",crv:"Ed25519",x:le,d:ge,kid:T,alg:"EdDSA",use:"sig"},publicJwks:{keys:[{kty:"OKP",crv:"Ed25519",x:le,kid:T,alg:"EdDSA",use:"sig"}]}}}var _n={jwksTtlSeconds:{min:60,max:86400,default:600},jwksMaxEntries:{min:16,max:4096,default:256},sessionReadTtlSeconds:{min:1,max:300,default:30},sessionReadMaxEntries:{min:16,max:65536,default:1024}};function Fn(T,_){if(typeof T!=="number"||!Number.isFinite(T))return _.default;let j=Math.floor(T);if(j<_.min)return _.min;if(j>_.max)return _.max;return j}function Is(T){return{ttlMs:Fn(T?.ttlSeconds,_n.jwksTtlSeconds)*1000,maxEntries:Fn(T?.maxEntries,_n.jwksMaxEntries)}}function Ts(T){let _=T?.read;return{read:{enabled:_?.enabled===!0,ttlMs:Fn(_?.ttlSeconds,_n.sessionReadTtlSeconds)*1000,maxEntries:Fn(_?.maxEntries,_n.sessionReadMaxEntries)}}}function jo(T){return{jwks:Is(T?.jwks),session:Ts(T?.session)}}var Yn=new TextEncoder,Lo=new TextDecoder;function Us(T){let _="";for(let j of T)_+=String.fromCharCode(j);return btoa(_).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function xs(T){return Us(Yn.encode(JSON.stringify(T)))}function Es(T){if(!/^[A-Za-z0-9_-]+$/.test(T))return;let _=T.replace(/-/g,"+").replace(/_/g,"/").padEnd(Math.ceil(T.length/4)*4,"=");try{return Uint8Array.from(atob(_),(j)=>j.charCodeAt(0))}catch{return}}function Ps(T){let _=Es(T);if(!_)return;try{let j=JSON.parse(Lo.decode(_));return j!==null&&typeof j==="object"&&!Array.isArray(j)?j:void 0}catch{return}}function No(T){return Yn.encode(T)}function Ds(T){let _=new Uint8Array(T.byteLength);return _.set(T),_.buffer}async function Ms(T){return crypto.subtle.importKey("raw",Ds(No(T)),{name:"HMAC",hash:"SHA-256"},!1,["sign","verify"])}function $o(T){let _=T.active.trim(),j=new Map(Object.entries(T.keys).map(([le,ge])=>[le.trim(),{kid:le.trim(),secret:ge}])),X=j.get(_);if(!_||!X?.secret)throw Error("Signing key ring must name a non-empty active key.");for(let le of j.values())if(!le.kid||!le.secret)throw Error("Signing key ring ids and secrets must be non-empty.");return{current:()=>X,find:(le)=>j.get(le)}}async function Wo(T,_,j){let X=Math.floor(j.ttlSeconds);if(!Number.isFinite(X)||X<1)throw Error("Compact JWT ttlSeconds must be a positive integer.");let le=_.current();if(!le.kid||!le.secret)throw Error("Signing key ring returned an invalid active key.");let ge=Math.floor(Date.now()/1000),he=xs({alg:"HS256",kid:le.kid,typ:"JWT"}),ke=xs({...T,iat:ge,exp:ge+X}),ye=`${he}.${ke}`,fe=await crypto.subtle.sign("HMAC",await Ms(le.secret),Yn.encode(ye));return`${ye}.${Us(new Uint8Array(fe))}`}async function Vo(T,_){let j=T.split(".");if(j.length!==3)return null;let[X,le,ge]=j;if(!X||!le||!ge)return null;let he=Ps(X);if(he?.alg!=="HS256"||he.typ!=="JWT"||typeof he.kid!=="string")return null;let ke=_.find(he.kid);if(!ke?.secret)return null;let ye=Es(ge);if(!ye)return null;if(!await crypto.subtle.verify("HMAC",await Ms(ke.secret),Ds(ye),Yn.encode(`${X}.${le}`)))return null;let ze=Ps(le);if(!ze)return null;let{iat:Ye,exp:Qe}=ze;if(typeof Ye!=="number"||typeof Qe!=="number"||!Number.isSafeInteger(Ye)||!Number.isSafeInteger(Qe))return null;let ct=Math.floor(Date.now()/1000);if(Ye>ct+60||Qe+60<=ct)return null;return ze}function qo(T){let _={};if(!T)return _;let j=T.split(";");for(let X of j){let le=X.trim();if(!le)continue;let ge=le.indexOf("=");if(ge===-1)continue;_[le.slice(0,ge).trim()]=le.slice(ge+1).trim()}return _}function Os(T){if(!T.expiresAt)return!1;let _=T.expiresAt instanceof Date?T.expiresAt:new Date(T.expiresAt);return!Number.isNaN(_.getTime())&&Date.now()>_.getTime()}function zo(T){if(!T||typeof T!=="object"||Array.isArray(T))return;let{access_token:_,id_token:j,refresh_token:X,tokens:le,...ge}=T;return ge}function jt(T,_){let j=T[_];return typeof j==="string"?j:""}function Bo(T,_){let j=T.exp;if(typeof j==="number")return new Date(j*1000);if(typeof j==="string"&&j.trim()){let X=Number(j);if(!Number.isNaN(X))return new Date(X*1000)}if(_ instanceof Date)return _;if(_){let X=new Date(_);if(!Number.isNaN(X.getTime()))return X}return new Date}function Go(T){let _=T.claims;if(!_?.sub||typeof _.sub!=="string")return;let j=Bo(_,T.expiresAt);if(T.authType==="sso")return{id:_.sub,userName:jt(_,"preferred_username"),name:jt(_,"name"),email:jt(_,"email"),avatar:jt(_,"picture")||void 0,sso:{profile:_,tenant:{id:jt(_,"idp")||jt(_,"iss"),name:jt(_,"iss")},tokenType:"Bearer",expires:j}};return{id:_.sub,userName:jt(_,"preferred_username"),name:jt(_,"name"),email:jt(_,"email"),avatar:jt(_,"picture")||void 0,userType:"customer",ciam:{profile:_,scope:"openid profile email",tokenType:"Bearer",expires:j}}}function Ko(T){if(T.authType!=="sso"&&T.authType!=="ciam")return;if(Os(T))return;return{sid:T.sid,authType:T.authType,tenantId:typeof T.tenantId==="string"?T.tenantId:void 0,sub:T.sub,expiresAt:T.expiresAt,createdAt:T.createdAt,claims:zo(T.claims)}}function Jo(T,_){if(!T.endsWith(".session"))return!1;if(!_||_.length===0)return!0;return _.some((j)=>T===`${j}.session`)}function Ho(T){if(T===void 0)return;let _=(Array.isArray(T)?T:[T]).map((j)=>j.trim()).filter((j)=>j.length>0);return _.length>0?_:void 0}async function _s(T,_,j){return(await js(T,_,j)).map(Ko).filter((le)=>Boolean(le))}async function js(T,_,j){let X=qo(T.headers.get("cookie")),le=Ho(j?.cookiesPrefix),ge=[],he=new Set;for(let[ke,ye]of Object.entries(X)){if(!Jo(ke,le)||!ye)continue;if(he.has(ye))continue;he.add(ye);let fe=await _.get(ye);if(!fe)continue;if(fe.authType!=="sso"&&fe.authType!=="ciam")continue;if(Os(fe))continue;ge.push(fe)}return ge}async function Fo(T,_,j){return(await _s(T,_,j)).map(Go).filter((le)=>Boolean(le))}var Yo="@ionite/core",Xo=l(y(Yo));async function Zo(T,_){let j=await Zt({idToken:T,jwksUri:_.jwksUri,issuer:_.issuer,audience:_.audience}),X=await Xo.validate(j);if(X.issues)throw Error(`ID token claims validation failed: ${X.issues.map((he)=>he.message).join("; ")}`);let le=X.value;if(le===void 0)throw Error("ID token claims missing");return H(le)}function wt(T){return Date.now()-T}function Vr(T){if(T instanceof Error)return{"error.name":T.name,"error.message":T.message};return{"error.name":typeof T,"error.message":String(T)}}function Xn(T,_){if(!T)return{};try{let j=new URL(T);return{[`${_}.origin`]:j.origin,[`${_}.path`]:j.pathname}}catch{return{[`${_}.path`]:T.startsWith("/")?T:`/${T}`}}}function Zn(T,_=5){if(!Array.isArray(T))return[String(T)];return T.slice(0,_).map((j)=>{if(!j||typeof j!=="object")return String(j);let X=j,le=Array.isArray(X.path)?X.path.join("."):String(X.path??""),ge=typeof X.message==="string"?X.message:String(X.message??"validation failed");return le?`${le}: ${ge}`:ge})}function Qo(T){if(!T||typeof T!=="object")return{};let _=T;return{oidc_error:typeof _.error==="string"?_.error:void 0,oidc_error_description:typeof _.error_description==="string"?_.error_description:void 0,oidc_error_uri:typeof _.error_uri==="string"?_.error_uri:void 0}}function ea(T,_={}){let j=typeof T==="string"?T:T?.headers.get("cookie")??void 0;if(!j)return[];let le=`${_.cookiePrefix??"ion.sso"}.`,ge=new Set;for(let he of Object.keys(na(j))){if(!he.startsWith(le))continue;let ke=he.slice(le.length),ye=ke.lastIndexOf(".");if(ye<=0)continue;let fe=ke.slice(0,ye).trim();if(fe)ge.add(fe)}return Array.from(ge)}function ta(T,_,j,X,le){if(!j&&!X)return;let ge=new WeakMap,he=new Map,ke={...j,...X},ye=!!(ke.authority&&ke.tokenUrl&&ke.authorizationUrl&&ke.clientId&&ke.redirectUri&&ke.scope),fe={...ke,authority:ye?t(ke.authority,"Missing 'authority' from SSO Config"):ke.authority,tokenUrl:ye?t(ke.tokenUrl,"Missing 'tokenUrl' from SSO Config"):ke.tokenUrl,authorizationUrl:ye?t(ke.authorizationUrl,"Missing 'authorizationUrl' from SSO Config"):ke.authorizationUrl,clientId:ye?t(ke.clientId,"Missing 'clientId' from SSO Config"):ke.clientId,redirectUri:ye?t(ke.redirectUri,"Missing 'redirectUri' from SSO Config"):ke.redirectUri,scope:ye?t(ke.scope,"Missing 'scope' from SSO Config"):ke.scope,responseType:ke.responseType??"code",cookiesSecure:ke.cookiesSecure!==void 0?ke.cookiesSecure:!0,cookiesSameSite:ke.cookiesSameSite!==void 0?ke.cookiesSameSite:"Strict",cookiesPrefix:ke.cookiesPrefix??(ke.clientId?`ion.sso.${ke.clientId}`:"ion.sso"),cookiesPath:ke.cookiesPath??"/",cookiesDomain:Nn(ke.cookiesDomain)},ze=Math.min(600,Math.max(0,Math.floor(Number(fe.rotationGraceSeconds??60))||0))*1000,Ye=Math.floor(Number(fe.sessionWindowSeconds??86400)),Qe=Number.isFinite(Ye)&&Ye>=1?Ye:86400;function ct(){let Ce=[];if(!fe.authority)Ce.push("authority");if(!fe.tokenUrl)Ce.push("tokenUrl");if(!fe.authorizationUrl)Ce.push("authorizationUrl");if(!fe.clientId)Ce.push("clientId");if(!fe.redirectUri)Ce.push("redirectUri");if(!fe.scope)Ce.push("scope");if(Ce.length>0)throw Error(`Missing OIDC configuration fields: ${Ce.join(", ")}. OIDC configuration is required for SSO operations. Please provide these fields either in your vault configuration or in the SSO config when initializing ionite.`)}async function st(Ce){if(!fe)throw Error("ionite SSO Manager not initialized");let me=ge.get(Ce);if(me)return me;let we=_e(Ce);return ge.set(Ce,we),we}async function _e(Ce){try{let{tokens:me,session:we,refreshedUser:be}=await At(Ce);if(!me)return{status:"unauthenticated"};if(we)vn(Ce,"user",we.entitlements);if(be)return{status:"authenticated",value:be};if(we?.claims)return{status:"authenticated",value:Rt(we.claims,me,xt(we.expiresAt))};return{status:"unauthenticated"}}catch(me){if(Ls(me))return{status:"unauthenticated"};return _.error("Error parsing user from cookies",{"ion.operation":"cookie.parse","ion.outcome":"degraded"},me),{status:"degraded",error:me instanceof Error?me:void 0}}}async function Le(Ce){let me=await st(Ce);return me.status==="authenticated"?me.value:void 0}async function et(Ce){if(!fe)throw Error("ionite SSO Manager not initialized");ct();let me=t(fe.redirectUri,"Missing 'redirectUri' from SSO Config"),we=t(fe.authorizationUrl,"Missing 'authorizationUrl' from SSO Config"),be=t(fe.clientId,"Missing 'clientId' from SSO Config"),Re=t(fe.scope,"Missing 'scope' from SSO Config"),Ue=fe.cookiesSecure?Ce.url.replace(/^http:\/\//,"https://"):Ce.url,je=_t(),We=_t(64),qe=_t(),Ee=me;try{new URL(Ee)}catch{if(Ue)try{let Te=new URL(Ue),xe=Ee.startsWith("//")?Ee.slice(1):Ee.startsWith("/")?Ee:`/${Ee}`;Ee=new URL(xe,Te.origin).toString()}catch{try{let Te=new URL(we),xe=Ee.startsWith("//")?Ee.slice(1):Ee.startsWith("/")?Ee:`/${Ee}`;Ee=new URL(xe,Te.origin).toString()}catch{throw Error(`Invalid redirectUri: "${me}". It must be a valid absolute URL.`)}}}let Ae=new URL(we);Ae.searchParams.append("client_id",be),Ae.searchParams.append("redirect_uri",Ee),Ae.searchParams.append("response_type","code"),Ae.searchParams.append("scope",Re),Ae.searchParams.append("state",je),Ae.searchParams.append("nonce",qe);let Se=await Pn(We);Ae.searchParams.append("code_challenge",Se),Ae.searchParams.append("code_challenge_method","S256");let ve=await fe.beforeLogin?.({request:Ce}),Ie=ve===void 0?{state:je,codeVerifier:We,nonce:qe}:{state:je,codeVerifier:We,nonce:qe,context:ve};return new Response("Redirecting to SSO Provider",{status:302,headers:{Location:Ae.toString(),"Set-Cookie":Wt(Je(je),Ie,fe.loginStateTtl??600,"Lax")}})}async function De(Ce){if(!fe)throw Error("ionite SSO Manager not initialized");let me;try{me=await Le(Ce)}catch{me=void 0}let we=await fe.beforeLogout?.({request:Ce,user:me}),be=Ze("session",Ce),Re;try{Re=await At(Ce);let Se=Re.tokens?.refresh_token??Ze("refresh",Ce);if(Se)await Jt(Se)}catch(Se){_.warn("Failed to revoke token",{"ion.operation":"token.revoke","ion.outcome":"degraded"},Se)}if(fe.sessionStore)try{let Se=Re?.sid??be;if(Se)await fe.sessionStore.delete(Se)}catch(Se){_.warn("Failed to delete session",{"ion.operation":"session.delete","ion.outcome":"degraded"},Se)}let Ue=Ve(),je=await fe.afterLogout?.({request:Ce,context:we}),We=Qt(je,"/",Ce.url);if(We.response){let Se=new Headers(We.response.headers);for(let[,ve]of Ue)Se.append("Set-Cookie",ve);return new Response(We.response.body,{status:We.response.status,statusText:We.response.statusText,headers:Se})}let qe=We.location??"/",Ee=Ce.headers.get("accept");if(Ee?.includes(s)||Ee?.includes("text/javascript"))return new Response(JSON.stringify({success:!0,message:"Logged out",redirect:qe}),{status:200,headers:[["Content-Type",s],...Ue]});return new Response("Logged out",{status:302,headers:[["Location",qe],...Ue]})}async function it(Ce){if(!fe)throw Error("ionite SSO Manager not initialized");if(!fe.sessionStore)throw Error("Back-Channel Logout requires sessionStore configuration");try{if(!Ce.headers.get("content-type")?.includes(D))return new Response("Invalid Content-Type, expected application/x-www-form-urlencoded",{status:400});let we=await Ce.text(),Re=new URLSearchParams(we).get("logout_token");if(!Re)return new Response("Missing logout_token parameter",{status:400});let Ue=t(fe.authority,"Missing 'authority' from SSO Config. OIDC configuration is required to verify logout tokens."),je=t(fe.clientId,"Missing 'clientId' from SSO Config. OIDC configuration is required to verify logout tokens."),We=fe.jwksUri||`${Ue}/protocol/openid-connect/certs`,qe=await Cr({logoutToken:Re,jwksUri:We,issuer:Ue,audience:je,log:_}),Ee=typeof qe.sid==="string"?qe.sid:void 0;if(!Ee)return _.warn("Back-Channel Logout: logout_token missing sid claim",{"ion.operation":"backchannel_logout","ion.outcome":"failure"}),new Response("Invalid logout_token: missing sid claim",{status:400});return await fe.sessionStore.delete(Ee),_.info("Back-Channel Logout: successfully deleted session",{"ion.module":"sso",sid:Ee}),new Response("OK",{status:200})}catch(me){return _.error("Error during back-channel logout",{"ion.operation":"backchannel_logout","ion.outcome":"failure"},me),new Response("Internal Server Error",{status:500})}}async function pt(Ce){if(!fe)throw Error("ionite SSO Manager not initialized");let me=Date.now(),we=new URL(Ce.url),be=new URLSearchParams(we.search);_.debug("SSO callback received",{"ion.event":"ion.sso.callback.received","ion.module":"sso","ion.operation":"sign_in.callback","http.method":Ce.method,"url.path":we.pathname,hasCode:be.has("code"),hasState:be.has("state"),hasError:be.has("error"),...Xn(be.get("iss")??void 0,"oidc.issuer")});let Re=Object.fromEntries(be.entries()),Ue=await T.callbackParams.validate(Re);if(Ue.issues)return _.warn("SSO callback parameter validation failed",{"ion.event":"ion.sso.callback.validation_failed","ion.operation":"sign_in.callback","ion.outcome":"failure","validation.issues":Zn(Ue.issues)}),ce(Ue.issues,"OIDC callback parameters validation failed");let{code:je,state:We}=Ue.value,qe;try{let Ee=t(We,'OIDC "state" was not present in the callback parameters'),Ae=Ze(Je(Ee),Ce,!0),{codeVerifier:Se,state:ve,nonce:Ie,context:Te}=Ae??{};qe=Te,_.debug("SSO callback state cookie read",{"ion.event":"ion.sso.callback.state_cookie_read","ion.module":"sso","ion.operation":"sign_in.callback",hasStateCookie:Boolean(Ae),hasCodeVerifier:Boolean(Se),hasStateVerifier:Boolean(ve),hasNonce:Boolean(Ie),hasContext:Te!==void 0});let xe=t(Se,'OIDC "codeVerifier" was not present in cookies, ensure that the SSO login was initiated correctly');t(ve,'OIDC "stateVerifier" was not present in cookies, ensure that the SSO login was initiated correctly');let Ne=t(Ie,'OIDC "nonce" was not present in cookies, ensure that the SSO login was initiated correctly'),Oe=t(je,'OIDC "code" was not present in the callback parameters');if(We!==ve)throw _.warn("SSO callback state verification failed",{"ion.event":"ion.sso.callback.state_verification_failed","ion.operation":"sign_in.callback","ion.outcome":"failure"}),Error('SSO State Verifier failed, the "state" request parameter does not equal the "state" in the SSO cookie');_.debug("SSO callback state verified",{"ion.event":"ion.sso.callback.state_verified","ion.module":"sso","ion.operation":"sign_in.callback"});let Ge=fe.cookiesSecure?Ce.url.replace(/^http:\/\//,"https://"):Ce.url,Fe=await Mt(Oe,xe,Ge),{tokenExpiresAt:rt,sessionExpiresAt:at}=bt(Fe);Fe.expires=rt.toISOString();let ft=Date.now();_.debug("SSO ID token parsing started",{"ion.event":"ion.sso.id_token.parse_started","ion.module":"sso","ion.operation":"id_token.parse"});let dt=await mt(Fe,Ne,at);_.debug("SSO ID token parsing completed",{"ion.event":"ion.sso.id_token.parse_completed","ion.module":"sso","ion.operation":"id_token.parse","duration.ms":wt(ft),"user.id":dt.id});let nt,ht;{let Ct=Ht("SSO requires sessionStore configuration for opaque session cookies."),Vt=typeof dt.sso.profile.sid==="string"?dt.sso.profile.sid:void 0,Dt=Vt||_t(32),vt=dt.id;if(_.debug("SSO session creation evaluated",{"ion.event":"ion.sso.session.create_evaluated","ion.module":"sso","ion.operation":"session.create",hasSid:Boolean(Dt),hasIdpSid:Boolean(Vt),hasSub:Boolean(vt),"user.id":vt}),!vt)throw Error("Session creation failed: missing sub in ID token claims");let qt=Date.now(),wn=await nn({sid:Dt,sub:vt,idpSid:Vt,authType:"sso",tenantId:fe.tenantId,tokens:Fe,claims:dt.sso.profile,expiresAt:at,createdAt:new Date},vt,dt.sso.profile,Fe);await dn(Ct,wn),ht=wn,nt=["Set-Cookie",Wt("session",Dt,at)],_.info("SSO session created",{"ion.event":"ion.sso.session.created","ion.operation":"session.create","ion.outcome":"success","duration.ms":wt(qt),"user.id":vt})}if(fe.userStore)try{let Ct=dt.id;if(Ct){let Vt=new Date,Dt=Date.now();_.debug("SSO user store lookup started",{"ion.event":"ion.sso.user.lookup_started","ion.module":"sso","ion.operation":"user.lookup","user.id":Ct});let vt=await fe.userStore.get(Ct);if(_.debug("SSO user store lookup completed",{"ion.event":"ion.sso.user.lookup_completed","ion.module":"sso","ion.operation":"user.lookup","duration.ms":wt(Dt),"user.id":Ct,found:Boolean(vt)}),vt||fe.enableJitUserProvisioning){let qt=Date.now(),wn={...vt??{},...dt,id:Ct,tenantId:vt?.tenantId,createdAt:vt?.createdAt??Vt,updatedAt:Vt};await fe.userStore.upsert(wn),_.info("SSO user stored",{"ion.event":"ion.sso.user.stored","ion.operation":"user.store","ion.outcome":"success","duration.ms":wt(qt),"user.id":Ct,existing:Boolean(vt),jitProvisioning:Boolean(fe.enableJitUserProvisioning)})}else _.warn("JIT user provisioning disabled: user not found in store and will not be created",{"ion.event":"ion.sso.user.skipped","ion.operation":"user.store","ion.outcome":"skipped","user.id":Ct})}else _.warn("User storage skipped: missing sub in ID token claims",{"ion.event":"ion.sso.user.skipped","ion.operation":"user.store","ion.outcome":"skipped"})}catch(Ct){_.warn("Failed to store user",{"ion.event":"ion.sso.user.store_failed","ion.operation":"user.store","ion.outcome":"degraded",...Vr(Ct)})}_.info("SSO sign-in succeeded",{"ion.event":"ion.sso.sign_in.succeeded","ion.operation":"sign_in.callback","ion.outcome":"success","duration.ms":wt(me),"user.id":dt.id});let tt=[["Set-Cookie",rn(Je(Ee))],...nt?[nt]:[],...nt?await Be(Ce,await Tt(dt),at):[]],Ut=await fe.afterLogin?.({ok:!0,request:Ce,user:dt,session:ht,context:qe,displayCookie:fe.displayCookie,displayCookieAttributes:Ot()}),Et=Qt(Ut,"/",Ce.url);if(Et.response)return sn(Et.response,tt.map(([,Ct])=>Ct));return new Response("Authentication successful, redirecting",{status:302,headers:[["Location",Et.location],...tt]})}catch(Ee){_.error("Error during sign-in callback",{"ion.event":"ion.sso.sign_in.callback_failed","ion.operation":"sign_in.callback","ion.outcome":"failure","duration.ms":wt(me),...Vr(Ee)});let Ae=We?[["Set-Cookie",rn(Je(We))]]:[],Se=await fe.afterLogin?.({ok:!1,request:Ce,error:Ee,context:qe,displayCookie:fe.displayCookie,displayCookieAttributes:Ot()}),ve=Qt(Se,"/",Ce.url);if(ve.response)return sn(ve.response,Ae.map(([,Ie])=>Ie));return new Response("Authentication failed, redirecting",{status:302,headers:[["Location",ve.location],...Ae]})}}function bt(Ce){let me=Date.now(),we=Number(Ce.expires_in??3600)||3600,be=new Date(me+we*1000),Re;if(Ce.refresh_expires_in!=null&&Number.isFinite(Number(Ce.refresh_expires_in)))Re=Number(Ce.refresh_expires_in);else if(Ce.refresh_token)Re=Qe;else Re=we;return{tokenExpiresAt:be,sessionExpiresAt:new Date(me+Re*1000)}}async function mt(Ce,me,we){if(!fe)throw Error("ionite SSO Manager not initialized");let be=Date.now(),Re=await un(Ce.id_token,me);return _.debug("SSO user parsed from ID token",{"ion.event":"ion.sso.user.parse_completed","ion.module":"sso","ion.operation":"id_token.parse","duration.ms":wt(be),"user.id":Re.sub,hasEmail:Boolean(Re.email),hasName:Boolean(Re.name)}),Rt(Re,Ce,we)}function Rt(Ce,me,we){let be=we??bt(me).sessionExpiresAt,Re=Ce.ecid!==void 0&&Ce.ecid!==null?O(Ce.ecid):void 0;return{id:Ce.sub,userName:Ce.preferred_username||"",name:Ce.name||"",email:Ce.email||"",emails:[{value:Ce.email||"",primary:!0}],...Re?{ecid:Re}:{},avatar:Ce.picture,sso:{profile:{...Ce},tenant:{id:Ce.idp||Ce.iss||"",name:Ce.iss||""},scope:me.scope,tokenType:me.token_type,sessionState:me.session_state,expires:be}}}async function Tt(Ce){if(!fe.userStore)return Ce;let me=await fe.userStore.lookup(Ce);if(!me)return Ce;return{...Ce,...me,id:Ce.id,sso:Ce.sso}}async function Mt(Ce,me,we){if(!fe)throw Error("ionite SSO Manager not initialized");ct();let be=t(fe.tokenUrl,"Missing 'tokenUrl' from SSO Config"),Re=t(fe.redirectUri,"Missing 'redirectUri' from SSO Config"),Ue=t(fe.clientId,"Missing 'clientId' from SSO Config"),je=Re;try{new URL(je)}catch{if(we)try{let qe=new URL(we),Ee=je.startsWith("//")?je.slice(1):je.startsWith("/")?je:`/${je}`;je=new URL(Ee,qe.origin).toString()}catch{try{let qe=new URL(be),Ee=je.startsWith("//")?je.slice(1):je.startsWith("/")?je:`/${je}`;je=new URL(Ee,qe.origin).toString()}catch{throw Error(`Invalid redirectUri: "${Re}". It must be a valid absolute URL.`)}}}let We=new URLSearchParams;if(We.append("grant_type","authorization_code"),We.append("code",Ce),We.append("redirect_uri",je),We.append("client_id",Ue),fe.clientSecret)We.append("client_secret",fe.clientSecret);We.append("code_verifier",me);try{let qe=Date.now();_.debug("SSO token exchange started",{"ion.event":"ion.sso.token.exchange_started","ion.module":"sso","ion.operation":"token.exchange",...Xn(be,"oidc.token_url"),...Xn(je,"oidc.redirect_uri"),hasClientSecret:Boolean(fe.clientSecret)});let Ee=await fetch(be,{method:"POST",headers:{...h,...i},body:We.toString()});_.debug("SSO token exchange response received",{"ion.event":"ion.sso.token.response_received","ion.module":"sso","ion.operation":"token.exchange","http.status_code":Ee.status,"duration.ms":wt(qe)}),_.debug("SSO token exchange response body read started",{"ion.event":"ion.sso.token.response_body_read_started","ion.module":"sso","ion.operation":"token.exchange"});let Ae=await a(Ee,{log:_,operation:"token.exchange"});if(_.debug("SSO token exchange response body read completed",{"ion.event":"ion.sso.token.response_body_read_completed","ion.module":"sso","ion.operation":"token.exchange","duration.ms":wt(qe)}),!Ee.ok){_.error("Token exchange error",{"ion.event":"ion.sso.token.exchange_failed","ion.operation":"token.exchange","ion.outcome":"failure","http.status_code":Ee.status,"duration.ms":wt(qe),...Qo(Ae)});let ve=Ae;throw Error(`Token exchange failed: ${ve.error||Ee.statusText} - ${ve.error_description||""}`.trim())}let Se=await T.tokenResponse.validate(Ae);if(Se.issues)throw _.error("Token response validation failed",{"ion.event":"ion.sso.token.response_validation_failed","ion.operation":"token.exchange","ion.outcome":"failure","duration.ms":wt(qe),"validation.issues":Zn(Se.issues)}),Error(`Token response validation failed: ${Se.issues}`);return _.debug("SSO token exchange completed",{"ion.event":"ion.sso.token.exchange_completed","ion.module":"sso","ion.operation":"token.exchange","ion.outcome":"success","duration.ms":wt(qe),tokenType:Se.value.token_type,hasAccessToken:Boolean(Se.value.access_token),hasIdToken:Boolean(Se.value.id_token),hasRefreshToken:Boolean(Se.value.refresh_token),expiresIn:Se.value.expires_in}),Se.value}catch(qe){throw _.error("Error during token exchange",{"ion.event":"ion.sso.token.exchange_failed","ion.operation":"token.exchange","ion.outcome":"failure",...Vr(qe)}),qe}}async function kn(Ce){return yr(async()=>{if(!fe)throw Error("ionite SSO Manager not initialized");ct();let me=t(fe.tokenUrl,"Missing 'tokenUrl' from SSO Config"),we=t(fe.clientId,"Missing 'clientId' from SSO Config"),be=new URLSearchParams;if(be.append("grant_type","refresh_token"),be.append("refresh_token",Ce),be.append("client_id",we),fe.clientSecret)be.append("client_secret",fe.clientSecret);let Re=await fetch(me,{method:"POST",headers:{...h,...i},body:be.toString()}),Ue=await a(Re,{log:_,operation:"token.refresh"});if(!Re.ok){_.error("Token refresh error",{"ion.operation":"token.refresh","ion.outcome":"failure",response:Ue});let We=Ue;throw Error(`Token refresh failed: ${We.error||Re.statusText} - ${We.error_description||""}`.trim())}let je=await T.tokenResponse.validate(Ue);if(je.issues)throw _.error("Token refresh response validation failed",{"ion.event":"ion.sso.token.refresh_validation_failed","ion.operation":"token.refresh","ion.outcome":"failure","validation.issues":Zn(je.issues)}),Error(`Token refresh response validation failed: ${je.issues}`);return je.value},void 0,void 0,void 0,_)}async function Jt(Ce){try{if(!fe)throw Error("ionite SSO Manager not initialized");if(!fe.revocationEndpoint)return;let me=t(fe.clientId,"Missing 'clientId' from SSO Config"),we=new URLSearchParams;if(we.append("token",Ce),we.append("token_type_hint","refresh_token"),we.append("client_id",me),fe.clientSecret)we.append("client_secret",fe.clientSecret);let be=await fetch(fe.revocationEndpoint,{method:"POST",headers:{...i,...h},body:we.toString()});if(!be.ok)_.warn("Token revocation failed",{"ion.operation":"token.revoke","ion.outcome":"degraded",status:be.status,statusText:be.statusText});else _.info("Token revoked successfully",{"ion.module":"sso"})}catch(me){_.warn("Error revoking token",{"ion.operation":"token.revoke","ion.outcome":"degraded"},me)}}async function Sn(){if(!fe)throw Error("ionite SSO Manager not initialized");let Ce=fe.authority;if(!fe.jwksUri&&!Ce)throw Error("Missing 'jwksUri' or 'authority' from SSO Config. OIDC configuration is required for this operation.");let me=fe.jwksUri||`${Ce}/protocol/openid-connect/certs`;return In(me,_)}async function un(Ce,me){let we=Date.now(),be=t(fe.authority,"Missing 'authority' from SSO Config. OIDC configuration is required to verify ID tokens."),Re=t(fe.clientId,"Missing 'clientId' from SSO Config. OIDC configuration is required to verify ID tokens."),Ue=fe.jwksUri||`${be}/protocol/openid-connect/certs`;_.debug("SSO ID token verification started",{"ion.event":"ion.sso.id_token.verify_started","ion.module":"sso","ion.operation":"id_token.verify",...Xn(Ue,"oidc.jwks_uri")});let je;try{je=await Zt({idToken:Ce,jwksUri:Ue,issuer:be,audience:Re,expectedNonce:me,log:_})}catch(qe){throw _.error("SSO ID token verification failed",{"ion.event":"ion.sso.id_token.verify_failed","ion.module":"sso","ion.operation":"id_token.verify","ion.outcome":"failure","duration.ms":wt(we)},qe),qe}_.debug("SSO ID token signature verified",{"ion.event":"ion.sso.id_token.signature_verified","ion.module":"sso","ion.operation":"id_token.verify","duration.ms":wt(we)});let We=await T.idTokenClaims.validate(je);if(We.issues)throw _.error("ID token claims validation failed",{"ion.event":"ion.sso.id_token.validation_failed","ion.operation":"id_token.validate","ion.outcome":"failure","duration.ms":wt(we),"validation.issues":Zn(We.issues)}),Error(`ID token claims validation failed: ${We.issues}`);return _.debug("SSO ID token claims validated",{"ion.event":"ion.sso.id_token.claims_validated","ion.module":"sso","ion.operation":"id_token.validate","ion.outcome":"success","duration.ms":wt(we),"user.id":We.value.sub,hasIssuer:Boolean(We.value.iss),hasAudience:Boolean(We.value.aud)}),We.value}function Ht(Ce="SSO sessionStore is required for opaque session cookies."){if(!fe.sessionStore)throw Error(Ce);return fe.sessionStore}let Ft=!1;async function nn(Ce,me,we,be){let Re=fe.claimsAsEntitlements;if(!Re?.claims?.length)return Ce;if(fe.sessionStore?.capabilities?.derivedEntitlements!==!0){if(!Ft)Ft=!0,_.warn("SSO claims entitlements are configured but the session store does not persist them",{"ion.event":"ion.sso.claims.incapable","ion.module":"sso","ion.outcome":"degraded"});return Ce}let Ue=await bn({block:Re,claims:we,accessClaims:Cn(be?.access_token),scope:be?.scope,subjectType:"user",subjectId:me,catalog:le?.catalogView?.(),log:_});return{...Ce,entitlements:Ue}}async function dn(Ce,me){try{await Ce.create(me)}catch(we){if(!await Ce.get(me.sid))throw we;await Ce.update(me.sid,me)}}function xt(Ce){if(!Ce)return;if(Ce instanceof Date)return Ce;let me=new Date(Ce);return Number.isNaN(me.getTime())?void 0:me}function ln(Ce){let me=Ce.tokens;if(!me?.access_token||!me.id_token||!me.token_type)return;return me}async function Yt(Ce,me=!1){let we=Ht(),be=Ze("session",Ce);if(!be)return{tokens:void 0,refreshHeaders:[]};let Re=await we.get(be);if(Re&&fe.tenantId&&Re.tenantId&&Re.tenantId!==fe.tenantId)return{tokens:void 0,refreshHeaders:Ve(),sid:be};if(Re?.authType!=="sso")return{tokens:void 0,refreshHeaders:Ve(),sid:be};let Ue=ln(Re);if(!Ue)return{tokens:void 0,refreshHeaders:Ve(),sid:be};let je=xt(Re.expiresAt);if(je?Date.now()>je.getTime():!1)return await we.delete(be),{tokens:void 0,sid:be,refreshHeaders:Ve()};let qe=xt(Ue.expires),Ee=qe?Date.now()>qe.getTime():!0;if((me||Ee)&&Ue.refresh_token)return Pt(Ce,be,Re,Ue);return{tokens:Ue,sid:be,session:Re,refreshHeaders:Xe(Ce)}}function Pt(Ce,me,we,be){let Re=he.get(me);if(Re)return Re;let Ue=Ht(),je=(async()=>{let We=await kn(be.refresh_token),{tokenExpiresAt:qe,sessionExpiresAt:Ee}=bt(We);We.expires=qe.toISOString();let Ae=await mt(We,void 0,Ee),Se=Ae.sso.profile,ve=_t(32),Ie=await nn({...we,sid:ve,tokens:We,claims:Se,expiresAt:Ee,createdAt:new Date},we.sub,Se,We);await dn(Ue,Ie);try{if(ze<=0)await Ue.delete(me);else{let{refresh_token:Te,...xe}=be;await Ue.update(me,{tokens:xe,expiresAt:new Date(Date.now()+ze)})}}catch(Te){_.warn("Failed to retire rotated SSO session record",{"ion.operation":"session.rotate","ion.outcome":"degraded"},Te)}return{tokens:We,sid:ve,session:Ie,refreshedUser:Ae,refreshHeaders:[["Set-Cookie",Wt("session",ve,Ee)],...await Be(Ce,Ae,Ee)]}})();return he.set(me,je),je.finally(()=>{he.delete(me)})}async function At(Ce,me=!1){return Yt(Ce,me)}async function $t(Ce){let{tokens:me}=await At(Ce);if(!me)return;return me.access_token}function Wt(Ce,me,we,be=fe.cookiesSameSite??"Strict"){if(!fe)throw Error("ionite SSO Manager not initialized");if(Ce=`${fe.cookiesPrefix}.${Ce}`,typeof me!=="string")me=btoa(JSON.stringify(me));let Re;if(we instanceof Date)Re=`Expires=${we.toUTCString()}`;else if(typeof we==="number")Re=`Max-Age=${we}`;else throw Error("Invalid expires type",we);if(me.length>4000)throw Error(`Error setting cookie: ${Ce}. Cookie length is: ${me.length}`);return`${Ce}=${me}; ${Re}; Path=${fe.cookiesPath};${Xt(fe.cookiesDomain)} HttpOnly;${fe.cookiesSecure?" Secure;":""} SameSite=${be};`}function rn(Ce){if(!fe)throw Error("ionite SSO Manager not initialized");return`${fe.cookiesPrefix}.${Ce}=; Max-Age=0; Path=${fe.cookiesPath};${Xt(fe.cookiesDomain)} HttpOnly;${fe.cookiesSecure?" Secure;":""} SameSite=${fe.cookiesSameSite};`}function Ot(){return{path:fe.cookiesPath??"/",domain:fe.cookiesDomain,secure:fe.cookiesSecure!==!1,sameSite:fe.cookiesSameSite??"Strict"}}function Ve(){return[["Set-Cookie",rn("session")],["Set-Cookie",Bt(`${fe.cookiesPrefix}.profile`,Ot())]]}function Xe(Ce){if(fe.displayCookie?.enabled===!0)return[];return mn(Ce.headers.get("cookie"),fe.cookiesPrefix??"ion.sso",Ot()).map((me)=>["Set-Cookie",me])}async function Be(Ce,me,we){return(await Rn({cookieHeader:Ce.headers.get("cookie"),sessionStore:fe.sessionStore,cookiesPrefix:fe.cookiesPrefix??"ion.sso",authType:"sso",tenantId:fe.tenantId,expiresAt:we,user:me,projector:fe.displayUser,displayCookie:fe.displayCookie,trim:fe.trimDisplayCookies,attr:Ot()})).map((Re)=>["Set-Cookie",Re])}function Ze(Ce,me,we=!1){if(!fe)throw Error("ionite SSO Manager not initialized");let be=me.headers.get("cookie");if(!be)return null;let Re=`${fe.cookiesPrefix}.${Ce}`,Ue=be.split(";").find((Ee)=>Ee.trim().startsWith(`${Re}=`));if(!Ue)return null;let je=Ue.indexOf("="),We=Ue.slice(je+1).trim();if(!we)return We;let qe=atob(We);return JSON.parse(qe)}function Je(Ce){return`state_${Ce}`}async function He(Ce,me){if(!fe)throw Error("ionite SSO Manager not initialized");let{loginUrl:we,userUrl:be,tokenUrl:Re,refreshUrl:Ue,logoutUrl:je,logoutBackChannelUrl:We,jwksUrl:qe,redirectUri:Ee}={...fe,...me},Ae=new URL(Ce.url).pathname;if(Ee){let Se;try{Se=new URL(Ee).pathname}catch{try{let ve=new URL(Ce.url),Ie=Ee.startsWith("//")?Ee.slice(1):Ee;Se=new URL(Ie,ve.origin).pathname}catch{Se=Ee.startsWith("/")?Ee:`/${Ee}`}}if(Se===Ae)return pt(Ce)}if(we===Ae)return et(Ce);if(be===Ae){if((fe.userEndpoint??"full")==="off")return new Response("Not Found",{status:404,headers:Xe(Ce)});try{let{tokens:Se,session:ve,refreshedUser:Ie,refreshHeaders:Te}=await At(Ce);if(!Se)return new Response("User not logged in",{status:401,headers:Te});let xe=Ie??(ve?.claims?Rt(ve.claims,Se,xt(ve.expiresAt)):void 0);if(!xe)return new Response("User not logged in",{status:401,headers:Te});let Ne=await Tt(xe),Oe=`${fe.cookiesPrefix}.profile`,Ge=xt(ve?.expiresAt),Fe=fe.displayCookie?.enabled===!0&&Ge&&!Ze("profile",Ce)&&!Te.some(([,at])=>at.startsWith(`${Oe}=`))?await Be(Ce,Ne,Ge):[],rt=fe.userEndpoint==="display"?m(Ne,fe.displayUser):Ne;return new Response(JSON.stringify(rt),{headers:[["Content-Type",s],...Te,...Fe]})}catch(Se){if(Ls(Se))return new Response("User not logged in",{status:401});return _.error("Error resolving SSO user",{"ion.operation":"sso.user","ion.outcome":"degraded"},Se),new Response(JSON.stringify({error:"auth_unavailable"}),{status:503,headers:r})}}if(Re===Ae){let{tokens:Se,refreshHeaders:ve}=await At(Ce);if(!Se)return new Response("User not logged in",{status:401,headers:ve});return new Response(JSON.stringify({token:Se.access_token,expires:Se.expires}),{headers:[["Content-Type",s],...ve]})}if(Ue===Ae){let{tokens:Se,refreshHeaders:ve}=await At(Ce,!0);if(!Se)return new Response("User not logged in",{status:401});return new Response("Refresh Complete",{status:200,headers:ve})}if(je===Ae)return De(Ce);if(We===Ae)return it(Ce);if(qe===Ae){let Se=await Sn();return new Response(JSON.stringify(Se),{headers:[["Content-Type",s]]})}return new Response("Not Found",{status:404})}let ut;return ut={...fe,describe:()=>({module:"sso",active:!0,ready:ut.isReady?.()??!0,authority:fe.authority,tokenUrl:fe.tokenUrl,authorizationUrl:fe.authorizationUrl,clientId:fe.clientId,redirectUri:fe.redirectUri,responseType:fe.responseType,scope:fe.scope,silentRedirectUri:fe.silentRedirectUri,jwksUri:fe.jwksUri,endSessionEndpoint:fe.endSessionEndpoint,revocationEndpoint:fe.revocationEndpoint,cookies:{prefix:fe.cookiesPrefix,path:fe.cookiesPath,secure:fe.cookiesSecure,sameSite:fe.cookiesSameSite,domain:fe.cookiesDomain},loginStateTtl:fe.loginStateTtl,rotationGraceSeconds:fe.rotationGraceSeconds,sessionWindowSeconds:fe.sessionWindowSeconds,displayCookie:fe.displayCookie,jit:{enabled:fe.enableJitUserProvisioning===!0,userStore:fe.userStore!==void 0},sessionStore:fe.sessionStore!==void 0,...fe.claimsAsEntitlements?.claims?.length?{claimsAsEntitlements:{claims:[...fe.claimsAsEntitlements.claims],expand:fe.claimsAsEntitlements.expand===!0,resources:fe.claimsAsEntitlements.expand===!0&&fe.claimsAsEntitlements.resources===!0,capable:fe.sessionStore?.capabilities?.derivedEntitlements===!0}}:{},urls:{loginUrl:fe.loginUrl??"",userUrl:fe.userUrl??"",logoutUrl:fe.logoutUrl??"",logoutBackChannelUrl:fe.logoutBackChannelUrl??"",refreshUrl:fe.refreshUrl??"",callbackUrl:fe.redirectUri??""}}),getUser:Le,resolveUser:st,getJwt:$t,initiateLogin:et,logout:De,logoutBackChannel:it,callbackHandler:pt,handler:He},ut}function na(T){let _={},j=T.split(";");for(let X of j){let le=X.trim();if(!le)continue;let ge=le.indexOf("=");if(ge===-1)continue;let he=le.slice(0,ge).trim(),ke=le.slice(ge+1).trim();_[he]=ke}return _}function Ls(T){if(!(T instanceof Error))return!1;return["Public key not found","Invalid JWT","Invalid JWT signature","ID token expired","ID token issuer mismatch","ID token audience mismatch","ID token nonce mismatch","ID token missing exp","invalid_grant"].some((_)=>T.message.includes(_))}function Ns(T){return T=T??"SSO Unavailable",new Response(JSON.stringify({error:T}),{status:503,statusText:T,headers:r})}var Qn="Ionite instance is required. Create one with ionite(source, config) and pass it to this function.";async function ra(T,_){return t(_,Qn),_.sso?.getUser(T)}async function qr(T,_){return t(_,Qn),await _.sso?.resolveUser(T)??{status:"unauthenticated"}}async function sa(T,_){t(_,Qn);let j=_.sso;if(!j)return Ns();return j.initiateLogin(T)}async function ia(T,_){t(_,Qn);let j=_.sso;if(!j)return Ns();return j.callbackHandler(T)}var Br="tenant.owner",zr="tenant.owner.",oa="tenant:";function aa(T){return{id:Br,name:"Tenant owner",description:"Administer one tenant resource",requestable:!1,permissionTypes:["Admin"],resourceTypes:["tenant"],assignableSubjectTypes:["customer"],...T}}function Gr(T){let _=T.trim();if(!_)throw Error("tenantId is required");return`${oa}${_}`}function ca(T){let _=T.trim();if(!_)throw Error("tenantId is required");return`${zr}${_}`}function gt(T){return{allow:!1,reason:T,response(){if(T==="not_found")return Response.json({error:"Not Found"},{status:404});if(T==="forbidden")return Response.json({error:"Forbidden"},{status:403});if(T==="unavailable")return Response.json({error:"Tenant runtime unavailable"},{status:503});return Response.json({error:"Unauthorized"},{status:401})}}}function er(T,_){if(!T.id)return gt("unavailable");return{allow:!0,session:{id:T.id,email:T.email,name:T.name,kind:_}}}function $s(T){return T==="access_index_not_configured"||T==="error"}async function Ws(T,_){let j;try{j=await Vn(T,_.rootIon)}catch{return gt("unavailable")}if(j.status==="degraded")return gt("unavailable");if(j.status==="unauthenticated")return gt("unauthenticated");if(!j.value.id)return gt("unavailable");try{let X=await _.rootIon.authz.hasPermission(j.value.id,_.ownerPermission??Br,Gr(_.tenantId),"customer");if(X.allow)return er(j.value,"owner");return gt($s(X.metadata?.reason)?"unavailable":"forbidden")}catch{return gt("unavailable")}}async function ua(T,_){let{tenantIon:j}=_;if(!j)return gt("not_found");if(j.isReady()){let le;try{le=await qr(T,j)}catch{return gt("unavailable")}if(le.status==="degraded")return gt("unavailable");if(le.status==="authenticated"){if(!le.value.id)return gt("unavailable");if(!_.permission)return er(le.value,"sso");try{let ge=await j.authz.hasPermission(le.value.id,_.permission,void 0,"user");if(ge.allow)return er(le.value,"sso");return gt($s(ge.metadata?.reason)?"unavailable":"forbidden")}catch{return gt("unavailable")}}if(_.allowTenantCustomer){let ge;try{ge=await Vn(T,j)}catch{return gt("unavailable")}if(ge.status==="degraded")return gt("unavailable");if(ge.status==="authenticated"){if(!ge.value.id)return gt("unavailable");return er(ge.value,"customer")}}}let X=await Ws(T,_);if(X.allow||X.reason==="unavailable")return X;if(!j.isReady())return gt("unavailable");return gt("unauthenticated")}async function da(T,_){let j=T.authz.accessStore;if(!j)throw Error("Cannot list owned tenants: no AccessAssignmentStore is wired.");let X=new Set;for await(let le of c((ge,he)=>j.listBySubject(_,"customer",{start:ge,limit:he}))){let ge=typeof le.target==="string"?le.target:le.target.id;if(le.targetType!=="group"||!ge.startsWith(zr))continue;let he=ge.slice(zr.length);if(!he||!le.resources?.includes(Gr(he)))continue;X.add(he)}return[...X].sort()}function la(T,_){let j=_.redirectTo.trim()||"/",X=_.tenantIon?.sso?.isReady?.()===!0?`${_.tenantIonBasePath?.(T)??`/api/${encodeURIComponent(T)}/ionite`}/auth/login`:_.fallbackPath,le=new URL(X,"http://localhost");return le.searchParams.set("redirect",j),`${le.pathname}${le.search}`}export{_n as CACHE_BOUNDS,Yr as CIAM_PROVIDER_PRESETS,Q as CatalogAdjacencyCache,Me as InMemoryTenantStore,Br as TENANT_OWNER_PERMISSION,Li as allowHosts,ji as allowOrigins,ms as allowRelativePaths,fs as allowSameOrigin,Rs as assertSubjectTypeAssignable,us as assertTrustedIdTokenClaims,Er as baseCustomerToScim,Pr as baseUserToScimUser,Ur as baseWorkloadToScim,ps as blockDangerousUrls,wr as buildAuthorizationUrl,Wr as buildLfvSigningInput,ia as callback,$i as captureRedirect,zi as ciam,Ei as clearDiscoveryCache,bi as clearJwksCache,$e as collectReferencedDefinitions,yi as configureJwksCache,Cn as decodeUnverifiedJwtPayload,Ni as defaultRedirectPolicies,bn as deriveClaimsEntitlements,nr as derivedEntitlementsFor,vr as discoverOidcEndpoints,js as discoverSessionRecords,_s as discoverSessions,xr as entitlementToScimGroup,br as exchangeAuthorizationCode,E as expandRoot,Rr as fetchUserInfo,Bt as formatDisplayClearCookie,dr as formatDisplaySetCookie,Ar as generateAppleClientSecret,_o as generateLfvEd25519KeyPair,hr as getCachedVerificationKey,Bi as getCustomer,Fo as getDiscoveredSessionUsers,In as getJwks,da as getOwnedTenantIds,ir as getProviderPreset,Ri as getPublicKeyForKid,vi as getPublicKeyFromJwks,ra as getUser,kr as getVerificationKeyForKid,ri as has,ci as hasAll,li as hasAllScope,ai as hasAny,di as hasAnyScope,oi as hasGroup,si as hasPermission,ii as hasRole,ui as hasScope,To as iam,sa as initiateLogin,gs as isRedirectAllowed,ea as listSsoClientIdsFromCookies,xn as normalizeOidcIssuer,ar as orderedEnabledProviders,As as parseLfvJwks,Pn as pkceChallengeFromVerifier,gi as planDiscoveredTenantCookies,mn as planDisplayCookieClear,Rn as planDisplayCookieHeaders,pe as reconcileSubjectAccess,vn as rememberDerivedEntitlements,Qt as resolveAfterRedirect,jo as resolveCacheConfig,Wi as resolveCapturedRedirect,Ln as resolveCiamProvider,Vn as resolveCustomer,Ci as resolveJwkForKid,Is as resolveJwksCacheConfig,or as resolveProviderBranding,Tr as resolveRedirect,Ts as resolveSessionCacheConfig,Ws as resolveTenantOwner,ua as resolveTenantSession,qr as resolveUser,Ir as sameOriginRedirectRules,Qr as selectDisplayCookies,ot as sendTenantWebhook,Ui as setDiscoveryClock,hi as setJwksClock,ki as setJwksRetry,Wo as signCompactJwt,Oo as signLfvPayload,ta as sso,$o as staticSigningKeyRing,Uo as stringifyLfvJwks,la as tenantAccessLoginUrl,ca as tenantOwnerEntitlementId,aa as tenantOwnerPermission,Gr as tenantResourceId,Vo as verifyCompactJwt,Zt as verifyIdToken,Mo as verifyLfvSignature,Cr as verifyLogoutToken,Zo as verifyUser,sn as withSetCookies};