@ionite/core 0.0.24-beta.20261006.21 → 0.0.24-beta.20261007.23
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/index.d.ts +267 -110
- package/dist/index.js +2 -2
- package/dist/server.d.ts +179 -48
- package/dist/server.js +1 -1
- package/dist/shared/core-y6y95p25.js +4 -0
- package/package.json +1 -1
- package/dist/shared/core-knezf9yx.js +0 -4
package/dist/server.js
CHANGED
|
@@ -1 +1 @@
|
|
|
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};
|
|
1
|
+
import{Y,l,I,v,x,i,r,u,Z,g,e,y,E,L,K,q,ee,W,n,m,te,P,me,qe,V,ne,re,z,se,f,B,oe,G,U,_,F,D,ie,ae,ce,h,o,M,a,ue,s,w,S,J,c,p,t,de,R,k,H,A,j,Ne,it,d,b,C,le,pe}from"./shared/core-y6y95p25.js";var Ks=new Set(ie.map((T)=>T.id));async function vn(T){let O=Js(T.block);if(O.length===0||!T.subjectId)return[];let N=Hs(T.claims,T.accessClaims,T.scope),X=T.block.expand===!0,Q=X&&T.block.resources===!0,ye=[],he=new Set,we=(ke)=>{let fe=`${ke.targetType}:${ke.target}:${ke.resource??""}`;if(he.has(fe))return;he.add(fe),ye.push(ke)};for(let ke of O){let fe=Fs(N,ke);for(let Be of fe){let He=await Xs(T.catalog,Be);if(!He){T.log?.debug("claims entitlement dropped: value is not a catalog id",{"ion.event":"ion.authz.claims.unmatched","ion.module":"authz",claim:ke,value:Be});continue}if(!X||!T.catalog){we({targetType:He,target:Be,claim:ke});continue}let et={subject:T.subjectId,subjectType:T.subjectType,targetType:He,target:Be,...Q?ei(await Qs(T.catalog,He,Be)):{applyToApplication:!0}},dt=await P(et,T.catalog),ot=et.id;for(let $e of dt){if($e.resource&&!Q)continue;we({targetType:$e.targetType,target:$e.target,...$e.resource?{resource:$e.resource}:{},claim:ke,root:ot??$e.rootId})}}}return ye}function fn(T){if(!T)return;let O=T.split(".");if(O.length!==3||!O[1])return;try{let N=O[1].replace(/-/g,"+").replace(/_/g,"/"),X=N.padEnd(N.length+(4-N.length%4)%4,"="),Q=JSON.parse(atob(X));return Q&&typeof Q==="object"&&!Array.isArray(Q)?Q:void 0}catch{return}}var nr=new WeakMap;function Rn(T,O,N){let X=nr.get(T)??{};X[O]=N??[],nr.set(T,X)}function rr(T,O){return nr.get(T)?.[O]}function Js(T){return T.claims.filter((O)=>typeof O==="string"&&O.length>0)}function Hs(T,O,N){let X={...T};if(O){for(let[Q,ye]of Object.entries(O))if(X[Q]===void 0)X[Q]=ye}if(X.scope===void 0&&N)X.scope=N;return X}function Fs(T,O){let N=Ys(T,O);if(typeof N==="string")return O==="scope"||O.endsWith(".scope")?N.split(/\s+/).filter(Boolean):N.length>0?[N]:[];if(Array.isArray(N))return N.filter((X)=>typeof X==="string"&&X.length>0);return[]}function Ys(T,O){let N=T;for(let X of O.split(".")){if(!N||typeof N!=="object"||Array.isArray(N))return;N=N[X]}return N}async function Xs(T,O){if(Ks.has(O))return"permission";if(!T)return;for(let N of["permission","role","group"])if(await Zs(T,N,O))return N;return}async function Zs(T,O,N){if(Yr(T,O,N))return!0;let Q=O==="permission"?T.catalog?.permissions:O==="role"?T.catalog?.roles:T.catalog?.groups;if(!Q)return!1;return await Q.get(N)!==void 0}function Yr(T,O,N){if(!T.code)return;if(O==="permission")return T.code.permissions.get(N);if(O==="role")return T.code.roles.get(N);return T.code.groups.get(N)}async function Qs(T,O,N){let X=Yr(T,O,N),Q=O==="permission"?T.catalog?.permissions:O==="role"?T.catalog?.roles:T.catalog?.groups,we=((Q?await Q.get(N):void 0)?.resources??X?.resources??[]).map((ke)=>ke.trim()).filter(Boolean);return we.length>0?we:void 0}function ei(T){if(!T||T.length===0)return{applyToApplication:!0};return{resources:T}}var ti="Ionite instance is required. Create one with ionite(source, config) and pass it to this function.",Xr=["user","customer","workload"],ni={user:async(T,O)=>O.sso?.getUser(T),customer:async(T,O)=>O.ciam?.getCustomer(T),workload:async(T,O)=>{let N=await O.workload?.getWorkloadIdentity?.(T);if(!N)return;let X=N.clientId??N.workloadId??N.claims.sub;return X?{...N,id:X}:void 0}};function ri(T){if(T==="any")return Xr;let O=Array.isArray(T)?T:[T];return Xr.filter((N)=>O.includes(N))}function si(T){let O=T.headers.get("cookie");if(!O)return[];return O.split(";").map((N)=>N.slice(0,N.indexOf("=")===-1?N.length:N.indexOf("=")).trim()).filter(Boolean)}function ii(T,O){let N=T.headers.get("authorization")?.toLowerCase().startsWith("bearer ")??!1,X=si(T),Q=new Set;for(let he of X){if(he.startsWith("ion.sso"))Q.add("user");if(he.startsWith("ion.ciam"))Q.add("customer")}let ye=X.length>0&&!Q.has("user")&&!Q.has("customer");return O.filter((he)=>{if(he==="workload")return N;if(X.length===0)return!1;return Q.has(he)||ye})}function pt(T){return typeof T==="string"?T:T.id}function oi(T){let{subject:O,subjectType:N}=T,X;if(N==="user")X=O.sso?.scope;else if(N==="customer")X=O.ciam?.scope;else if(N==="workload")X=O.scope;return new Set((X??"").split(/\s+/).filter(Boolean))}function ir(T,O,N){let X=oi(T),Q=O.filter((he)=>X.has(he));return{allow:N==="any"?Q.length>0:O.length>0&&Q.length===O.length,metadata:{reason:"scope",wantedScopes:O,matchedScopes:Q}}}function Zr(T,O){if(T.targetType!==O.targetType||T.target!==O.id)return!1;return O.resource?T.resource===O.resource:T.resource===void 0}function gn(T,O){return(N)=>{if(T.length===0)return;let X=N.derivedEntitlements??[];if(X.length===0)return;let Q=T.filter((he)=>X.some((we)=>Zr(we,he)));if(!(O==="any"?Q.length>0:Q.length===T.length))return;return X.filter((he)=>Q.some((we)=>Zr(he,we)))}}function jn(T,O,N){return(X)=>{if(O.length===0||X.subjectType!=="workload")return;let Q=Y(T.config?.authz,X.subject);if(!Q)return;let ye=O.filter((we)=>Q.has(we));return(N==="any"?ye.length>0:ye.length===O.length)?ye:void 0}}function sr(T,O,N,X,Q){return{allow:N==="ok",subject:O?.subject,subjectType:O?.subjectType,reason:N,decision:X,response(){if(N==="ok")return new Response(null,{status:204});if(N==="unauthenticated")return T.log.warn("authz.denied",{reason:N,...Q()}),Response.json({error:"Unauthorized"},{status:401});if(N==="not_configured")return T.log.warn("authz.denied",{reason:N,subject:O?.subject?.id,subjectType:O?.subjectType,...Q()}),Response.json({error:"not_configured"},{status:503});return T.log.warn("authz.denied",{reason:N,subject:O?.subject?.id,subjectType:O?.subjectType,...Q()}),Response.json({error:"Forbidden"},{status:403})}}}function ai(T,O,N){return new Promise((X)=>{let Q=[],ye=T.length,he=!1,we=()=>{if(ye-=1,ye===0&&!he)he=!0,X({outcomes:Q})};for(let ke of T)O(ke).then((fe)=>{if(Q.push({principal:ke,decision:fe}),!he&&fe.allow){he=!0,X({matched:{principal:ke,decision:fe},outcomes:Q});return}we()},(fe)=>{N?.(ke,fe),Q.push({principal:ke,decision:{allow:!1,metadata:{reason:"error"}}}),we()})})}async function Bt(T,O,N,X,Q,ye,he){t(O,ti);let we=ii(T,ri(N)),fe=(await Promise.all(we.map(async(nt)=>{let Oe=await ni[nt](T,O);if(!Oe?.id)return;let ut=nt==="workload"?Oe.derivedEntitlements:nt==="user"||nt==="customer"?rr(T,nt):void 0;return{subject:Oe,subjectType:nt,subjectId:Oe.id,derivedEntitlements:ut}}))).filter((nt)=>nt!==void 0);if(fe.length===0)return sr(O,void 0,"unauthenticated",void 0,Q);let Be=async(nt)=>{let Oe=O.authz.accessIndex;if(!Oe?.isSubjectDisabled)return!1;return Oe.isSubjectDisabled(nt.subjectId,nt.subjectType)},He=async(nt)=>{if(he){let Oe=he(nt);if(Oe&&Oe.length>0){if(await Be(nt))return{allow:!1,metadata:{reason:"subject_disabled"}};return{allow:!0,metadata:{reason:"trusted-client",matchedPermissions:Oe}}}}if(ye){let Oe=ye(nt);if(Oe&&Oe.length>0){if(await Be(nt))return{allow:!1,metadata:{reason:"subject_disabled"}};return{allow:!0,metadata:{reason:"claims",matchedIds:Oe.map((ut)=>ut.target),matchedClaims:[...new Set(Oe.map((ut)=>ut.claim))],roots:[...new Set(Oe.map((ut)=>ut.root).filter((ut)=>Boolean(ut)))]}}}}return X(nt)},{matched:et,outcomes:dt}=await ai(fe,He,(nt,Oe)=>{O.log.warn("authz.check_error",{"ion.operation":"authz.check","ion.outcome":"error",subject:nt.subjectId,subjectType:nt.subjectType,error:Oe instanceof Error?Oe.message:String(Oe),...Q()})});if(et){if(et.decision.metadata?.reason==="claims")O.log.info("authz.claims_honor",{"ion.operation":"authz.claims_honor","ion.outcome":"allow",subject:et.principal.subjectId,subjectType:et.principal.subjectType,matchedIds:et.decision.metadata.matchedIds,matchedClaims:et.decision.metadata.matchedClaims,roots:et.decision.metadata.roots,...Q()});return sr(O,et.principal,"ok",et.decision,Q)}let ot=dt.length>0&&dt.every((nt)=>{let Oe=nt.decision.metadata?.reason;return Oe==="access_index_not_configured"||Oe==="error"}),$e=dt[0],Ve=ot?"not_configured":"forbidden";return sr(O,$e?.principal,Ve,$e?.decision,Q)}async function ci(T,O,N,X,Q,ye="any"){return Bt(T,O,ye,(he)=>O.authz.has(he.subjectId,N,X,Q,he.subjectType),()=>({targetType:N,target:pt(X),resource:Q?pt(Q):void 0}),gn([{targetType:N,id:pt(X),resource:Q?pt(Q):void 0}],"any"),N==="permission"&&!Q?jn(O,[pt(X)],"any"):void 0)}async function ui(T,O,N,X,Q="any"){return Bt(T,O,Q,(ye)=>O.authz.hasPermission(ye.subjectId,N,X,ye.subjectType),()=>({targetType:"permission",target:pt(N),resource:X?pt(X):void 0}),gn([{targetType:"permission",id:pt(N),resource:X?pt(X):void 0}],"any"),X?void 0:jn(O,[pt(N)],"any"))}async function di(T,O,N,X,Q="any"){return Bt(T,O,Q,(ye)=>O.authz.hasRole(ye.subjectId,N,X,ye.subjectType),()=>({targetType:"role",target:pt(N),resource:X?pt(X):void 0}),gn([{targetType:"role",id:pt(N),resource:X?pt(X):void 0}],"any"))}async function li(T,O,N,X,Q="any"){return Bt(T,O,Q,(ye)=>O.authz.hasGroup(ye.subjectId,N,X,ye.subjectType),()=>({targetType:"group",target:pt(N),resource:X?pt(X):void 0}),gn([{targetType:"group",id:pt(N),resource:X?pt(X):void 0}],"any"))}async function pi(T,O,N,X="any"){let Q=N.map((he)=>({targetType:he.targetType,id:pt(he.target),resource:he.resource?pt(he.resource):void 0})),ye=N.filter((he)=>!he.resource&&he.targetType==="permission").map((he)=>pt(he.target));return Bt(T,O,X,(he)=>O.authz.hasAny(he.subjectId,N,he.subjectType),()=>({targets:N.map((he)=>`${he.targetType}:${pt(he.target)}`)}),Q.length>0?gn(Q,"any"):void 0,ye.length>0?jn(O,ye,"any"):void 0)}async function mi(T,O,N,X="any"){let Q=N.map((we)=>({targetType:we.targetType,id:pt(we.target),resource:we.resource?pt(we.resource):void 0})),ye=N.length>0&&N.every((we)=>!we.resource&&we.targetType==="permission"),he=N.map((we)=>pt(we.target));return Bt(T,O,X,(we)=>O.authz.hasAll(we.subjectId,N,we.subjectType),()=>({targets:N.map((we)=>`${we.targetType}:${pt(we.target)}`)}),Q.length>0?gn(Q,"all"):void 0,ye?jn(O,he,"all"):void 0)}async function fi(T,O,N,X="any"){return Bt(T,O,X,(Q)=>Promise.resolve(ir(Q,[N],"any")),()=>({scope:N}))}async function gi(T,O,N,X="any"){return Bt(T,O,X,(Q)=>Promise.resolve(ir(Q,N,"any")),()=>({scopes:N}))}async function yi(T,O,N,X="any"){return Bt(T,O,X,(Q)=>Promise.resolve(ir(Q,N,"all")),()=>({scopes:N}))}function St(T){return typeof T==="string"&&T.length>0?T:void 0}function Qr(T){let O=St(T.email);return{sub:String(T.sub??""),email:O,name:St(T.name),userName:St(T.preferred_username)??O,avatar:St(T.picture)}}var es={oidc:{flow:"id_token",scope:"openid profile email",branding:{displayName:"Single sign-on"},mapClaims:Qr},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:Qr},microsoft:{flow:"id_token",authority:"https://login.microsoftonline.com/common/v2.0",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 O=St(T.email)??St(T.preferred_username);return{sub:String(T.sub??T.oid??""),email:O,name:St(T.name),userName:St(T.preferred_username)??O,avatar:St(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 O=St(T.email);return{sub:String(T.sub??""),email:O,name:St(T.name),userName:O}}},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:St(T.email),name:St(T.name)??St(T.login),userName:St(T.login),avatar:St(T.avatar_url)})}};function or(T){if(T==="magic-link")return;return es[T]}function Ln(T,O){if(O.type==="magic-link")return;let N=or(O.type);if(!N)return;return{name:T,type:O.type,flow:N.flow,authority:O.authority??N.authority,authorizationUrl:O.authorizationUrl??N.authorizationUrl,tokenUrl:O.tokenUrl??N.tokenUrl,jwksUri:O.jwksUri??N.jwksUri,userInfoUrl:O.userInfoUrl??N.userInfoUrl,scope:O.scope??N.scope,clientId:O.clientId,clientSecret:O.clientSecret,extraAuthParams:N.extraAuthParams,branding:{...N.branding,...O.branding},mapClaims:N.mapClaims,config:O}}function ar(T){return{...or(T.type)?.branding??{displayName:T.type},...T.branding}}function cr(T){if(!T)return[];return Object.entries(T).filter(([,O])=>O.enabled!==!1).map(([O,N],X)=>({name:O,config:N,index:X})).sort((O,N)=>{let X=O.config.order??Number.MAX_SAFE_INTEGER,Q=N.config.order??Number.MAX_SAFE_INTEGER;if(X!==Q)return X-Q;return O.index-N.index}).map(({name:O,config:N})=>({name:O,config:N}))}var hi=/^(?=.{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 O=T.trim().toLowerCase();if(!hi.test(O))throw Error(`Invalid cookiesDomain "${T}": expected a hostname such as "app.example.com" without a scheme, port, path, or leading dot.`);return O}function Qt(T){return T?` Domain=${T};`:""}var ts=4000;function ki(T){return`Expires=${T.toUTCString()}`}function ns(T){return`Path=${T.path};${Qt(T.domain)}${T.secure?" Secure;":""} SameSite=${T.sameSite};`}function lr(T,O,N,X){if(O.length>ts)throw Error(`Display cookie ${T} value is ${O.length} bytes; the limit is ${ts}.`);return`${T}=${O}; ${ki(N)}; ${ns(X)}`}function Gt(T,O){return`${T}=; Max-Age=0; ${ns(O)}`}function ur(T){if(!T)return;let O=T instanceof Date?T:new Date(T);return Number.isNaN(O.getTime())?void 0:O}function dr(T){return!T||T.getTime()>Date.now()}async function Si(T,O,N){let X=T.envelope.kind??"session";if(X==="discovered"){let we=ur(T.envelope.expiresAt);return{...T,kind:X,live:Boolean(we&&dr(we))}}let Q=O[`${T.prefix}.session`];if(!Q)return{...T,kind:X,live:!1};let ye=await N.get(Q);if(!ye||ye.authType!=="sso"&&ye.authType!=="ciam")return{...T,kind:X,live:!1};let he=ur(ye.expiresAt);return{...T,kind:X,live:dr(he),...he?{sessionExpiresAt:he}:{}}}function yn(T,O,N){let X=_(O);return T?.includes(`${X}=`)?[Gt(X,N)]:[]}function rs(T,O,N,X,Q){let ye=[...T.filter((Be)=>Be.kind==="session").slice(0,N),...T.filter((Be)=>Be.kind==="discovered").slice(0,X)],he=Q?Q(T,{max:N,maxDiscovered:X}):ye,we=[...he.filter((Be)=>Be.kind==="session").slice(0,N),...he.filter((Be)=>Be.kind==="discovered").slice(0,X)];if(we.some((Be)=>Be.name===O))return we;let ke=T.find((Be)=>Be.name===O);if(!ke)return we;return[...[ke,...we.filter((Be)=>Be.kind==="session")].slice(0,N),...we.filter((Be)=>Be.kind==="discovered")]}async function An(T){let O=_(T.cookiesPrefix),N=T.attr;if(T.displayCookie?.enabled!==!0)return yn(T.cookieHeader,T.cookiesPrefix,N);if(!T.sessionStore)return[];let X=f(T.user,T.projector),Q={v:V,...T.tenantId?{tenantId:T.tenantId}:{},authType:T.authType,expiresAt:T.expiresAt.toISOString(),user:X},ye={name:O,prefix:T.cookiesPrefix,envelope:Q,kind:"session",sessionExpiresAt:T.expiresAt,live:!0},he=oe(T.cookieHeader),we=T.sessionStore,ke=await Promise.all(G(T.cookieHeader).filter((Ve)=>Ve.name!==O).map((Ve)=>Si(Ve,he,we))),fe=[ye,...ke.filter((Ve)=>Ve.live&&Ve.kind==="session")].sort((Ve,nt)=>U(Ve.sessionExpiresAt?.toISOString()??Ve.envelope.expiresAt,nt.sessionExpiresAt?.toISOString()??nt.envelope.expiresAt)),Be=T.displayCookie.discovered?.enabled===!0?ke.filter((Ve)=>Ve.live&&Ve.kind==="discovered"&&(!T.tenantId||Ve.envelope.tenantId!==T.tenantId)).sort((Ve,nt)=>U(Ve.envelope.expiresAt,nt.envelope.expiresAt)):[],He=[...fe,...Be],et=re(T.displayCookie?.max),dt=z(T.displayCookie.discovered?.max),ot=new Set(rs(He,O,et,dt,T.trim).map((Ve)=>Ve.name)),$e=[lr(O,B(Q),T.expiresAt,N)];for(let Ve of ke)if(!ot.has(Ve.name))$e.push(Gt(Ve.name,N));return $e}function wi(T){let O=oe(T.cookieHeader),N=Object.keys(O).filter(($e)=>$e.startsWith(`${ne}.`)&&$e.endsWith(".profile"));if(!(T.displayCookie?.enabled===!0&&T.displayCookie.discovered?.enabled===!0))return N.map(($e)=>Gt($e,T.attr));let Q=T.now??new Date,ye=se(T.displayCookie?.discovered?.ttlSeconds),he=new Date(Q.getTime()+ye*1000),we=z(T.displayCookie?.discovered?.max),ke=G(T.cookieHeader),fe=new Set(ke.filter(($e)=>($e.envelope.kind??"session")==="session").flatMap(($e)=>$e.envelope.tenantId?[$e.envelope.tenantId]:[])),Be=new Map;for(let $e of ke){if($e.envelope.kind!=="discovered"||!$e.envelope.tenantId)continue;let Ve=ur($e.envelope.expiresAt);if(Ve&&dr(Ve)&&!fe.has($e.envelope.tenantId))Be.set($e.envelope.tenantId,$e.envelope)}let He=f(T.user,T.projector);for(let $e of T.tenants){let Ve=$e.tenantId.trim();if(!Ve||fe.has(Ve))continue;Be.set(Ve,{v:V,kind:"discovered",tenantId:Ve,authType:T.authType,expiresAt:he.toISOString(),user:He,...$e.tenantName?{tenantName:$e.tenantName}:{}})}let et=[...Be.values()].sort(($e,Ve)=>U($e.expiresAt,Ve.expiresAt)).slice(0,we),dt=new Set(et.map(($e)=>F($e.tenantId??""))),ot=et.map(($e)=>lr(F($e.tenantId??""),B($e),new Date($e.expiresAt),T.attr));for(let $e of N)if(!dt.has($e))ot.push(Gt($e,T.attr));return ot}var yr=60000,is=86400000,os=600000,mr=256,Tt=new Map;function bi(T){if(typeof T?.ttlMs==="number"&&Number.isFinite(T.ttlMs))os=Math.min(Math.max(T.ttlMs,yr),is);if(typeof T?.maxEntries==="number"&&Number.isFinite(T.maxEntries)){mr=Math.max(1,Math.floor(T.maxEntries));while(Tt.size>mr){let O=Tt.keys().next().value;if(O===void 0)break;Tt.delete(O)}}}function ss(T,O){Tt.delete(T),Tt.set(T,O);while(Tt.size>mr){let N=Tt.keys().next().value;if(N===void 0)break;Tt.delete(N)}}var In=new Map,fr=()=>Date.now();function Ci(T){fr=T??(()=>Date.now())}var gr={};function vi(T){gr=T??{}}function Ri(T){if(!T)return;if(/\bno-store\b/i.test(T))return yr;let O=/max-age\s*=\s*(\d+)/i.exec(T);if(!O)return;let N=Number(O[1]);return Number.isFinite(N)?N*1000:void 0}function Ai(T){let N=Ri(T)??os;return Math.min(Math.max(N,yr),is)}async function hr(T,O=3,N=1000,X=30000,Q){let ye=Error("Placeholder Error");for(let he=0;he<=O;he++)try{return await T()}catch(we){if(ye=we instanceof Error?we:Error(String(we)),we instanceof Error&&we.message.includes("400"))throw we;if(he===O)throw ye;let ke=Math.min(N*2**he,X),fe=Math.random()*0.1*ke;await new Promise((Be)=>setTimeout(Be,ke+fe)),Q?.warn(`Retry attempt ${he+1} after ${ke+fe}ms delay`)}throw ye}async function Tn(T,O,N){let X=Tt.get(T);if(!N?.forceRefresh&&X&&X.expiresAt>fr())return ss(T,X),X.jwks;let Q=In.get(T);if(Q)return Q;let ye=(async()=>{try{return await hr(async()=>{let he=await fetch(T,{headers:a});if(!he.ok){let fe=await J(he);throw O?.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 we=await c(he,{log:O,operation:"jwks.fetch"}),ke=Ai(he.headers.get("cache-control"));return ss(T,{jwks:we,expiresAt:fr()+ke,importedKeys:new Map}),we},gr.maxRetries,gr.baseDelayMs,void 0,O)}catch(he){let we=Tt.get(T);if(we)return O?.warn("JWKS refresh failed; serving last-known-good keys",{"ion.operation":"jwks.refresh","ion.outcome":"degraded"}),we.jwks;throw he}finally{In.delete(T)}})();return In.set(T,ye),ye}function Ii(T){if(T){Tt.delete(T),In.delete(T);return}Tt.clear(),In.clear()}async function Ti(T,O,N){return(await as(T,O,N)).jwk}async function as(T,O,N){if(!O?.trim())throw Error("JWT header missing kid");await Tn(T,N);let X=Tt.get(T),Q=X?.jwks.keys.find((ye)=>ye.kid===O);if(!Q)await Tn(T,N,{forceRefresh:!0}),X=Tt.get(T),Q=X?.jwks.keys.find((ye)=>ye.kid===O);if(!X||!Q)throw Error("Public key not found");return{jwk:Q,entry:X}}async function kr(T,O,N,X,Q){let{jwk:ye,entry:he}=await as(T,O,Q),we=`${O}\x00${N}`,ke=he.importedKeys.get(we);if(ke)return ke;let fe=X(ye);return fe.catch(()=>{if(he.importedKeys.get(we)===fe)he.importedKeys.delete(we)}),he.importedKeys.set(we,fe),fe}async function xi(T,O){let N=T.keys.find((X)=>X.kid===O);if(!N)throw Error("Public key not found");return cs(N)}function cs(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 Pi(T,O,N){return kr(T,O,"rs256",cs,N)}var pr={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 Sr(T,O,N,X){if(typeof N!=="string"||!(N in pr))throw Error(`Unsupported JWT alg "${String(N)}" (allowed: ${Object.keys(pr).join(", ")})`);let Q=pr[N];return{key:await kr(T,O,`oidc:${N}`,(he)=>{if(he.kty!==Q.kty)throw Error(`JWK type "${he.kty}" does not match token alg "${N}"`);if(Q.kty==="EC"){let we=he;if(we.crv!==Q.crv)throw Error(`JWK curve "${String(we.crv)}" does not match token alg "${N}"`);return crypto.subtle.importKey("jwk",{kty:"EC",crv:we.crv,x:we.x,y:we.y},Q.importParams,!1,["verify"])}return crypto.subtle.importKey("jwk",{kty:he.kty,n:he.n,e:he.e},Q.importParams,!1,["verify"])},X),algorithm:Q.verifyParams}}function jt(T=32){let O=new Uint8Array(T);return crypto.getRandomValues(O),Array.from(O,(N)=>N.toString(16).padStart(2,"0")).join("").substring(0,T)}function $n(T){let O="";return T.forEach((N)=>{O+=String.fromCharCode(N)}),btoa(O).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function ls(T){let O=T.replace(/-/g,"+").replace(/_/g,"/"),N=O.padEnd(O.length+(4-O.length%4)%4,"="),X=atob(N),Q=new Uint8Array(X.length);for(let ye=0;ye<X.length;ye++)Q[ye]=X.charCodeAt(ye);return Q}function us(T){let O=new TextDecoder().decode(ls(T));return JSON.parse(O)}async function Pn(T){let O=new TextEncoder().encode(T),N=await crypto.subtle.digest("SHA-256",O);return $n(new Uint8Array(N))}function Cr(T){let O=new URL(T.authorizationUrl);if(O.searchParams.set("client_id",T.clientId),O.searchParams.set("redirect_uri",T.redirectUri),O.searchParams.set("response_type","code"),O.searchParams.set("scope",T.scope),O.searchParams.set("state",T.state),T.codeChallenge)O.searchParams.set("code_challenge",T.codeChallenge),O.searchParams.set("code_challenge_method","S256");if(T.nonce)O.searchParams.set("nonce",T.nonce);for(let[N,X]of Object.entries(T.extraParams??{}))O.searchParams.set(N,X);return O.toString()}async function vr(T){let O=new URLSearchParams;if(O.append("grant_type","authorization_code"),O.append("code",T.code),O.append("redirect_uri",T.redirectUri),O.append("client_id",T.clientId),T.clientSecret)O.append("client_secret",T.clientSecret);if(T.codeVerifier)O.append("code_verifier",T.codeVerifier);let N=await fetch(T.tokenUrl,{method:"POST",headers:{...S,...a},body:O.toString()}),X=await c(N,{log:T.log,operation:"oidc.token.exchange"});if(!N.ok){let Q=X,ye=Q.error==="invalid_client"&&!T.clientSecret;throw T.log?.error(ye?"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:Q.error,...ye?{client_auth:"none"}:{}}),Error(`Token exchange failed: ${Q.error||N.statusText} - ${Q.error_description||""}`.trim())}if(typeof X.access_token!=="string")throw Error("Token exchange response missing access_token");return X}var ps=60;function on(T){return T.trim().replace(/\/$/,"")}var wr="9188040d-6c67-4c5b-b112-36a304b66dad",Ui=new Set(["common","organizations","consumers"]),Ei=/^https:\/\/login\.microsoftonline\.com\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\/v2\.0$/i;function Rr(T){let O=/^https:\/\/login\.microsoftonline\.com\/([^/]+)(?:\/v2\.0)?$/i.exec(on(T));return O?Ui.has(O[1].toLowerCase()):!1}function Wn(T){let O=Ei.exec(on(T));return O?O[1].toLowerCase():void 0}function ms(T){let O=Wn(T.iss);if(!O)return!1;if(T.tid!==void 0){if(typeof T.tid!=="string"||T.tid.toLowerCase()!==O)return!1}let N=T.allowedTenants??"any";if(N==="any")return!0;if(N==="consumers")return O===wr;if(!Array.isArray(N)||N.length===0)return!1;return N.some((X)=>{let Q=X.trim().toLowerCase();if(Q==="consumers")return O===wr;return Q===O})}function fs(T){let{claims:O,audience:N}=T,X=on(T.issuer),Q=T.nowSec??Math.floor(Date.now()/1000),ye=T.clockSkewSec??ps,he=O.iss;if(typeof he!=="string")throw Error("ID token issuer mismatch");let we=T.issuerPolicy??{mode:"exact"};if(!(on(he)===X||we.mode==="microsoft-tenant"&&ms({iss:he,tid:O.tid,allowedTenants:we.allowedTenants})))throw Error("ID token issuer mismatch");let fe=O.aud,Be=Array.isArray(fe)?fe.includes(N):typeof fe==="string"&&fe===N,He=typeof O.azp==="string"&&O.azp===N;if(!Be&&!He)throw Error("ID token audience mismatch");if(typeof O.exp!=="number")throw Error("ID token missing exp");if(O.exp<Q-ye)throw Error("ID token expired");if(T.expectedNonce!==void 0){if(O.nonce!==T.expectedNonce)throw Error("ID token nonce mismatch")}}async function gs(T,O,N){let X=T.split(".");if(X.length!==3)throw Error("Invalid JWT");let Q=us(X[0]),ye=us(X[1]),he=ls(X[2]),{key:we,algorithm:ke}=await Sr(O,Q.kid,Q.alg,N),fe=new TextEncoder().encode(`${X[0]}.${X[1]}`);if(!await crypto.subtle.verify(ke,we,he,fe))throw Error("Invalid JWT signature");return{header:Q,payload:ye}}async function en(T){let{payload:O}=await gs(T.idToken,T.jwksUri,T.log);return fs({claims:O,issuer:T.issuer,issuerPolicy:T.issuerPolicy,audience:T.audience,clockSkewSec:T.clockSkewSec,expectedNonce:T.expectedNonce}),O}var Di="http://schemas.openid.net/event/backchannel-logout";async function Ar(T){let{payload:O}=await gs(T.logoutToken,T.jwksUri,T.log),N=on(T.issuer),X=O.iss;if(typeof X!=="string"||on(X)!==N)throw Error("Logout token issuer mismatch");let Q=O.aud,ye=Array.isArray(Q)?Q.includes(T.audience):typeof Q==="string"&&Q===T.audience,he=typeof O.azp==="string"&&O.azp===T.audience;if(!ye&&!he)throw Error("Logout token audience mismatch");if(O.nonce!=null)throw Error("Logout token must not contain a nonce");let we=O.events;if(!(typeof we==="object"&&we!==null&&!Array.isArray(we)&&Object.hasOwn(we,Di)))throw Error("Logout token missing back-channel logout event");let fe=typeof O.sid==="string"&&O.sid.length>0,Be=typeof O.sub==="string"&&O.sub.length>0;if(!fe&&!Be)throw Error("Logout token missing sid and sub");if(typeof O.exp==="number"){let He=Math.floor(Date.now()/1000),et=T.clockSkewSec??ps;if(O.exp<He-et)throw Error("Logout token expired")}return O}var Mi=3600000,Oi=60000,_i=86400000,ji=256,Kt=new Map,xn=new Map;function ds(T,O){Kt.delete(T),Kt.set(T,O);while(Kt.size>ji){let N=Kt.keys().next().value;if(N===void 0)break;Kt.delete(N)}}var br=()=>Date.now();function Li(T){br=T??(()=>Date.now())}function Ni(T){if(T){Kt.delete(T),xn.delete(T);return}Kt.clear(),xn.clear()}function $i(T){let O=T?/max-age\s*=\s*(\d+)/i.exec(T):null,N=O?Number(O[1]):Number.NaN,X=Number.isFinite(N)?N*1000:Mi;return Math.min(Math.max(X,Oi),_i)}async function Vn(T){let O=Kt.get(T);if(O&&O.expiresAt>br())return ds(T,O),O.endpoints;let N=xn.get(T);if(N)return N;let X=(async()=>{try{let Q=T.replace(/\/$/,""),ye=await fetch(`${Q}/.well-known/openid-configuration`,{headers:a});if(!ye.ok)throw Error(`OIDC discovery failed for ${T} with status ${ye.status}`);let he=await c(ye),we={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 ds(T,{endpoints:we,expiresAt:br()+$i(ye.headers.get("cache-control"))}),we}catch(Q){let ye=Kt.get(T);if(ye)return ye.endpoints;throw Q}finally{xn.delete(T)}})();return xn.set(T,X),X}async function Ir(T,O){let N=await fetch(T,{headers:{Authorization:`Bearer ${O}`,...a,"User-Agent":"ionite-ciam"}});if(!N.ok)throw Error(`UserInfo request failed with status ${N.status}`);return await c(N)}function Wi(T){let O=T.replace(/-----BEGIN [^-]+-----/g,"").replace(/-----END [^-]+-----/g,"").replace(/\s+/g,""),N=atob(O),X=new Uint8Array(N.length);for(let Q=0;Q<N.length;Q++)X[Q]=N.charCodeAt(Q);return X}async function Tr(T){let O=Math.floor(Date.now()/1000),N={alg:"ES256",kid:T.keyId,typ:"JWT"},X={iss:T.teamId,iat:O,exp:O+(T.expiresInSeconds??3600),aud:"https://appleid.apple.com",sub:T.clientId},Q=$n(new TextEncoder().encode(JSON.stringify(N))),ye=$n(new TextEncoder().encode(JSON.stringify(X))),he=`${Q}.${ye}`,we=await crypto.subtle.importKey("pkcs8",Wi(T.privateKey),{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),ke=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},we,new TextEncoder().encode(he));return`${he}.${$n(new Uint8Array(ke))}`}function Vi(T){for(let O=0;O<T.length;O++){let N=T.charCodeAt(O);if(N<=31||N===127)return!0}return!1}function qi(T,O){let N=null;try{N=new URL(T,O)}catch{N=null}let X="";try{X=new URL(O).origin}catch{X=""}return{candidate:T,url:N,requestOrigin:X}}function ys(T,O,N){let X=qi(T,N),Q=!1;for(let ye of O){let he=ye(X);if(he==="deny")return!1;if(he==="allow")Q=!0}return Q}function hs(){return({candidate:T,url:O})=>{if(Vi(T))return"deny";if(T.includes("\\"))return"deny";if(T.startsWith("//"))return"deny";if(!O)return"deny";if(O.protocol!=="http:"&&O.protocol!=="https:")return"deny";if(O.username||O.password)return"deny";return"abstain"}}function ks(){return({candidate:T})=>T.startsWith("/")&&!T.startsWith("//")&&!T.startsWith("/\\")?"allow":"abstain"}function Ss(){return({url:T,requestOrigin:O})=>T&&O&&T.origin===O?"allow":"abstain"}function zi(...T){let O=new Set(T.map((N)=>{try{return new URL(N).origin}catch{return N}}));return({url:N})=>N&&O.has(N.origin)?"allow":"abstain"}function Bi(...T){let O=T.map((N)=>N.toLowerCase());return({url:N})=>{if(!N)return"abstain";let X=N.hostname.toLowerCase();for(let Q of O)if(Q.startsWith(".")){if(X===Q.slice(1)||X.endsWith(Q))return"allow"}else if(X===Q)return"allow";return"abstain"}}function xr(){return[hs(),ks(),Ss()]}function ws(T,O,N){if(!T)return!1;return ys(T,O,N)}function Pr(T,O){if(!T)return O.fallback;return ys(T,O.rules,O.requestUrl)?T:O.fallback}var Gi={rules:xr(),fallback:"/"};function Ki(T,O,N="redirect"){let X=new URL(T.url).searchParams.get(N)??void 0;return ws(X,O.rules,T.url)?{redirect:X}:void 0}function Ji(T,O){let N=T.context;return Pr(N?.redirect,{rules:O.rules,fallback:O.fallback,requestUrl:T.request.url})}function tn(T,O,N){if(T instanceof Response)return{response:T};if(typeof T==="string")return{location:Pr(T,{rules:xr(),fallback:O,requestUrl:N})};return{location:O}}function an(T,O){if(O.length===0)return T;let N=new Headers(T.headers);for(let X of O)N.append("Set-Cookie",X);return new Response(T.body,{status:T.status,statusText:T.statusText,headers:N})}var qn="ciam",Hi="id_token",Fi="access_token";function Yi(T,O,N,X,Q,ye){if(!N&&!X)return;let he=new WeakMap,we={...N,...X},ke={...we,magicLinkTtl:we.magicLinkTtl??3600,sessionTtl:we.sessionTtl??86400,cookiesSecure:we.cookiesSecure!==void 0?we.cookiesSecure:!0,cookiesSameSite:we.cookiesSameSite!==void 0?we.cookiesSameSite:"Strict",cookiesPrefix:we.cookiesPrefix??(we.ciamId?`ion.ciam.${we.ciamId}`:"ion.ciam"),cookiesPath:we.cookiesPath??"/",cookiesDomain:Nn(we.cookiesDomain)};function fe(){if(!ke.sessionStore)throw Error("Missing CIAM configuration field: sessionStore. CIAM sessionStore is required for server-side session tracking and first-party logout.");return ke.sessionStore}function Be(){fe()}let He=T.callbackParams??p(ae("ionite.ciam")),et=T.idTokenClaims??p(h("ionite.ciam")),dt=T.tokenResponse??p(ce("ionite.ciam"));function ot(ge=32){let be=new Uint8Array(ge);return crypto.getRandomValues(be),Array.from(be,(xe)=>xe.toString(16).padStart(2,"0")).join("").substring(0,ge)}function $e(ge,be,xe,Ie=ke.cookiesSameSite??"Strict"){if(!ke)throw Error("ionite CIAM Manager not initialized");if(ge=`${ke.cookiesPrefix}.${ge}`,typeof be!=="string")be=btoa(JSON.stringify(be));let Pe;if(xe instanceof Date)Pe=`Expires=${xe.toUTCString()}`;else if(typeof xe==="number")Pe=`Max-Age=${xe}`;else throw Error("Invalid expires type",xe);if(be.length>4000)throw Error(`Error setting cookie: ${ge}. Cookie length is: ${be.length}`);return`${ge}=${be}; ${Pe}; Path=${ke.cookiesPath};${Qt(ke.cookiesDomain)} HttpOnly;${ke.cookiesSecure?" Secure;":""} SameSite=${Ie};`}function Ve(ge){if(!ke)throw Error("ionite CIAM Manager not initialized");return`${ke.cookiesPrefix}.${ge}=; Max-Age=0; Path=${ke.cookiesPath};${Qt(ke.cookiesDomain)} HttpOnly;${ke.cookiesSecure?" Secure;":""} SameSite=${ke.cookiesSameSite};`}function nt(ge,be,xe=!1){if(!ke)throw Error("ionite CIAM Manager not initialized");let Ie=be.headers.get("cookie");if(!Ie)return null;let Pe=`${ke.cookiesPrefix}.${ge}`,ze=Ie.split(";").find((Se)=>Se.trim().startsWith(`${Pe}=`));if(!ze)return null;let We=ze.indexOf("="),Re=ze.substring(We+1).trim();if(!xe)return Re;try{let Se=atob(Re);return JSON.parse(Se)}catch(Se){return O.error("[CIAM] Failed to parse cookie",{"ion.operation":"cookie.parse","ion.outcome":"failure",cookieName:Pe},Se),null}}function Oe(ge){return`cstate_${ge}`}async function ut(ge,be,xe,Ie){let Pe=await ke.afterLogin?.({...be,request:ge,context:xe,displayCookie:ke.displayCookie,displayCookieAttributes:Ct()}),ze=tn(Pe,"/",ge.url);if(ze.response)return an(ze.response,Ie.map(([,We])=>We));return new Response(be.ok?"Authentication successful, redirecting":"Authentication failed, redirecting",{status:302,headers:[["Location",ze.location],...Ie]})}function gt(ge,be){return["Set-Cookie",$e("session",ge,be)]}function Ct(){return{path:ke.cookiesPath??"/",domain:ke.cookiesDomain,secure:ke.cookiesSecure!==!1,sameSite:ke.cookiesSameSite??"Strict"}}function yt(){return[["Set-Cookie",Ve("session")],["Set-Cookie",Gt(`${ke.cookiesPrefix}.profile`,Ct())]]}function At(ge){if(ke.displayCookie?.enabled===!0)return[];return yn(ge.headers.get("cookie"),ke.cookiesPrefix??"ion.ciam",Ct()).map((be)=>["Set-Cookie",be])}async function xt(ge,be,xe){return(await An({cookieHeader:ge.headers.get("cookie"),sessionStore:ke.sessionStore,cookiesPrefix:ke.cookiesPrefix??"ion.ciam",authType:"ciam",tenantId:ke.tenantId,expiresAt:xe,user:be,projector:ke.displayUser,displayCookie:ke.displayCookie,trim:ke.trimDisplayCookies,attr:Ct()})).map((Pe)=>["Set-Cookie",Pe])}function _t(ge){if(!ge)return;if(ge instanceof Date)return ge;let be=new Date(ge);return Number.isNaN(be.getTime())?void 0:be}async function wn(ge){let be=nt("session",ge);if(!be)return;let xe=await fe().get(be);if(xe&&ke.tenantId&&xe.tenantId&&xe.tenantId!==ke.tenantId)return;if(xe?.authType!=="ciam")return;let Ie=_t(xe.expiresAt);if(Ie&&Date.now()>Ie.getTime()){await fe().delete(be);return}return xe}async function Ht(ge){if(!ke)throw Error("ionite CIAM Manager not initialized");Be();let be=he.get(ge);if(be)return be;let xe=bn(ge);return he.set(ge,xe),xe}async function bn(ge){try{let be=await wn(ge);if(!be?.claims?.sub)return{status:"unauthenticated"};return Rn(ge,"customer",be.entitlements),{status:"authenticated",value:Pt(be.claims)}}catch(be){return O.error("CIAM session resolution failed",{"ion.operation":"ciam.session","ion.outcome":"degraded"},be),{status:"degraded",error:be instanceof Error?be:void 0}}}async function ln(ge){let be=await Ht(ge);return be.status==="authenticated"?be.value:void 0}async function Ft(ge){if(!ke)throw Error("ionite CIAM Manager not initialized");Be();let be;try{be=await ln(ge)}catch{be=void 0}let xe=await ke.beforeLogout?.({request:ge,user:be});try{let ve=nt("session",ge);if(ve)await fe().delete(ve)}catch(ve){O.warn("Failed to delete CIAM session",{"ion.operation":"session.delete","ion.outcome":"degraded"},ve)}let Ie=yt(),Pe=await ke.afterLogout?.({request:ge,context:xe}),ze=tn(Pe,"/",ge.url);if(ze.response)return an(ze.response,Ie.map(([,ve])=>ve));let We=ze.location??"/",Re=ge.headers.get("accept");if(Re?.includes(o)||Re?.includes("text/javascript"))return new Response(JSON.stringify({success:!0,message:"Logged out",redirect:We}),{status:200,headers:[["Content-Type",o],...Ie]});return new Response("Logged out",{status:302,headers:[["Location",We],...Ie]})}function Yt(ge){return ge.id||ge.email||`ciam-${ge.userName}`}function sn(ge,be,xe){return{sub:Yt(ge),iss:qn,aud:qn,typ:Hi,exp:Math.floor(xe.getTime()/1000),iat:Math.floor(Date.now()/1000),email:ge.email,name:ge.name,preferred_username:ge.userName,picture:ge.avatar,sid:be}}function pn(ge,be,xe){return{sub:ge,iss:qn,aud:qn,typ:Fi,exp:Math.floor(xe.getTime()/1000),iat:Math.floor(Date.now()/1000),sid:be,scope:"openid profile email"}}function Pt(ge){let be=ge.exp?new Date(ge.exp*1000):new Date;return{id:ge.sub,userName:ge.preferred_username??"",name:ge.name??"",email:ge.email??"",avatar:ge.picture,userType:"customer",ciam:{profile:ge,scope:"openid profile email",tokenType:"Bearer",expires:be}}}async function mn(ge){if(!ke)throw Error("ionite CIAM Manager not initialized");if(!Q)return new Response(JSON.stringify({error:"Workload authentication required"}),{status:401,headers:s});if(!await Q.getWorkloadIdentity(ge))return new Response(JSON.stringify({error:"Unauthorized: Valid workload token required"}),{status:401,headers:s});let xe,Ie;try{if(!ge.headers.get("content-type")?.includes(o))return new Response(JSON.stringify({error:"Content-Type must be application/json"}),{status:400,headers:s});let je=await ge.text(),Ee=JSON.parse(je);Ie=typeof Ee?.redirect==="string"&&Ee.redirect.length>0?Ee.redirect:void 0;let Le={userName:Ee.userName,name:Ee.name,email:Ee.email,avatar:Ee.avatar},Ye=await T.customer.validate(Le);if(Ye.issues)return new Response(JSON.stringify({error:"Missing required fields: userName, name, email"}),{status:400,headers:s});xe=Ye.value}catch(De){return new Response(JSON.stringify({error:"Invalid JSON in request body"}),{status:400,headers:s})}let ze=new URL(ge.url).searchParams.get("ttl"),We=ze?parseInt(ze,10):ke.magicLinkTtl??3600;if(Number.isNaN(We)||We<=0)return new Response(JSON.stringify({error:"Invalid TTL parameter"}),{status:400,headers:s});let Re=ot(32),Se=new Date(Date.now()+We*1000);if(!ke.magicLinkStore)return new Response(JSON.stringify({error:"Magic link store not configured"}),{status:501,headers:s});try{await ke.magicLinkStore.create(Re,xe,Se)}catch(De){return O.error("Error creating magic link",{"ion.operation":"magic_link.create","ion.outcome":"failure"},De),new Response(JSON.stringify({error:"Failed to create magic link"}),{status:500,headers:s})}let ve=new URL(ge.url),Te=ke.magicLinkLoginUrl||"/magic-link/login",Ae=new URL(Te,ve.origin);if(Ae.searchParams.set("token",Re),Ie)Ae.searchParams.set("redirect",Ie);return new Response(JSON.stringify({magicLink:Ae.toString(),expiresAt:Se.toISOString()}),{status:200,headers:s})}async function Xt(ge){if(!ke)throw Error("ionite CIAM Manager not initialized");Be();let xe=new URL(ge.url).searchParams.get("token");if(!xe)return ut(ge,{ok:!1,error:Error("Missing magic-link token")},void 0,[]);if(!ke.magicLinkStore)return ut(ge,{ok:!1,error:Error("Magic link store not configured")},void 0,[]);let Ie=await ke.magicLinkStore.getAndDelete(xe);if(!Ie)return ut(ge,{ok:!1,error:Error("Magic link invalid, expired, or already used")},void 0,[]);let Pe=new Date(Date.now()+(ke.sessionTtl??86400)*1000),ze=ot(32),We=Yt(Ie.customer),Re=sn(Ie.customer,ze,Pe),Se=pn(We,ze,Pe),ve=Pt(Re),Te;try{let De={sid:ze,sub:We,authType:"ciam",tenantId:ke.tenantId,expiresAt:Pe,claims:Re,accessClaims:Se,createdAt:new Date};await fe().create(De),Te=De}catch(De){throw O.warn("Failed to create session",{"ion.operation":"session.create","ion.outcome":"degraded"},De),De}if(ke.customerStore)try{let De=ve.id;if(De){let je=new Date,Ee=await ke.customerStore.get(De);if(Ee||ke.enableJitUserProvisioning){let Le={...Ee??{},...ve,id:De,tenantId:Ee?.tenantId,createdAt:Ee?.createdAt??je,updatedAt:je,userType:Ee?.userType??"customer"};await ke.customerStore.upsert(Le)}}}catch(De){O.warn("Failed to store customer",{"ion.operation":"customer.store","ion.outcome":"degraded"},De)}let Ae=[gt(ze,Pe),...await xt(ge,ve,Pe)];return ut(ge,{ok:!0,user:ve,session:Te},void 0,Ae)}function Ut(ge,be=200,xe=[]){return new Response(JSON.stringify(ge),{status:be,headers:[["Content-Type",o],...xe]})}function It(ge,be){try{return new URL(ge).toString()}catch{let xe=new URL(be).origin,Ie=ke.cookiesSecure?xe.replace(/^http:\/\//,"https://"):xe;return new URL(ge,Ie).toString()}}function Wt(){let ge=ke.customerLoginUrl||"/auth/customer/login",be=ge.includes("?")?"&":"?";return cr(ke.providers).map(({name:xe,config:Ie})=>{let Pe=ar(Ie);return{name:xe,type:Ie.type,displayName:Pe.displayName,loginUrl:`${ge}${be}provider=${encodeURIComponent(xe)}`,iconUrl:Pe.iconUrl,colors:Pe.colors,url:Pe.url}})}async function Vt(ge){if(!ge)return{};let{authorizationUrl:be,tokenUrl:xe,jwksUri:Ie,userInfoUrl:Pe}=ge,ze=ge.authority;if(ze&&(!be||!xe||ge.flow==="id_token"&&!Ie))try{let Re=await Vn(ze);be=be??Re.authorizationUrl,xe=xe??Re.tokenUrl,Ie=Ie??Re.jwksUri,Pe=Pe??Re.userInfoUrl}catch(Re){O.error("CIAM provider OIDC discovery failed",{"ion.operation":"ciam.oidc.discovery","ion.outcome":"failure"},Re)}return{authorizationUrl:be,tokenUrl:xe,jwksUri:Ie,userInfoUrl:Pe}}function Zt(ge,be){if(ge.type!=="microsoft"||!Rr(be))return{mode:"exact"};return{mode:"microsoft-tenant",allowedTenants:ge.config.allowedTenants??"any"}}async function Et(ge,be){let xe=fn(ge),Ie=typeof xe?.iss==="string"?xe.iss:void 0,Pe=Ie?Wn(Ie):void 0;if(!Pe)return be;try{let ze=await Vn(`https://login.microsoftonline.com/${Pe}/v2.0`);if(ze.jwksUri)return ze.jwksUri}catch(ze){O.warn("CIAM tenant-scoped OIDC discovery failed; falling back to configured JWKS",{"ion.operation":"ciam.oidc.discovery","ion.outcome":"failure"},ze)}return be}async function Ge(ge){if(ge.type==="apple"){let{teamId:be,keyId:xe,privateKey:Ie,clientId:Pe}=ge.config;if(be&&xe&&Ie&&Pe)return Tr({teamId:be,keyId:xe,privateKey:Ie,clientId:Pe})}return ge.clientSecret}async function Ze(ge){fe();let xe=new URL(ge.url).searchParams.get("provider");if(!xe)return Ut({error:"Missing required query parameter: provider"},400);let Ie=ke.providers?.[xe];if(!Ie||Ie.enabled===!1||Ie.type==="magic-link")return Ut({error:`Unknown or disabled CIAM provider: ${xe}`},404);let Pe=Ln(xe,Ie);if(!Pe?.clientId)return Ut({error:`CIAM provider ${xe} is not fully configured`},500);let ze=await Vt(Pe);if(!ze.authorizationUrl)return Ut({error:`CIAM provider ${xe} is missing an authorization endpoint`},500);let We=ke.customerCallbackUrl||"/auth/customer/callback",Re=It(We,ge.url),Se=jt(),ve=jt(64),Te=jt(),Ae=Pe.flow==="id_token",De=Ae?await Pn(ve):void 0,je=await ke.beforeLogin?.({request:ge}),Ee=Cr({authorizationUrl:ze.authorizationUrl,clientId:Pe.clientId,redirectUri:Re,scope:Pe.scope,state:Se,codeChallenge:De,nonce:Te,extraParams:Pe.extraAuthParams}),Le={provider:xe,state:Se,codeVerifier:Ae?ve:void 0,nonce:Te,redirectUri:Re,...je===void 0?{}:{context:je}};return new Response("Redirecting to CIAM provider",{status:302,headers:[["Location",Ee],["Set-Cookie",$e(Oe(Se),Le,ke.loginStateTtl??600,"Lax")]]})}async function Ke(ge){if(ge.method==="POST"){if((ge.headers.get("content-type")??"").includes(M)){let xe=await ge.text();return Object.fromEntries(new URLSearchParams(xe).entries())}}return Object.fromEntries(new URL(ge.url).searchParams.entries())}let Qe=!1;async function Fe(ge,be,xe,Ie){let Pe=ge.config.claimsAsEntitlements;if(!Pe?.claims?.length||ge.type==="magic-link")return;if(ke.sessionStore?.capabilities?.derivedEntitlements!==!0){if(!Qe)Qe=!0,O.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 vn({block:Pe,claims:be,accessClaims:fn(Ie),subjectType:"customer",subjectId:xe,catalog:ye?.catalogView?.(),log:O})}async function Xe(ge,be,xe){let Ie=ge.mapClaims(be);if(!Ie.sub)return{ok:!1};let Pe=`${ge.name}:${Ie.sub}`,ze={id:Pe,userName:Ie.userName||Ie.email||Pe,name:Ie.name||"",email:Ie.email||"",avatar:Ie.avatar,userType:"customer"},We=Pe;if(ke.customerStore){let De=await ke.customerStore.lookup(ze)??await ke.customerStore.get(Pe);if(We=De?.id??Pe,!De&&!ke.enableJitUserProvisioning)return O.warn("CIAM JIT customer provisioning disabled: unknown customer rejected",{"ion.operation":"customer.store","ion.outcome":"skipped"}),{ok:!1};let je=new Date,Ee={...De??{},...ze,id:We,tenantId:De?.tenantId,createdAt:De?.createdAt??je,updatedAt:je,userType:De?.userType??"customer"};await ke.customerStore.upsert(Ee)}let Re=new Date(Date.now()+(ke.sessionTtl??86400)*1000),Se=jt(32),ve={sub:We,iss:ge.name,aud:ge.clientId,exp:Math.floor(Re.getTime()/1000),iat:Math.floor(Date.now()/1000),email:Ie.email,name:Ie.name,preferred_username:Ie.userName??Ie.email,picture:Ie.avatar,sid:Se},Te={sid:Se,sub:We,authType:"ciam",tenantId:ke.tenantId,expiresAt:Re,claims:ve,accessClaims:{sub:We,sid:Se,scope:ge.scope},entitlements:await Fe(ge,be,We,xe),createdAt:new Date},Ae=fe();try{await Ae.create(Te)}catch(De){if(!await Ae.get(Se))throw De;await Ae.update(Se,Te)}return{ok:!0,claims:ve,sid:Se,expires:Re}}async function lt(ge){fe();let be,xe,Ie=(Pe)=>{let ze=be?[["Set-Cookie",Ve(be)]]:[];return ut(ge,{ok:!1,error:Pe},xe,ze)};try{let Pe=await Ke(ge),ze=await He.validate(Pe);if(ze.issues||!ze.value)return Ie(Error("Invalid CIAM callback parameters"));let{code:We,state:Re}=ze.value;if(!Re)return Ie(Error("Missing CIAM callback state"));be=Oe(Re);let Se=nt(be,ge,!0);if(xe=Se?.context,!Se?.provider||!Se.state||Se.state!==Re)return O.warn("CIAM callback state verification failed",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),Ie(Error("CIAM callback state verification failed"));let ve=ke.providers?.[Se.provider];if(!ve)return Ie(Error("Unknown CIAM provider"));let Te=Ln(Se.provider,ve);if(!Te?.clientId)return Ie(Error("CIAM provider not configured"));let Ae=await Vt(Te);if(!Ae.tokenUrl)return Ie(Error("CIAM provider missing token endpoint"));let De=await Ge(Te),je=await vr({tokenUrl:Ae.tokenUrl,clientId:Te.clientId,clientSecret:De,redirectUri:Se.redirectUri||It(ke.customerCallbackUrl||"/auth/customer/callback",ge.url),code:We,codeVerifier:Te.flow==="id_token"?Se.codeVerifier:void 0,log:O}),Ee;if(Te.flow==="id_token"){let ct=Te.authority;if(!je.id_token||!Ae.jwksUri||!ct)return Ie(Error("CIAM id_token flow misconfigured"));if(!Se.nonce)return Ie(Error("CIAM callback state cookie missing nonce"));if((await dt.validate(je)).issues)return O.warn("CIAM token response validation failed",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),Ie(Error("CIAM token response validation failed"));let at=Zt(Te,ct),tt=at.mode==="microsoft-tenant"?await Et(je.id_token,Ae.jwksUri):Ae.jwksUri;Ee=await en({idToken:je.id_token,jwksUri:tt,issuer:ct,issuerPolicy:at,audience:Te.clientId,expectedNonce:Se.nonce,log:O});let ft=await et.validate(Ee);if(!ft.issues)Ee=ft.value}else{if(!Ae.userInfoUrl)return Ie(Error("CIAM provider missing userinfo endpoint"));Ee=await Ir(Ae.userInfoUrl,je.access_token);let ct=Te.authority;if(je.id_token&&Ae.jwksUri&&ct){let mt=Zt(Te,ct),at=mt.mode==="microsoft-tenant"?await Et(je.id_token,Ae.jwksUri):Ae.jwksUri,tt=await en({idToken:je.id_token,jwksUri:at,issuer:ct,issuerPolicy:mt,audience:Te.clientId,expectedNonce:Se.nonce||void 0,log:O}),ft=typeof tt.sub==="string"?tt.sub:"";if(ft){if(typeof Ee.sub==="string"&&Ee.sub.length>0&&Ee.sub!==ft)return O.warn("CIAM UserInfo sub does not match verified id_token sub",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),Ie(Error("CIAM UserInfo sub mismatch"));Ee.sub=ft}}if(typeof Ee.sub!=="string"||Ee.sub.length===0)return O.warn("CIAM UserInfo response missing sub",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),Ie(Error("CIAM UserInfo response missing sub"))}let Le=await Xe(Te,Ee,je.access_token);if(!Le.ok)return Ie(Error("Failed to persist CIAM customer"));let Ye=Pt(Le.claims);O.info("CIAM third-party sign-in succeeded",{"ion.operation":"ciam.oidc.callback","ion.outcome":"success",provider:Te.name});let st=[["Set-Cookie",Ve(be)],gt(Le.sid,Le.expires),...await xt(ge,Ye,Le.expires)];return ut(ge,{ok:!0,user:Ye,session:void 0},xe,st)}catch(Pe){return O.error("Error during CIAM third-party sign-in callback",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"},Pe),Ie(Pe)}}async function Ce(ge){if(!ke)throw Error("ionite CIAM Manager not initialized");Be();let be=ke.magicLinkUrl||"/magic-link",xe=ke.magicLinkLoginUrl||"/magic-link/login",Ie=ke.logoutUrl||"/auth/customer/logout",Pe=ke.customerLoginUrl||"/auth/customer/login",ze=ke.customerCallbackUrl||"/auth/customer/callback",We=ke.customerProvidersUrl||"/auth/customer/providers",Re=new URL(ge.url).pathname,Se=(Le)=>{if(!Le)return;try{return new URL(Le).pathname}catch{return Le.startsWith("/")?Le:`/${Le}`}};if(Se(be)===Re&&ge.method==="POST")return mn(ge);if(Se(xe)===Re&&ge.method==="GET")return Xt(ge);if(Se(Ie)===Re&&ge.method==="GET")return Ft(ge);if(Se(We)===Re&&ge.method==="GET")return Ut({providers:Wt()});if(Se(Pe)===Re&&ge.method==="GET")return Ze(ge);if(Se(ze)===Re&&(ge.method==="GET"||ge.method==="POST"))return lt(ge);return new Response("Not Found",{status:404})}async function Ue(ge){if((ke.userEndpoint??"full")==="off")return new Response("Not Found",{status:404,headers:At(ge)});let be=await Ht(ge);if(be.status==="degraded")return new Response(JSON.stringify({error:"auth_unavailable"}),{status:503,headers:s});if(be.status==="unauthenticated")return new Response(JSON.stringify({error:"Unauthorized"}),{status:401,headers:s});let xe=_t(be.value.ciam?.expires),Ie=ke.displayCookie?.enabled===!0?xe&&!nt("profile",ge)?await xt(ge,be.value,xe):[]:At(ge),Pe=ke.userEndpoint==="display"?f(be.value,ke.displayUser):be.value;return new Response(JSON.stringify(Pe),{headers:[["Content-Type",o],...Ie]})}let _e;return _e={...ke,describe:()=>({module:"ciam",active:!0,ready:_e.isReady?.()??!0,magicLinkTtl:ke.magicLinkTtl,loginStateTtl:ke.loginStateTtl,sessionTtl:ke.sessionTtl,cookies:{prefix:ke.cookiesPrefix,path:ke.cookiesPath,secure:ke.cookiesSecure,sameSite:ke.cookiesSameSite,domain:ke.cookiesDomain},displayCookie:ke.displayCookie,jit:{enabled:ke.enableJitUserProvisioning===!0,customerStore:ke.customerStore!==void 0},sessionStore:ke.sessionStore!==void 0,magicLinkStore:ke.magicLinkStore!==void 0,providers:Object.entries(ke.providers??{}).map(([ge,be])=>({name:ge,type:be.type,enabled:be.enabled!==!1,order:be.order,branding:be.branding,authority:be.authority,authorizationUrl:be.authorizationUrl,tokenUrl:be.tokenUrl,jwksUri:be.jwksUri,userInfoUrl:be.userInfoUrl,clientId:be.clientId,scope:be.scope,...be.claimsAsEntitlements?.claims?.length?{claimsAsEntitlements:{claims:[...be.claimsAsEntitlements.claims],expand:be.claimsAsEntitlements.expand===!0,resources:be.claimsAsEntitlements.expand===!0&&be.claimsAsEntitlements.resources===!0,capable:ke.sessionStore?.capabilities?.derivedEntitlements===!0}}:{},loginUrl:`${ke.customerLoginUrl??""}?provider=${encodeURIComponent(ge)}`})),urls:{magicLinkUrl:ke.magicLinkUrl??"",magicLinkLoginUrl:ke.magicLinkLoginUrl??"",customerUrl:ke.customerUrl??"",customerLoginUrl:ke.customerLoginUrl??"",customerCallbackUrl:ke.customerCallbackUrl??"",customerProvidersUrl:ke.customerProvidersUrl??"",logoutUrl:ke.logoutUrl??""}}),getCustomer:ln,resolveCustomer:Ht,logout:Ft,handler:Ce,customerHandler:Ue,listCustomerProviders:Wt},_e}async function Xi(T,O){return t(O,"Ionite instance is required. Create one with ionite(source, config) and pass it to this function."),O.ciam?.getCustomer(T)}async function zn(T,O){return t(O,"Ionite instance is required. Create one with ionite(source, config) and pass it to this function."),await O.ciam?.resolveCustomer(T)??{status:"unauthenticated"}}var Zi="urn:ietf:params:scim:schemas:core:2.0:User",bs="urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",Qi="urn:ietf:params:scim:schemas:core:2.0:Group";function Ur(T,O,N){let Q=(O==="group"?T.resources:void 0)?.map((ye)=>typeof ye==="string"?ye:ye.id).filter(Boolean);return{schemas:[Qi,e],id:T.id,externalId:T.providerId,displayName:T.displayName??T.name,members:N,[e]:{type:O,requestable:T.requestable,riskLevel:T.riskLevel??g,providerId:T.providerId,requestUrl:T.requestUrl,source:T.source,deprecated:T.deprecated,description:T.description,resources:Q&&Q.length>0?Q:void 0,assignableSubjectTypes:T.assignableSubjectTypes,recommendedSubjectTypes:T.recommendedSubjectTypes,attributes:i(T,l)}}}function eo(T){if(T.scimName)return T.scimName;if(!T.name)return;let[O,...N]=T.name.split(" ");return{givenName:O,familyName:N.join(" ")||void 0}}function to(T){let O={attributes:i(T,I)};if(T.ecid!==void 0)O.ecid=T.ecid;if(T.accountClass!==void 0)O.accountClass=T.accountClass;return O.ecid!==void 0||O.accountClass!==void 0||O.attributes!==void 0?O:void 0}function no(T){return Object.keys(T.scimSchemaExtensions??{}).filter((O)=>O.startsWith("urn:")&&T.scimSchemaExtensions?.[O]!==void 0)}function Er(T){let O=T.userName||T.email||T.id||"",N=T.emails??(T.email?[{value:T.email,primary:!0}]:[]),X=new Set([Zi]);if(T.scimEnterprise!==void 0)X.add(bs);let Q=to(T);if(Q!==void 0)X.add(d);for(let he of no(T))X.add(he);let ye={};if(T.scimEnterprise!==void 0)ye[bs]=T.scimEnterprise;if(Q!==void 0)ye[d]=Q;for(let[he,we]of Object.entries(T.scimSchemaExtensions??{}))if(he.startsWith("urn:")&&he!==d&&we!==void 0)ye[he]=we;return{schemas:Array.from(X),id:T.id,externalId:T.externalId,userName:O,displayName:T.displayName??T.name??O,name:eo(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:N,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()},...ye}}function Dr(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:i(T,x),meta:{resourceType:"Workload",created:(T.createdAt??T.updatedAt??new Date).toISOString(),lastModified:(T.updatedAt??T.createdAt??new Date).toISOString()}}}function Mr(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:i(T,v),meta:{resourceType:"Customer",created:(T.createdAt??T.updatedAt??new Date).toISOString(),lastModified:(T.updatedAt??T.createdAt??new Date).toISOString()}}}function hn(T){return{enabled:T?.enabled!==!1,assignment:T?.assignment??"app",delta:T?.delta}}var ro="urn:ietf:params:scim:api:messages:2.0:ListResponse",Nr="urn:ietf:params:scim:api:messages:2.0:Error",$r="urn:ietf:params:scim:schemas:core:2.0:User",Mn="urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",Wr="urn:ietf:params:scim:schemas:core:2.0:Group",so="urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig",Bn="urn:ietf:params:scim:schemas:core:2.0:ResourceType",cn="urn:ietf:params:scim:schemas:core:2.0:Schema",io="00000000000000000000000000000000";function oo(T){let O={timestamp:new Date().toISOString()};if(T)O.actor=T;try{let Q=globalThis[Symbol.for("opentelemetry.js.api.1")]?.trace?.getActiveSpan?.()?.spanContext?.(),ye=Q?.traceId;if(ye&&ye!==io){if(O.traceId=ye,Q?.spanId)O.spanId=Q.spanId}}catch{}return O}class Fn extends r{constructor(T){super(T,{status:409,statusText:"subject_type_not_assignable"})}}async function Ps(T,O,N,X){let Q=N.subjectType;if(!y.includes(Q))throw new Fn(`Cannot grant ${N.targetType} "${n(N.target)}" to a "${Q}" principal: only [${y.join(", ")}] principals are assignable on this platform.`);let ye=W(O,T);if(!ye&&!X)return;let he=n(N.target),we;if(X)we=await X.getNode(N.targetType,he);else if(ye)we=await(N.targetType==="group"?ye.groups:N.targetType==="role"?ye.roles:ye.permissions).get(he);if(!we)return;let ke=we.assignableSubjectTypes;if(!ke||ke.length===0||!ke.includes(Q))throw new Fn(`Cannot grant ${N.targetType} "${he}" to a "${Q}" principal: this entitlement restricts assignment to [${(ke??[]).join(", ")||"none"}].`)}async function ao(T,O){let N=L(T.codeCatalog,n(O.target));if(!N)return;if(N.kind!==O.targetType)throw Error(`Cannot grant ${O.targetType} "${N.entity.id}": code declares that id as ${N.kind}.`);if(!T.catalogStore)throw Error(`Cannot grant code entitlement "${N.entity.id}": no AccessCatalogStore is wired for materialization.`);await q(N.kind,N.entity,K(T.catalogStore,N.kind))}async function co(T,O,N,X){await ao(T,O),await Ps(T.catalogStore,T.codeCatalog,O,X);let Q={...O,status:O.status??"active",provenance:O.provenance??oo()};if(Q.id=m(Q),await T.accessStore?.grant(Q),T.accessIndex&&(T.catalogStore||T.codeCatalog)){let ye=await P(Q,{catalog:T.catalogStore,code:T.codeCatalog,resources:T.resources,cache:X});await T.accessIndex.materialize(Q.id,ye)}return N?.push({op:"add",change:Q}),Q}async function En(T,O,N){let X=O.id??m(O);await T.accessStore?.revoke(O),await T.accessIndex?.removeByRoot(X),N?.push({op:"delete",change:{...O,id:X}})}async function Jn(T,O){let N=await uo(T,O),X=await po(T,O);return{oaa:N,delta:X}}async function uo(T,O){if(O.length===0||!T.authz.oaa.isReady())return{status:"skipped"};return rn(T,"authz.oaa.push","OAA incremental access push failed after SCIM mutation; full sync will reconcile",()=>T.authz.oaa.pushAccessChanges(O),{count:O.length})}async function rn(T,O,N,X,Q){try{return await X(),{status:"ok"}}catch(ye){return T.log?.warn(N,{"ion.operation":O,"ion.outcome":"degraded",...Q,error:$t(ye)}),{status:"degraded",reason:$t(ye)}}}var lo=6;async function po(T,O){let N=T.iamDelta;if(!N?.isReady()||O.length===0)return{status:"skipped"};let X=new Map;for(let ke of O){let fe=`${ke.change.subjectType}:${n(ke.change.subject)}\x00${ke.change.targetType}:${n(ke.change.target)}`;X.set(fe,ke)}let Q=[...X.values()],ye=Q.map(({op:ke,change:fe})=>()=>ke==="add"?N.onGrant(fe):N.onRevoke(fe)),we=(await mo(ye,lo)).filter((ke)=>ke.status==="rejected");if(we.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:we.length,total:Q.length,error:$t(we[0]?.reason)}),{status:"degraded",reason:$t(we[0]?.reason)};return{status:"ok"}}async function mo(T,O){let N=Array(T.length),X=0,Q=async()=>{while(!0){let he=X++;if(he>=T.length)return;let we=T[he];if(!we)continue;try{N[he]={status:"fulfilled",value:await we()}}catch(ke){N[he]={status:"rejected",reason:ke}}}},ye=Array.from({length:Math.min(O,T.length)},Q);return await Promise.all(ye),N}class qr extends r{constructor(T){super(T,{status:409,statusText:"derived_access"})}}class On extends r{constructor(T,O,N=!1){super(T,{status:N?409:500});this.summary=O,this.clientError=N}}function Je(T,O,N){return new Response(JSON.stringify({schemas:[Nr],status:String(T),scimType:N,detail:O}),{status:T,headers:w})}function Jt(T,O){let N=O?.totalResults??T.length,X=O?.startIndex??1,Q=O?.itemsPerPage??T.length;return new Response(JSON.stringify({schemas:[ro],totalResults:N,startIndex:X,itemsPerPage:Q,Resources:T}),{status:200,headers:w})}function wt(T,O=200,N){let X=new Headers(w);if(N)X.set("Location",N);return new Response(JSON.stringify(T),{status:O,headers:X})}function Cs(T){return Je(T.clientError?409:500,`${T.message}; authz mutation summary: ${JSON.stringify(T.summary)}`,T.clientError?"mutability":"invalidValue")}function Dn(T){return m(T)}function Or(T,O){return Hn(vs(T),vs(O))}function vs(T){let O=new Map;if(!T?.id)return O;for(let N of T.groups??[]){let X={subject:T.id,subjectType:"user",targetType:"group",target:N.value,metadata:N.display||N.type?{display:N.display,type:N.type}:void 0};O.set(Dn(X),X)}for(let N of T.roles??[]){let X={subject:T.id,subjectType:"user",targetType:"role",target:N.value,metadata:N.display||N.type?{display:N.display,type:N.type,primary:N.primary}:void 0};O.set(Dn(X),X)}for(let N of T.entitlements??[]){let X={subject:T.id,subjectType:"user",targetType:"permission",target:N.value,metadata:N.display||N.type?{display:N.display,type:N.type,primary:N.primary}:void 0};O.set(Dn(X),X)}return O}class zr extends r{constructor(T){super(T,{status:400,statusText:"ambiguous_member"})}}function fo(T,O,N){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=O??[];if(X.length===1)return X[0];throw new zr(`SCIM Group member "${T.value}" of entitlement "${N}" 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 Gn(T,O,N,X,Q){let ye=new Map,he=X&&X.length>0?X:void 0;for(let we of T??[]){let ke=fo(we,Q,N);if(!ke)continue;let fe={subject:we.value,subjectType:ke,targetType:O,target:N,resources:he,metadata:we.display||we.type?{display:we.display,type:we.type}:void 0};ye.set(Dn(fe),fe)}return ye}function Rs(T){let O=T[e]?.resources;return O&&O.length>0?O:void 0}function go(T,O){let N=(Q,ye)=>[...Q??[]].sort().join(",")===[...ye??[]].sort().join(","),X=T[e];if(X?.type!==void 0&&X.type!==O.kind)return!0;if(X?.requestable!==void 0&&X.requestable!==O.entity.requestable)return!0;if(X?.resources!==void 0&&!N(X.resources,Vr(O.entity)))return!0;if(X?.assignableSubjectTypes!==void 0&&!N(X.assignableSubjectTypes,O.entity.assignableSubjectTypes))return!0;if(X?.recommendedSubjectTypes!==void 0&&!N(X.recommendedSubjectTypes,O.entity.recommendedSubjectTypes))return!0;return!1}function yo(T,O){let N=(ye,he)=>[...ye??[]].sort().join(",")===[...he??[]].sort().join(","),X=T[e],Q=O[e];if(X?.type!==void 0&&X.type!==Q?.type)return!0;if(X?.requestable!==void 0&&X.requestable!==Q?.requestable)return!0;if(X?.resources!==void 0&&!N(X.resources,Q?.resources))return!0;if(X?.assignableSubjectTypes!==void 0&&!N(X.assignableSubjectTypes,Q?.assignableSubjectTypes))return!0;if(X?.recommendedSubjectTypes!==void 0&&!N(X.recommendedSubjectTypes,Q?.recommendedSubjectTypes))return!0;return!1}function ho(T){let O=new Map;for(let N of T)O.set(Dn(N),N);return O}async function un(T,O,N,X,Q,ye){let he=[],we=new Set,ke=(Be,He)=>`${He}\x00${Be}`,fe=ye?ye.get(`${N}:${X}`)??[]:O?(await O.listByTarget(N,X)).items:[];for(let Be of fe){let He=n(Be.subject),et=Be.metadata,dt=Be.subjectType==="workload"?"Workload":Be.subjectType==="customer"?"Customer":et?.type??"User",ot=ke(He,dt);if(we.has(ot))continue;we.add(ot),he.push({value:He,...et?.display?{display:et.display}:{},type:dt})}for(let Be of Q??[]){if(Be.targetType!==N||n(Be.target)!==X)continue;let He=n(Be.subject),et=ke(He,"Workload");if(we.has(et))continue;we.add(et),he.push({value:He,type:"Workload"})}if(N==="group"){let Be=await T.groups.get(X);for(let He of Be?.groups??[]){let et=n(He),dt=ke(et,"Group");if(!et||we.has(dt))continue;we.add(dt),he.push({value:et,type:"Group"})}}return he.length>0?he:void 0}function Hn(T,O){let N=[];for(let[X,Q]of O)if(!T.has(X))N.push({action:"grant",change:Q});for(let[X,Q]of T)if(!O.has(X))N.push({action:"revoke",change:Q});return N}async function _r(T,O){if(T.oaa.isReady())await T.oaa.pushUser(O)}async function As(T,O,N){if(O?.externalId&&O.externalId!==N.externalId)await T?.onUserDelete(O.externalId);await T?.onUserUpsert(N)}async function kn(T,O,N,X){let Q={metadataApplied:!1,access:[]},ye={status:"skipped"},he=[],we=new te(T.catalogStore,T.resources,T.codeCatalog);try{try{await O(),Q.metadataApplied=!0}catch(ke){for(let fe of N)Q.access.push({change:fe.change,status:"rolled_back"});throw Q.metadataApplied=!1,new On(`SCIM metadata write failed: ${$t(ke)}`,Q,!1)}if(X?.oaa)await rn(T,"authz.oaa.metadata","OAA metadata projection failed after SCIM write; full sync will reconcile",X.oaa);if(X?.delta&&T.iamDelta?.isReady())ye=await rn(T,"iam.delta.egress","IAM delta metadata projection failed after SCIM write; full aggregation will reconcile",X.delta);for(let ke=0;ke<N.length;ke++){let fe=N[ke];try{if(fe.action==="grant")await co(T,fe.change,he,we);else await Co(T,fe.change,he);Q.access.push({change:fe.change,status:"applied"})}catch(Be){Q.access.push({change:fe.change,status:"failed",error:Be});for(let et=ke+1;et<N.length;et++)Q.access.push({change:N[et].change,status:"rolled_back"});let He=Be instanceof qr||Be instanceof Fn;if(!He)await wo(T,fe.change,we);throw new On(He?$t(Be):`SCIM access mutation failed: ${$t(Be)}`,Q,He)}}return Q}finally{await So(T),Q.egress=await Jn(T,he),Q.egress.delta=ko(ye,Q.egress.delta),bo(T,Q)}}function ko(T,O){if(T.status==="degraded")return T;if(O.status==="degraded")return O;return T.status==="ok"||O.status==="ok"?{status:"ok"}:{status:"skipped"}}function $t(T){return T instanceof Error?T.message:String(T)}async function So(T){try{await T.settleAuthz?.()}catch{}}async function wo(T,O,N){if(!T.accessIndex||!T.catalogStore&&!T.codeCatalog||!T.accessStore)return;let X=n(O.subject);if(!X)return;let Q=O.subjectType;try{await me(X,Q,{accessStore:T.accessStore,accessIndex:T.accessIndex,catalogStore:T.catalogStore,code:T.codeCatalog,resources:T.resources},N)}catch(ye){T.log?.warn("Per-subject reconcile after failed SCIM access mutation failed",{"ion.operation":"authz.reconcile.subject.repair","ion.outcome":"degraded",subject:X,subjectType:Q,error:$t(ye)})}}function bo(T,O){if(!T.onAccessMutation)return;try{T.onAccessMutation(O)}catch{}}async function Co(T,O,N){if(T.accessStore){let X=O.id??m(O);if(!await T.accessStore.get(X)){if((T.accessIndex?await T.accessIndex.has(O.subject,O.targetType,O.target,O.resources?.[0],O.subjectType):{allow:!1}).allow)throw new qr(`Cannot revoke ${O.targetType} "${n(O.target)}" for "${n(O.subject)}": it is not a directly granted root (it is derived from group/role membership). Remove the granting group/role instead.`);await En(T,O,N);return}}await En(T,O,N)}function Sn(T){let O=T[e]?.type??"group";if(O==="group"||O==="role"||O==="permission")return O;throw Error(`Unsupported ionite SCIM Group authz type "${String(O)}"`)}async function jr(T,O,N){if(!T.oaa.isReady())return;if(N==="role"){await T.oaa.pushRole(O);return}if(N==="permission"){await T.oaa.pushPermission(O);return}await T.oaa.pushGroup(O)}function Vr(T){let O=T.resources;if(!O||O.length===0)return;let N=O.map((X)=>typeof X==="string"?X:X.id).filter(Boolean);return N.length>0?N:void 0}function dn(T,O,N){return Ur(T,O,N)}function vo(T,O){let N=T[e],Q={...i(N?.attributes??{},l),id:O,name:T.displayName,displayName:T.displayName,description:N?.description??T.displayName,requestable:N?.requestable,riskLevel:N?.riskLevel??g,providerId:N?.providerId??T.externalId,requestUrl:N?.requestUrl,assignableSubjectTypes:["user"]};if(N?.resources!==void 0)Q.resources=N.resources;return Q}function Ro(T){if(!T)return;let O=T.trim().match(/^requestable\s+eq\s+(true|false)$/i);if(!O)return;return{requestable:O[1]?.toLowerCase()==="true"}}function Is(T){if(!T)return;let O=T.trim().match(/^externalId\s+eq\s+"([^"]*)"$/i);return O?O[1]:void 0}function Ao(T){if(!T)return;let O=T.trim(),N=O.match(/^userName\s+eq\s+"([^"]*)"$/i);if(N)return{userName:N[1]};let X=O.match(/^externalId\s+eq\s+"([^"]*)"$/i);if(X)return{externalId:X[1]};let Q=O.match(/^meta\.lastModified\s+gt\s+"([^"]*)"$/i);if(Q)return{updatedAfter:Q[1]};return}function Io(T,O,N){let X=new Set(["id","schemas"]),Q={...T};if(O){let ye=new Set(O.split(",").map((he)=>he.trim()).filter(Boolean));for(let he of Object.keys(Q))if(!X.has(he)&&!ye.has(he))delete Q[he]}if(N){for(let ye of N.split(",").map((he)=>he.trim()).filter(Boolean))if(!X.has(ye))delete Q[ye]}return Q}function Ts(T,O){let N=async(ye,he,we)=>{let ke=await T.toScim(ye),fe=ye.id;return{...ke,id:fe,meta:{...ke.meta??{},resourceType:T.resourceType,location:fe?kt(he,`${we}/${encodeURIComponent(fe)}`):void 0}}},X=(ye,he)=>{let we=he.op.toLowerCase();if(!he.path){if(we!=="remove"&&he.value&&typeof he.value==="object"&&!Array.isArray(he.value))Object.assign(ye,he.value);return}if(we==="remove"){delete ye[he.path];return}ye[he.path]=he.value};return{handler:async(ye,he)=>{if(!await O.validateAuth(ye))return Je(401,"Authorization required");let we=new URL(ye.url),ke=he?.basePath??`/${T.resourceType}s`,fe=we.pathname;if(fe.startsWith(ke))fe=fe.substring(ke.length);let Be=fe.match(/^\/([^/]+)$/),He=Be?.[1]?decodeURIComponent(Be[1]):void 0,et=we.searchParams.get("attributes"),dt=we.searchParams.get("excludedAttributes"),ot=($e)=>Io($e,et,dt);try{if(He){if(ye.method==="GET"){let $e=await T.store.get(He);if(!$e)return Je(404,`${T.resourceType} not found`);return wt(ot(await N($e,ye,ke)))}if(ye.method==="PUT"||ye.method==="PATCH"){let $e=await T.store.get(He);if(!$e)return Je(404,`${T.resourceType} not found`);let Ve=await ye.json(),nt=Ve;if(ye.method==="PATCH"){let yt=Ve.Operations;if(!Array.isArray(yt))return Je(400,"PATCH requires Operations","invalidSyntax");let At=await T.toScim($e);for(let xt of yt)X(At,xt);nt=At}let Oe=await nn(T.validator,nt);if(Oe.issues)return Je(400,Oe.issues.map((yt)=>yt.message).join("; "),"invalidValue");let ut=ye.method==="PATCH"?"patch":"replace",gt=await T.store.upsert({...await T.fromScim(Oe.value,{existing:$e,mode:ut}),id:$e.id??He});if($e.active!==gt.active)await O.accessIndex?.setSubjectDisabled?.(gt.id,T.subjectType,gt.active===!1);let Ct=gt.id?kt(ye,`${ke}/${encodeURIComponent(gt.id)}`):void 0;for(let yt of T.projections??[])await rn(O,`${yt.channel}.${T.subjectType}.upsert`,`${T.resourceType} projection degraded after SCIM upsert; aggregation will reconcile`,()=>yt.upsert(gt,$e));return wt(ot(await N(gt,ye,ke)),200,Ct)}if(ye.method==="DELETE"){let $e=await T.store.get(He);if(!$e)return Je(404,`${T.resourceType} not found`);if(O.revokeSubjectAccess)await O.revokeSubjectAccess(He,T.subjectType);await T.store.delete(He),await O.accessIndex?.setSubjectDisabled?.(He,T.subjectType,!1);for(let Ve of T.projections??[])await rn(O,`${Ve.channel}.${T.subjectType}.delete`,`${T.resourceType} projection degraded after SCIM delete; aggregation will reconcile`,()=>Ve.delete($e));return new Response(null,{status:204})}return Je(405,"Method not allowed")}if(ye.method==="GET"){let $e=parseInt(we.searchParams.get("startIndex")??"",10),Ve=parseInt(we.searchParams.get("count")??"",10),nt=$e!=null&&!Number.isNaN($e)?Math.max(0,$e-1):0,Oe=Ve!=null&&!Number.isNaN(Ve)?Ve:void 0,ut=Ao(we.searchParams.get("filter"));if(ut?.externalId!==void 0){let yt=T.store.getByExternalId?await T.store.getByExternalId(ut.externalId):await T.store.lookup({externalId:ut.externalId}),At=yt?[ot(await N(yt,ye,ke))]:[];return Jt(At,{totalResults:At.length,startIndex:1,itemsPerPage:At.length})}let gt=await T.store.list({start:nt,limit:Oe,filter:ut}),Ct=await Promise.all(gt.items.map(async(yt)=>ot(await N(yt,ye,ke))));return Jt(Ct,{totalResults:gt.total,startIndex:nt+1,itemsPerPage:gt.count})}if(ye.method==="POST"){let $e=await ye.json(),Ve=await nn(T.validator,$e);if(Ve.issues)return Je(400,Ve.issues.map((ut)=>ut.message).join("; "),"invalidValue");let nt=await T.store.upsert(await T.fromScim(Ve.value,{mode:"create"}));if(nt.active===!1)await O.accessIndex?.setSubjectDisabled?.(nt.id,T.subjectType,!0);for(let ut of T.projections??[])await rn(O,`${ut.channel}.${T.subjectType}.upsert`,`${T.resourceType} projection degraded after SCIM create; aggregation will reconcile`,()=>ut.upsert(nt,void 0));let Oe=nt.id?kt(ye,`${ke}/${encodeURIComponent(nt.id)}`):void 0;return wt(ot(await N(nt,ye,ke)),201,Oe)}return Je(405,"Method not allowed")}catch($e){if(j($e))return Je(409,$e.message,"uniqueness");return Je(500,$e instanceof Error?$e.message:"Internal error")}}}}async function To(T,O,N,X){let Q=[],ye=[["group",T.groups],["role",T.roles],["permission",T.permissions]];for(let[we,ke]of ye)for await(let fe of u((Be,He)=>ke.list({start:Be,limit:He,filter:{requestable:!0}})))if(fe.providerId===N)Q.push({entity:fe,type:we});if(Q.length>1)throw new A(`Ambiguous providerId "${N}": ${Q.length} entitlements share it (${Q.map((we)=>`${we.type}:${we.entity.id}`).join(", ")})`,"unique_violation","providerId");let he=Q[0];if(he?.entity.requestable!==!0)return;return dn(he.entity,he.type,await un(T,O,he.type,he.entity.id,X))}async function xo(T,O,N,X){let Q=Math.max(0,N.start),ye=N.limit!=null?Q+N.limit:void 0,he={start:0,limit:ye,filter:N.filter},[we,ke,fe]=await Promise.all([T.groups.list(he),T.roles.list(he),T.permissions.list(he)]),Be=[...we.items.map(($e)=>({entity:$e,type:"group"})),...ke.items.map(($e)=>({entity:$e,type:"role"})),...fe.items.map(($e)=>({entity:$e,type:"permission"}))],He=we.total+ke.total+fe.total,et=Be.slice(Q,ye),dt=O?.listByTargets?await O.listByTargets(et.map(({entity:$e,type:Ve})=>({targetType:Ve,target:$e.id}))):void 0,ot=await Promise.all(et.map(async({entity:$e,type:Ve})=>dn($e,Ve,await un(T,O,Ve,$e.id,X,dt))));return{resources:ot,total:He,count:ot.length}}async function Un(T,O,N,X){let[Q,ye,he]=await Promise.all([T.groups.get(N),T.roles.get(N),T.permissions.get(N)]);if(Q)return dn(Q,"group",await un(T,O,"group",N,X));if(ye)return dn(ye,"role",await un(T,O,"role",N,X));if(he)return dn(he,"permission",await un(T,O,"permission",N,X));return}async function Lr(T,O,N,X,Q){let ye=Sn(O),he=ye==="role"?await T.roles.get(N):ye==="permission"?await T.permissions.get(N):await T.groups.get(N),we=vo(O,N),ke=he?.assignableSubjectTypes&&he.assignableSubjectTypes.length>0?he.assignableSubjectTypes:["user"],fe={...he??{},...we,source:he?.source??"scim",assignableSubjectTypes:Q?.assignableSubjectTypes??ke,recommendedSubjectTypes:Q?.recommendedSubjectTypes??he?.recommendedSubjectTypes};if(Q){if(delete fe.groups,delete fe.roles,delete fe.permissions,delete fe.resources,ye==="group")fe.groups=Q.groups,fe.roles=Q.roles,fe.permissions=Q.permissions,fe.resources=Q.resources;else if(ye==="role")fe.permissions=Q.permissions}let Be=X?X.displayName??X.name:he?.name;if(we.displayName===Be)delete fe.displayName;if(we.riskLevel===(X?.riskLevel??g))delete fe.riskLevel;let He=i(we,l),et=X?i(X,l):void 0;if(O[e]?.attributes!==void 0){for(let ot of Object.keys(i(he??{},l)??{}))if(!(ot in(He??{})))delete fe[ot]}for(let[ot,$e]of Object.entries(He??{}))if(k($e,et?.[ot]))delete fe[ot];if(X)fe.name=X.name;let dt=ye==="role"?T.roles.set(fe):ye==="permission"?T.permissions.set(fe):T.groups.set(fe);return await dt.ready(),dt}async function Po(T,O){await Promise.all([T.groups.delete(O),T.roles.delete(O),T.permissions.delete(O)])}function Kn(){return crypto.randomUUID()}function nn(T,O){let N=T;if(typeof N.validate==="function")return N.validate(O);return Promise.resolve(T["~standard"].validate(O))}function Uo(T){if(!T)return;try{return new URL(T).pathname}catch{return T.startsWith("/")?T:`/${T}`}}function Nt(T){let O=Uo(T);return O?R(O):void 0}function xs(...T){for(let O of T){let N=Nt(O);if(!N)continue;for(let X of["/Users","/Groups","/Workloads","/Customers"])if(N.endsWith(X))return N.slice(0,-X.length)}return}function kt(T,O){return new URL(O,T.url).toString()}function Me(T,O,N,X){let{multiValued:Q=!1,...ye}=X??{};return{name:T,type:O,description:N,multiValued:Q,...ye}}function Eo(T,O){return{schemas:[so],documentationUri:O?.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:kt(T.request,`${T.basePath}/ServiceProviderConfig`)}}}function Do(T){let O=[];if(T.supportsUsers)O.push({schemas:[Bn],id:"User",name:"User",description:"User Account",endpoint:T.usersUrl,schema:$r,schemaExtensions:[{schema:Mn,required:!1},{schema:d,required:!1}],meta:{resourceType:"ResourceType",location:kt(T.request,`${T.basePath}/ResourceTypes/User`)}});if(T.supportsGroups)O.push({schemas:[Bn],id:"Group",name:"Group",description:"Group",endpoint:T.groupsUrl,schema:Wr,schemaExtensions:[{schema:e,required:!1}],meta:{resourceType:"ResourceType",location:kt(T.request,`${T.basePath}/ResourceTypes/Group`)}});if(T.supportsWorkloads)O.push({schemas:[Bn],id:"Workload",name:"Workload",description:"Workload (machine) principal",endpoint:T.workloadsUrl,schema:b,meta:{resourceType:"ResourceType",location:kt(T.request,`${T.basePath}/ResourceTypes/Workload`)}});if(T.supportsCustomers)O.push({schemas:[Bn],id:"Customer",name:"Customer",description:"Customer (CIAM) principal",endpoint:T.customersUrl,schema:C,meta:{resourceType:"ResourceType",location:kt(T.request,`${T.basePath}/ResourceTypes/Customer`)}});return O}function Mo(T){let O=[];if(T.supportsUsers)O.push({schemas:[cn],id:$r,name:"User",description:"User Account",meta:{resourceType:"Schema",location:kt(T.request,`${T.basePath}/Schemas/${encodeURIComponent($r)}`)},attributes:[Me("id","string","Unique identifier for the User.",{multiValued:!1,required:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),Me("externalId","string","External identifier from the provisioning client.",{multiValued:!1,required:!1,mutability:"readWrite",returned:"default",uniqueness:"none"}),Me("userName","string","Unique identifier typically used for login.",{multiValued:!1,required:!0,caseExact:!1,mutability:"readWrite",returned:"default",uniqueness:"server"}),Me("name","complex","The components of the user name.",{multiValued:!1,required:!1,mutability:"readWrite",returned:"default",subAttributes:[Me("formatted","string","The full name, including titles and suffixes.",{multiValued:!1}),Me("familyName","string","The family name of the User.",{multiValued:!1}),Me("givenName","string","The given name of the User.",{multiValued:!1}),Me("middleName","string","The middle name(s) of the User.",{multiValued:!1}),Me("honorificPrefix","string","The honorific prefix(es) of the User.",{multiValued:!1}),Me("honorificSuffix","string","The honorific suffix(es) of the User.",{multiValued:!1})]}),Me("displayName","string","The name of the User, suitable for display.",{multiValued:!1}),Me("nickName","string","The casual way to address the user.",{multiValued:!1}),Me("profileUrl","reference","A URL pointing to the User profile.",{multiValued:!1,referenceTypes:["external"]}),Me("title","string","The user title, such as Vice President.",{multiValued:!1}),Me("userType","string","The relationship between the organization and the User.",{multiValued:!1}),Me("preferredLanguage","string","Preferred written or spoken language.",{multiValued:!1}),Me("locale","string","Default location for localizing values.",{multiValued:!1}),Me("timezone","string","The User time zone.",{multiValued:!1}),Me("active","boolean","The User administrative status.",{multiValued:!1}),Me("emails","complex","Email addresses for the User.",{multiValued:!0,subAttributes:[Me("value","string","Email address value.",{multiValued:!1,required:!0}),Me("display","string","Display label for the email.",{multiValued:!1}),Me("type","string","Email type such as work or home.",{multiValued:!1}),Me("primary","boolean","Primary email indicator.",{multiValued:!1})]}),Me("phoneNumbers","complex","Phone numbers for the User.",{multiValued:!0,subAttributes:[Me("value","string","Phone number value.",{multiValued:!1,required:!0}),Me("display","string","Display label for the phone number.",{multiValued:!1}),Me("type","string","Phone number type.",{multiValued:!1}),Me("primary","boolean","Primary phone number indicator.",{multiValued:!1})]}),Me("photos","complex","Photo URLs for the User.",{multiValued:!0,subAttributes:[Me("value","reference","Photo URL.",{multiValued:!1,required:!0,referenceTypes:["external"]}),Me("display","string","Display label for the photo.",{multiValued:!1}),Me("type","string","Photo type.",{multiValued:!1}),Me("primary","boolean","Primary photo indicator.",{multiValued:!1})]}),Me("addresses","complex","Physical mailing addresses for the User.",{multiValued:!0,subAttributes:[Me("formatted","string","Formatted mailing address.",{multiValued:!1}),Me("streetAddress","string","Full street address component.",{multiValued:!1}),Me("locality","string","City or locality.",{multiValued:!1}),Me("region","string","State or region.",{multiValued:!1}),Me("postalCode","string","Postal code.",{multiValued:!1}),Me("country","string","Country.",{multiValued:!1}),Me("type","string","Address type.",{multiValued:!1}),Me("primary","boolean","Primary address indicator.",{multiValued:!1})]}),Me("groups","complex","Groups to which the User belongs.",{multiValued:!0,mutability:"readOnly",subAttributes:[Me("value","string","Group identifier.",{multiValued:!1,required:!0}),Me("$ref","reference","Reference to the Group resource.",{multiValued:!1,referenceTypes:["Group"]}),Me("display","string","Display name of the group.",{multiValued:!1}),Me("type","string","Relationship type.",{multiValued:!1})]}),Me("entitlements","complex","Entitlements for the User.",{multiValued:!0,subAttributes:[Me("value","string","Entitlement value.",{multiValued:!1,required:!0}),Me("display","string","Display value.",{multiValued:!1}),Me("type","string","Entitlement type.",{multiValued:!1}),Me("primary","boolean","Primary entitlement indicator.",{multiValued:!1})]}),Me("roles","complex","Roles for the User.",{multiValued:!0,subAttributes:[Me("value","string","Role value.",{multiValued:!1,required:!0}),Me("display","string","Display value.",{multiValued:!1}),Me("type","string","Role type.",{multiValued:!1}),Me("primary","boolean","Primary role indicator.",{multiValued:!1})]}),Me("x509Certificates","complex","Certificates issued to the User.",{multiValued:!0,subAttributes:[Me("value","string","Certificate value.",{multiValued:!1,required:!0}),Me("display","string","Display value.",{multiValued:!1}),Me("type","string","Certificate type.",{multiValued:!1}),Me("primary","boolean","Primary certificate indicator.",{multiValued:!1})]})]}),O.push({schemas:[cn],id:Mn,name:"EnterpriseUser",description:"Enterprise User extension",meta:{resourceType:"Schema",location:kt(T.request,`${T.basePath}/Schemas/${encodeURIComponent(Mn)}`)},attributes:[Me("employeeNumber","string","Numeric or alphanumeric identifier assigned to a person.",{multiValued:!1}),Me("costCenter","string","Name of a cost center.",{multiValued:!1}),Me("organization","string","Name of an organization.",{multiValued:!1}),Me("division","string","Name of a division.",{multiValued:!1}),Me("department","string","Name of a department.",{multiValued:!1}),Me("manager","complex","The User manager.",{multiValued:!1,subAttributes:[Me("value","string","Identifier of the manager User resource.",{multiValued:!1}),Me("$ref","reference","Reference to the manager User resource.",{multiValued:!1,referenceTypes:["User"]}),Me("displayName","string","Display name of the manager.",{multiValued:!1})]})]}),O.push({schemas:[cn],id:d,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:kt(T.request,`${T.basePath}/Schemas/${encodeURIComponent(d)}`)},attributes:[Me("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}),Me("accountClass","string","Account purpose (distinct from userType persona). Open value set: 'daily', 'privileged', 'break_glass', 'service'.",{multiValued:!1}),Me("attributes","complex","AppDev custom attributes. IAM may override seeded values.",{multiValued:!1,required:!1,mutability:"readWrite"})]});if(T.supportsGroups)O.push({schemas:[cn],id:e,name:"IoniteAuthzGroup",description:"ionite authorization metadata for SCIM Group resources.",meta:{resourceType:"Schema",location:kt(T.request,`${T.basePath}/Schemas/${encodeURIComponent(e)}`)},attributes:[Me("type","string","Authorization entity kind: group, role, or permission.",{multiValued:!1,required:!1}),Me("requestable","boolean","Whether this catalog entry is exposed as assignable access to IAM tooling. Only true entries are served.",{multiValued:!1,required:!1}),Me("riskLevel","string",`Advisory access-risk classification. Unset values project as ${g}; canonical values are suggestions, not a closed enum.`,{multiValued:!1,required:!1,mutability:"readWrite",canonicalValues:[...Z]}),Me("providerId","string","IAM service-provider id captured when this entitlement is materialized at the destination.",{multiValued:!1,required:!1,mutability:"readWrite"}),Me("requestUrl","reference","IAM-owned deep link where a principal can request this entitlement.",{multiValued:!1,required:!1,mutability:"readWrite",referenceTypes:["external"]}),Me("source","string","Provenance of the catalog row.",{multiValued:!1,required:!1,mutability:"readOnly",canonicalValues:["code","app","scim"]}),Me("deprecated","boolean","Whether this retired entitlement may be deleted.",{multiValued:!1,required:!1,mutability:"readOnly"}),Me("description","string","Human-readable authorization entity description.",{multiValued:!1,required:!1}),Me("resources","string","Resource ids this entitlement is scoped to.",{multiValued:!0,required:!1}),Me("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"]}),Me("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"]}),Me("attributes","complex","AppDev custom attributes. IAM may override seeded values.",{multiValued:!1,required:!1,mutability:"readWrite"})]});if(T.supportsGroups)O.push({schemas:[cn],id:Wr,name:"Group",description:"Group",meta:{resourceType:"Schema",location:kt(T.request,`${T.basePath}/Schemas/${encodeURIComponent(Wr)}`)},attributes:[Me("id","string","Unique identifier for the Group.",{multiValued:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),Me("externalId","string","External identifier from the provisioning client.",{multiValued:!1,uniqueness:"none"}),Me("displayName","string","Human-readable name for the Group.",{multiValued:!1,required:!0,uniqueness:"none"}),Me("members","complex","Members of the Group.",{multiValued:!0,subAttributes:[Me("value","string","Identifier of the member resource.",{multiValued:!1,required:!0}),Me("$ref","reference","Reference to the member resource.",{multiValued:!1,referenceTypes:["User","Group","Workload","Customer"]}),Me("display","string","Display name of the member.",{multiValued:!1}),Me("type","string","Member type.",{multiValued:!1})]})]});if(T.supportsWorkloads)O.push({schemas:[cn],id:b,name:"Workload",description:"Workload (machine) principal",meta:{resourceType:"Schema",location:kt(T.request,`${T.basePath}/Schemas/${encodeURIComponent(b)}`)},attributes:[Me("id","string","Unique identifier for the Workload.",{multiValued:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),Me("externalId","string","External identifier from the provisioning client.",{multiValued:!1}),Me("userName","string","Login identifier, typically the OAuth clientId.",{multiValued:!1}),Me("displayName","string","Human-readable name for the Workload.",{multiValued:!1}),Me("description","string","Free-form description of the Workload.",{multiValued:!1}),Me("active","boolean","Administrative status of the Workload.",{multiValued:!1}),Me("attributes","complex","AppDev custom attributes.",{multiValued:!1,required:!1,mutability:"readWrite"})]});if(T.supportsCustomers)O.push({schemas:[cn],id:C,name:"Customer",description:"Customer (CIAM) principal",meta:{resourceType:"Schema",location:kt(T.request,`${T.basePath}/Schemas/${encodeURIComponent(C)}`)},attributes:[Me("id","string","Unique identifier for the Customer.",{multiValued:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),Me("externalId","string","External identifier from the provisioning client.",{multiValued:!1}),Me("userName","string","Unique identifier typically used for login.",{multiValued:!1}),Me("displayName","string","Human-readable name for the Customer.",{multiValued:!1}),Me("active","boolean","Administrative status of the Customer.",{multiValued:!1}),Me("emails","complex","Email addresses for the Customer.",{multiValued:!0,subAttributes:[Me("value","string","Email address.",{multiValued:!1,required:!0}),Me("primary","boolean","Whether this is the primary email.",{multiValued:!1})]}),Me("attributes","complex","AppDev custom attributes.",{multiValued:!1,required:!1,mutability:"readWrite"})]});return O}function Oo(T,O,N,X,Q,ye,he,we,ke,fe,Be,He,et,dt,ot,$e){let Ve={authz:X,settleAuthz:$e,accessStore:Q,accessIndex:ye,catalogStore:he,codeCatalog:we,resources:ke,log:O,iamDelta:He,onAccessMutation:et,onInboundEntitlement:dt};if(!fe&&!Be)return;let Oe={...fe,...Be},ut=Oe.users?.enabled!==!1,gt=Oe.groups?.enabled!==!1,Ct=Oe.workloads?.enabled!==!1,yt=Oe.customers?.enabled!==!1;if(Boolean(Oe.url||Oe.userStore||he||we)&&!N)O.error("IAM requires workload identity for SCIM push/pull operations",{"ion.operation":"workload.require","ion.outcome":"failure"});function xt(){if(!N)throw O.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 _t(Ge){let Ze=xt(),Ke=Ge.headers.get("Authorization");if(!Ke?.startsWith("Bearer "))return!1;try{let Qe=Ke.substring(7);return(await Ze.validateToken(Qe)).valid}catch{return!1}}async function wn(){let Ge=xt(),Ze=typeof Ge.getServerToken==="function"?await Ge.getServerToken():await Ge.getToken();return new Headers({...w,...ue,Authorization:`Bearer ${Ze}`})}async function Ht(Ge,Ze,Ke,Qe){if(!Oe.url)throw Error("IAM URL not configured for outgoing requests");let Fe=`${Oe.url}${Ze}`;try{let Xe=await wn(),lt=await fetch(Fe,{method:Ge,headers:Xe,body:Ke?JSON.stringify(Ke):void 0}),Ce=await c(lt,{log:O,operation:"scim.request"});if(!lt.ok)return{success:!1,error:Ce,status:lt.status};let Ue=await Qe["~standard"].validate(Ce);if(Ue.issues)return O.error("SCIM response validation failed",{"ion.operation":"scim.response.validate","ion.outcome":"failure",validationIssues:Ue.issues}),{success:!1,error:{schemas:[Nr],status:"400",scimType:"invalidValue",detail:`Response validation failed: ${Ue.issues.map((_e)=>_e.message).join("; ")}`},status:400};return{success:!0,data:Ue.value,status:lt.status}}catch(Xe){return{success:!1,error:{schemas:[Nr],status:"500",detail:Xe instanceof Error?Xe.message:"Unknown error occurred"},status:500}}}function bn(){return Oe.url}function ln(Ge,Ze){let Ke=Nt(Ze?.usersUrl??Oe.usersUrl??"/api/iam/Users")??"/api/iam/Users",Qe=Nt(Ze?.groupsUrl??Oe.groupsUrl??"/api/iam/Groups")??"/api/iam/Groups",Fe=Nt(Ze?.workloadsUrl??Oe.workloadsUrl??"/api/iam/Workloads")??"/api/iam/Workloads",Xe=Nt(Ze?.customersUrl??Oe.customersUrl??"/api/iam/Customers")??"/api/iam/Customers",lt=Nt(Ze?.discovery?.basePath??Oe.discovery?.basePath)??xs(Ke,Qe,Fe,Xe);if(!lt)return;return{request:Ge,basePath:lt,usersUrl:Ke,groupsUrl:Qe,workloadsUrl:Fe,customersUrl:Xe,supportsUsers:ut&&Boolean(Oe.userStore),supportsGroups:gt&&Boolean(he||we),supportsWorkloads:Ct&&Boolean(Oe.workloadIdentityStore),supportsCustomers:yt&&Boolean(Oe.customerStore)}}async function Ft(Ge){let Ze=Eo(Ge,Oe.discovery);return await Oe.discovery?.buildServiceProviderConfig?.(Ge,Ze)??Ze}async function Yt(Ge){let Ze=Do(Ge);return await Oe.discovery?.buildResourceTypes?.(Ge,Ze)??Ze}async function sn(Ge){let Ze=Mo(Ge);return await Oe.discovery?.buildSchemas?.(Ge,Ze)??Ze}async function pn(Ge,Ze){let Ke=ln(Ge,Ze);if(!Ke)return;let Qe=R(new URL(Ge.url).pathname),{basePath:Fe}=Ke;if(Qe!==Fe&&!Qe.startsWith(`${Fe}/`))return;let Xe=R(Qe.slice(Fe.length)||"/");if(!(Xe==="/ServiceProviderConfig"||Xe==="/ResourceTypes"||Xe.startsWith("/ResourceTypes/")||Xe==="/Schemas"||Xe.startsWith("/Schemas/")))return;if(Ge.method!=="GET")return Je(405,"Method not allowed");if(!await _t(Ge))return Je(401,"Authorization required");if(Xe==="/ServiceProviderConfig")return wt(await Ft(Ke));if(Xe==="/ResourceTypes")return Jt(await Yt(Ke));if(Xe.startsWith("/ResourceTypes/")){let Ue=decodeURIComponent(Xe.slice(15)),_e=(await Yt(Ke)).find((ge)=>ge.id===Ue||ge.name===Ue);return _e?wt(_e):Je(404,"Resource not found")}if(Xe==="/Schemas")return Jt(await sn(Ke));if(Xe.startsWith("/Schemas/")){let Ue=decodeURIComponent(Xe.slice(9)),_e=(await sn(Ke)).find((ge)=>ge.id===Ue);return _e?wt(_e):Je(404,"Resource not found")}return}let Pt,mn;if(Oe.url)mn=async(Ze,Ke)=>{let Qe={...Ze,schemas:Ze.schemas??["urn:ietf:params:scim:schemas:core:2.0:User","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"]};return Ht("POST","/Users",Qe,T.user)},Pt={createGroup:async(Ze,Ke)=>{let Qe={schemas:["urn:ietf:params:scim:schemas:core:2.0:Group"],displayName:Ze,externalId:Ke?.id,members:Ke?.members};return Ht("POST","/Groups",Qe,T.group)}};let Xt;if(he||we){let Ge=W(we,he),Ze=(Re,Se,ve)=>{let Te=Re[e]??{},Ae=Sn(Re),De=Re.id,je=De?kt(Se,`${ve}/${encodeURIComponent(De)}`):void 0,Ee={id:De??Re.externalId??Re.displayName,name:Re.displayName,displayName:Re.displayName,description:Te.description??Re.displayName,requestable:Te.requestable,providerId:Te.providerId??Re.externalId,requestUrl:Te.requestUrl,source:Te.source,deprecated:Te.deprecated,riskLevel:Te.riskLevel,assignableSubjectTypes:Te.assignableSubjectTypes,recommendedSubjectTypes:Te.recommendedSubjectTypes},Le=Te.requestUrl??Oe.entitlementRequestUrl?.(Ee,Ae,{request:Se});return{...Re,meta:{...Re.meta,resourceType:"Group",location:je},[e]:{...Te,requestUrl:Le}}},Ke=(Re)=>L(we,Re),Qe=async(Re,Se)=>{if(!he){if(Se)throw Error(`Cannot persist access for code entitlement "${Re.entity.id}": no AccessCatalogStore is wired.`);return Re.entity}try{return await q(Re.kind,Re.entity,K(he,Re.kind))}catch(ve){if(Se)throw ve;return O.warn("Code entitlement discovery materialization failed; serving the code template",{"ion.operation":"iam.catalog.materialize","ion.outcome":"degraded",entitlementId:Re.entity.id,entitlementType:Re.kind,error:$t(ve)}),Re.entity}},Fe=async(Re)=>{if(!he)return;try{await ee(we,he,Re)}catch(Se){O.warn("Retired code entitlement deprecation failed; serving the last durable row",{"ion.operation":"iam.catalog.deprecate","ion.outcome":"degraded",entitlementId:Re,error:$t(Se)})}},Xe=(Re,Se)=>Je(403,`Entitlement "${Re}" 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"),lt=(Re)=>Re.path==="members"||Boolean(Re.path?.startsWith("members[")),Ce=(Re)=>lt(Re)||Re.path==="displayName"||Re.path===`${e}.description`||Re.path===`${e}.riskLevel`||Re.path===`${e}.providerId`||Re.path===`${e}.requestUrl`||Re.path===`${e}.attributes`||Boolean(Re.path?.startsWith(`${e}.attributes.`)),Ue=(Re)=>Re?.[e]?.requestable===!0,_e=(Re)=>Je(404,`Requestable Group ${Re} not found`,"invalidValue"),ge=async(Re,Se)=>{if(!await _t(Re))return Je(401,"Authorization required");let Te=new URL(Re.url),Ae=Se?.basePath??"/Groups",De=Te.pathname;if(De.startsWith(Ae))De=De.substring(Ae.length);let Ee=De.match(/^\/([^/]+)$/)?.[1],Le=Re.method;try{if(Ee)switch(Le){case"GET":return await xe(Re,Ae,Ee);case"PUT":return await Pe(Re,Ae,Ee);case"PATCH":return await ze(Re,Ae,Ee);case"DELETE":return await We(Ee);default:return Je(405,"Method not allowed")}else if(De===""||De==="/")switch(Le){case"GET":return await be(Re,Ae);case"POST":return await Ie(Re,Ae);default:return Je(405,"Method not allowed")}return Je(404,"Resource not found")}catch(Ye){if(Ye instanceof On)return Cs(Ye);if(Ye instanceof zr)return Je(400,Ye.message,"invalidValue");if(j(Ye))return Je(409,Ye.message,"uniqueness");return O.error("Groups inbound handler error",{"ion.operation":"scim.groups.handler","ion.outcome":"failure"},Ye),Je(500,Ye instanceof Error?Ye.message:"Internal server error")}},be=async(Re,Se)=>{let ve=new URL(Re.url),Te=ve.searchParams.get("startIndex"),Ae=ve.searchParams.get("count"),De=Te!=null?parseInt(Te,10):void 0,je=Ae!=null?parseInt(Ae,10):void 0,Ee=De!=null&&!Number.isNaN(De)?Math.max(0,De-1):0,Le=je!=null&&!Number.isNaN(je)?je:void 0,Ye=ve.searchParams.get("filter"),st=Is(Ye);if(st!==void 0){await Fe();let tt=await To(Ge,Q,st,ot),ft=tt?[Ze(tt,Re,Se)]:[];return Jt(ft,{totalResults:ft.length,startIndex:1,itemsPerPage:ft.length})}if(Ro(Ye)?.requestable===!1)return Jt([],{totalResults:0,startIndex:1,itemsPerPage:0});let mt={requestable:!0};if(we)await Promise.all([...we.groups.list().filter((tt)=>tt.requestable===!0).map((tt)=>({entity:tt,kind:"group"})),...we.roles.list().filter((tt)=>tt.requestable===!0).map((tt)=>({entity:tt,kind:"role"})),...we.permissions.list().filter((tt)=>tt.requestable===!0).map((tt)=>({entity:tt,kind:"permission"}))].map((tt)=>Qe(tt,!1)));await Fe();let at=await xo(Ge,Q,{start:Ee,limit:Le,filter:mt},ot);return Jt(at.resources.map((tt)=>Ze(tt,Re,Se)),{totalResults:at.total,startIndex:Ee+1,itemsPerPage:at.count})},xe=async(Re,Se,ve)=>{let Te=Ke(ve);if(Te&&Te.entity.requestable!==!0)return _e(ve);if(Te)await Qe(Te,!1);await Fe(ve);let Ae=await Un(Ge,Q,ve,ot);if(!Ue(Ae))return _e(ve);return wt(Ze(Ae,Re,Se))},Ie=async(Re,Se)=>{let ve=await Re.json(),Te=await nn(T.group,ve);if(Te.issues)return O.error("Group creation validation failed",{"ion.operation":"scim.group.create","ion.outcome":"failure",validationIssues:Te.issues}),Je(400,`Request validation failed: ${Te.issues.map((Ot)=>Ot.message).join("; ")}`,"invalidValue");let Ae=Te.value;if(!Ae.displayName)return Je(400,"displayName is required","invalidValue");if(Ae[e]?.requestable===!1)return Je(400,"SCIM may create only requestable entitlements; non-requestable definitions are App-owned.","invalidValue");if(Ae[e]={...Ae[e],requestable:!0},!Ve.onInboundEntitlement)return Je(501,"IAM-sourced entitlement creation is not implemented: this application declares no authz.onInboundEntitlement callback.","invalidValue");if(!he)return Je(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 je=Sn(Ae),Ee=Ae[e],Le=await Ve.onInboundEntitlement({type:je,displayName:Ae.displayName,description:Ee?.description,externalId:Ae.externalId,riskLevel:Ee?.riskLevel,attributes:Ee?.attributes,resources:Ee?.resources,members:Ae.members??[],request:Re});if(!Le.accept)return Je(403,Le.reason??"The application rejected the IAM-sourced entitlement");if((je==="role"?[...Le.groups??[],...Le.roles??[],...Le.resources??[]]:je==="permission"?[...Le.groups??[],...Le.roles??[],...Le.permissions??[],...Le.resources??[]]:[]).length>0)throw Error(`onInboundEntitlement returned structure that is invalid for entitlement type "${je}".`);let st=Le.assignableSubjectTypes??["user"];E({id:Le.id,assignableSubjectTypes:st,recommendedSubjectTypes:Le.recommendedSubjectTypes});let ct=async(Ot,Rt)=>{await Promise.all((Rt??[]).map(async(zt)=>{if(!(Ot==="group"?await Ge.groups.get(zt):Ot==="role"?await Ge.roles.get(zt):Ot==="permission"?await Ge.permissions.get(zt):await ke?.get(zt)))throw Error(`onInboundEntitlement accepted "${Ae.displayName}" with unknown ${Ot} binding "${zt}".`)}))};await Promise.all([ct("group",Le.groups),ct("role",Le.roles),ct("permission",Le.permissions),ct("resource",Le.resources)]);let mt=Le.id??Kn(),[at,tt,ft]=await Promise.all([Ge.groups.get(mt),Ge.roles.get(mt),Ge.permissions.get(mt)]);if(at||tt||ft)throw new A(`id "${mt}" already exists in the entitlement catalog`,"unique_violation","id");let rt=Le.resources,Dt=Hn(new Map,Gn(Ae.members,je,mt,rt,st)),Mt;await kn(Ve,async()=>{Mt=await Lr(Ge,Ae,mt,void 0,{...Le,assignableSubjectTypes:st})},Dt,{oaa:()=>jr(X,Mt,je)});let vt=await un(Ge,Q,je,mt),qt=Ze(dn(Mt,je,vt),Re,Se);return wt(qt,201,qt.meta?.location)},Pe=async(Re,Se,ve)=>{let Te=await Re.json(),Ae=await nn(T.group,Te);if(Ae.issues)return O.error("Group replacement validation failed",{"ion.operation":"scim.group.replace","ion.outcome":"failure",validationIssues:Ae.issues}),Je(400,`Request validation failed: ${Ae.issues.map((ft)=>ft.message).join("; ")}`,"invalidValue");let De=Ae.value,je=Sn(De),Ee=Ke(ve);if(Ee&&Ee.entity.requestable!==!0)return _e(ve);if(Ee){if(await Qe(Ee,!0),go(De,Ee))return Xe(ve,"replaced")}let Le=await Un(Ge,Q,ve);if(!Ue(Le))return _e(ve);if(!Ee&&Le[e]?.source==="code"&&yo(De,Le))return Xe(ve,"replaced");let Ye=Ee?.kind??je,st=Ee?Vr(Ee.entity):Rs(De),ct=Q?(await Q.listByTarget(Ye,ve)).items:[],mt=Hn(ho(ct),Gn(De.members,Ye,ve,st,Ee?.entity.assignableSubjectTypes??Le[e]?.assignableSubjectTypes??De[e]?.assignableSubjectTypes)),at;await kn(Ve,async()=>{at=await Lr(Ge,De,ve,Ee?.entity)},mt,{oaa:()=>jr(X,at,Ye)});let tt=await un(Ge,Q,Ye,ve);return wt(Ze(dn(at,Ye,tt),Re,Se))},ze=async(Re,Se,ve)=>{let Te=Ke(ve);if(Te&&Te.entity.requestable!==!0)return _e(ve);if(Te)await Qe(Te,!0);let Ae=await Un(Ge,Q,ve);if(!Ue(Ae))return _e(ve);let De=await Re.json();if((Te!==void 0||Ae[e]?.source==="code")&&(De.Operations??[]).some((rt)=>!Ce(rt)))return Xe(ve,"patched");let Ee={...Ae};for(let rt of De.Operations??[])if(rt.op==="replace"&&rt.path&&rt.value!==void 0){if(rt.path==="displayName")Ee.displayName=rt.value;else if(rt.path===`${e}.requestable`)Ee[e]={...Ee[e],requestable:Boolean(rt.value)};else if(rt.path===`${e}.description`)Ee[e]={...Ee[e],description:String(rt.value)};else if(rt.path===`${e}.riskLevel`)Ee[e]={...Ee[e],riskLevel:String(rt.value)};else if(rt.path===`${e}.providerId`)Ee[e]={...Ee[e],providerId:String(rt.value)};else if(rt.path===`${e}.requestUrl`)Ee[e]={...Ee[e],requestUrl:String(rt.value)};else if(rt.path===`${e}.attributes`&&typeof rt.value==="object"&&rt.value!==null&&!Array.isArray(rt.value))Ee[e]={...Ee[e],attributes:rt.value};else if(rt.path.startsWith(`${e}.attributes.`)){let Dt=rt.path.slice(`${e}.attributes.`.length);Ee[e]={...Ee[e],attributes:{...Ee[e]?.attributes,[Dt]:rt.value}}}}else if(rt.op==="add"&&rt.path==="members"&&rt.value!==void 0){let Dt=rt.value;Ee.members=[...Ee.members??[],...Dt]}else if(rt.op==="remove"&&rt.path?.startsWith("members[")){let Dt=rt.path.match(/members\[value eq "([^"]+)"\]/);if(Dt)Ee.members=(Ee.members??[]).filter((Mt)=>Mt.value!==Dt[1])}else if(rt.op==="remove"&&rt.path?.startsWith(`${e}.attributes.`)){let Dt=rt.path.slice(`${e}.attributes.`.length),Mt={...Ee[e]?.attributes};delete Mt[Dt],Ee[e]={...Ee[e],attributes:Mt}}let Le=await nn(T.group,Ee);if(Le.issues)return O.error("Group patch validation failed",{"ion.operation":"scim.group.patch","ion.outcome":"failure",validationIssues:Le.issues}),Je(400,`Request validation failed: ${Le.issues.map((rt)=>rt.message).join("; ")}`,"invalidValue");let Ye=Te?.kind??Sn(Ee),st=Te?Vr(Te.entity):Rs(Ee),ct=Te?.entity.assignableSubjectTypes??Ae[e]?.assignableSubjectTypes??Ee[e]?.assignableSubjectTypes,mt=Hn(Gn(Ae.members,Ye,ve,st,ct),Gn(Ee.members,Ye,ve,st,ct)),at,tt=!Te||(De.Operations??[]).some((rt)=>!lt(rt));await kn(Ve,async()=>{if(tt)at=await Lr(Ge,Ee,ve,Te?.entity)},mt,tt?{oaa:()=>jr(X,at,Ye)}:void 0);let ft=await Un(Ge,Q,ve);return wt(Ze(ft,Re,Se))},We=async(Re)=>{let Se=Ke(Re);if(Se&&Se.entity.requestable!==!0)return _e(Re);if(Se)await Qe(Se,!0);let ve=await Un(Ge,Q,Re);if(!Ue(ve))return _e(Re);let Te=ve[e];if((Se||Te?.source==="code")&&Te?.deprecated!==!0)return Je(403,`Code-owned entitlement "${Re}" can be deleted only after it is marked deprecated.`,"mutability");let Ae=Sn(ve);if(Q){let De=await Q.listByTarget(Ae,Re),je=[];for(let Ee of De.items)await En(Ve,Ee,je);await Jn(Ve,je)}return await Po(Ge,Re),new Response(null,{status:204})};Xt={handler:ge}}let Ut,It,Wt;if(Oe.userStore){let{userStore:Ge,inboundUsers:Ze}=Oe,Ke=(Se)=>Se?.find((ve)=>ve.primary)?.value||Se?.[0]?.value,Qe=async(Se)=>{if(Ze?.mapBaseUserToScim)return await Ze.mapBaseUserToScim(Se);return Er(Se)},Fe=async(Se,ve,Te)=>{let Ae=await Qe(Se),De=Ae.id??Se.id;return{...Ae,id:De,meta:{...Ae.meta,resourceType:"User",location:De?kt(ve,`${Te}/${encodeURIComponent(De)}`):void 0}}},Xe=async(Se,ve)=>{if(Ze?.mapValidatedScimToBaseUser)return await Ze.mapValidatedScimToBaseUser(Se,ve);let Te=new Date,Ae=Ke(Se.emails),De=Se.name?.formatted||[Se.name?.givenName,Se.name?.middleName,Se.name?.familyName].filter(Boolean).join(" ").trim()||Se.displayName,je=Se.id||ve.existing?.id||Kn(),Ee=Se.userName||Ae||ve.existing?.userName||je,Le=De||Se.displayName||ve.existing?.name||Ee,Ye=Object.fromEntries(Object.entries(Se).filter(([ft,rt])=>ft.startsWith("urn:")&&ft!==Mn&&ft!==d&&rt!==void 0)),st=Se[d],ct=i(st?.attributes??{},I),mt=st?.ecid!==void 0&&st.ecid!==null?D(st.ecid):ve.existing?.ecid,at=st?.accountClass??ve.existing?.accountClass,tt=ve.existing?.sso;return{...ve.existing??{},id:je,userName:Ee,name:Le,email:Ae||ve.existing?.email||Ee,avatar:Se.profileUrl,sso:{...tt??{},profile:{...tt?.profile??{},sub:je,iss:tt?.profile.iss??"iam-provisioned",aud:tt?.profile.aud??"iam-provisioned",exp:tt?.profile.exp??Math.floor(Date.now()/1000)+3600,iat:tt?.profile.iat??Math.floor(Date.now()/1000),email:Ae||ve.existing?.email||Ee,email_verified:!0,name:Le,preferred_username:Ee},tenant:tt?.tenant??{id:"iam-provisioned",name:"IAM Provisioned"},scope:tt?.scope??"openid profile email",tokenType:tt?.tokenType??"Bearer",expires:tt?.expires??new Date(Date.now()+3600000)},externalId:Se.externalId,ecid:mt,accountClass:at,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(Ye).length>0?Ye:void 0,createdAt:ve.existing?.createdAt??(Se.meta?.created?new Date(Se.meta.created):Te),updatedAt:Se.meta?.lastModified?new Date(Se.meta.lastModified):Te,userType:Se.userType,...ct}},lt=(Se,ve,Te)=>{Se[ve]=Te},Ce=(Se,ve,Te)=>{let Ae=Se[ve];if(Array.isArray(Ae)){Se[ve]=[...Ae,...Array.isArray(Te)?Te:[Te]];return}if(Ae&&typeof Ae==="object"&&!Array.isArray(Ae)&&Te&&typeof Te==="object"&&!Array.isArray(Te)){Se[ve]={...Ae,...Te};return}Se[ve]=Te},Ue=(Se,ve,Te)=>{let Ae=ve.match(/^(urn:.*:(?:User|Group))(?::(.+))?$/),De=Ae?[Ae[1],...Ae[2]?.split(":")??[]]:ve.split("."),je=Se;for(let Le of De.slice(0,-1)){let Ye=je[Le];if(Ye===void 0){if(!Te)return null;je[Le]={}}else if(Ye===null||typeof Ye!=="object"||Array.isArray(Ye)){if(!Te)return null;je[Le]={}}je=je[Le]}let Ee=De.at(-1);if(!Ee)return null;return{parent:je,key:Ee}},_e=(Se,ve)=>{let Te=ve.op.toLowerCase();if(!ve.path){if(Te!=="remove"&&ve.value&&typeof ve.value==="object"&&!Array.isArray(ve.value))Object.assign(Se,ve.value);return}let Ae=ve.path.match(/^([A-Za-z0-9]+)\[value eq "([^"]+)"\]$/);if(Ae&&Te==="remove"){let[,je,Ee]=Ae,Le=Se[je];if(Array.isArray(Le))Se[je]=Le.filter((Ye)=>!(Ye&&typeof Ye==="object"&&("value"in Ye)&&Ye.value===Ee));return}let De=Ue(Se,ve.path,Te!=="remove");if(!De)return;if(Te==="remove"){delete De.parent[De.key];return}if(Te==="add"){Ce(De.parent,De.key,ve.value);return}lt(De.parent,De.key,ve.value)},ge=async(Se,ve)=>{if(!await _t(Se))return Je(401,"Authorization required");let Ae=new URL(Se.url),De=ve?.basePath??"/Users",je=Ae.pathname;if(je.startsWith(De))je=je.substring(De.length);let Le=je.match(/^\/([^/]+)$/)?.[1],Ye=Se.method;try{if(Le)switch(Ye){case"GET":return await xe(Se,De,Le);case"PUT":return await ze(Se,De,Le);case"PATCH":return await We(Se,De,Le);case"DELETE":return await Re(Le);default:return Je(405,"Method not allowed")}else if(je===""||je==="/")switch(Ye){case"GET":return await be(Se,De);case"POST":return await Pe(Se,De);default:return Je(405,"Method not allowed")}return Je(404,"Resource not found")}catch(st){if(st instanceof On)return Cs(st);if(j(st))return Je(409,st.message,"uniqueness");return O.error("Users inbound handler error",{"ion.operation":"scim.users.handler","ion.outcome":"failure"},st),Je(500,st instanceof Error?st.message:"Internal server error")}},be=async(Se,ve)=>{let Te=new URL(Se.url),Ae=Te.searchParams.get("startIndex"),De=Te.searchParams.get("count"),je=Ae!=null?parseInt(Ae,10):void 0,Ee=De!=null?parseInt(De,10):void 0,Le=je!=null&&!Number.isNaN(je)?Math.max(0,je-1):0,Ye=Ee!=null&&!Number.isNaN(Ee)?Ee:void 0,st=Is(Te.searchParams.get("filter"));if(st!==void 0){let at=await Ge.lookup({externalId:st}),tt=at?[await Fe(at,Se,ve)]:[];return Jt(tt,{totalResults:tt.length,startIndex:1,itemsPerPage:tt.length})}let ct=await Ge.list({start:Le,limit:Ye}),mt=await Promise.all(ct.items.map((at)=>Fe(at,Se,ve)));return Jt(mt,{totalResults:ct.total,startIndex:Le+1,itemsPerPage:ct.count})},xe=async(Se,ve,Te)=>{let Ae=await Ge.get(Te);if(!Ae)return Je(404,`User ${Te} not found`,"invalidValue");return wt(await Fe(Ae,Se,ve))},Ie=async(Se,ve)=>{let Te=Ve.accessIndex;if(!Te?.setSubjectDisabled||!ve.id)return;let Ae=Se?Se.active??!0:!0,De=ve.active??!0;if(Se&&Ae===De)return;if(!Se&&De)return;await Te.setSubjectDisabled(ve.id,"user",!De)},Pe=async(Se,ve)=>{let Te=await Se.json(),Ae=await nn(T.user,Te);if(Ae.issues)return O.error("User creation validation failed",{"ion.operation":"scim.user.create","ion.outcome":"failure",validationIssues:Ae.issues}),Je(400,`Request validation failed: ${Ae.issues.map((Le)=>Le.message).join("; ")}`,"invalidValue");let De=Ae.value;if(!De.userName&&!De.emails?.[0]?.value)return Je(400,"userName or email is required","invalidValue");let je=await Xe(De,{mode:"create"});await kn(Ve,async()=>{await Ge.upsert(je),await Ie(void 0,je)},Or(void 0,je),{oaa:async()=>{await _r(X,je)},delta:async()=>{await Ve.iamDelta?.onUserUpsert(je)}});let Ee=await Fe(je,Se,ve);return wt(Ee,201,Ee.meta?.location)},ze=async(Se,ve,Te)=>{let Ae=await Ge.get(Te);if(!Ae)return Je(404,`User ${Te} not found`,"invalidValue");let De=await Se.json(),je=await nn(T.user,De);if(je.issues)return O.error("User replacement validation failed",{"ion.operation":"scim.user.replace","ion.outcome":"failure",validationIssues:je.issues}),Je(400,`Request validation failed: ${je.issues.map((Ye)=>Ye.message).join("; ")}`,"invalidValue");let Ee=je.value,Le=await Xe({...Ee,id:Te},{existing:Ae,mode:"replace"});return Le.createdAt=Ae.createdAt,Le.updatedAt=new Date,await kn(Ve,async()=>{await Ge.upsert(Le),await Ie(Ae,Le)},Or(Ae,Le),{oaa:async()=>{await _r(X,Le)},delta:async()=>{await As(Ve.iamDelta,Ae,Le)}}),wt(await Fe(Le,Se,ve))},We=async(Se,ve,Te)=>{let Ae=await Ge.get(Te);if(!Ae)return Je(404,`User ${Te} not found`,"invalidValue");let je=(await Se.json()).Operations??[],Le={...await Qe(Ae)};for(let ct of je)_e(Le,ct);let Ye=await nn(T.user,Le);if(Ye.issues)return O.error("User patch validation failed",{"ion.operation":"scim.user.patch","ion.outcome":"failure",validationIssues:Ye.issues}),Je(400,`Request validation failed: ${Ye.issues.map((ct)=>ct.message).join("; ")}`,"invalidValue");let st=await Xe(Ye.value,{existing:Ae,mode:"patch"});return st.updatedAt=new Date,await kn(Ve,async()=>{await Ge.upsert(st),await Ie(Ae,st)},Or(Ae,st),{oaa:async()=>{await _r(X,st)},delta:async()=>{await As(Ve.iamDelta,Ae,st)}}),wt(await Fe(st,Se,ve))},Re=async(Se)=>{let ve=await Ge.get(Se);if(!ve)return Je(404,`User ${Se} not found`,"invalidValue");if(Q){let Te=[];for await(let Ae of u((De,je)=>Q.listBySubject(Se,"user",{start:De,limit:je})))await En(Ve,Ae,Te);await Jn(Ve,Te)}if(await Ge.delete(Se),await Ve.accessIndex?.setSubjectDisabled?.(Se,"user",!1),ve.externalId&&Ve.iamDelta?.isReady())await rn(Ve,"iam.delta.egress","IAM delta user delete failed after SCIM write; full aggregation will reconcile",()=>Ve.iamDelta?.onUserDelete(ve.externalId)??Promise.resolve(),{id:Se,kind:"user"});else if(Ve.iamDelta?.isReady())Ve.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(Ve.authz.oaa.isReady())await rn(Ve,"authz.oaa.delete","OAA incremental user delete failed; full sync will reconcile",()=>Ve.authz.oaa.deleteUser(Se),{id:Se,kind:"user"});return new Response(null,{status:204})};Ut={handler:ge}}let Vt=async(Ge,Ze)=>{if(!Q)return;let Ke=[];for await(let Qe of u((Fe,Xe)=>Q.listBySubject(Ge,Ze,{start:Fe,limit:Xe})))await En(Ve,Qe,Ke);await Jn(Ve,Ke)};if(Oe.workloadIdentityStore){let{workloadIdentityStore:Ge,inboundWorkloads:Ze}=Oe;It=Ts({resourceType:"Workload",subjectType:"workload",store:Ge,validator:T.workload??le,toScim:async(Ke)=>await(Ze?.mapBaseWorkloadToScim?.(Ke)??Dr(Ke)),fromScim:async(Ke,Qe)=>{if(Ze?.mapValidatedScimToBaseWorkload)return Ze.mapValidatedScimToBaseWorkload(Ke,Qe);let Fe=Qe.existing,Xe=Ke,lt=Xe.id?.trim()||Fe?.id||Kn(),Ce=i(Xe.attributes??{},x);return{...Fe??{},id:lt,externalId:Xe.externalId??Fe?.externalId,clientId:Xe.userName??Fe?.clientId??lt,displayName:Xe.displayName??Fe?.displayName,description:Xe.description??Fe?.description,active:Xe.active??Fe?.active??!0,providerId:Fe?.providerId,requestUrl:Fe?.requestUrl,...Ce}},projections:[{channel:"oaa",upsert:async(Ke)=>{if(X.oaa.isReady())await X.oaa.pushWorkload(Ke)},delete:async(Ke)=>{if(X.oaa.isReady())await X.oaa.deleteWorkload(Ke.id)}},{channel:"delta",upsert:async(Ke,Qe)=>{let Fe=Qe?.externalId??Qe?.id,Xe=Ke.externalId??Ke.id;if(Fe&&Fe!==Xe)await He?.onWorkloadDelete(Fe);await He?.onWorkloadUpsert(Ke)},delete:async(Ke)=>{await He?.onWorkloadDelete(Ke.externalId??Ke.id)}}]},{validateAuth:_t,accessStore:Q,accessIndex:ye,revokeSubjectAccess:Vt,log:O})}if(Oe.customerStore){let{customerStore:Ge,inboundCustomers:Ze}=Oe;Wt=Ts({resourceType:"Customer",subjectType:"customer",store:Ge,validator:T.customer??pe,toScim:async(Ke)=>await(Ze?.mapBaseCustomerToScim?.(Ke)??Mr(Ke)),fromScim:async(Ke,Qe)=>{if(Ze?.mapValidatedScimToBaseCustomer)return Ze.mapValidatedScimToBaseCustomer(Ke,Qe);let Fe=Qe.existing,Xe=Ke,lt=Xe.id?.trim()||Fe?.id||Kn(),Ce=i(Xe.attributes??{},v),Ue=Xe.emails?.find((_e)=>_e.primary)?.value??Xe.emails?.[0]?.value;return{...Fe??{},id:lt,externalId:Xe.externalId??Fe?.externalId??lt,userName:Xe.userName??Fe?.userName??lt,name:Xe.displayName??Fe?.name??Xe.userName??lt,email:Ue??Fe?.email??"",displayName:Xe.displayName??Fe?.displayName,emails:Xe.emails??Fe?.emails,active:Xe.active??Fe?.active??!0,providerId:Fe?.providerId,requestUrl:Fe?.requestUrl,...Ce}},projections:[{channel:"oaa",upsert:async(Ke)=>{if(X.oaa.isReady())await X.oaa.pushCustomer(Ke)},delete:async(Ke)=>{if(X.oaa.isReady()&&Ke.id)await X.oaa.deleteCustomer(Ke.id)}},{channel:"delta",upsert:async(Ke,Qe)=>{let Fe=Qe?.externalId??Qe?.id,Xe=Ke.externalId??Ke.id;if(Fe&&Fe!==Xe)await He?.onCustomerDelete(Fe);await He?.onCustomerUpsert(Ke)},delete:async(Ke)=>{let Qe=Ke.externalId??Ke.id;if(Qe)await He?.onCustomerDelete(Qe)}}]},{validateAuth:_t,accessStore:Q,accessIndex:ye,revokeSubjectAccess:Vt,log:O})}async function Zt(Ge,Ze){xt();let Ke=new URL(Ge.url).pathname,Qe=Nt(Ze?.usersUrl??Oe.usersUrl??"/api/iam/Users")??"/api/iam/Users",Fe=Nt(Ze?.groupsUrl??Oe.groupsUrl??"/api/iam/Groups")??"/api/iam/Groups",Xe=Nt(Ze?.workloadsUrl??Oe.workloadsUrl??"/api/iam/Workloads")??"/api/iam/Workloads",lt=Nt(Ze?.customersUrl??Oe.customersUrl??"/api/iam/Customers")??"/api/iam/Customers",Ce=`${xs(Qe,Fe,Xe,lt)??"/api/iam"}/AccessRequests`,Ue=await pn(Ge,Ze);if(Ue)return Ue;let _e=(ge)=>Ke===ge||Ke.startsWith(`${ge}/`);if(_e(Qe)){if(!ut)return Je(404,"SCIM Users endpoint is disabled by RemoteConfig");if(!Ut)return Je(501,"SCIM Users endpoint is enabled by RemoteConfig but no user store capability is wired by the application.");return Ut.handler(Ge,{basePath:Qe})}if(_e(Fe)){if(!gt)return Je(404,"SCIM Groups endpoint is disabled by RemoteConfig");if(!Xt)return Je(501,"SCIM Groups endpoint is enabled by RemoteConfig but no AccessCatalogStore capability is wired by the application.");return Xt.handler(Ge,{basePath:Fe})}if(_e(Xe)){if(!Ct)return Je(404,"SCIM Workloads endpoint is disabled by RemoteConfig");if(!It)return Je(501,"SCIM Workloads endpoint is enabled by RemoteConfig but no workload identity store capability is wired by the application.");return It.handler(Ge,{basePath:Xe})}if(_e(lt)){if(!yt)return Je(404,"SCIM Customers endpoint is disabled by RemoteConfig");if(!Wt)return Je(501,"SCIM Customers endpoint is enabled by RemoteConfig but no customer store capability is wired by the application.");return Wt.handler(Ge,{basePath:lt})}if(_e(Ce)){if(!Oe.accessRequests)return Je(404,"AccessRequests endpoint is not configured");if(!await _t(Ge))return Je(401,"Authorization required");if(Ge.method==="GET"){if(!Oe.accessRequests.get)return Je(404,"AccessRequests read endpoint is not configured");let xe=Ke.startsWith(`${Ce}/`)?Ke.slice(Ce.length+1):void 0;if(!xe||xe.includes("/"))return Je(404,"AccessRequest not found");let Ie;try{Ie=decodeURIComponent(xe)}catch{return Je(400,"AccessRequest id is invalid","invalidValue")}let Pe=await Oe.accessRequests.get(Ie);if(!Pe)return Je(404,"AccessRequest not found");return wt(Pe,200,Pe.trackingUrl)}if(Ge.method!=="POST"||Ke!==Ce)return Je(405,"Method not allowed");let ge;try{ge=await Ge.json()}catch{return Je(400,"Request body must be valid JSON","invalidSyntax")}if(typeof ge.subject!=="string"||!ge.subject||typeof ge.target!=="string"||!ge.target||ge.subjectType!=="user"&&ge.subjectType!=="workload"&&ge.subjectType!=="customer"||ge.targetType!=="group"&&ge.targetType!=="role"&&ge.targetType!=="permission"||ge.operation!=="grant"&&ge.operation!=="revoke")return Je(400,"subject, subjectType, targetType, target, and operation are required","invalidValue");let be=await Oe.accessRequests.create({subject:ge.subject,subjectType:ge.subjectType,targetType:ge.targetType,target:ge.target,operation:ge.operation,justification:typeof ge.justification==="string"?ge.justification:void 0});return wt(be.request,be.created?201:200,be.request.trackingUrl)}return Je(404,"Resource not found")}let Et;return Et={...Oe,describe:()=>({module:"iam",active:!0,ready:Et.isReady?.()??!0,url:Oe.url,deltaAudience:Oe.deltaAudience,accessRequests:{...Oe.url?{iam:`${R(Oe.url)}/AccessRequests`}:{},ciam:{}},users:{...hn(Oe.users),storeWired:Oe.userStore!==void 0},workloads:{...hn(Oe.workloads),storeWired:Oe.workloadIdentityStore!==void 0},customers:{...hn(Oe.customers),storeWired:Oe.customerStore!==void 0},groups:{enabled:gt,catalogWired:he!==void 0},urls:{usersUrl:Oe.usersUrl??"",groupsUrl:Oe.groupsUrl??"",workloadsUrl:Oe.workloadsUrl??"",customersUrl:Oe.customersUrl??""}}),users:hn(Oe.users),workloads:hn(Oe.workloads),customers:hn(Oe.customers),groups:{enabled:gt},createUser:mn,getBaseUrl:bn,groups_outbound:Pt,groups_inbound:Xt,users_inbound:Ut,workloads_inbound:It,customers_inbound:Wt,handler:Zt,delta:He},Et}function Br(T,O){let N=new TextEncoder().encode(T),X=typeof O==="string"?new TextEncoder().encode(O):O,Q=new Uint8Array(N.length+1+X.length);return Q.set(N,0),Q[N.length]=46,Q.set(X,N.length+1),Q}function _o(T){let O=T.replace(/-/g,"+").replace(/_/g,"/"),N=O.length%4===0?"":"=".repeat(4-O.length%4),X=atob(O+N),Q=new Uint8Array(X.length);for(let ye=0;ye<X.length;ye++)Q[ye]=X.charCodeAt(ye);return Q}function jo(T){let O="";for(let N of T)O+=String.fromCharCode(N);return btoa(O).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function Us(T){let O=JSON.parse(T);if(!O||typeof O!=="object"||!Array.isArray(O.keys))throw Error("Invalid JWKS: expected { keys: [...] }");return O}function Lo(T){return JSON.stringify(T)}async function No(T){return crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:T.x},{name:"Ed25519"},!0,["verify"])}async function $o(T){return crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:T.x,d:T.d},{name:"Ed25519"},!0,["sign"])}async function Wo(T){let N=(typeof T.jwks==="string"?Us(T.jwks):T.jwks).keys.find((X)=>X.kid===T.kid&&X.kty==="OKP"&&X.crv==="Ed25519");if(!N?.x)return!1;try{let X=await No(N),Q=Br(T.requestId,T.rawBody),ye=_o(T.signatureB64Url);return crypto.subtle.verify({name:"Ed25519"},X,ye,Q)}catch{return!1}}async function Vo(T){let O=await $o(T.privateKeyJwk),N=Br(T.requestId,T.rawBody),X=await crypto.subtle.sign({name:"Ed25519"},O,N);return jo(new Uint8Array(X))}async function qo(T){let O=await crypto.subtle.generateKey({name:"Ed25519"},!0,["sign","verify"]),N=await crypto.subtle.exportKey("jwk",O.privateKey),Q=(await crypto.subtle.exportKey("jwk",O.publicKey)).x,ye=N.d;if(!Q||!ye)throw Error("Failed to export Ed25519 key material (missing x/d)");return{privateJwk:{kty:"OKP",crv:"Ed25519",x:Q,d:ye,kid:T,alg:"EdDSA",use:"sig"},publicJwks:{keys:[{kty:"OKP",crv:"Ed25519",x:Q,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 Yn(T,O){if(typeof T!=="number"||!Number.isFinite(T))return O.default;let N=Math.floor(T);if(N<O.min)return O.min;if(N>O.max)return O.max;return N}function Es(T){return{ttlMs:Yn(T?.ttlSeconds,_n.jwksTtlSeconds)*1000,maxEntries:Yn(T?.maxEntries,_n.jwksMaxEntries)}}function Ds(T){let O=T?.read;return{read:{enabled:O?.enabled===!0,ttlMs:Yn(O?.ttlSeconds,_n.sessionReadTtlSeconds)*1000,maxEntries:Yn(O?.maxEntries,_n.sessionReadMaxEntries)}}}function zo(T){return{jwks:Es(T?.jwks),session:Ds(T?.session)}}var Xn=new TextEncoder,Bo=new TextDecoder;function _s(T){let O="";for(let N of T)O+=String.fromCharCode(N);return btoa(O).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function Ms(T){return _s(Xn.encode(JSON.stringify(T)))}function js(T){if(!/^[A-Za-z0-9_-]+$/.test(T))return;let O=T.replace(/-/g,"+").replace(/_/g,"/").padEnd(Math.ceil(T.length/4)*4,"=");try{return Uint8Array.from(atob(O),(N)=>N.charCodeAt(0))}catch{return}}function Os(T){let O=js(T);if(!O)return;try{let N=JSON.parse(Bo.decode(O));return N!==null&&typeof N==="object"&&!Array.isArray(N)?N:void 0}catch{return}}function Go(T){return Xn.encode(T)}function Ls(T){let O=new Uint8Array(T.byteLength);return O.set(T),O.buffer}async function Ns(T){return crypto.subtle.importKey("raw",Ls(Go(T)),{name:"HMAC",hash:"SHA-256"},!1,["sign","verify"])}function Ko(T){let O=T.active.trim(),N=new Map(Object.entries(T.keys).map(([Q,ye])=>[Q.trim(),{kid:Q.trim(),secret:ye}])),X=N.get(O);if(!O||!X?.secret)throw Error("Signing key ring must name a non-empty active key.");for(let Q of N.values())if(!Q.kid||!Q.secret)throw Error("Signing key ring ids and secrets must be non-empty.");return{current:()=>X,find:(Q)=>N.get(Q)}}async function Jo(T,O,N){let X=Math.floor(N.ttlSeconds);if(!Number.isFinite(X)||X<1)throw Error("Compact JWT ttlSeconds must be a positive integer.");let Q=O.current();if(!Q.kid||!Q.secret)throw Error("Signing key ring returned an invalid active key.");let ye=Math.floor(Date.now()/1000),he=Ms({alg:"HS256",kid:Q.kid,typ:"JWT"}),we=Ms({...T,iat:ye,exp:ye+X}),ke=`${he}.${we}`,fe=await crypto.subtle.sign("HMAC",await Ns(Q.secret),Xn.encode(ke));return`${ke}.${_s(new Uint8Array(fe))}`}async function Ho(T,O){let N=T.split(".");if(N.length!==3)return null;let[X,Q,ye]=N;if(!X||!Q||!ye)return null;let he=Os(X);if(he?.alg!=="HS256"||he.typ!=="JWT"||typeof he.kid!=="string")return null;let we=O.find(he.kid);if(!we?.secret)return null;let ke=js(ye);if(!ke)return null;if(!await crypto.subtle.verify("HMAC",await Ns(we.secret),Ls(ke),Xn.encode(`${X}.${Q}`)))return null;let Be=Os(Q);if(!Be)return null;let{iat:He,exp:et}=Be;if(typeof He!=="number"||typeof et!=="number"||!Number.isSafeInteger(He)||!Number.isSafeInteger(et))return null;let dt=Math.floor(Date.now()/1000);if(He>dt+60||et+60<=dt)return null;return Be}function Fo(T){let O={};if(!T)return O;let N=T.split(";");for(let X of N){let Q=X.trim();if(!Q)continue;let ye=Q.indexOf("=");if(ye===-1)continue;O[Q.slice(0,ye).trim()]=Q.slice(ye+1).trim()}return O}function $s(T){if(!T.expiresAt)return!1;let O=T.expiresAt instanceof Date?T.expiresAt:new Date(T.expiresAt);return!Number.isNaN(O.getTime())&&Date.now()>O.getTime()}function Yo(T){if(!T||typeof T!=="object"||Array.isArray(T))return;let{access_token:O,id_token:N,refresh_token:X,tokens:Q,...ye}=T;return ye}function Lt(T,O){let N=T[O];return typeof N==="string"?N:""}function Xo(T,O){let N=T.exp;if(typeof N==="number")return new Date(N*1000);if(typeof N==="string"&&N.trim()){let X=Number(N);if(!Number.isNaN(X))return new Date(X*1000)}if(O instanceof Date)return O;if(O){let X=new Date(O);if(!Number.isNaN(X.getTime()))return X}return new Date}function Zo(T){let O=T.claims;if(!O?.sub||typeof O.sub!=="string")return;let N=Xo(O,T.expiresAt);if(T.authType==="sso")return{id:O.sub,userName:Lt(O,"preferred_username"),name:Lt(O,"name"),email:Lt(O,"email"),avatar:Lt(O,"picture")||void 0,sso:{profile:O,tenant:{id:Lt(O,"idp")||Lt(O,"iss"),name:Lt(O,"iss")},tokenType:"Bearer",expires:N}};return{id:O.sub,userName:Lt(O,"preferred_username"),name:Lt(O,"name"),email:Lt(O,"email"),avatar:Lt(O,"picture")||void 0,userType:"customer",ciam:{profile:O,scope:"openid profile email",tokenType:"Bearer",expires:N}}}function Qo(T){if(T.authType!=="sso"&&T.authType!=="ciam")return;if($s(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:Yo(T.claims)}}function ea(T,O){if(!T.endsWith(".session"))return!1;if(!O||O.length===0)return!0;return O.some((N)=>T===`${N}.session`)}function ta(T){if(T===void 0)return;let O=(Array.isArray(T)?T:[T]).map((N)=>N.trim()).filter((N)=>N.length>0);return O.length>0?O:void 0}async function Ws(T,O,N){return(await Vs(T,O,N)).map(Qo).filter((Q)=>Boolean(Q))}async function Vs(T,O,N){let X=Fo(T.headers.get("cookie")),Q=ta(N?.cookiesPrefix),ye=[],he=new Set;for(let[we,ke]of Object.entries(X)){if(!ea(we,Q)||!ke)continue;if(he.has(ke))continue;he.add(ke);let fe=await O.get(ke);if(!fe)continue;if(fe.authType!=="sso"&&fe.authType!=="ciam")continue;if($s(fe))continue;ye.push(fe)}return ye}async function na(T,O,N){return(await Ws(T,O,N)).map(Zo).filter((Q)=>Boolean(Q))}var ra="@ionite/core",sa=p(h(ra));async function ia(T,O){let N=await en({idToken:T,jwksUri:O.jwksUri,issuer:O.issuer,audience:O.audience}),X=await sa.validate(N);if(X.issues)throw Error(`ID token claims validation failed: ${X.issues.map((he)=>he.message).join("; ")}`);let Q=X.value;if(Q===void 0)throw Error("ID token claims missing");return H(Q)}function bt(T){return Date.now()-T}function Gr(T){if(T instanceof Error)return{"error.name":T.name,"error.message":T.message};return{"error.name":typeof T,"error.message":String(T)}}function Zn(T,O){if(!T)return{};try{let N=new URL(T);return{[`${O}.origin`]:N.origin,[`${O}.path`]:N.pathname}}catch{return{[`${O}.path`]:T.startsWith("/")?T:`/${T}`}}}function Qn(T,O=5){if(!Array.isArray(T))return[String(T)];return T.slice(0,O).map((N)=>{if(!N||typeof N!=="object")return String(N);let X=N,Q=Array.isArray(X.path)?X.path.join("."):String(X.path??""),ye=typeof X.message==="string"?X.message:String(X.message??"validation failed");return Q?`${Q}: ${ye}`:ye})}function oa(T){if(!T||typeof T!=="object")return{};let O=T;return{oidc_error:typeof O.error==="string"?O.error:void 0,oidc_error_description:typeof O.error_description==="string"?O.error_description:void 0,oidc_error_uri:typeof O.error_uri==="string"?O.error_uri:void 0}}function aa(T,O={}){let N=typeof T==="string"?T:T?.headers.get("cookie")??void 0;if(!N)return[];let Q=`${O.cookiePrefix??"ion.sso"}.`,ye=new Set;for(let he of Object.keys(ua(N))){if(!he.startsWith(Q))continue;let we=he.slice(Q.length),ke=we.lastIndexOf(".");if(ke<=0)continue;let fe=we.slice(0,ke).trim();if(fe)ye.add(fe)}return Array.from(ye)}function ca(T,O,N,X,Q){if(!N&&!X)return;let ye=new WeakMap,he=new Map,we={...N,...X},ke=!!(we.authority&&we.tokenUrl&&we.authorizationUrl&&we.clientId&&we.redirectUri&&we.scope),fe={...we,authority:ke?t(we.authority,"Missing 'authority' from SSO Config"):we.authority,tokenUrl:ke?t(we.tokenUrl,"Missing 'tokenUrl' from SSO Config"):we.tokenUrl,authorizationUrl:ke?t(we.authorizationUrl,"Missing 'authorizationUrl' from SSO Config"):we.authorizationUrl,clientId:ke?t(we.clientId,"Missing 'clientId' from SSO Config"):we.clientId,redirectUri:ke?t(we.redirectUri,"Missing 'redirectUri' from SSO Config"):we.redirectUri,scope:ke?t(we.scope,"Missing 'scope' from SSO Config"):we.scope,responseType:we.responseType??"code",cookiesSecure:we.cookiesSecure!==void 0?we.cookiesSecure:!0,cookiesSameSite:we.cookiesSameSite!==void 0?we.cookiesSameSite:"Strict",cookiesPrefix:we.cookiesPrefix??(we.clientId?`ion.sso.${we.clientId}`:"ion.sso"),cookiesPath:we.cookiesPath??"/",cookiesDomain:Nn(we.cookiesDomain)},Be=Math.min(600,Math.max(0,Math.floor(Number(fe.rotationGraceSeconds??60))||0))*1000,He=Math.floor(Number(fe.sessionWindowSeconds??86400)),et=Number.isFinite(He)&&He>=1?He:86400;function dt(){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 ot(Ce){if(!fe)throw Error("ionite SSO Manager not initialized");let Ue=ye.get(Ce);if(Ue)return Ue;let _e=$e(Ce);return ye.set(Ce,_e),_e}async function $e(Ce){try{let{tokens:Ue,session:_e,refreshedUser:ge}=await It(Ce);if(!Ue)return{status:"unauthenticated"};if(_e)Rn(Ce,"user",_e.entitlements);if(ge)return{status:"authenticated",value:ge};if(_e?.claims)return{status:"authenticated",value:At(_e.claims,Ue,Pt(_e.expiresAt))};return{status:"unauthenticated"}}catch(Ue){if(qs(Ue))return{status:"unauthenticated"};return O.error("Error parsing user from cookies",{"ion.operation":"cookie.parse","ion.outcome":"degraded"},Ue),{status:"degraded",error:Ue instanceof Error?Ue:void 0}}}async function Ve(Ce){let Ue=await ot(Ce);return Ue.status==="authenticated"?Ue.value:void 0}async function nt(Ce){if(!fe)throw Error("ionite SSO Manager not initialized");dt();let Ue=t(fe.redirectUri,"Missing 'redirectUri' from SSO Config"),_e=t(fe.authorizationUrl,"Missing 'authorizationUrl' from SSO Config"),ge=t(fe.clientId,"Missing 'clientId' from SSO Config"),be=t(fe.scope,"Missing 'scope' from SSO Config"),xe=fe.cookiesSecure?Ce.url.replace(/^http:\/\//,"https://"):Ce.url,Ie=jt(),Pe=jt(64),ze=jt(),We=Ue;try{new URL(We)}catch{if(xe)try{let Ae=new URL(xe),De=We.startsWith("//")?We.slice(1):We.startsWith("/")?We:`/${We}`;We=new URL(De,Ae.origin).toString()}catch{try{let Ae=new URL(_e),De=We.startsWith("//")?We.slice(1):We.startsWith("/")?We:`/${We}`;We=new URL(De,Ae.origin).toString()}catch{throw Error(`Invalid redirectUri: "${Ue}". It must be a valid absolute URL.`)}}}let Re=new URL(_e);Re.searchParams.append("client_id",ge),Re.searchParams.append("redirect_uri",We),Re.searchParams.append("response_type","code"),Re.searchParams.append("scope",be),Re.searchParams.append("state",Ie),Re.searchParams.append("nonce",ze);let Se=await Pn(Pe);Re.searchParams.append("code_challenge",Se),Re.searchParams.append("code_challenge_method","S256");let ve=await fe.beforeLogin?.({request:Ce}),Te=ve===void 0?{state:Ie,codeVerifier:Pe,nonce:ze}:{state:Ie,codeVerifier:Pe,nonce:ze,context:ve};return new Response("Redirecting to SSO Provider",{status:302,headers:{Location:Re.toString(),"Set-Cookie":Vt(Fe(Ie),Te,fe.loginStateTtl??600,"Lax")}})}async function Oe(Ce){if(!fe)throw Error("ionite SSO Manager not initialized");let Ue;try{Ue=await Ve(Ce)}catch{Ue=void 0}let _e=await fe.beforeLogout?.({request:Ce,user:Ue}),ge=Qe("session",Ce),be;try{be=await It(Ce);let Se=be.tokens?.refresh_token??Qe("refresh",Ce);if(Se)await Ht(Se)}catch(Se){O.warn("Failed to revoke token",{"ion.operation":"token.revoke","ion.outcome":"degraded"},Se)}if(fe.sessionStore)try{let Se=be?.sid??ge;if(Se)await fe.sessionStore.delete(Se)}catch(Se){O.warn("Failed to delete session",{"ion.operation":"session.delete","ion.outcome":"degraded"},Se)}let xe=Ge(),Ie=await fe.afterLogout?.({request:Ce,context:_e}),Pe=tn(Ie,"/",Ce.url);if(Pe.response){let Se=new Headers(Pe.response.headers);for(let[,ve]of xe)Se.append("Set-Cookie",ve);return new Response(Pe.response.body,{status:Pe.response.status,statusText:Pe.response.statusText,headers:Se})}let ze=Pe.location??"/",We=Ce.headers.get("accept");if(We?.includes(o)||We?.includes("text/javascript"))return new Response(JSON.stringify({success:!0,message:"Logged out",redirect:ze}),{status:200,headers:[["Content-Type",o],...xe]});return new Response("Logged out",{status:302,headers:[["Location",ze],...xe]})}async function ut(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(M))return new Response("Invalid Content-Type, expected application/x-www-form-urlencoded",{status:400});let _e=await Ce.text(),be=new URLSearchParams(_e).get("logout_token");if(!be)return new Response("Missing logout_token parameter",{status:400});let xe=t(fe.authority,"Missing 'authority' from SSO Config. OIDC configuration is required to verify logout tokens."),Ie=t(fe.clientId,"Missing 'clientId' from SSO Config. OIDC configuration is required to verify logout tokens."),Pe=fe.jwksUri||`${xe}/protocol/openid-connect/certs`,ze=await Ar({logoutToken:be,jwksUri:Pe,issuer:xe,audience:Ie,log:O}),We=typeof ze.sid==="string"?ze.sid:void 0;if(!We)return O.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(We),O.info("Back-Channel Logout: successfully deleted session",{"ion.module":"sso",sid:We}),new Response("OK",{status:200})}catch(Ue){return O.error("Error during back-channel logout",{"ion.operation":"backchannel_logout","ion.outcome":"failure"},Ue),new Response("Internal Server Error",{status:500})}}async function gt(Ce){if(!fe)throw Error("ionite SSO Manager not initialized");let Ue=Date.now(),_e=new URL(Ce.url),ge=new URLSearchParams(_e.search);O.debug("SSO callback received",{"ion.event":"ion.sso.callback.received","ion.module":"sso","ion.operation":"sign_in.callback","http.method":Ce.method,"url.path":_e.pathname,hasCode:ge.has("code"),hasState:ge.has("state"),hasError:ge.has("error"),...Zn(ge.get("iss")??void 0,"oidc.issuer")});let be=Object.fromEntries(ge.entries()),xe=await T.callbackParams.validate(be);if(xe.issues)return O.warn("SSO callback parameter validation failed",{"ion.event":"ion.sso.callback.validation_failed","ion.operation":"sign_in.callback","ion.outcome":"failure","validation.issues":Qn(xe.issues)}),de(xe.issues,"OIDC callback parameters validation failed");let{code:Ie,state:Pe}=xe.value,ze;try{let We=t(Pe,'OIDC "state" was not present in the callback parameters'),Re=Qe(Fe(We),Ce,!0),{codeVerifier:Se,state:ve,nonce:Te,context:Ae}=Re??{};ze=Ae,O.debug("SSO callback state cookie read",{"ion.event":"ion.sso.callback.state_cookie_read","ion.module":"sso","ion.operation":"sign_in.callback",hasStateCookie:Boolean(Re),hasCodeVerifier:Boolean(Se),hasStateVerifier:Boolean(ve),hasNonce:Boolean(Te),hasContext:Ae!==void 0});let De=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 je=t(Te,'OIDC "nonce" was not present in cookies, ensure that the SSO login was initiated correctly'),Ee=t(Ie,'OIDC "code" was not present in the callback parameters');if(Pe!==ve)throw O.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');O.debug("SSO callback state verified",{"ion.event":"ion.sso.callback.state_verified","ion.module":"sso","ion.operation":"sign_in.callback"});let Le=fe.cookiesSecure?Ce.url.replace(/^http:\/\//,"https://"):Ce.url,Ye=await _t(Ee,De,Le),{tokenExpiresAt:st,sessionExpiresAt:ct}=Ct(Ye);Ye.expires=st.toISOString();let mt=Date.now();O.debug("SSO ID token parsing started",{"ion.event":"ion.sso.id_token.parse_started","ion.module":"sso","ion.operation":"id_token.parse"});let at=await yt(Ye,je,ct);O.debug("SSO ID token parsing completed",{"ion.event":"ion.sso.id_token.parse_completed","ion.module":"sso","ion.operation":"id_token.parse","duration.ms":bt(mt),"user.id":at.id});let tt,ft;{let vt=Ft("SSO requires sessionStore configuration for opaque session cookies."),qt=typeof at.sso.profile.sid==="string"?at.sso.profile.sid:void 0,Ot=qt||jt(32),Rt=at.id;if(O.debug("SSO session creation evaluated",{"ion.event":"ion.sso.session.create_evaluated","ion.module":"sso","ion.operation":"session.create",hasSid:Boolean(Ot),hasIdpSid:Boolean(qt),hasSub:Boolean(Rt),"user.id":Rt}),!Rt)throw Error("Session creation failed: missing sub in ID token claims");let zt=Date.now(),Cn=await sn({sid:Ot,sub:Rt,idpSid:qt,authType:"sso",tenantId:fe.tenantId,tokens:Ye,claims:at.sso.profile,expiresAt:ct,createdAt:new Date},Rt,at.sso.profile,Ye);await pn(vt,Cn),ft=Cn,tt=["Set-Cookie",Vt("session",Ot,ct)],O.info("SSO session created",{"ion.event":"ion.sso.session.created","ion.operation":"session.create","ion.outcome":"success","duration.ms":bt(zt),"user.id":Rt})}if(fe.userStore)try{let vt=at.id;if(vt){let qt=new Date,Ot=Date.now();O.debug("SSO user store lookup started",{"ion.event":"ion.sso.user.lookup_started","ion.module":"sso","ion.operation":"user.lookup","user.id":vt});let Rt=await fe.userStore.get(vt);if(O.debug("SSO user store lookup completed",{"ion.event":"ion.sso.user.lookup_completed","ion.module":"sso","ion.operation":"user.lookup","duration.ms":bt(Ot),"user.id":vt,found:Boolean(Rt)}),Rt||fe.enableJitUserProvisioning){let zt=Date.now(),Cn={...Rt??{},...at,id:vt,tenantId:Rt?.tenantId,createdAt:Rt?.createdAt??qt,updatedAt:qt};await fe.userStore.upsert(Cn),O.info("SSO user stored",{"ion.event":"ion.sso.user.stored","ion.operation":"user.store","ion.outcome":"success","duration.ms":bt(zt),"user.id":vt,existing:Boolean(Rt),jitProvisioning:Boolean(fe.enableJitUserProvisioning)})}else O.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":vt})}else O.warn("User storage skipped: missing sub in ID token claims",{"ion.event":"ion.sso.user.skipped","ion.operation":"user.store","ion.outcome":"skipped"})}catch(vt){O.warn("Failed to store user",{"ion.event":"ion.sso.user.store_failed","ion.operation":"user.store","ion.outcome":"degraded",...Gr(vt)})}O.info("SSO sign-in succeeded",{"ion.event":"ion.sso.sign_in.succeeded","ion.operation":"sign_in.callback","ion.outcome":"success","duration.ms":bt(Ue),"user.id":at.id});let rt=[["Set-Cookie",Zt(Fe(We))],...tt?[tt]:[],...tt?await Ke(Ce,await xt(at),ct):[]],Dt=await fe.afterLogin?.({ok:!0,request:Ce,user:at,session:ft,context:ze,displayCookie:fe.displayCookie,displayCookieAttributes:Et()}),Mt=tn(Dt,"/",Ce.url);if(Mt.response)return an(Mt.response,rt.map(([,vt])=>vt));return new Response("Authentication successful, redirecting",{status:302,headers:[["Location",Mt.location],...rt]})}catch(We){O.error("Error during sign-in callback",{"ion.event":"ion.sso.sign_in.callback_failed","ion.operation":"sign_in.callback","ion.outcome":"failure","duration.ms":bt(Ue),...Gr(We)});let Re=Pe?[["Set-Cookie",Zt(Fe(Pe))]]:[],Se=await fe.afterLogin?.({ok:!1,request:Ce,error:We,context:ze,displayCookie:fe.displayCookie,displayCookieAttributes:Et()}),ve=tn(Se,"/",Ce.url);if(ve.response)return an(ve.response,Re.map(([,Te])=>Te));return new Response("Authentication failed, redirecting",{status:302,headers:[["Location",ve.location],...Re]})}}function Ct(Ce){let Ue=Date.now(),_e=Number(Ce.expires_in??3600)||3600,ge=new Date(Ue+_e*1000),be;if(Ce.refresh_expires_in!=null&&Number.isFinite(Number(Ce.refresh_expires_in)))be=Number(Ce.refresh_expires_in);else if(Ce.refresh_token)be=et;else be=_e;return{tokenExpiresAt:ge,sessionExpiresAt:new Date(Ue+be*1000)}}async function yt(Ce,Ue,_e){if(!fe)throw Error("ionite SSO Manager not initialized");let ge=Date.now(),be=await ln(Ce.id_token,Ue);return O.debug("SSO user parsed from ID token",{"ion.event":"ion.sso.user.parse_completed","ion.module":"sso","ion.operation":"id_token.parse","duration.ms":bt(ge),"user.id":be.sub,hasEmail:Boolean(be.email),hasName:Boolean(be.name)}),At(be,Ce,_e)}function At(Ce,Ue,_e){let ge=_e??Ct(Ue).sessionExpiresAt,be=Ce.ecid!==void 0&&Ce.ecid!==null?D(Ce.ecid):void 0;return{id:Ce.sub,userName:Ce.preferred_username||"",name:Ce.name||"",email:Ce.email||"",emails:[{value:Ce.email||"",primary:!0}],...be?{ecid:be}:{},avatar:Ce.picture,sso:{profile:{...Ce},tenant:{id:Ce.idp||Ce.iss||"",name:Ce.iss||""},scope:Ue.scope,tokenType:Ue.token_type,sessionState:Ue.session_state,expires:ge}}}async function xt(Ce){if(!fe.userStore)return Ce;let Ue=await fe.userStore.lookup(Ce);if(!Ue)return Ce;return{...Ce,...Ue,id:Ce.id,sso:Ce.sso}}async function _t(Ce,Ue,_e){if(!fe)throw Error("ionite SSO Manager not initialized");dt();let ge=t(fe.tokenUrl,"Missing 'tokenUrl' from SSO Config"),be=t(fe.redirectUri,"Missing 'redirectUri' from SSO Config"),xe=t(fe.clientId,"Missing 'clientId' from SSO Config"),Ie=be;try{new URL(Ie)}catch{if(_e)try{let ze=new URL(_e),We=Ie.startsWith("//")?Ie.slice(1):Ie.startsWith("/")?Ie:`/${Ie}`;Ie=new URL(We,ze.origin).toString()}catch{try{let ze=new URL(ge),We=Ie.startsWith("//")?Ie.slice(1):Ie.startsWith("/")?Ie:`/${Ie}`;Ie=new URL(We,ze.origin).toString()}catch{throw Error(`Invalid redirectUri: "${be}". It must be a valid absolute URL.`)}}}let Pe=new URLSearchParams;if(Pe.append("grant_type","authorization_code"),Pe.append("code",Ce),Pe.append("redirect_uri",Ie),Pe.append("client_id",xe),fe.clientSecret)Pe.append("client_secret",fe.clientSecret);Pe.append("code_verifier",Ue);try{let ze=Date.now();O.debug("SSO token exchange started",{"ion.event":"ion.sso.token.exchange_started","ion.module":"sso","ion.operation":"token.exchange",...Zn(ge,"oidc.token_url"),...Zn(Ie,"oidc.redirect_uri"),hasClientSecret:Boolean(fe.clientSecret)});let We=await fetch(ge,{method:"POST",headers:{...S,...a},body:Pe.toString()});O.debug("SSO token exchange response received",{"ion.event":"ion.sso.token.response_received","ion.module":"sso","ion.operation":"token.exchange","http.status_code":We.status,"duration.ms":bt(ze)}),O.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 Re=await c(We,{log:O,operation:"token.exchange"});if(O.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":bt(ze)}),!We.ok){O.error("Token exchange error",{"ion.event":"ion.sso.token.exchange_failed","ion.operation":"token.exchange","ion.outcome":"failure","http.status_code":We.status,"duration.ms":bt(ze),...oa(Re)});let ve=Re;throw Error(`Token exchange failed: ${ve.error||We.statusText} - ${ve.error_description||""}`.trim())}let Se=await T.tokenResponse.validate(Re);if(Se.issues)throw O.error("Token response validation failed",{"ion.event":"ion.sso.token.response_validation_failed","ion.operation":"token.exchange","ion.outcome":"failure","duration.ms":bt(ze),"validation.issues":Qn(Se.issues)}),Error(`Token response validation failed: ${Se.issues}`);return O.debug("SSO token exchange completed",{"ion.event":"ion.sso.token.exchange_completed","ion.module":"sso","ion.operation":"token.exchange","ion.outcome":"success","duration.ms":bt(ze),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(ze){throw O.error("Error during token exchange",{"ion.event":"ion.sso.token.exchange_failed","ion.operation":"token.exchange","ion.outcome":"failure",...Gr(ze)}),ze}}async function wn(Ce){return hr(async()=>{if(!fe)throw Error("ionite SSO Manager not initialized");dt();let Ue=t(fe.tokenUrl,"Missing 'tokenUrl' from SSO Config"),_e=t(fe.clientId,"Missing 'clientId' from SSO Config"),ge=new URLSearchParams;if(ge.append("grant_type","refresh_token"),ge.append("refresh_token",Ce),ge.append("client_id",_e),fe.clientSecret)ge.append("client_secret",fe.clientSecret);let be=await fetch(Ue,{method:"POST",headers:{...S,...a},body:ge.toString()}),xe=await c(be,{log:O,operation:"token.refresh"});if(!be.ok){O.error("Token refresh error",{"ion.operation":"token.refresh","ion.outcome":"failure",response:xe});let Pe=xe;throw Error(`Token refresh failed: ${Pe.error||be.statusText} - ${Pe.error_description||""}`.trim())}let Ie=await T.tokenResponse.validate(xe);if(Ie.issues)throw O.error("Token refresh response validation failed",{"ion.event":"ion.sso.token.refresh_validation_failed","ion.operation":"token.refresh","ion.outcome":"failure","validation.issues":Qn(Ie.issues)}),Error(`Token refresh response validation failed: ${Ie.issues}`);return Ie.value},void 0,void 0,void 0,O)}async function Ht(Ce){try{if(!fe)throw Error("ionite SSO Manager not initialized");if(!fe.revocationEndpoint)return;let Ue=t(fe.clientId,"Missing 'clientId' from SSO Config"),_e=new URLSearchParams;if(_e.append("token",Ce),_e.append("token_type_hint","refresh_token"),_e.append("client_id",Ue),fe.clientSecret)_e.append("client_secret",fe.clientSecret);let ge=await fetch(fe.revocationEndpoint,{method:"POST",headers:{...a,...S},body:_e.toString()});if(!ge.ok)O.warn("Token revocation failed",{"ion.operation":"token.revoke","ion.outcome":"degraded",status:ge.status,statusText:ge.statusText});else O.info("Token revoked successfully",{"ion.module":"sso"})}catch(Ue){O.warn("Error revoking token",{"ion.operation":"token.revoke","ion.outcome":"degraded"},Ue)}}async function bn(){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 Ue=fe.jwksUri||`${Ce}/protocol/openid-connect/certs`;return Tn(Ue,O)}async function ln(Ce,Ue){let _e=Date.now(),ge=t(fe.authority,"Missing 'authority' from SSO Config. OIDC configuration is required to verify ID tokens."),be=t(fe.clientId,"Missing 'clientId' from SSO Config. OIDC configuration is required to verify ID tokens."),xe=fe.jwksUri||`${ge}/protocol/openid-connect/certs`;O.debug("SSO ID token verification started",{"ion.event":"ion.sso.id_token.verify_started","ion.module":"sso","ion.operation":"id_token.verify",...Zn(xe,"oidc.jwks_uri")});let Ie;try{Ie=await en({idToken:Ce,jwksUri:xe,issuer:ge,audience:be,expectedNonce:Ue,log:O})}catch(ze){throw O.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":bt(_e)},ze),ze}O.debug("SSO ID token signature verified",{"ion.event":"ion.sso.id_token.signature_verified","ion.module":"sso","ion.operation":"id_token.verify","duration.ms":bt(_e)});let Pe=await T.idTokenClaims.validate(Ie);if(Pe.issues)throw O.error("ID token claims validation failed",{"ion.event":"ion.sso.id_token.validation_failed","ion.operation":"id_token.validate","ion.outcome":"failure","duration.ms":bt(_e),"validation.issues":Qn(Pe.issues)}),Error(`ID token claims validation failed: ${Pe.issues}`);return O.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":bt(_e),"user.id":Pe.value.sub,hasIssuer:Boolean(Pe.value.iss),hasAudience:Boolean(Pe.value.aud)}),Pe.value}function Ft(Ce="SSO sessionStore is required for opaque session cookies."){if(!fe.sessionStore)throw Error(Ce);return fe.sessionStore}let Yt=!1;async function sn(Ce,Ue,_e,ge){let be=fe.claimsAsEntitlements;if(!be?.claims?.length)return Ce;if(fe.sessionStore?.capabilities?.derivedEntitlements!==!0){if(!Yt)Yt=!0,O.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 xe=await vn({block:be,claims:_e,accessClaims:fn(ge?.access_token),scope:ge?.scope,subjectType:"user",subjectId:Ue,catalog:Q?.catalogView?.(),log:O});return{...Ce,entitlements:xe}}async function pn(Ce,Ue){try{await Ce.create(Ue)}catch(_e){if(!await Ce.get(Ue.sid))throw _e;await Ce.update(Ue.sid,Ue)}}function Pt(Ce){if(!Ce)return;if(Ce instanceof Date)return Ce;let Ue=new Date(Ce);return Number.isNaN(Ue.getTime())?void 0:Ue}function mn(Ce){let Ue=Ce.tokens;if(!Ue?.access_token||!Ue.id_token||!Ue.token_type)return;return Ue}async function Xt(Ce,Ue=!1){let _e=Ft(),ge=Qe("session",Ce);if(!ge)return{tokens:void 0,refreshHeaders:[]};let be=await _e.get(ge);if(be&&fe.tenantId&&be.tenantId&&be.tenantId!==fe.tenantId)return{tokens:void 0,refreshHeaders:Ge(),sid:ge};if(be?.authType!=="sso")return{tokens:void 0,refreshHeaders:Ge(),sid:ge};let xe=mn(be);if(!xe)return{tokens:void 0,refreshHeaders:Ge(),sid:ge};let Ie=Pt(be.expiresAt);if(Ie?Date.now()>Ie.getTime():!1)return await _e.delete(ge),{tokens:void 0,sid:ge,refreshHeaders:Ge()};let ze=Pt(xe.expires),We=ze?Date.now()>ze.getTime():!0;if((Ue||We)&&xe.refresh_token)return Ut(Ce,ge,be,xe);return{tokens:xe,sid:ge,session:be,refreshHeaders:Ze(Ce)}}function Ut(Ce,Ue,_e,ge){let be=he.get(Ue);if(be)return be;let xe=Ft(),Ie=(async()=>{let Pe=await wn(ge.refresh_token),{tokenExpiresAt:ze,sessionExpiresAt:We}=Ct(Pe);Pe.expires=ze.toISOString();let Re=await yt(Pe,void 0,We),Se=Re.sso.profile,ve=jt(32),Te=await sn({..._e,sid:ve,tokens:Pe,claims:Se,expiresAt:We,createdAt:new Date},_e.sub,Se,Pe);await pn(xe,Te);try{if(Be<=0)await xe.delete(Ue);else{let{refresh_token:Ae,...De}=ge;await xe.update(Ue,{tokens:De,expiresAt:new Date(Date.now()+Be)})}}catch(Ae){O.warn("Failed to retire rotated SSO session record",{"ion.operation":"session.rotate","ion.outcome":"degraded"},Ae)}return{tokens:Pe,sid:ve,session:Te,refreshedUser:Re,refreshHeaders:[["Set-Cookie",Vt("session",ve,We)],...await Ke(Ce,Re,We)]}})();return he.set(Ue,Ie),Ie.finally(()=>{he.delete(Ue)})}async function It(Ce,Ue=!1){return Xt(Ce,Ue)}async function Wt(Ce){let{tokens:Ue}=await It(Ce);if(!Ue)return;return Ue.access_token}function Vt(Ce,Ue,_e,ge=fe.cookiesSameSite??"Strict"){if(!fe)throw Error("ionite SSO Manager not initialized");if(Ce=`${fe.cookiesPrefix}.${Ce}`,typeof Ue!=="string")Ue=btoa(JSON.stringify(Ue));let be;if(_e instanceof Date)be=`Expires=${_e.toUTCString()}`;else if(typeof _e==="number")be=`Max-Age=${_e}`;else throw Error("Invalid expires type",_e);if(Ue.length>4000)throw Error(`Error setting cookie: ${Ce}. Cookie length is: ${Ue.length}`);return`${Ce}=${Ue}; ${be}; Path=${fe.cookiesPath};${Qt(fe.cookiesDomain)} HttpOnly;${fe.cookiesSecure?" Secure;":""} SameSite=${ge};`}function Zt(Ce){if(!fe)throw Error("ionite SSO Manager not initialized");return`${fe.cookiesPrefix}.${Ce}=; Max-Age=0; Path=${fe.cookiesPath};${Qt(fe.cookiesDomain)} HttpOnly;${fe.cookiesSecure?" Secure;":""} SameSite=${fe.cookiesSameSite};`}function Et(){return{path:fe.cookiesPath??"/",domain:fe.cookiesDomain,secure:fe.cookiesSecure!==!1,sameSite:fe.cookiesSameSite??"Strict"}}function Ge(){return[["Set-Cookie",Zt("session")],["Set-Cookie",Gt(`${fe.cookiesPrefix}.profile`,Et())]]}function Ze(Ce){if(fe.displayCookie?.enabled===!0)return[];return yn(Ce.headers.get("cookie"),fe.cookiesPrefix??"ion.sso",Et()).map((Ue)=>["Set-Cookie",Ue])}async function Ke(Ce,Ue,_e){return(await An({cookieHeader:Ce.headers.get("cookie"),sessionStore:fe.sessionStore,cookiesPrefix:fe.cookiesPrefix??"ion.sso",authType:"sso",tenantId:fe.tenantId,expiresAt:_e,user:Ue,projector:fe.displayUser,displayCookie:fe.displayCookie,trim:fe.trimDisplayCookies,attr:Et()})).map((be)=>["Set-Cookie",be])}function Qe(Ce,Ue,_e=!1){if(!fe)throw Error("ionite SSO Manager not initialized");let ge=Ue.headers.get("cookie");if(!ge)return null;let be=`${fe.cookiesPrefix}.${Ce}`,xe=ge.split(";").find((We)=>We.trim().startsWith(`${be}=`));if(!xe)return null;let Ie=xe.indexOf("="),Pe=xe.slice(Ie+1).trim();if(!_e)return Pe;let ze=atob(Pe);return JSON.parse(ze)}function Fe(Ce){return`state_${Ce}`}async function Xe(Ce,Ue){if(!fe)throw Error("ionite SSO Manager not initialized");let{loginUrl:_e,userUrl:ge,tokenUrl:be,refreshUrl:xe,logoutUrl:Ie,logoutBackChannelUrl:Pe,jwksUrl:ze,redirectUri:We}={...fe,...Ue},Re=new URL(Ce.url).pathname;if(We){let Se;try{Se=new URL(We).pathname}catch{try{let ve=new URL(Ce.url),Te=We.startsWith("//")?We.slice(1):We;Se=new URL(Te,ve.origin).pathname}catch{Se=We.startsWith("/")?We:`/${We}`}}if(Se===Re)return gt(Ce)}if(_e===Re)return nt(Ce);if(ge===Re){if((fe.userEndpoint??"full")==="off")return new Response("Not Found",{status:404,headers:Ze(Ce)});try{let{tokens:Se,session:ve,refreshedUser:Te,refreshHeaders:Ae}=await It(Ce);if(!Se)return new Response("User not logged in",{status:401,headers:Ae});let De=Te??(ve?.claims?At(ve.claims,Se,Pt(ve.expiresAt)):void 0);if(!De)return new Response("User not logged in",{status:401,headers:Ae});let je=await xt(De),Ee=`${fe.cookiesPrefix}.profile`,Le=Pt(ve?.expiresAt),Ye=fe.displayCookie?.enabled===!0&&Le&&!Qe("profile",Ce)&&!Ae.some(([,ct])=>ct.startsWith(`${Ee}=`))?await Ke(Ce,je,Le):[],st=fe.userEndpoint==="display"?f(je,fe.displayUser):je;return new Response(JSON.stringify(st),{headers:[["Content-Type",o],...Ae,...Ye]})}catch(Se){if(qs(Se))return new Response("User not logged in",{status:401});return O.error("Error resolving SSO user",{"ion.operation":"sso.user","ion.outcome":"degraded"},Se),new Response(JSON.stringify({error:"auth_unavailable"}),{status:503,headers:s})}}if(be===Re){let{tokens:Se,refreshHeaders:ve}=await It(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",o],...ve]})}if(xe===Re){let{tokens:Se,refreshHeaders:ve}=await It(Ce,!0);if(!Se)return new Response("User not logged in",{status:401});return new Response("Refresh Complete",{status:200,headers:ve})}if(Ie===Re)return Oe(Ce);if(Pe===Re)return ut(Ce);if(ze===Re){let Se=await bn();return new Response(JSON.stringify(Se),{headers:[["Content-Type",o]]})}return new Response("Not Found",{status:404})}let lt;return lt={...fe,describe:()=>({module:"sso",active:!0,ready:lt.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:Ve,resolveUser:ot,getJwt:Wt,initiateLogin:nt,logout:Oe,logoutBackChannel:ut,callbackHandler:gt,handler:Xe},lt}function ua(T){let O={},N=T.split(";");for(let X of N){let Q=X.trim();if(!Q)continue;let ye=Q.indexOf("=");if(ye===-1)continue;let he=Q.slice(0,ye).trim(),we=Q.slice(ye+1).trim();O[he]=we}return O}function qs(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((O)=>T.message.includes(O))}function zs(T){return T=T??"SSO Unavailable",new Response(JSON.stringify({error:T}),{status:503,statusText:T,headers:s})}var er="Ionite instance is required. Create one with ionite(source, config) and pass it to this function.";async function da(T,O){return t(O,er),O.sso?.getUser(T)}async function Kr(T,O){return t(O,er),await O.sso?.resolveUser(T)??{status:"unauthenticated"}}async function la(T,O){t(O,er);let N=O.sso;if(!N)return zs();return N.initiateLogin(T)}async function pa(T,O){t(O,er);let N=O.sso;if(!N)return zs();return N.callbackHandler(T)}var Hr="tenant.owner",Jr="tenant.owner.",ma="tenant:";function fa(T){return{id:Hr,name:"Tenant owner",description:"Administer one tenant resource",requestable:!1,permissionTypes:["Admin"],resourceTypes:["tenant"],assignableSubjectTypes:["customer"],...T}}function Fr(T){let O=T.trim();if(!O)throw Error("tenantId is required");return`${ma}${O}`}function ga(T){let O=T.trim();if(!O)throw Error("tenantId is required");return`${Jr}${O}`}function ht(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 tr(T,O){if(!T.id)return ht("unavailable");return{allow:!0,session:{id:T.id,email:T.email,name:T.name,kind:O}}}function Bs(T){return T==="access_index_not_configured"||T==="error"}async function Gs(T,O){let N;try{N=await zn(T,O.rootIon)}catch{return ht("unavailable")}if(N.status==="degraded")return ht("unavailable");if(N.status==="unauthenticated")return ht("unauthenticated");if(!N.value.id)return ht("unavailable");try{let X=await O.rootIon.authz.hasPermission(N.value.id,O.ownerPermission??Hr,Fr(O.tenantId),"customer");if(X.allow)return tr(N.value,"owner");return ht(Bs(X.metadata?.reason)?"unavailable":"forbidden")}catch{return ht("unavailable")}}async function ya(T,O){let{tenantIon:N}=O;if(!N)return ht("not_found");if(N.isReady()){let Q;try{Q=await Kr(T,N)}catch{return ht("unavailable")}if(Q.status==="degraded")return ht("unavailable");if(Q.status==="authenticated"){if(!Q.value.id)return ht("unavailable");if(!O.permission)return tr(Q.value,"sso");try{let ye=await N.authz.hasPermission(Q.value.id,O.permission,void 0,"user");if(ye.allow)return tr(Q.value,"sso");return ht(Bs(ye.metadata?.reason)?"unavailable":"forbidden")}catch{return ht("unavailable")}}if(O.allowTenantCustomer){let ye;try{ye=await zn(T,N)}catch{return ht("unavailable")}if(ye.status==="degraded")return ht("unavailable");if(ye.status==="authenticated"){if(!ye.value.id)return ht("unavailable");return tr(ye.value,"customer")}}}let X=await Gs(T,O);if(X.allow||X.reason==="unavailable")return X;if(!N.isReady())return ht("unavailable");return ht("unauthenticated")}async function ha(T,O){let N=T.authz.accessStore;if(!N)throw Error("Cannot list owned tenants: no AccessAssignmentStore is wired.");let X=new Set;for await(let Q of u((ye,he)=>N.listBySubject(O,"customer",{start:ye,limit:he}))){let ye=typeof Q.target==="string"?Q.target:Q.target.id;if(Q.targetType!=="group"||!ye.startsWith(Jr))continue;let he=ye.slice(Jr.length);if(!he||!Q.resources?.includes(Fr(he)))continue;X.add(he)}return[...X].sort()}function ka(T,O){let N=O.redirectTo.trim()||"/",X=O.tenantIon?.sso?.isReady?.()===!0?`${O.tenantIonBasePath?.(T)??`/api/${encodeURIComponent(T)}/ionite`}/auth/login`:O.fallbackPath,Q=new URL(X,"http://localhost");return Q.searchParams.set("redirect",N),`${Q.pathname}${Q.search}`}export{_n as CACHE_BOUNDS,es as CIAM_PROVIDER_PRESETS,te as CatalogAdjacencyCache,Ne as InMemoryTenantStore,wr as MICROSOFT_CONSUMERS_TENANT_ID,Hr as TENANT_OWNER_PERMISSION,Bi as allowHosts,zi as allowOrigins,ks as allowRelativePaths,Ss as allowSameOrigin,Ps as assertSubjectTypeAssignable,fs as assertTrustedIdTokenClaims,Mr as baseCustomerToScim,Er as baseUserToScimUser,Dr as baseWorkloadToScim,hs as blockDangerousUrls,Cr as buildAuthorizationUrl,Br as buildLfvSigningInput,pa as callback,Ki as captureRedirect,Yi as ciam,Ni as clearDiscoveryCache,Ii as clearJwksCache,qe as collectReferencedDefinitions,bi as configureJwksCache,fn as decodeUnverifiedJwtPayload,Gi as defaultRedirectPolicies,vn as deriveClaimsEntitlements,rr as derivedEntitlementsFor,Vn as discoverOidcEndpoints,Vs as discoverSessionRecords,Ws as discoverSessions,Ur as entitlementToScimGroup,vr as exchangeAuthorizationCode,P as expandRoot,Ir as fetchUserInfo,Gt as formatDisplayClearCookie,lr as formatDisplaySetCookie,Tr as generateAppleClientSecret,qo as generateLfvEd25519KeyPair,kr as getCachedVerificationKey,Xi as getCustomer,na as getDiscoveredSessionUsers,Tn as getJwks,ha as getOwnedTenantIds,or as getProviderPreset,Pi as getPublicKeyForKid,xi as getPublicKeyFromJwks,da as getUser,Sr as getVerificationKeyForKid,ci as has,mi as hasAll,yi as hasAllScope,pi as hasAny,gi as hasAnyScope,li as hasGroup,ui as hasPermission,di as hasRole,fi as hasScope,Oo as iam,la as initiateLogin,Rr as isMicrosoftMultiTenantAuthority,ws as isRedirectAllowed,aa as listSsoClientIdsFromCookies,ms as matchesMicrosoftIssuer,Wn as microsoftIssuerTenantId,on as normalizeOidcIssuer,cr as orderedEnabledProviders,Us as parseLfvJwks,Pn as pkceChallengeFromVerifier,wi as planDiscoveredTenantCookies,yn as planDisplayCookieClear,An as planDisplayCookieHeaders,me as reconcileSubjectAccess,Rn as rememberDerivedEntitlements,tn as resolveAfterRedirect,zo as resolveCacheConfig,Ji as resolveCapturedRedirect,Ln as resolveCiamProvider,zn as resolveCustomer,Ti as resolveJwkForKid,Es as resolveJwksCacheConfig,ar as resolveProviderBranding,Pr as resolveRedirect,Ds as resolveSessionCacheConfig,Gs as resolveTenantOwner,ya as resolveTenantSession,Kr as resolveUser,xr as sameOriginRedirectRules,rs as selectDisplayCookies,it as sendTenantWebhook,Li as setDiscoveryClock,Ci as setJwksClock,vi as setJwksRetry,Jo as signCompactJwt,Vo as signLfvPayload,ca as sso,Ko as staticSigningKeyRing,Lo as stringifyLfvJwks,ka as tenantAccessLoginUrl,ga as tenantOwnerEntitlementId,fa as tenantOwnerPermission,Fr as tenantResourceId,Ho as verifyCompactJwt,en as verifyIdToken,Wo as verifyLfvSignature,Ar as verifyLogoutToken,ia as verifyUser,an as withSetCookies};
|