@ionite/core 0.0.24-beta.20261007.23 → 0.0.24-beta.20261007.24
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 +7 -2
- package/dist/index.js +2 -2
- package/dist/server.js +1 -1
- package/dist/shared/core-jcvkk7kx.js +4 -0
- package/package.json +1 -1
- package/dist/shared/core-y6y95p25.js +0 -4
package/dist/server.js
CHANGED
|
@@ -1 +1 @@
|
|
|
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};
|
|
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-jcvkk7kx.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"});this.name="SubjectTypeNotAssignableError"}}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"});this.name="DerivedRevokeError"}}class On extends r{constructor(T,O,N=!1){super(T,{status:N?409:500});this.name="ScimMutationError";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"});this.name="AmbiguousMemberSubjectTypeError"}}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};
|