@ionite/core 0.0.23 → 0.0.24-beta.20260907.2
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 +555 -314
- package/dist/index.js +1 -1
- package/dist/server.d.ts +539 -331
- package/dist/server.js +1 -1
- package/dist/shared/core-ys2a23v0.js +4 -0
- package/package.json +1 -1
- package/dist/shared/core-fm0d5w83.js +0 -4
package/dist/server.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C as w1,D as p9,E as u9,F as z1,G as d5,H as c,I as Y2,M as A1,Q as Q2,S as _9,T as K9,W as FJ,X as VJ,Y as M5,a as E9,d as o9,h as F9,i as V9,k as H9,l as r9,m as D9,n as k,o as j1,r as B5,s as L1,t as M9,u as N9,v as z9,w as LJ}from"./shared/core-fm0d5w83.js";var G2="Ionite instance is required. Create one with ionite(source, config) and pass it to this function.",A9=["user","customer","workload"],W2={user:async(J,$)=>$.sso?.getUser(J),customer:async(J,$)=>$.ciam?.getCustomer(J),workload:async(J,$)=>{let Z=await $.workload?.getWorkloadIdentity?.(J);if(!Z)return;let X=Z.clientId??Z.workloadId??Z.claims.sub;return X?{...Z,id:X}:void 0}};function L2(J){if(J==="any")return A9;let $=Array.isArray(J)?J:[J];return A9.filter((Z)=>$.includes(Z))}function F2(J){let $=J.headers.get("cookie");if(!$)return[];return $.split(";").map((Z)=>Z.slice(0,Z.indexOf("=")===-1?Z.length:Z.indexOf("=")).trim()).filter(Boolean)}function V2(J,$){let Z=J.headers.get("authorization")?.toLowerCase().startsWith("bearer ")??!1,X=F2(J),K=new Set;for(let L of X){if(L.startsWith("ion.sso"))K.add("user");if(L.startsWith("ion.ciam"))K.add("customer")}let W=X.length>0&&!K.has("user")&&!K.has("customer");return $.filter((L)=>{if(L==="workload")return Z;if(X.length===0)return!1;return K.has(L)||W})}function s(J){return typeof J==="string"?J:J.id}function w9(J){let{subject:$,subjectType:Z}=J,X;if(Z==="user")X=$.sso?.scope;else if(Z==="customer")X=$.ciam?.scope;else if(Z==="workload")X=$.scope;return new Set((X??"").split(/\s+/).filter(Boolean))}function v1(J,$,Z){let X=w9(J),K=$.filter((L)=>X.has(L));return{allow:Z==="any"?K.length>0:$.length>0&&K.length===$.length,metadata:{reason:"scope",wantedScopes:$,matchedScopes:K}}}function c5(J,$){return(Z)=>{if(J.length===0)return;let X=w9(Z),K=J.filter((L)=>X.has(L));return($==="any"?K.length>0:K.length===J.length)?K:void 0}}function H1(J,$,Z){return(X)=>{if($.length===0||X.subjectType!=="workload")return;let K=E9(J.config?.authz,X.subject);if(!K)return;let W=$.filter((G)=>K.has(G));return(Z==="any"?W.length>0:W.length===$.length)?W:void 0}}function H2(J,$){if(J.subjectType==="workload"){let Z=J.subject.scopesAsEntitlements;if(typeof Z==="boolean")return Z}return $.config?.authz?.scopesAsEntitlements===!0}function y1(J,$,Z,X,K){return{allow:Z==="ok",subject:$?.subject,subjectType:$?.subjectType,reason:Z,decision:X,response(){if(Z==="ok")return new Response(null,{status:204});if(Z==="unauthenticated")return J.log.warn("authz.denied",{reason:Z,...K()}),Response.json({error:"Unauthorized"},{status:401});if(Z==="not_configured")return J.log.warn("authz.denied",{reason:Z,subject:$?.subject?.id,subjectType:$?.subjectType,...K()}),Response.json({error:"not_configured"},{status:503});return J.log.warn("authz.denied",{reason:Z,subject:$?.subject?.id,subjectType:$?.subjectType,...K()}),Response.json({error:"Forbidden"},{status:403})}}}function D2(J,$,Z){return new Promise((X)=>{let K=[],W=J.length,L=!1,G=()=>{if(W-=1,W===0&&!L)L=!0,X({outcomes:K})};for(let D of J)$(D).then((F)=>{if(K.push({principal:D,decision:F}),!L&&F.allow){L=!0,X({matched:{principal:D,decision:F},outcomes:K});return}G()},(F)=>{Z?.(D,F),K.push({principal:D,decision:{allow:!1,metadata:{reason:"error"}}}),G()})})}async function E5(J,$,Z,X,K,W,L){c($,G2);let G=V2(J,L2(Z)),F=(await Promise.all(G.map(async(v)=>{let a=await W2[v](J,$);return a?.id?{subject:a,subjectType:v,subjectId:a.id}:void 0}))).filter((v)=>v!==void 0);if(F.length===0)return y1($,void 0,"unauthenticated",void 0,K);let f=async(v)=>{let a=$.authz.accessIndex;if(!a?.isSubjectDisabled)return!1;return a.isSubjectDisabled(v.subjectId,v.subjectType)},n=async(v)=>{if(L){let a=L(v);if(a&&a.length>0){if(await f(v))return{allow:!1,metadata:{reason:"subject_disabled"}};return{allow:!0,metadata:{reason:"trusted-client",matchedPermissions:a}}}}if(W&&H2(v,$)){let a=W(v);if(a&&a.length>0){if(await f(v))return{allow:!1,metadata:{reason:"subject_disabled"}};return{allow:!0,metadata:{reason:"scope",matchedScopes:a}}}}return X(v)},{matched:d,outcomes:o}=await D2(F,n,(v,a)=>{$.log.warn("authz.check_error",{"ion.operation":"authz.check","ion.outcome":"error",subject:v.subjectId,subjectType:v.subjectType,error:a instanceof Error?a.message:String(a),...K()})});if(d){if(d.decision.metadata?.reason==="scope")$.log.info("authz.scope_honor",{"ion.operation":"authz.scope_honor","ion.outcome":"allow",subject:d.principal.subjectId,subjectType:d.principal.subjectType,matchedScopes:d.decision.metadata.matchedScopes,...K()});return y1($,d.principal,"ok",d.decision,K)}let Z5=o.length>0&&o.every((v)=>{let a=v.decision.metadata?.reason;return a==="access_index_not_configured"||a==="error"}),C=o[0],X5=Z5?"not_configured":"forbidden";return y1($,C?.principal,X5,C?.decision,K)}async function M2(J,$,Z,X,K,W="any"){return E5(J,$,W,(L)=>$.authz.has(L.subjectId,Z,X,K,L.subjectType),()=>({targetType:Z,target:s(X),resource:K?s(K):void 0}),K?void 0:c5([s(X)],"any"),Z==="permission"&&!K?H1($,[s(X)],"any"):void 0)}async function N2(J,$,Z,X,K="any"){return E5(J,$,K,(W)=>$.authz.hasPermission(W.subjectId,Z,X,W.subjectType),()=>({targetType:"permission",target:s(Z),resource:X?s(X):void 0}),X?void 0:c5([s(Z)],"any"),X?void 0:H1($,[s(Z)],"any"))}async function z2(J,$,Z,X,K="any"){return E5(J,$,K,(W)=>$.authz.hasRole(W.subjectId,Z,X,W.subjectType),()=>({targetType:"role",target:s(Z),resource:X?s(X):void 0}),X?void 0:c5([s(Z)],"any"))}async function _2(J,$,Z,X,K="any"){return E5(J,$,K,(W)=>$.authz.hasGroup(W.subjectId,Z,X,W.subjectType),()=>({targetType:"group",target:s(Z),resource:X?s(X):void 0}),X?void 0:c5([s(Z)],"any"))}async function O2(J,$,Z,X="any"){let K=Z.filter((L)=>!L.resource).map((L)=>s(L.target)),W=Z.filter((L)=>!L.resource&&L.targetType==="permission").map((L)=>s(L.target));return E5(J,$,X,(L)=>$.authz.hasAny(L.subjectId,Z,L.subjectType),()=>({targets:Z.map((L)=>`${L.targetType}:${s(L.target)}`)}),K.length>0?c5(K,"any"):void 0,W.length>0?H1($,W,"any"):void 0)}async function j2(J,$,Z,X="any"){let K=Z.length>0&&Z.every((G)=>!G.resource),W=Z.length>0&&Z.every((G)=>!G.resource&&G.targetType==="permission"),L=Z.map((G)=>s(G.target));return E5(J,$,X,(G)=>$.authz.hasAll(G.subjectId,Z,G.subjectType),()=>({targets:Z.map((G)=>`${G.targetType}:${s(G.target)}`)}),K?c5(L,"all"):void 0,W?H1($,L,"all"):void 0)}async function A2(J,$,Z,X="any"){return E5(J,$,X,(K)=>Promise.resolve(v1(K,[Z],"any")),()=>({scope:Z}))}async function E2(J,$,Z,X="any"){return E5(J,$,X,(K)=>Promise.resolve(v1(K,Z,"any")),()=>({scopes:Z}))}async function w2(J,$,Z,X="any"){return E5(J,$,X,(K)=>Promise.resolve(v1(K,Z,"all")),()=>({scopes:Z}))}function J5(J){return typeof J==="string"&&J.length>0?J:void 0}function P9(J){let $=J5(J.email);return{sub:String(J.sub??""),email:$,name:J5(J.name),userName:J5(J.preferred_username)??$,avatar:J5(J.picture)}}var I9={oidc:{flow:"id_token",scope:"openid profile email",branding:{displayName:"Single sign-on"},mapClaims:P9},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:P9},microsoft:{flow:"id_token",authorizationUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/authorize",tokenUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/token",jwksUri:"https://login.microsoftonline.com/common/discovery/v2.0/keys",scope:"openid email profile",branding:{displayName:"Microsoft",colors:{light:"#ffffff",dark:"#2f2f2f",secondary:"#0067b8"},url:"https://login.microsoftonline.com"},mapClaims:(J)=>{let $=J5(J.email)??J5(J.preferred_username);return{sub:String(J.sub??J.oid??""),email:$,name:J5(J.name),userName:J5(J.preferred_username)??$,avatar:J5(J.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:(J)=>{let $=J5(J.email);return{sub:String(J.sub??""),email:$,name:J5(J.name),userName:$}}},github:{flow:"userinfo",authorizationUrl:"https://github.com/login/oauth/authorize",tokenUrl:"https://github.com/login/oauth/access_token",userInfoUrl:"https://api.github.com/user",scope:"read:user user:email",branding:{displayName:"GitHub",colors:{light:"#24292f",dark:"#ffffff"},url:"https://github.com"},mapClaims:(J)=>({sub:String(J.id??J.node_id??""),email:J5(J.email),name:J5(J.name)??J5(J.login),userName:J5(J.login),avatar:J5(J.avatar_url)})}};function q1(J){if(J==="magic-link")return;return I9[J]}function D1(J,$){if($.type==="magic-link")return;let Z=q1($.type);if(!Z)return;return{name:J,type:$.type,flow:Z.flow,authorizationUrl:$.authorizationUrl??Z.authorizationUrl,tokenUrl:$.tokenUrl??Z.tokenUrl,jwksUri:$.jwksUri??Z.jwksUri,userInfoUrl:$.userInfoUrl??Z.userInfoUrl,scope:$.scope??Z.scope,clientId:$.clientId,clientSecret:$.clientSecret,extraAuthParams:Z.extraAuthParams,branding:{...Z.branding,...$.branding},mapClaims:Z.mapClaims,config:$}}function U1(J){return{...q1(J.type)?.branding??{displayName:J.type},...J.branding}}function C1(J){if(!J)return[];return Object.entries(J).filter(([,$])=>$.enabled!==!1).map(([$,Z],X)=>({name:$,config:Z,index:X})).sort(($,Z)=>{let X=$.config.order??Number.MAX_SAFE_INTEGER,K=Z.config.order??Number.MAX_SAFE_INTEGER;if(X!==K)return X-K;return $.index-Z.index}).map(({name:$,config:Z})=>({name:$,config:Z}))}var S9=600000,f1=256,K5=new Map;function P2(J){if(typeof J?.ttlMs==="number"&&Number.isFinite(J.ttlMs))S9=Math.min(Math.max(J.ttlMs,60000),86400000);if(typeof J?.maxEntries==="number"&&Number.isFinite(J.maxEntries)){f1=Math.max(1,Math.floor(J.maxEntries));while(K5.size>f1){let $=K5.keys().next().value;if($===void 0)break;K5.delete($)}}}function T9(J,$){K5.delete(J),K5.set(J,$);while(K5.size>f1){let Z=K5.keys().next().value;if(Z===void 0)break;K5.delete(Z)}}var s5=new Map,h1=()=>Date.now();function I2(J){h1=J??(()=>Date.now())}var g1={};function T2(J){g1=J??{}}function S2(J){if(!J)return;if(/\bno-store\b/i.test(J))return 60000;let $=/max-age\s*=\s*(\d+)/i.exec(J);if(!$)return;let Z=Number($[1]);return Number.isFinite(Z)?Z*1000:void 0}function x2(J){let Z=S2(J)??S9;return Math.min(Math.max(Z,60000),86400000)}async function m1(J,$=3,Z=1000,X=30000,K){let W=Error("Placeholder Error");for(let L=0;L<=$;L++)try{return await J()}catch(G){if(W=G instanceof Error?G:Error(String(G)),G instanceof Error&&G.message.includes("400"))throw G;if(L===$)throw W;let D=Math.min(Z*2**L,X),F=Math.random()*0.1*D;await new Promise((f)=>setTimeout(f,D+F)),K?.warn(`Retry attempt ${L+1} after ${D+F}ms delay`)}throw W}async function e5(J,$,Z){let X=K5.get(J);if(!Z?.forceRefresh&&X&&X.expiresAt>h1())return T9(J,X),X.jwks;let K=s5.get(J);if(K)return K;let W=(async()=>{try{return await m1(async()=>{let L=await fetch(J);if(!L.ok)throw Error("Failed to fetch JWKS");let G=await L.json(),D=x2(L.headers.get("cache-control"));return T9(J,{jwks:G,expiresAt:h1()+D,importedKeys:new Map}),G},g1.maxRetries,g1.baseDelayMs,void 0,$)}catch(L){let G=K5.get(J);if(G)return $?.warn("JWKS refresh failed; serving last-known-good keys",{"ion.operation":"jwks.refresh","ion.outcome":"degraded"}),G.jwks;throw L}finally{s5.delete(J)}})();return s5.set(J,W),W}function R2(J){if(J){K5.delete(J),s5.delete(J);return}K5.clear(),s5.clear()}async function b2(J,$,Z){return(await x9(J,$,Z)).jwk}async function x9(J,$,Z){if(!$?.trim())throw Error("JWT header missing kid");await e5(J,Z);let X=K5.get(J),K=X?.jwks.keys.find((W)=>W.kid===$);if(!K)await e5(J,Z,{forceRefresh:!0}),X=K5.get(J),K=X?.jwks.keys.find((W)=>W.kid===$);if(!X||!K)throw Error("Public key not found");return{jwk:K,entry:X}}async function p1(J,$,Z,X,K){let{jwk:W,entry:L}=await x9(J,$,K),G=`${$}\x00${Z}`,D=L.importedKeys.get(G);if(D)return D;let F=X(W);return F.catch(()=>{if(L.importedKeys.get(G)===F)L.importedKeys.delete(G)}),L.importedKeys.set(G,F),F}async function y2(J,$){let Z=J.keys.find((X)=>X.kid===$);if(!Z)throw Error("Public key not found");return R9(Z)}function R9(J){return crypto.subtle.importKey("jwk",{kty:J.kty,n:J.n,e:J.e},{name:"RSASSA-PKCS1-v1_5",hash:"SHA-256"},!1,["verify"])}async function v2(J,$,Z){return p1(J,$,"rs256",R9,Z)}var k1={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 u1(J,$,Z,X){if(typeof Z!=="string"||!(Z in k1))throw Error(`Unsupported JWT alg "${String(Z)}" (allowed: ${Object.keys(k1).join(", ")})`);let K=k1[Z];return{key:await p1(J,$,`oidc:${Z}`,(L)=>{if(L.kty!==K.kty)throw Error(`JWK type "${L.kty}" does not match token alg "${Z}"`);if(K.kty==="EC"){let G=L;if(G.crv!==K.crv)throw Error(`JWK curve "${String(G.crv)}" does not match token alg "${Z}"`);return crypto.subtle.importKey("jwk",{kty:"EC",crv:G.crv,x:G.x,y:G.y},K.importParams,!1,["verify"])}return crypto.subtle.importKey("jwk",{kty:L.kty,n:L.n,e:L.e},K.importParams,!1,["verify"])},X),algorithm:K.verifyParams}}function V5(J=32){let $=new Uint8Array(J);return crypto.getRandomValues($),Array.from($,(Z)=>Z.toString(16).padStart(2,"0")).join("").substring(0,J)}function M1(J){let $="";return J.forEach((Z)=>{$+=String.fromCharCode(Z)}),btoa($).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function v9(J){let $=J.replace(/-/g,"+").replace(/_/g,"/"),Z=$.padEnd($.length+(4-$.length%4)%4,"="),X=atob(Z),K=new Uint8Array(X.length);for(let W=0;W<X.length;W++)K[W]=X.charCodeAt(W);return K}function b9(J){let $=new TextDecoder().decode(v9(J));return JSON.parse($)}async function Z1(J){let $=new TextEncoder().encode(J),Z=await crypto.subtle.digest("SHA-256",$);return M1(new Uint8Array(Z))}function c1(J){let $=new URL(J.authorizationUrl);if($.searchParams.set("client_id",J.clientId),$.searchParams.set("redirect_uri",J.redirectUri),$.searchParams.set("response_type","code"),$.searchParams.set("scope",J.scope),$.searchParams.set("state",J.state),J.codeChallenge)$.searchParams.set("code_challenge",J.codeChallenge),$.searchParams.set("code_challenge_method","S256");if(J.nonce)$.searchParams.set("nonce",J.nonce);for(let[Z,X]of Object.entries(J.extraParams??{}))$.searchParams.set(Z,X);return $.toString()}async function d1(J){let $=new URLSearchParams;if($.append("grant_type","authorization_code"),$.append("code",J.code),$.append("redirect_uri",J.redirectUri),$.append("client_id",J.clientId),J.clientSecret)$.append("client_secret",J.clientSecret);if(J.codeVerifier)$.append("code_verifier",J.codeVerifier);let Z=await fetch(J.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:$.toString()}),X=await Z.json();if(!Z.ok){let K=X;throw J.log?.error("OIDC authorization-code exchange failed",{"ion.operation":"token.exchange","ion.outcome":"failure","http.status_code":Z.status,oidc_error:K.error}),Error(`Token exchange failed: ${K.error||Z.statusText} - ${K.error_description||""}`.trim())}if(typeof X.access_token!=="string")throw Error("Token exchange response missing access_token");return X}var q9=60;function $1(J){return J.trim().replace(/\/$/,"")}function U9(J){let{claims:$,audience:Z}=J,X=$1(J.issuer),K=J.nowSec??Math.floor(Date.now()/1000),W=J.clockSkewSec??q9,L=$.iss;if(typeof L!=="string"||$1(L)!==X)throw Error("ID token issuer mismatch");let G=$.aud,D=Array.isArray(G)?G.includes(Z):typeof G==="string"&&G===Z,F=typeof $.azp==="string"&&$.azp===Z;if(!D&&!F)throw Error("ID token audience mismatch");if(typeof $.exp!=="number")throw Error("ID token missing exp");if($.exp<K-W)throw Error("ID token expired");if(J.expectedNonce!==void 0){if($.nonce!==J.expectedNonce)throw Error("ID token nonce mismatch")}}async function C9(J,$,Z){let X=J.split(".");if(X.length!==3)throw Error("Invalid JWT");let K=b9(X[0]),W=b9(X[1]),L=v9(X[2]),{key:G,algorithm:D}=await u1($,K.kid,K.alg,Z),F=new TextEncoder().encode(`${X[0]}.${X[1]}`);if(!await crypto.subtle.verify(D,G,L,F))throw Error("Invalid JWT signature");return{header:K,payload:W}}async function T5(J){let{payload:$}=await C9(J.idToken,J.jwksUri,J.log);return U9({claims:$,issuer:J.issuer,audience:J.audience,clockSkewSec:J.clockSkewSec,expectedNonce:J.expectedNonce}),$}var q2="http://schemas.openid.net/event/backchannel-logout";async function n1(J){let{payload:$}=await C9(J.logoutToken,J.jwksUri,J.log),Z=$1(J.issuer),X=$.iss;if(typeof X!=="string"||$1(X)!==Z)throw Error("Logout token issuer mismatch");let K=$.aud,W=Array.isArray(K)?K.includes(J.audience):typeof K==="string"&&K===J.audience,L=typeof $.azp==="string"&&$.azp===J.audience;if(!W&&!L)throw Error("Logout token audience mismatch");if($.nonce!=null)throw Error("Logout token must not contain a nonce");let G=$.events;if(!(typeof G==="object"&&G!==null&&!Array.isArray(G)&&Object.hasOwn(G,q2)))throw Error("Logout token missing back-channel logout event");let F=typeof $.sid==="string"&&$.sid.length>0,f=typeof $.sub==="string"&&$.sub.length>0;if(!F&&!f)throw Error("Logout token missing sid and sub");if(typeof $.exp==="number"){let n=Math.floor(Date.now()/1000),d=J.clockSkewSec??q9;if($.exp<n-d)throw Error("Logout token expired")}return $}var U2=3600000,C2=60000,k2=86400000,f2=256,w5=new Map,J1=new Map;function y9(J,$){w5.delete(J),w5.set(J,$);while(w5.size>f2){let Z=w5.keys().next().value;if(Z===void 0)break;w5.delete(Z)}}var l1=()=>Date.now();function h2(J){l1=J??(()=>Date.now())}function g2(J){if(J){w5.delete(J),J1.delete(J);return}w5.clear(),J1.clear()}function m2(J){let $=J?/max-age\s*=\s*(\d+)/i.exec(J):null,Z=$?Number($[1]):Number.NaN,X=Number.isFinite(Z)?Z*1000:U2;return Math.min(Math.max(X,C2),k2)}async function a1(J){let $=w5.get(J);if($&&$.expiresAt>l1())return y9(J,$),$.endpoints;let Z=J1.get(J);if(Z)return Z;let X=(async()=>{try{let K=J.replace(/\/$/,""),W=await fetch(`${K}/.well-known/openid-configuration`,{headers:{Accept:"application/json"}});if(!W.ok)throw Error(`OIDC discovery failed for ${J} with status ${W.status}`);let L=await W.json(),G={authorizationUrl:typeof L.authorization_endpoint==="string"?L.authorization_endpoint:void 0,tokenUrl:typeof L.token_endpoint==="string"?L.token_endpoint:void 0,jwksUri:typeof L.jwks_uri==="string"?L.jwks_uri:void 0,userInfoUrl:typeof L.userinfo_endpoint==="string"?L.userinfo_endpoint:void 0};return y9(J,{endpoints:G,expiresAt:l1()+m2(W.headers.get("cache-control"))}),G}catch(K){let W=w5.get(J);if(W)return W.endpoints;throw K}finally{J1.delete(J)}})();return J1.set(J,X),X}async function i1(J,$){let Z=await fetch(J,{headers:{Authorization:`Bearer ${$}`,Accept:"application/json","User-Agent":"ionite-ciam"}});if(!Z.ok)throw Error(`UserInfo request failed with status ${Z.status}`);return await Z.json()}function p2(J){let $=J.replace(/-----BEGIN [^-]+-----/g,"").replace(/-----END [^-]+-----/g,"").replace(/\s+/g,""),Z=atob($),X=new Uint8Array(Z.length);for(let K=0;K<Z.length;K++)X[K]=Z.charCodeAt(K);return X}async function t1(J){let $=Math.floor(Date.now()/1000),Z={alg:"ES256",kid:J.keyId,typ:"JWT"},X={iss:J.teamId,iat:$,exp:$+(J.expiresInSeconds??3600),aud:"https://appleid.apple.com",sub:J.clientId},K=M1(new TextEncoder().encode(JSON.stringify(Z))),W=M1(new TextEncoder().encode(JSON.stringify(X))),L=`${K}.${W}`,G=await crypto.subtle.importKey("pkcs8",p2(J.privateKey),{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),D=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},G,new TextEncoder().encode(L));return`${L}.${M1(new Uint8Array(D))}`}function u2(J){for(let $=0;$<J.length;$++){let Z=J.charCodeAt($);if(Z<=31||Z===127)return!0}return!1}function l2(J,$){let Z=null;try{Z=new URL(J,$)}catch{Z=null}let X="";try{X=new URL($).origin}catch{X=""}return{candidate:J,url:Z,requestOrigin:X}}function k9(J,$,Z){let X=l2(J,Z),K=!1;for(let W of $){let L=W(X);if(L==="deny")return!1;if(L==="allow")K=!0}return K}function f9(){return({candidate:J,url:$})=>{if(u2(J))return"deny";if(J.includes("\\"))return"deny";if(J.startsWith("//"))return"deny";if(!$)return"deny";if($.protocol!=="http:"&&$.protocol!=="https:")return"deny";if($.username||$.password)return"deny";return"abstain"}}function h9(){return({candidate:J})=>J.startsWith("/")&&!J.startsWith("//")&&!J.startsWith("/\\")?"allow":"abstain"}function g9(){return({url:J,requestOrigin:$})=>J&&$&&J.origin===$?"allow":"abstain"}function c2(...J){let $=new Set(J.map((Z)=>{try{return new URL(Z).origin}catch{return Z}}));return({url:Z})=>Z&&$.has(Z.origin)?"allow":"abstain"}function d2(...J){let $=J.map((Z)=>Z.toLowerCase());return({url:Z})=>{if(!Z)return"abstain";let X=Z.hostname.toLowerCase();for(let K of $)if(K.startsWith(".")){if(X===K.slice(1)||X.endsWith(K))return"allow"}else if(X===K)return"allow";return"abstain"}}function o1(){return[f9(),h9(),g9()]}function m9(J,$,Z){if(!J)return!1;return k9(J,$,Z)}function r1(J,$){if(!J)return $.fallback;return k9(J,$.rules,$.requestUrl)?J:$.fallback}var n2={rules:o1(),fallback:"/"};function a2(J,$,Z="redirect"){let X=new URL(J.url).searchParams.get(Z)??void 0;return m9(X,$.rules,J.url)?{redirect:X}:void 0}function i2(J,$){let Z=J.context;return r1(Z?.redirect,{rules:$.rules,fallback:$.fallback,requestUrl:J.request.url})}function S5(J,$,Z){if(J instanceof Response)return{response:J};if(typeof J==="string")return{location:r1(J,{rules:o1(),fallback:$,requestUrl:Z})};return{location:$}}function R5(J,$){if($.length===0)return J;let Z=new Headers(J.headers);for(let X of $)Z.append("Set-Cookie",X);return new Response(J.body,{status:J.status,statusText:J.statusText,headers:Z})}var N1="ciam",t2="id_token",o2="access_token";function r2(J,$,Z,X,K,W){if(!Z&&!X)return;let L=new WeakMap,G={...Z,...X},D={...G,magicLinkTtl:G.magicLinkTtl??3600,sessionTtl:G.sessionTtl??86400,cookiesSecure:G.cookiesSecure!==void 0?G.cookiesSecure:!0,cookiesSameSite:G.cookiesSameSite!==void 0?G.cookiesSameSite:"Strict",cookiesPrefix:G.cookiesPrefix??(G.ciamId?`ion.ciam.${G.ciamId}`:"ion.ciam"),cookiesPath:G.cookiesPath??"/"};function F(){if(!D.sessionStore)throw Error("Missing CIAM configuration field: sessionStore. CIAM sessionStore is required for server-side session tracking and first-party logout.");return D.sessionStore}function f(){F()}let n=J.callbackParams??d5(p9("ionite.ciam")),d=J.idTokenClaims??d5(z1("ionite.ciam")),o=J.tokenResponse??d5(u9("ionite.ciam"));function Z5(Q=32){let B=new Uint8Array(Q);return crypto.getRandomValues(B),Array.from(B,(V)=>V.toString(16).padStart(2,"0")).join("").substring(0,Q)}function C(Q,B,V,z=D.cookiesSameSite??"Strict"){if(!D)throw Error("ionite CIAM Manager not initialized");if(Q=`${D.cookiesPrefix}.${Q}`,typeof B!=="string")B=btoa(JSON.stringify(B));let O;if(V instanceof Date)O=`Expires=${V.toUTCString()}`;else if(typeof V==="number")O=`Max-Age=${V}`;else throw Error("Invalid expires type",V);if(B.length>4000)throw Error(`Error setting cookie: ${Q}. Cookie length is: ${B.length}`);return`${Q}=${B}; ${O}; Path=${D.cookiesPath}; HttpOnly;${D.cookiesSecure?" Secure;":""} SameSite=${z};`}function X5(Q){if(!D)throw Error("ionite CIAM Manager not initialized");return`${D.cookiesPrefix}.${Q}=; Max-Age=0; Path=${D.cookiesPath}; HttpOnly;${D.cookiesSecure?" Secure;":""} SameSite=${D.cookiesSameSite};`}function v(Q,B,V=!1){if(!D)throw Error("ionite CIAM Manager not initialized");let z=B.headers.get("cookie");if(!z)return null;let O=`${D.cookiesPrefix}.${Q}`,w=z.split(";").find((P)=>P.trim().startsWith(`${O}=`));if(!w)return null;let T=w.indexOf("="),E=w.substring(T+1).trim();if(!V)return E;try{let P=atob(E);return JSON.parse(P)}catch(P){return $.error("[CIAM] Failed to parse cookie",{"ion.operation":"cookie.parse","ion.outcome":"failure",cookieName:O},P),null}}function a(Q){return`cstate_${Q}`}async function G5(Q,B,V,z){let O=await D.afterLogin?.({...B,request:Q,context:V}),w=S5(O,"/",Q.url);if(w.response)return R5(w.response,z.map(([,T])=>T));return new Response(B.ok?"Authentication successful, redirecting":"Authentication failed, redirecting",{status:302,headers:[["Location",w.location],...z]})}function U5(Q,B){return["Set-Cookie",C("session",Q,B)]}function _5(Q){if(!Q)return;if(Q instanceof Date)return Q;let B=new Date(Q);return Number.isNaN(B.getTime())?void 0:B}async function P5(Q){let B=v("session",Q);if(!B)return;let V=await F().get(B);if(V&&D.tenantId&&V.tenantId&&V.tenantId!==D.tenantId)return;if(V?.authType!=="ciam")return;let z=_5(V.expiresAt);if(z&&Date.now()>z.getTime()){await F().delete(B);return}return V}async function I5(Q){if(!D)throw Error("ionite CIAM Manager not initialized");f();let B=L.get(Q);if(B)return B;let V=C5(Q);return L.set(Q,V),V}async function C5(Q){try{let B=await P5(Q);if(!B?.claims?.sub)return{status:"unauthenticated"};return{status:"authenticated",value:O5(B.claims)}}catch(B){return $.error("CIAM session resolution failed",{"ion.operation":"ciam.session","ion.outcome":"degraded"},B),{status:"degraded",error:B instanceof Error?B:void 0}}}async function k5(Q){let B=await I5(Q);return B.status==="authenticated"?B.value:void 0}async function f5(Q){if(!D)throw Error("ionite CIAM Manager not initialized");f();let B;try{B=await k5(Q)}catch{B=void 0}let V=await D.beforeLogout?.({request:Q,user:B});try{let I=v("session",Q);if(I)await F().delete(I)}catch(I){$.warn("Failed to delete CIAM session",{"ion.operation":"session.delete","ion.outcome":"degraded"},I)}let z=[["Set-Cookie",X5("session")]],O=await D.afterLogout?.({request:Q,context:V}),w=S5(O,"/",Q.url);if(w.response)return R5(w.response,z.map(([,I])=>I));let T=w.location??"/",E=Q.headers.get("accept");if(E?.includes("application/json")||E?.includes("text/javascript"))return new Response(JSON.stringify({success:!0,message:"Logged out",redirect:T}),{status:200,headers:[["Content-Type","application/json"],...z]});return new Response("Logged out",{status:302,headers:[["Location",T],...z]})}function h5(Q){return Q.id||Q.email||`ciam-${Q.userName}`}function g5(Q,B,V){return{sub:h5(Q),iss:N1,aud:N1,typ:t2,exp:Math.floor(V.getTime()/1000),iat:Math.floor(Date.now()/1000),email:Q.email,name:Q.name,preferred_username:Q.userName,picture:Q.avatar,sid:B}}function m5(Q,B,V){return{sub:Q,iss:N1,aud:N1,typ:o2,exp:Math.floor(V.getTime()/1000),iat:Math.floor(Date.now()/1000),sid:B,scope:"openid profile email"}}function O5(Q){let B=Q.exp?new Date(Q.exp*1000):new Date;return{id:Q.sub,userName:Q.preferred_username??"",name:Q.name??"",email:Q.email??"",avatar:Q.picture,userType:"customer",ciam:{profile:Q,scope:"openid profile email",tokenType:"Bearer",expires:B}}}async function x5(Q){if(!D)throw Error("ionite CIAM Manager not initialized");if(!K)return new Response(JSON.stringify({error:"Workload authentication required"}),{status:401,headers:{"Content-Type":"application/json"}});if(!await K.getWorkloadIdentity(Q))return new Response(JSON.stringify({error:"Unauthorized: Valid workload token required"}),{status:401,headers:{"Content-Type":"application/json"}});let V,z;try{if(!Q.headers.get("content-type")?.includes("application/json"))return new Response(JSON.stringify({error:"Content-Type must be application/json"}),{status:400,headers:{"Content-Type":"application/json"}});let _=await Q.text(),M=JSON.parse(_);z=typeof M?.redirect==="string"&&M.redirect.length>0?M.redirect:void 0;let j={userName:M.userName,name:M.name,email:M.email,avatar:M.avatar},x=await J.customer.validate(j);if(x.issues)return new Response(JSON.stringify({error:"Missing required fields: userName, name, email"}),{status:400,headers:{"Content-Type":"application/json"}});V=x.value}catch(H){return new Response(JSON.stringify({error:"Invalid JSON in request body"}),{status:400,headers:{"Content-Type":"application/json"}})}let w=new URL(Q.url).searchParams.get("ttl"),T=w?parseInt(w,10):D.magicLinkTtl??3600;if(Number.isNaN(T)||T<=0)return new Response(JSON.stringify({error:"Invalid TTL parameter"}),{status:400,headers:{"Content-Type":"application/json"}});let E=Z5(32),P=new Date(Date.now()+T*1000);if(!D.magicLinkStore)return new Response(JSON.stringify({error:"Magic link store not configured"}),{status:500,headers:{"Content-Type":"application/json"}});try{await D.magicLinkStore.create(E,V,P)}catch(H){return $.error("Error creating magic link",{"ion.operation":"magic_link.create","ion.outcome":"failure"},H),new Response(JSON.stringify({error:"Failed to create magic link"}),{status:500,headers:{"Content-Type":"application/json"}})}let I=new URL(Q.url),N=D.magicLinkLoginUrl||"/magic-link/login",Y=new URL(N,I.origin);if(Y.searchParams.set("token",E),z)Y.searchParams.set("redirect",z);return new Response(JSON.stringify({magicLink:Y.toString(),expiresAt:P.toISOString()}),{status:200,headers:{"Content-Type":"application/json"}})}async function j5(Q){if(!D)throw Error("ionite CIAM Manager not initialized");f();let V=new URL(Q.url).searchParams.get("token");if(!V)return G5(Q,{ok:!1,error:Error("Missing magic-link token")},void 0,[]);if(!D.magicLinkStore)return G5(Q,{ok:!1,error:Error("Magic link store not configured")},void 0,[]);let z=await D.magicLinkStore.getAndDelete(V);if(!z)return G5(Q,{ok:!1,error:Error("Magic link invalid, expired, or already used")},void 0,[]);let O=new Date(Date.now()+(D.sessionTtl??86400)*1000),w=Z5(32),T=h5(z.customer),E=g5(z.customer,w,O),P=m5(T,w,O),I=O5(E),N;try{let H={sid:w,sub:T,authType:"ciam",tenantId:D.tenantId,expiresAt:O,claims:E,accessClaims:P,createdAt:new Date};await F().create(H),N=H}catch(H){throw $.warn("Failed to create session",{"ion.operation":"session.create","ion.outcome":"degraded"},H),H}if(D.customerStore)try{let H=I.id;if(H){let _=new Date,M=await D.customerStore.get(H);if(M||D.enableJitUserProvisioning){let j={...M??{},...I,id:H,tenantId:M?.tenantId,createdAt:M?.createdAt??_,updatedAt:_,userType:M?.userType??"customer"};await D.customerStore.upsert(j)}}}catch(H){$.warn("Failed to store customer",{"ion.operation":"customer.store","ion.outcome":"degraded"},H)}let Y=[U5(w,O)];return G5(Q,{ok:!0,user:I,session:N},void 0,Y)}function W5(Q,B=200,V=[]){return new Response(JSON.stringify(Q),{status:B,headers:[["Content-Type","application/json"],...V]})}function A5(Q,B){try{return new URL(Q).toString()}catch{let V=new URL(B).origin,z=D.cookiesSecure?V.replace(/^http:\/\//,"https://"):V;return new URL(Q,z).toString()}}function p5(){let Q=D.customerLoginUrl||"/auth/customer/login",B=Q.includes("?")?"&":"?";return C1(D.providers).map(({name:V,config:z})=>{let O=U1(z);return{name:V,type:z.type,displayName:O.displayName,loginUrl:`${Q}${B}provider=${encodeURIComponent(V)}`,iconUrl:O.iconUrl,colors:O.colors,url:O.url}})}async function R(Q){if(!Q)return{};let{authorizationUrl:B,tokenUrl:V,jwksUri:z,userInfoUrl:O}=Q,w=Q.config.authority;if(w&&(!B||!V||Q.flow==="id_token"&&!z))try{let E=await a1(w);B=B??E.authorizationUrl,V=V??E.tokenUrl,z=z??E.jwksUri,O=O??E.userInfoUrl}catch(E){$.error("CIAM provider OIDC discovery failed",{"ion.operation":"ciam.oidc.discovery","ion.outcome":"failure"},E)}return{authorizationUrl:B,tokenUrl:V,jwksUri:z,userInfoUrl:O}}async function q(Q){if(Q.type==="apple"){let{teamId:B,keyId:V,privateKey:z,clientId:O}=Q.config;if(B&&V&&z&&O)return t1({teamId:B,keyId:V,privateKey:z,clientId:O})}return Q.clientSecret}async function m(Q){F();let V=new URL(Q.url).searchParams.get("provider");if(!V)return W5({error:"Missing required query parameter: provider"},400);let z=D.providers?.[V];if(!z||z.enabled===!1||z.type==="magic-link")return W5({error:`Unknown or disabled CIAM provider: ${V}`},404);let O=D1(V,z);if(!O?.clientId)return W5({error:`CIAM provider ${V} is not fully configured`},500);let w=await R(O);if(!w.authorizationUrl)return W5({error:`CIAM provider ${V} is missing an authorization endpoint`},500);let T=D.customerCallbackUrl||"/auth/customer/callback",E=A5(T,Q.url),P=V5(),I=V5(64),N=V5(),Y=O.flow==="id_token",H=Y?await Z1(I):void 0,_=await D.beforeLogin?.({request:Q}),M=c1({authorizationUrl:w.authorizationUrl,clientId:O.clientId,redirectUri:E,scope:O.scope,state:P,codeChallenge:H,nonce:N,extraParams:O.extraAuthParams}),j={provider:V,state:P,codeVerifier:Y?I:void 0,nonce:N,redirectUri:E,..._===void 0?{}:{context:_}};return new Response("Redirecting to CIAM provider",{status:302,headers:[["Location",M],["Set-Cookie",C(a(P),j,D.loginStateTtl??600,"Lax")]]})}async function p(Q){if(Q.method==="POST"){if((Q.headers.get("content-type")??"").includes("application/x-www-form-urlencoded")){let V=await Q.text();return Object.fromEntries(new URLSearchParams(V).entries())}}return Object.fromEntries(new URL(Q.url).searchParams.entries())}async function i(Q,B){let V=Q.mapClaims(B);if(!V.sub)return{ok:!1};let z=`${Q.name}:${V.sub}`,O={id:z,userName:V.userName||V.email||z,name:V.name||"",email:V.email||"",avatar:V.avatar,userType:"customer"},w=z;if(D.customerStore){let Y=await D.customerStore.lookup(O)??await D.customerStore.get(z);if(w=Y?.id??z,!Y&&!D.enableJitUserProvisioning)return $.warn("CIAM JIT customer provisioning disabled: unknown customer rejected",{"ion.operation":"customer.store","ion.outcome":"skipped"}),{ok:!1};let H=new Date,_={...Y??{},...O,id:w,tenantId:Y?.tenantId,createdAt:Y?.createdAt??H,updatedAt:H,userType:Y?.userType??"customer"};await D.customerStore.upsert(_)}let T=new Date(Date.now()+(D.sessionTtl??86400)*1000),E=V5(32),P={sub:w,iss:Q.name,aud:Q.clientId,exp:Math.floor(T.getTime()/1000),iat:Math.floor(Date.now()/1000),email:V.email,name:V.name,preferred_username:V.userName??V.email,picture:V.avatar,sid:E},I={sid:E,sub:w,authType:"ciam",tenantId:D.tenantId,expiresAt:T,claims:P,accessClaims:{sub:w,sid:E,scope:Q.scope},createdAt:new Date},N=F();try{await N.create(I)}catch(Y){if(!await N.get(E))throw Y;await N.update(E,I)}return{ok:!0,claims:P,sid:E,expires:T}}async function u(Q){F();let B,V,z=(O)=>{let w=B?[["Set-Cookie",X5(B)]]:[];return G5(Q,{ok:!1,error:O},V,w)};try{let O=await p(Q),w=await n.validate(O);if(w.issues||!w.value)return z(Error("Invalid CIAM callback parameters"));let{code:T,state:E}=w.value;if(!E)return z(Error("Missing CIAM callback state"));B=a(E);let P=v(B,Q,!0);if(V=P?.context,!P?.provider||!P.state||P.state!==E)return $.warn("CIAM callback state verification failed",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),z(Error("CIAM callback state verification failed"));let I=D.providers?.[P.provider];if(!I)return z(Error("Unknown CIAM provider"));let N=D1(P.provider,I);if(!N?.clientId)return z(Error("CIAM provider not configured"));let Y=await R(N);if(!Y.tokenUrl)return z(Error("CIAM provider missing token endpoint"));let H=await q(N),_=await d1({tokenUrl:Y.tokenUrl,clientId:N.clientId,clientSecret:H,redirectUri:P.redirectUri||A5(D.customerCallbackUrl||"/auth/customer/callback",Q.url),code:T,codeVerifier:N.flow==="id_token"?P.codeVerifier:void 0,log:$}),M;if(N.flow==="id_token"){let b=N.config.authority;if(!_.id_token||!Y.jwksUri||!b)return z(Error("CIAM id_token flow misconfigured"));if(!P.nonce)return z(Error("CIAM callback state cookie missing nonce"));if((await o.validate(_)).issues)return $.warn("CIAM token response validation failed",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),z(Error("CIAM token response validation failed"));M=await T5({idToken:_.id_token,jwksUri:Y.jwksUri,issuer:b,audience:N.clientId,expectedNonce:P.nonce,log:$});let U=await d.validate(M);if(!U.issues)M=U.value}else{if(!Y.userInfoUrl)return z(Error("CIAM provider missing userinfo endpoint"));M=await i1(Y.userInfoUrl,_.access_token);let b=N.config.authority;if(_.id_token&&Y.jwksUri&&b){let y=await T5({idToken:_.id_token,jwksUri:Y.jwksUri,issuer:b,audience:N.clientId,expectedNonce:P.nonce||void 0,log:$}),U=typeof y.sub==="string"?y.sub:"";if(U){if(typeof M.sub==="string"&&M.sub.length>0&&M.sub!==U)return $.warn("CIAM UserInfo sub does not match verified id_token sub",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),z(Error("CIAM UserInfo sub mismatch"));M.sub=U}}if(typeof M.sub!=="string"||M.sub.length===0)return $.warn("CIAM UserInfo response missing sub",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),z(Error("CIAM UserInfo response missing sub"))}let j=await i(N,M);if(!j.ok)return z(Error("Failed to persist CIAM customer"));let x=O5(j.claims);$.info("CIAM third-party sign-in succeeded",{"ion.operation":"ciam.oidc.callback","ion.outcome":"success",provider:N.name});let S=[["Set-Cookie",X5(B)],U5(j.sid,j.expires)];return G5(Q,{ok:!0,user:x,session:void 0},V,S)}catch(O){return $.error("Error during CIAM third-party sign-in callback",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"},O),z(O)}}async function e(Q){if(!D)throw Error("ionite CIAM Manager not initialized");f();let B=D.magicLinkUrl||"/magic-link",V=D.magicLinkLoginUrl||"/magic-link/login",z=D.logoutUrl||"/auth/customer/logout",O=D.customerLoginUrl||"/auth/customer/login",w=D.customerCallbackUrl||"/auth/customer/callback",T=D.customerProvidersUrl||"/auth/customer/providers",E=new URL(Q.url).pathname,P=(j)=>{if(!j)return;try{return new URL(j).pathname}catch{return j.startsWith("/")?j:`/${j}`}};if(P(B)===E&&Q.method==="POST")return x5(Q);if(P(V)===E&&Q.method==="GET")return j5(Q);if(P(z)===E&&Q.method==="GET")return f5(Q);if(P(T)===E&&Q.method==="GET")return W5({providers:p5()});if(P(O)===E&&Q.method==="GET")return m(Q);if(P(w)===E&&(Q.method==="GET"||Q.method==="POST"))return u(Q);return new Response("Not Found",{status:404})}return{...D,getCustomer:k5,resolveCustomer:I5,logout:f5,handler:e,listCustomerProviders:p5}}async function s2(J,$){return c($,"Ionite instance is required. Create one with ionite(source, config) and pass it to this function."),$.ciam?.getCustomer(J)}async function e2(J,$){return c($,"Ionite instance is required. Create one with ionite(source, config) and pass it to this function."),await $.ciam?.resolveCustomer(J)??{status:"unauthenticated"}}var J4="urn:ietf:params:scim:schemas:core:2.0:User",l9="urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",$4="urn:ietf:params:scim:schemas:core:2.0:Group";function s1(J,$,Z){let K=($==="group"?J.resources:void 0)?.map((W)=>typeof W==="string"?W:W.id).filter(Boolean);return{schemas:[$4,k],id:J.id,externalId:J.providerId,displayName:J.displayName??J.name,members:Z,[k]:{type:$,requestable:J.requestable,providerId:J.providerId,requestUrl:J.requestUrl,source:J.source,deprecated:J.deprecated,description:J.description,resources:K&&K.length>0?K:void 0,assignableSubjectTypes:J.assignableSubjectTypes,recommendedSubjectTypes:J.recommendedSubjectTypes}}}function Z4(J){if(J.scimName)return J.scimName;if(!J.name)return;let[$,...Z]=J.name.split(" ");return{givenName:$,familyName:Z.join(" ")||void 0}}function X4(J){let $={};if(J.ecid!==void 0)$.ecid=J.ecid;if(J.accountClass!==void 0)$.accountClass=J.accountClass;return $.ecid!==void 0||$.accountClass!==void 0?$:void 0}function Q4(J){return Object.keys(J.scimSchemaExtensions??{}).filter(($)=>$.startsWith("urn:")&&J.scimSchemaExtensions?.[$]!==void 0)}function e1(J){let $=J.userName||J.email||J.id||"",Z=J.emails??(J.email?[{value:J.email,primary:!0}]:[]),X=new Set([J4]);if(J.scimEnterprise!==void 0)X.add(l9);let K=X4(J);if(K!==void 0)X.add(M5);for(let L of Q4(J))X.add(L);let W={};if(J.scimEnterprise!==void 0)W[l9]=J.scimEnterprise;if(K!==void 0)W[M5]=K;for(let[L,G]of Object.entries(J.scimSchemaExtensions??{}))if(L.startsWith("urn:")&&L!==M5&&G!==void 0)W[L]=G;return{schemas:Array.from(X),id:J.id,externalId:J.externalId,userName:$,displayName:J.displayName??J.name??$,name:Z4(J),nickName:J.nickName,profileUrl:J.avatar,title:J.title,userType:J.userType,preferredLanguage:J.preferredLanguage,locale:J.locale,timezone:J.timezone,active:J.active??!0,emails:Z,phoneNumbers:J.phoneNumbers,ims:J.ims,photos:J.photos,addresses:J.addresses,groups:J.groups,entitlements:J.entitlements,roles:J.roles,x509Certificates:J.x509Certificates,meta:{resourceType:"User",created:(J.createdAt??J.updatedAt??new Date).toISOString(),lastModified:(J.updatedAt??J.createdAt??new Date).toISOString()},...W}}var Y1="application/scim+json",K4="urn:ietf:params:scim:api:messages:2.0:ListResponse",Y9="urn:ietf:params:scim:api:messages:2.0:Error",B9="urn:ietf:params:scim:schemas:core:2.0:User",B1="urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",G9="urn:ietf:params:scim:schemas:core:2.0:Group",Y4="urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig",c9="urn:ietf:params:scim:schemas:core:2.0:ResourceType",X1="urn:ietf:params:scim:schemas:core:2.0:Schema",B4="00000000000000000000000000000000";function G4(J){let $={timestamp:new Date().toISOString()};if(J)$.actor=J;try{let K=globalThis[Symbol.for("opentelemetry.js.api.1")]?.trace?.getActiveSpan?.()?.spanContext?.(),W=K?.traceId;if(W&&W!==B4){if($.traceId=W,K?.spanId)$.spanId=K.spanId}}catch{}return $}class G1 extends Error{constructor(J){super(J);this.name="SubjectTypeNotAssignableError",Object.setPrototypeOf(this,G1.prototype)}}async function W4(J,$,Z,X){let K=Z.subjectType;if(!j1.includes(K))throw new G1(`Cannot grant ${Z.targetType} "${B5(Z.target)}" to a "${K}" principal: only [${j1.join(", ")}] principals are assignable on this platform.`);let W=D9($,J);if(!W&&!X)return;let L=B5(Z.target),G;if(X)G=await X.getNode(Z.targetType,L);else if(W)G=await(Z.targetType==="group"?W.groups:Z.targetType==="role"?W.roles:W.permissions).get(L);let D=G?.assignableSubjectTypes;if(D&&D.length>0&&!D.includes(K))throw new G1(`Cannot grant ${Z.targetType} "${L}" to a "${K}" principal: this entitlement restricts assignment to [${D.join(", ")}].`)}async function L4(J,$){let Z=F9(J.codeCatalog,B5($.target));if(!Z)return;if(Z.kind!==$.targetType)throw Error(`Cannot grant ${$.targetType} "${Z.entity.id}": code declares that id as ${Z.kind}.`);if(!J.catalogStore)throw Error(`Cannot grant code entitlement "${Z.entity.id}": no AccessCatalogStore is wired for materialization.`);await H9(Z.kind,Z.entity,V9(J.catalogStore,Z.kind))}async function F4(J,$,Z,X){await L4(J,$),await W4(J.catalogStore,J.codeCatalog,$,X);let K={...$,status:$.status??"active",provenance:$.provenance??G4()};if(K.id=L1(K),await J.accessStore?.grant(K),J.accessIndex&&(J.catalogStore||J.codeCatalog)){let W=await N9(K,{catalog:J.catalogStore,code:J.codeCatalog,resources:J.resources,cache:X});await J.accessIndex.materialize(K.id,W)}return Z?.push({op:"add",change:K}),K}async function E1(J,$,Z){let X=$.id??L1($);await J.accessStore?.revoke($),await J.accessIndex?.removeByRoot(X),Z?.push({op:"delete",change:{...$,id:X}})}async function W9(J,$){let Z=await V4(J,$),X=await D4(J,$);return{oaa:Z,delta:X}}async function V4(J,$){if($.length===0||!J.authz.oaa.isReady())return{status:"skipped"};return W1(J,"authz.oaa.push","OAA incremental access push failed after SCIM mutation; full sync will reconcile",()=>J.authz.oaa.pushAccessChanges($),{count:$.length})}async function W1(J,$,Z,X,K){try{return await X(),{status:"ok"}}catch(W){return J.log?.warn(Z,{"ion.operation":$,"ion.outcome":"degraded",...K,error:z5(W)}),{status:"degraded",reason:z5(W)}}}var H4=6;async function D4(J,$){let Z=J.iamDelta;if(!Z?.isReady()||$.length===0)return{status:"skipped"};let X=new Map;for(let D of $){let F=`${D.change.subjectType}:${B5(D.change.subject)}\x00${D.change.targetType}:${B5(D.change.target)}`;X.set(F,D)}let K=[...X.values()],W=K.map(({op:D,change:F})=>()=>D==="add"?Z.onGrant(F):Z.onRevoke(F)),G=(await M4(W,H4)).filter((D)=>D.status==="rejected");if(G.length>0)return J.log?.warn("IAM delta egress degraded after SCIM mutation; IAM server reconcile/aggregation will recover",{"ion.operation":"iam.delta.egress","ion.outcome":"degraded",failed:G.length,total:K.length,error:z5(G[0]?.reason)}),{status:"degraded",reason:z5(G[0]?.reason)};return{status:"ok"}}async function M4(J,$){let Z=Array(J.length),X=0,K=async()=>{while(!0){let L=X++;if(L>=J.length)return;let G=J[L];if(!G)continue;try{Z[L]={status:"fulfilled",value:await G()}}catch(D){Z[L]={status:"rejected",reason:D}}}},W=Array.from({length:Math.min($,J.length)},K);return await Promise.all(W),Z}class P1 extends Error{constructor(J){super(J);this.name="DerivedRevokeError",Object.setPrototypeOf(this,P1.prototype)}}class t5 extends Error{summary;clientError;constructor(J,$,Z=!1){super(J);this.name="ScimMutationError",this.summary=$,this.clientError=Z,Object.setPrototypeOf(this,t5.prototype)}}function h(J,$,Z){return new Response(JSON.stringify({schemas:[Y9],status:String(J),scimType:Z,detail:$}),{status:J,headers:{"Content-Type":Y1}})}function b5(J,$){let Z=$?.totalResults??J.length,X=$?.startIndex??1,K=$?.itemsPerPage??J.length;return new Response(JSON.stringify({schemas:[K4],totalResults:Z,startIndex:X,itemsPerPage:K,Resources:J}),{status:200,headers:{"Content-Type":Y1}})}function H5(J,$=200,Z){let X=new Headers({"Content-Type":Y1});if(Z)X.set("Location",Z);return new Response(JSON.stringify(J),{status:$,headers:X})}function d9(J){return h(J.clientError?409:500,`${J.message}; authz mutation summary: ${JSON.stringify(J.summary)}`,J.clientError?"mutability":"invalidValue")}function K1(J){return L1(J)}function J9(J,$){return O1(n9(J),n9($))}function n9(J){let $=new Map;if(!J?.id)return $;for(let Z of J.groups??[]){let X={subject:J.id,subjectType:"user",targetType:"group",target:Z.value,metadata:Z.display||Z.type?{display:Z.display,type:Z.type}:void 0};$.set(K1(X),X)}for(let Z of J.roles??[]){let X={subject:J.id,subjectType:"user",targetType:"role",target:Z.value,metadata:Z.display||Z.type?{display:Z.display,type:Z.type,primary:Z.primary}:void 0};$.set(K1(X),X)}for(let Z of J.entitlements??[]){let X={subject:J.id,subjectType:"user",targetType:"permission",target:Z.value,metadata:Z.display||Z.type?{display:Z.display,type:Z.type,primary:Z.primary}:void 0};$.set(K1(X),X)}return $}class I1 extends Error{constructor(J){super(J);this.name="AmbiguousMemberSubjectTypeError",Object.setPrototypeOf(this,I1.prototype)}}function N4(J,$,Z){if(J.type==="Group")return;if(J.type==="Workload")return"workload";if(J.type==="User")return"user";let X=$&&$.length>0?$:j1;if(X.length===1)return X[0];throw new I1(`SCIM Group member "${J.value}" of entitlement "${Z}" omits type, and the entitlement is assignable to more than one principal kind [${X.join(", ")}]. Set members[].type to User or Workload.`)}function _1(J,$,Z,X,K){let W=new Map,L=X&&X.length>0?X:void 0;for(let G of J??[]){let D=N4(G,K,Z);if(!D)continue;let F={subject:G.value,subjectType:D,targetType:$,target:Z,resources:L,metadata:G.display||G.type?{display:G.display,type:G.type}:void 0};W.set(K1(F),F)}return W}function $9(J){let $=J[k]?.resources;return $&&$.length>0?$:void 0}function z4(J,$){let Z=(K,W)=>[...K??[]].sort().join(",")===[...W??[]].sort().join(","),X=J[k];if(X?.type!==void 0&&X.type!==$.kind)return!0;if(X?.requestable!==void 0&&X.requestable!==$.entity.requestable)return!0;if(X?.resources!==void 0&&!Z(X.resources,L9($.entity)))return!0;if(X?.assignableSubjectTypes!==void 0&&!Z(X.assignableSubjectTypes,$.entity.assignableSubjectTypes))return!0;if(X?.recommendedSubjectTypes!==void 0&&!Z(X.recommendedSubjectTypes,$.entity.recommendedSubjectTypes))return!0;return!1}function _4(J,$){let Z=(W,L)=>[...W??[]].sort().join(",")===[...L??[]].sort().join(","),X=J[k],K=$[k];if(X?.type!==void 0&&X.type!==K?.type)return!0;if(X?.requestable!==void 0&&X.requestable!==K?.requestable)return!0;if(X?.resources!==void 0&&!Z(X.resources,K?.resources))return!0;if(X?.assignableSubjectTypes!==void 0&&!Z(X.assignableSubjectTypes,K?.assignableSubjectTypes))return!0;if(X?.recommendedSubjectTypes!==void 0&&!Z(X.recommendedSubjectTypes,K?.recommendedSubjectTypes))return!0;return!1}function O4(J){let $=new Map;for(let Z of J)$.set(K1(Z),Z);return $}async function v5(J,$,Z,X,K,W){let L=[],G=new Set,D=(f,n)=>`${n}\x00${f}`,F=W?W.get(`${Z}:${X}`)??[]:$?(await $.listByTarget(Z,X)).items:[];for(let f of F){let n=B5(f.subject),d=f.metadata,o=f.subjectType==="workload"?"Workload":d?.type??"User",Z5=D(n,o);if(G.has(Z5))continue;G.add(Z5),L.push({value:n,...d?.display?{display:d.display}:{},type:o})}for(let f of K??[]){if(f.targetType!==Z||B5(f.target)!==X)continue;let n=B5(f.subject),d=D(n,"Workload");if(G.has(d))continue;G.add(d),L.push({value:n,type:"Workload"})}if(Z==="group"){let f=await J.groups.get(X);for(let n of f?.groups??[]){let d=B5(n),o=D(d,"Group");if(!d||G.has(o))continue;G.add(o),L.push({value:d,type:"Group"})}}return L.length>0?L:void 0}function O1(J,$){let Z=[];for(let[X,K]of $)if(!J.has(X))Z.push({action:"grant",change:K});for(let[X,K]of J)if(!$.has(X))Z.push({action:"revoke",change:K});return Z}async function Z9(J,$){if(J.oaa.isReady())await J.oaa.pushUser($)}async function a9(J,$,Z){if($?.externalId&&$.externalId!==Z.externalId)await J?.onUserDelete($.externalId);await J?.onUserUpsert(Z)}async function n5(J,$,Z,X){let K={metadataApplied:!1,access:[]},W={status:"skipped"},L=[],G=new M9(J.catalogStore,J.resources,J.codeCatalog);try{try{await $(),K.metadataApplied=!0}catch(D){for(let F of Z)K.access.push({change:F.change,status:"rolled_back"});throw K.metadataApplied=!1,new t5(`SCIM metadata write failed: ${z5(D)}`,K,!1)}if(X?.oaa)await W1(J,"authz.oaa.metadata","OAA metadata projection failed after SCIM write; full sync will reconcile",X.oaa);if(X?.delta&&J.iamDelta?.isReady())W=await W1(J,"iam.delta.egress","IAM delta metadata projection failed after SCIM write; full aggregation will reconcile",X.delta);for(let D=0;D<Z.length;D++){let F=Z[D];try{if(F.action==="grant")await F4(J,F.change,L,G);else await P4(J,F.change,L);K.access.push({change:F.change,status:"applied"})}catch(f){K.access.push({change:F.change,status:"failed",error:f});for(let d=D+1;d<Z.length;d++)K.access.push({change:Z[d].change,status:"rolled_back"});let n=f instanceof P1||f instanceof G1;if(!n)await E4(J,F.change,G);throw new t5(n?z5(f):`SCIM access mutation failed: ${z5(f)}`,K,n)}}return K}finally{await A4(J),K.egress=await W9(J,L),K.egress.delta=j4(W,K.egress.delta),w4(J,K)}}function j4(J,$){if(J.status==="degraded")return J;if($.status==="degraded")return $;return J.status==="ok"||$.status==="ok"?{status:"ok"}:{status:"skipped"}}function z5(J){return J instanceof Error?J.message:String(J)}async function A4(J){try{await J.settleAuthz?.()}catch{}}async function E4(J,$,Z){if(!J.accessIndex||!J.catalogStore&&!J.codeCatalog||!J.accessStore)return;let X=B5($.subject);if(!X)return;let K=$.subjectType;try{await z9(X,K,{accessStore:J.accessStore,accessIndex:J.accessIndex,catalogStore:J.catalogStore,code:J.codeCatalog,resources:J.resources},Z)}catch(W){J.log?.warn("Per-subject reconcile after failed SCIM access mutation failed",{"ion.operation":"authz.reconcile.subject.repair","ion.outcome":"degraded",subject:X,subjectType:K,error:z5(W)})}}function w4(J,$){if(!J.onAccessMutation)return;try{J.onAccessMutation($)}catch{}}async function P4(J,$,Z){if(J.accessStore){let X=$.id??L1($);if(!await J.accessStore.get(X)){if((J.accessIndex?await J.accessIndex.has($.subject,$.targetType,$.target,$.resources?.[0],$.subjectType):{allow:!1}).allow)throw new P1(`Cannot revoke ${$.targetType} "${B5($.target)}" for "${B5($.subject)}": it is not a directly granted root (it is derived from group/role membership). Remove the granting group/role instead.`);await E1(J,$,Z);return}}await E1(J,$,Z)}function i5(J){let $=J[k]?.type??"group";if($==="group"||$==="role"||$==="permission")return $;throw Error(`Unsupported ionite SCIM Group authz type "${String($)}"`)}async function X9(J,$,Z){if(!J.oaa.isReady())return;if(Z==="role"){await J.oaa.pushRole($);return}if(Z==="permission"){await J.oaa.pushPermission($);return}await J.oaa.pushGroup($)}function L9(J){let $=J.resources;if(!$||$.length===0)return;let Z=$.map((X)=>typeof X==="string"?X:X.id).filter(Boolean);return Z.length>0?Z:void 0}function q5(J,$,Z){return s1(J,$,Z)}function I4(J,$){let Z=J[k],X={id:$,name:J.displayName,displayName:J.displayName,description:Z?.description??J.displayName,requestable:Z?.requestable,providerId:Z?.providerId??J.externalId,requestUrl:Z?.requestUrl};if(Z?.resources!==void 0)X.resources=Z.resources;return X}function T4(J){if(!J)return;let $=J.trim().match(/^requestable\s+eq\s+(true|false)$/i);if(!$)return;return{requestable:$[1]?.toLowerCase()==="true"}}function i9(J){if(!J)return;let $=J.trim().match(/^externalId\s+eq\s+"([^"]*)"$/i);return $?$[1]:void 0}async function S4(J,$,Z,X){let K=[],W=[["group",J.groups],["role",J.roles],["permission",J.permissions]];for(let[G,D]of W)for await(let F of o9((f,n)=>D.list({start:f,limit:n,filter:{requestable:!0}})))if(F.providerId===Z)K.push({entity:F,type:G});if(K.length>1)throw new _9(`Ambiguous providerId "${Z}": ${K.length} entitlements share it (${K.map((G)=>`${G.type}:${G.entity.id}`).join(", ")})`,"unique_violation","providerId");let L=K[0];if(L?.entity.requestable!==!0)return;return q5(L.entity,L.type,await v5(J,$,L.type,L.entity.id,X))}async function x4(J,$,Z,X){let K=Math.max(0,Z.start),W=Z.limit!=null?K+Z.limit:void 0,L={start:0,limit:W,filter:Z.filter},[G,D,F]=await Promise.all([J.groups.list(L),J.roles.list(L),J.permissions.list(L)]),f=[...G.items.map((C)=>({entity:C,type:"group"})),...D.items.map((C)=>({entity:C,type:"role"})),...F.items.map((C)=>({entity:C,type:"permission"}))],n=G.total+D.total+F.total,d=f.slice(K,W),o=$?.listByTargets?await $.listByTargets(d.map(({entity:C,type:X5})=>({targetType:X5,target:C.id}))):void 0,Z5=await Promise.all(d.map(async({entity:C,type:X5})=>q5(C,X5,await v5(J,$,X5,C.id,X,o))));return{resources:Z5,total:n,count:Z5.length}}async function Q1(J,$,Z,X){let[K,W,L]=await Promise.all([J.groups.get(Z),J.roles.get(Z),J.permissions.get(Z)]);if(K)return q5(K,"group",await v5(J,$,"group",Z,X));if(W)return q5(W,"role",await v5(J,$,"role",Z,X));if(L)return q5(L,"permission",await v5(J,$,"permission",Z,X));return}async function Q9(J,$,Z){let X=i5($),K=X==="role"?await J.roles.get(Z):X==="permission"?await J.permissions.get(Z):await J.groups.get(Z),W={...K??{},...I4($,Z),source:K?.source??"scim"},L=X==="role"?J.roles.set(W):X==="permission"?J.permissions.set(W):J.groups.set(W);return await L.ready(),L}async function R4(J,$){await Promise.all([J.groups.delete($),J.roles.delete($),J.permissions.delete($)])}function t9(){return crypto.randomUUID()}function a5(J,$){let Z=J;if(typeof Z.validate==="function")return Z.validate($);return Promise.resolve(J["~standard"].validate($))}function b4(J){if(!J)return;try{return new URL(J).pathname}catch{return J.startsWith("/")?J:`/${J}`}}function y5(J){let $=b4(J);return $?A1($):void 0}function y4(J,$){let Z=y5(J);if(Z?.endsWith("/Users"))return Z.slice(0,-6);let X=y5($);if(X?.endsWith("/Groups"))return X.slice(0,-7);return}function N5(J,$){return new URL($,J.url).toString()}function A(J,$,Z,X){let{multiValued:K=!1,...W}=X??{};return{name:J,type:$,description:Z,multiValued:K,...W}}function v4(J,$){return{schemas:[Y4],documentationUri:$?.documentationUri,patch:{supported:!0},bulk:{supported:!1},filter:{supported:!0,maxResults:1000},changePassword:{supported:!1},sort:{supported:!1},etag:{supported:!1},authenticationSchemes:[{type:"oauthbearertoken",name:"OAuth Bearer Token",description:"Use an ionite workload bearer token for IAM discovery and provisioning requests.",primary:!0}],meta:{resourceType:"ServiceProviderConfig",location:N5(J.request,`${J.basePath}/ServiceProviderConfig`)}}}function q4(J){let $=[];if(J.supportsUsers)$.push({schemas:[c9],id:"User",name:"User",description:"User Account",endpoint:J.usersUrl,schema:B9,schemaExtensions:[{schema:B1,required:!1},{schema:M5,required:!1}],meta:{resourceType:"ResourceType",location:N5(J.request,`${J.basePath}/ResourceTypes/User`)}});if(J.supportsGroups)$.push({schemas:[c9],id:"Group",name:"Group",description:"Group",endpoint:J.groupsUrl,schema:G9,schemaExtensions:[{schema:k,required:!1}],meta:{resourceType:"ResourceType",location:N5(J.request,`${J.basePath}/ResourceTypes/Group`)}});return $}function U4(J){let $=[];if(J.supportsUsers)$.push({schemas:[X1],id:B9,name:"User",description:"User Account",meta:{resourceType:"Schema",location:N5(J.request,`${J.basePath}/Schemas/${encodeURIComponent(B9)}`)},attributes:[A("id","string","Unique identifier for the User.",{multiValued:!1,required:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),A("externalId","string","External identifier from the provisioning client.",{multiValued:!1,required:!1,mutability:"readWrite",returned:"default",uniqueness:"none"}),A("userName","string","Unique identifier typically used for login.",{multiValued:!1,required:!0,caseExact:!1,mutability:"readWrite",returned:"default",uniqueness:"server"}),A("name","complex","The components of the user name.",{multiValued:!1,required:!1,mutability:"readWrite",returned:"default",subAttributes:[A("formatted","string","The full name, including titles and suffixes.",{multiValued:!1}),A("familyName","string","The family name of the User.",{multiValued:!1}),A("givenName","string","The given name of the User.",{multiValued:!1}),A("middleName","string","The middle name(s) of the User.",{multiValued:!1}),A("honorificPrefix","string","The honorific prefix(es) of the User.",{multiValued:!1}),A("honorificSuffix","string","The honorific suffix(es) of the User.",{multiValued:!1})]}),A("displayName","string","The name of the User, suitable for display.",{multiValued:!1}),A("nickName","string","The casual way to address the user.",{multiValued:!1}),A("profileUrl","reference","A URL pointing to the User profile.",{multiValued:!1,referenceTypes:["external"]}),A("title","string","The user title, such as Vice President.",{multiValued:!1}),A("userType","string","The relationship between the organization and the User.",{multiValued:!1}),A("preferredLanguage","string","Preferred written or spoken language.",{multiValued:!1}),A("locale","string","Default location for localizing values.",{multiValued:!1}),A("timezone","string","The User time zone.",{multiValued:!1}),A("active","boolean","The User administrative status.",{multiValued:!1}),A("emails","complex","Email addresses for the User.",{multiValued:!0,subAttributes:[A("value","string","Email address value.",{multiValued:!1,required:!0}),A("display","string","Display label for the email.",{multiValued:!1}),A("type","string","Email type such as work or home.",{multiValued:!1}),A("primary","boolean","Primary email indicator.",{multiValued:!1})]}),A("phoneNumbers","complex","Phone numbers for the User.",{multiValued:!0,subAttributes:[A("value","string","Phone number value.",{multiValued:!1,required:!0}),A("display","string","Display label for the phone number.",{multiValued:!1}),A("type","string","Phone number type.",{multiValued:!1}),A("primary","boolean","Primary phone number indicator.",{multiValued:!1})]}),A("photos","complex","Photo URLs for the User.",{multiValued:!0,subAttributes:[A("value","reference","Photo URL.",{multiValued:!1,required:!0,referenceTypes:["external"]}),A("display","string","Display label for the photo.",{multiValued:!1}),A("type","string","Photo type.",{multiValued:!1}),A("primary","boolean","Primary photo indicator.",{multiValued:!1})]}),A("addresses","complex","Physical mailing addresses for the User.",{multiValued:!0,subAttributes:[A("formatted","string","Formatted mailing address.",{multiValued:!1}),A("streetAddress","string","Full street address component.",{multiValued:!1}),A("locality","string","City or locality.",{multiValued:!1}),A("region","string","State or region.",{multiValued:!1}),A("postalCode","string","Postal code.",{multiValued:!1}),A("country","string","Country.",{multiValued:!1}),A("type","string","Address type.",{multiValued:!1}),A("primary","boolean","Primary address indicator.",{multiValued:!1})]}),A("groups","complex","Groups to which the User belongs.",{multiValued:!0,mutability:"readOnly",subAttributes:[A("value","string","Group identifier.",{multiValued:!1,required:!0}),A("$ref","reference","Reference to the Group resource.",{multiValued:!1,referenceTypes:["Group"]}),A("display","string","Display name of the group.",{multiValued:!1}),A("type","string","Relationship type.",{multiValued:!1})]}),A("entitlements","complex","Entitlements for the User.",{multiValued:!0,subAttributes:[A("value","string","Entitlement value.",{multiValued:!1,required:!0}),A("display","string","Display value.",{multiValued:!1}),A("type","string","Entitlement type.",{multiValued:!1}),A("primary","boolean","Primary entitlement indicator.",{multiValued:!1})]}),A("roles","complex","Roles for the User.",{multiValued:!0,subAttributes:[A("value","string","Role value.",{multiValued:!1,required:!0}),A("display","string","Display value.",{multiValued:!1}),A("type","string","Role type.",{multiValued:!1}),A("primary","boolean","Primary role indicator.",{multiValued:!1})]}),A("x509Certificates","complex","Certificates issued to the User.",{multiValued:!0,subAttributes:[A("value","string","Certificate value.",{multiValued:!1,required:!0}),A("display","string","Display value.",{multiValued:!1}),A("type","string","Certificate type.",{multiValued:!1}),A("primary","boolean","Primary certificate indicator.",{multiValued:!1})]})]}),$.push({schemas:[X1],id:B1,name:"EnterpriseUser",description:"Enterprise User extension",meta:{resourceType:"Schema",location:N5(J.request,`${J.basePath}/Schemas/${encodeURIComponent(B1)}`)},attributes:[A("employeeNumber","string","Numeric or alphanumeric identifier assigned to a person.",{multiValued:!1}),A("costCenter","string","Name of a cost center.",{multiValued:!1}),A("organization","string","Name of an organization.",{multiValued:!1}),A("division","string","Name of a division.",{multiValued:!1}),A("department","string","Name of a department.",{multiValued:!1}),A("manager","complex","The User manager.",{multiValued:!1,subAttributes:[A("value","string","Identifier of the manager User resource.",{multiValued:!1}),A("$ref","reference","Reference to the manager User resource.",{multiValued:!1,referenceTypes:["User"]}),A("displayName","string","Display name of the manager.",{multiValued:!1})]})]}),$.push({schemas:[X1],id:M5,name:"IoniteUser",description:"ionite User extension carrying the Enterprise Controlled ID (ECID) identity correlator and the account purpose (accountClass). See https://ionite.com/docs/llms-ecid.txt.",meta:{resourceType:"Schema",location:N5(J.request,`${J.basePath}/Schemas/${encodeURIComponent(M5)}`)},attributes:[A("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}),A("accountClass","string","Account purpose (distinct from userType persona). Open value set: 'daily', 'privileged', 'break_glass', 'service'.",{multiValued:!1})]});if(J.supportsGroups)$.push({schemas:[X1],id:k,name:"IoniteAuthzGroup",description:"ionite authorization metadata for SCIM Group resources.",meta:{resourceType:"Schema",location:N5(J.request,`${J.basePath}/Schemas/${encodeURIComponent(k)}`)},attributes:[A("type","string","Authorization entity kind: group, role, or permission.",{multiValued:!1,required:!1}),A("requestable","boolean","Whether this catalog entry is exposed as assignable access to IAM tooling. Only true entries are served.",{multiValued:!1,required:!1}),A("providerId","string","IAM service-provider id captured when this entitlement is materialized at the destination.",{multiValued:!1,required:!1,mutability:"readWrite"}),A("requestUrl","reference","IAM-owned deep link where a principal can request this entitlement.",{multiValued:!1,required:!1,mutability:"readWrite",referenceTypes:["external"]}),A("source","string","Provenance of the catalog row.",{multiValued:!1,required:!1,mutability:"readOnly",canonicalValues:["code","app","scim"]}),A("deprecated","boolean","Whether this retired entitlement may be deleted.",{multiValued:!1,required:!1,mutability:"readOnly"}),A("description","string","Human-readable authorization entity description.",{multiValued:!1,required:!1}),A("resources","string","Resource ids this entitlement is scoped to.",{multiValued:!0,required:!1}),A("assignableSubjectTypes","string","AppDev-owned hard ceiling of principal kinds (user, workload) that may hold this entitlement. Read-only to IAM tooling.",{multiValued:!0,required:!1,mutability:"readOnly",canonicalValues:["user","customer","workload"]}),A("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"]})]});if(J.supportsGroups)$.push({schemas:[X1],id:G9,name:"Group",description:"Group",meta:{resourceType:"Schema",location:N5(J.request,`${J.basePath}/Schemas/${encodeURIComponent(G9)}`)},attributes:[A("id","string","Unique identifier for the Group.",{multiValued:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),A("externalId","string","External identifier from the provisioning client.",{multiValued:!1,uniqueness:"none"}),A("displayName","string","Human-readable name for the Group.",{multiValued:!1,required:!0,uniqueness:"none"}),A("members","complex","Members of the Group.",{multiValued:!0,subAttributes:[A("value","string","Identifier of the member resource.",{multiValued:!1,required:!0}),A("$ref","reference","Reference to the member resource.",{multiValued:!1,referenceTypes:["User","Group"]}),A("display","string","Display name of the member.",{multiValued:!1}),A("type","string","Member type.",{multiValued:!1})]})]});return $}function C4(J,$,Z,X,K,W,L,G,D,F,f,n,d,o,Z5){let C={authz:X,settleAuthz:Z5,accessStore:K,accessIndex:W,catalogStore:L,codeCatalog:G,resources:D,log:$,iamDelta:n,onAccessMutation:d};if(!F&&!f)return;let v={...F,...f},a=v.users?.enabled!==!1,G5=v.groups?.enabled!==!1;if(Boolean(v.url||v.userStore||L||G)&&!Z)$.error("IAM requires workload identity for SCIM push/pull operations",{"ion.operation":"workload.require","ion.outcome":"failure"});function _5(){if(!Z)throw $.error("IAM requires workload identity for SCIM push/pull operations",{"ion.operation":"workload.require","ion.outcome":"failure"}),Error("IAM requires workload identity for SCIM push/pull operations");return Z}async function P5(R){let q=_5(),m=R.headers.get("Authorization");if(!m?.startsWith("Bearer "))return!1;try{let p=m.substring(7);return(await q.validateToken(p)).valid}catch{return!1}}async function I5(){let R=_5(),q=typeof R.getServerToken==="function"?await R.getServerToken():await R.getToken();return new Headers({"Content-Type":Y1,Accept:Y1,Authorization:`Bearer ${q}`})}async function C5(R,q,m,p){if(!v.url)throw Error("IAM URL not configured for outgoing requests");let i=`${v.url}${q}`;try{let u=await I5(),e=await fetch(i,{method:R,headers:u,body:m?JSON.stringify(m):void 0}),Q=await e.json();if(!e.ok)return{success:!1,error:Q,status:e.status};let B=await p["~standard"].validate(Q);if(B.issues)return $.error("SCIM response validation failed",{"ion.operation":"scim.response.validate","ion.outcome":"failure",validationIssues:B.issues}),{success:!1,error:{schemas:[Y9],status:"400",scimType:"invalidValue",detail:`Response validation failed: ${B.issues.map((V)=>V.message).join("; ")}`},status:400};return{success:!0,data:B.value,status:e.status}}catch(u){return{success:!1,error:{schemas:[Y9],status:"500",detail:u instanceof Error?u.message:"Unknown error occurred"},status:500}}}function k5(){return v.url}function f5(R,q){let m=y5(q?.usersUrl??v.usersUrl??"/api/iam/Users")??"/api/iam/Users",p=y5(q?.groupsUrl??v.groupsUrl??"/api/iam/Groups")??"/api/iam/Groups",i=y5(q?.discovery?.basePath??v.discovery?.basePath)??y4(m,p);if(!i)return;return{request:R,basePath:i,usersUrl:m,groupsUrl:p,supportsUsers:a&&Boolean(v.userStore),supportsGroups:G5&&Boolean(L||G)}}async function h5(R){let q=v4(R,v.discovery);return await v.discovery?.buildServiceProviderConfig?.(R,q)??q}async function g5(R){let q=q4(R);return await v.discovery?.buildResourceTypes?.(R,q)??q}async function m5(R){let q=U4(R);return await v.discovery?.buildSchemas?.(R,q)??q}async function O5(R,q){let m=f5(R,q);if(!m)return;let p=A1(new URL(R.url).pathname),{basePath:i}=m;if(p!==i&&!p.startsWith(`${i}/`))return;let u=A1(p.slice(i.length)||"/");if(!(u==="/ServiceProviderConfig"||u==="/ResourceTypes"||u.startsWith("/ResourceTypes/")||u==="/Schemas"||u.startsWith("/Schemas/")))return;if(R.method!=="GET")return h(405,"Method not allowed");if(!await P5(R))return h(401,"Authorization required");if(u==="/ServiceProviderConfig")return H5(await h5(m));if(u==="/ResourceTypes")return b5(await g5(m));if(u.startsWith("/ResourceTypes/")){let B=decodeURIComponent(u.slice(15)),V=(await g5(m)).find((z)=>z.id===B||z.name===B);return V?H5(V):h(404,"Resource not found")}if(u==="/Schemas")return b5(await m5(m));if(u.startsWith("/Schemas/")){let B=decodeURIComponent(u.slice(9)),V=(await m5(m)).find((z)=>z.id===B);return V?H5(V):h(404,"Resource not found")}return}let x5,j5;if(v.url)j5=async(q,m)=>{let p={...q,schemas:q.schemas??["urn:ietf:params:scim:schemas:core:2.0:User","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"]};return C5("POST","/Users",p,J.user)},x5={createGroup:async(q,m)=>{let p={schemas:["urn:ietf:params:scim:schemas:core:2.0:Group"],displayName:q,externalId:m?.id,members:m?.members};return C5("POST","/Groups",p,J.group)}};let W5;if(L||G){let R=D9(G,L),q=(N,Y,H)=>{let _=N[k]??{},M=i5(N),j=N.id,x=j?N5(Y,`${H}/${encodeURIComponent(j)}`):void 0,S={id:j??N.externalId??N.displayName,name:N.displayName,displayName:N.displayName,description:_.description??N.displayName,requestable:_.requestable,providerId:_.providerId??N.externalId,requestUrl:_.requestUrl,source:_.source,deprecated:_.deprecated,assignableSubjectTypes:_.assignableSubjectTypes,recommendedSubjectTypes:_.recommendedSubjectTypes},b=_.requestUrl??v.entitlementRequestUrl?.(S,M,{request:Y});return{...N,meta:{...N.meta,resourceType:"Group",location:x},[k]:{..._,requestUrl:b}}},m=(N)=>F9(G,N),p=async(N,Y)=>{if(!L){if(Y)throw Error(`Cannot persist access for code entitlement "${N.entity.id}": no AccessCatalogStore is wired.`);return N.entity}try{return await H9(N.kind,N.entity,V9(L,N.kind))}catch(H){if(Y)throw H;return $.warn("Code entitlement discovery materialization failed; serving the code template",{"ion.operation":"iam.catalog.materialize","ion.outcome":"degraded",entitlementId:N.entity.id,entitlementType:N.kind,error:z5(H)}),N.entity}},i=async(N)=>{if(!L)return;try{await r9(G,L,N)}catch(Y){$.warn("Retired code entitlement deprecation failed; serving the last durable row",{"ion.operation":"iam.catalog.deprecate","ion.outcome":"degraded",entitlementId:N,error:z5(Y)})}},u=(N,Y)=>h(403,`Entitlement "${N}" is declared in application code; its structural definition cannot be ${Y} through SCIM. IAM may change presentation and receipts, while code continues to own structure.`,"mutability"),e=(N)=>N.path==="members"||Boolean(N.path?.startsWith("members[")),Q=(N)=>e(N)||N.path==="displayName"||N.path===`${k}.description`||N.path===`${k}.providerId`||N.path===`${k}.requestUrl`,B=(N)=>N?.[k]?.requestable===!0,V=(N)=>h(404,`Requestable Group ${N} not found`,"invalidValue"),z=async(N,Y)=>{if(!await P5(N))return h(401,"Authorization required");let _=new URL(N.url),M=Y?.basePath??"/Groups",j=_.pathname;if(j.startsWith(M))j=j.substring(M.length);let S=j.match(/^\/([^/]+)$/)?.[1],b=N.method;try{if(S)switch(b){case"GET":return await w(N,M,S);case"PUT":return await E(N,M,S);case"PATCH":return await P(N,M,S);case"DELETE":return await I(S);default:return h(405,"Method not allowed")}else if(j===""||j==="/")switch(b){case"GET":return await O(N,M);case"POST":return await T(N,M);default:return h(405,"Method not allowed")}return h(404,"Resource not found")}catch(y){if(y instanceof t5)return d9(y);if(y instanceof I1)return h(400,y.message,"invalidValue");if(K9(y))return h(409,y.message,"uniqueness");return $.error("Groups inbound handler error",{"ion.operation":"scim.groups.handler","ion.outcome":"failure"},y),h(500,y instanceof Error?y.message:"Internal server error")}},O=async(N,Y)=>{let H=new URL(N.url),_=H.searchParams.get("startIndex"),M=H.searchParams.get("count"),j=_!=null?parseInt(_,10):void 0,x=M!=null?parseInt(M,10):void 0,S=j!=null&&!Number.isNaN(j)?Math.max(0,j-1):0,b=x!=null&&!Number.isNaN(x)?x:void 0,y=H.searchParams.get("filter"),U=i9(y);if(U!==void 0){await i();let l=await S4(R,K,U,o),L5=l?[q(l,N,Y)]:[];return b5(L5,{totalResults:L5.length,startIndex:1,itemsPerPage:L5.length})}if(T4(y)?.requestable===!1)return b5([],{totalResults:0,startIndex:1,itemsPerPage:0});let Q5={requestable:!0};if(G)await Promise.all([...G.groups.list().filter((l)=>l.requestable===!0).map((l)=>({entity:l,kind:"group"})),...G.roles.list().filter((l)=>l.requestable===!0).map((l)=>({entity:l,kind:"role"})),...G.permissions.list().filter((l)=>l.requestable===!0).map((l)=>({entity:l,kind:"permission"}))].map((l)=>p(l,!1)));await i();let g=await x4(R,K,{start:S,limit:b,filter:Q5},o);return b5(g.resources.map((l)=>q(l,N,Y)),{totalResults:g.total,startIndex:S+1,itemsPerPage:g.count})},w=async(N,Y,H)=>{let _=m(H);if(_&&_.entity.requestable!==!0)return V(H);if(_)await p(_,!1);await i(H);let M=await Q1(R,K,H,o);if(!B(M))return V(H);return H5(q(M,N,Y))},T=async(N,Y)=>{let H=await N.json(),_=await a5(J.group,H);if(_.issues)return $.error("Group creation validation failed",{"ion.operation":"scim.group.create","ion.outcome":"failure",validationIssues:_.issues}),h(400,`Request validation failed: ${_.issues.map((g)=>g.message).join("; ")}`,"invalidValue");let M=_.value;if(!M.displayName)return h(400,"displayName is required","invalidValue");if(M[k]?.requestable===!1)return h(400,"SCIM may create only requestable entitlements; non-requestable definitions are App-owned.","invalidValue");if(M[k]={...M[k],requestable:!0},!L)return h(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 x=i5(M),S=t9();if(m(S))throw new _9(`id "${S}" is reserved by the code catalog`,"unique_violation","id");let b=$9(M),y=O1(new Map,_1(M.members,x,S,b,M[k]?.assignableSubjectTypes)),U;await n5(C,async()=>{U=await Q9(R,M,S)},y,{oaa:()=>X9(X,U,x)});let r=await v5(R,K,x,S),Q5=q(q5(U,x,r),N,Y);return H5(Q5,201,Q5.meta?.location)},E=async(N,Y,H)=>{let _=await N.json(),M=await a5(J.group,_);if(M.issues)return $.error("Group replacement validation failed",{"ion.operation":"scim.group.replace","ion.outcome":"failure",validationIssues:M.issues}),h(400,`Request validation failed: ${M.issues.map((L5)=>L5.message).join("; ")}`,"invalidValue");let j=M.value,x=i5(j),S=m(H);if(S&&S.entity.requestable!==!0)return V(H);if(S){if(await p(S,!0),z4(j,S))return u(H,"replaced")}let b=await Q1(R,K,H);if(!B(b))return V(H);if(!S&&b[k]?.source==="code"&&_4(j,b))return u(H,"replaced");let y=S?.kind??x,U=S?L9(S.entity):$9(j),r=K?(await K.listByTarget(y,H)).items:[],Q5=O1(O4(r),_1(j.members,y,H,U,S?.entity.assignableSubjectTypes??b[k]?.assignableSubjectTypes??j[k]?.assignableSubjectTypes)),g;await n5(C,async()=>{g=await Q9(R,j,H)},Q5,{oaa:()=>X9(X,g,y)});let l=await v5(R,K,y,H);return H5(q(q5(g,y,l),N,Y))},P=async(N,Y,H)=>{let _=m(H);if(_&&_.entity.requestable!==!0)return V(H);if(_)await p(_,!0);let M=await Q1(R,K,H);if(!B(M))return V(H);let j=await N.json();if((_!==void 0||M[k]?.source==="code")&&(j.Operations??[]).some((t)=>!Q(t)))return u(H,"patched");let S={...M};for(let t of j.Operations??[])if(t.op==="replace"&&t.path&&t.value!==void 0){if(t.path==="displayName")S.displayName=t.value;else if(t.path===`${k}.requestable`)S[k]={...S[k],requestable:Boolean(t.value)};else if(t.path===`${k}.description`)S[k]={...S[k],description:String(t.value)};else if(t.path===`${k}.providerId`)S[k]={...S[k],providerId:String(t.value)};else if(t.path===`${k}.requestUrl`)S[k]={...S[k],requestUrl:String(t.value)}}else if(t.op==="add"&&t.path==="members"&&t.value!==void 0){let u5=t.value;S.members=[...S.members??[],...u5]}else if(t.op==="remove"&&t.path?.startsWith("members[")){let u5=t.path.match(/members\[value eq "([^"]+)"\]/);if(u5)S.members=(S.members??[]).filter((o5)=>o5.value!==u5[1])}let b=await a5(J.group,S);if(b.issues)return $.error("Group patch validation failed",{"ion.operation":"scim.group.patch","ion.outcome":"failure",validationIssues:b.issues}),h(400,`Request validation failed: ${b.issues.map((t)=>t.message).join("; ")}`,"invalidValue");let y=_?.kind??i5(S),U=_?L9(_.entity):$9(S),r=_?.entity.assignableSubjectTypes??M[k]?.assignableSubjectTypes??S[k]?.assignableSubjectTypes,Q5=O1(_1(M.members,y,H,U,r),_1(S.members,y,H,U,r)),g,l=!_||(j.Operations??[]).some((t)=>!e(t));await n5(C,async()=>{if(l)g=await Q9(R,S,H)},Q5,l?{oaa:()=>X9(X,g,y)}:void 0);let L5=await Q1(R,K,H);return H5(q(L5,N,Y))},I=async(N)=>{let Y=m(N);if(Y&&Y.entity.requestable!==!0)return V(N);if(Y)await p(Y,!0);let H=await Q1(R,K,N);if(!B(H))return V(N);let _=H[k];if((Y||_?.source==="code")&&_?.deprecated!==!0)return h(403,`Code-owned entitlement "${N}" can be deleted only after it is marked deprecated.`,"mutability");let M=i5(H);if(K){let j=await K.listByTarget(M,N),x=[];for(let S of j.items)await E1(C,S,x);await W9(C,x)}return await R4(R,N),new Response(null,{status:204})};W5={handler:z}}let A5;if(v.userStore){let{userStore:R,inboundUsers:q}=v,m=(Y)=>Y?.find((H)=>H.primary)?.value||Y?.[0]?.value,p=async(Y)=>{if(q?.mapBaseUserToScim)return await q.mapBaseUserToScim(Y);return e1(Y)},i=async(Y,H,_)=>{let M=await p(Y),j=M.id??Y.id;return{...M,id:j,meta:{...M.meta,resourceType:"User",location:j?N5(H,`${_}/${encodeURIComponent(j)}`):void 0}}},u=async(Y,H)=>{if(q?.mapValidatedScimToBaseUser)return await q.mapValidatedScimToBaseUser(Y,H);let _=new Date,M=m(Y.emails),j=Y.name?.formatted||[Y.name?.givenName,Y.name?.middleName,Y.name?.familyName].filter(Boolean).join(" ").trim()||Y.displayName,x=Y.id||H.existing?.id||t9(),S=Y.userName||M||H.existing?.userName||x,b=j||Y.displayName||H.existing?.name||S,y=Object.fromEntries(Object.entries(Y).filter(([l,L5])=>l.startsWith("urn:")&&l!==B1&&l!==M5&&L5!==void 0)),U=Y[M5],r=U?.ecid!==void 0&&U.ecid!==null?w1(U.ecid):H.existing?.ecid,Q5=U?.accountClass??H.existing?.accountClass,g=H.existing?.sso;return{...H.existing??{},id:x,userName:S,name:b,email:M||H.existing?.email||S,avatar:Y.profileUrl,sso:{...g??{},profile:{...g?.profile??{},sub:x,iss:g?.profile.iss??"iam-provisioned",aud:g?.profile.aud??"iam-provisioned",exp:g?.profile.exp??Math.floor(Date.now()/1000)+3600,iat:g?.profile.iat??Math.floor(Date.now()/1000),email:M||H.existing?.email||S,email_verified:!0,name:b,preferred_username:S},tenant:g?.tenant??{id:"iam-provisioned",name:"IAM Provisioned"},scope:g?.scope??"openid profile email",tokenType:g?.tokenType??"Bearer",expires:g?.expires??new Date(Date.now()+3600000)},externalId:Y.externalId,ecid:r,accountClass:Q5,displayName:Y.displayName,scimName:Y.name,emails:Y.emails,nickName:Y.nickName,title:Y.title,preferredLanguage:Y.preferredLanguage,locale:Y.locale,timezone:Y.timezone,active:Y.active,phoneNumbers:Y.phoneNumbers,ims:Y.ims,photos:Y.photos,addresses:Y.addresses,groups:Y.groups,entitlements:Y.entitlements,roles:Y.roles,x509Certificates:Y.x509Certificates,scimEnterprise:Y[B1],scimSchemaExtensions:Object.keys(y).length>0?y:void 0,createdAt:H.existing?.createdAt??(Y.meta?.created?new Date(Y.meta.created):_),updatedAt:Y.meta?.lastModified?new Date(Y.meta.lastModified):_,userType:Y.userType}},e=(Y,H,_)=>{Y[H]=_},Q=(Y,H,_)=>{let M=Y[H];if(Array.isArray(M)){Y[H]=[...M,...Array.isArray(_)?_:[_]];return}if(M&&typeof M==="object"&&!Array.isArray(M)&&_&&typeof _==="object"&&!Array.isArray(_)){Y[H]={...M,..._};return}Y[H]=_},B=(Y,H,_)=>{let M=H.match(/^(urn:.*:(?:User|Group))(?::(.+))?$/),j=M?[M[1],...M[2]?.split(":")??[]]:H.split("."),x=Y;for(let b of j.slice(0,-1)){let y=x[b];if(y===void 0){if(!_)return null;x[b]={}}else if(y===null||typeof y!=="object"||Array.isArray(y)){if(!_)return null;x[b]={}}x=x[b]}let S=j.at(-1);if(!S)return null;return{parent:x,key:S}},V=(Y,H)=>{let _=H.op.toLowerCase();if(!H.path){if(_!=="remove"&&H.value&&typeof H.value==="object"&&!Array.isArray(H.value))Object.assign(Y,H.value);return}let M=H.path.match(/^([A-Za-z0-9]+)\[value eq "([^"]+)"\]$/);if(M&&_==="remove"){let[,x,S]=M,b=Y[x];if(Array.isArray(b))Y[x]=b.filter((y)=>!(y&&typeof y==="object"&&("value"in y)&&y.value===S));return}let j=B(Y,H.path,_!=="remove");if(!j)return;if(_==="remove"){delete j.parent[j.key];return}if(_==="add"){Q(j.parent,j.key,H.value);return}e(j.parent,j.key,H.value)},z=async(Y,H)=>{if(!await P5(Y))return h(401,"Authorization required");let M=new URL(Y.url),j=H?.basePath??"/Users",x=M.pathname;if(x.startsWith(j))x=x.substring(j.length);let b=x.match(/^\/([^/]+)$/)?.[1],y=Y.method;try{if(b)switch(y){case"GET":return await w(Y,j,b);case"PUT":return await P(Y,j,b);case"PATCH":return await I(Y,j,b);case"DELETE":return await N(b);default:return h(405,"Method not allowed")}else if(x===""||x==="/")switch(y){case"GET":return await O(Y,j);case"POST":return await E(Y,j);default:return h(405,"Method not allowed")}return h(404,"Resource not found")}catch(U){if(U instanceof t5)return d9(U);if(K9(U))return h(409,U.message,"uniqueness");return $.error("Users inbound handler error",{"ion.operation":"scim.users.handler","ion.outcome":"failure"},U),h(500,U instanceof Error?U.message:"Internal server error")}},O=async(Y,H)=>{let _=new URL(Y.url),M=_.searchParams.get("startIndex"),j=_.searchParams.get("count"),x=M!=null?parseInt(M,10):void 0,S=j!=null?parseInt(j,10):void 0,b=x!=null&&!Number.isNaN(x)?Math.max(0,x-1):0,y=S!=null&&!Number.isNaN(S)?S:void 0,U=i9(_.searchParams.get("filter"));if(U!==void 0){let g=await R.lookup({externalId:U}),l=g?[await i(g,Y,H)]:[];return b5(l,{totalResults:l.length,startIndex:1,itemsPerPage:l.length})}let r=await R.list({start:b,limit:y}),Q5=await Promise.all(r.items.map((g)=>i(g,Y,H)));return b5(Q5,{totalResults:r.total,startIndex:b+1,itemsPerPage:r.count})},w=async(Y,H,_)=>{let M=await R.get(_);if(!M)return h(404,`User ${_} not found`,"invalidValue");return H5(await i(M,Y,H))},T=async(Y,H)=>{let _=C.accessIndex;if(!_?.setSubjectDisabled||!H.id)return;let M=Y?Y.active??!0:!0,j=H.active??!0;if(Y&&M===j)return;if(!Y&&j)return;await _.setSubjectDisabled(H.id,"user",!j)},E=async(Y,H)=>{let _=await Y.json(),M=await a5(J.user,_);if(M.issues)return $.error("User creation validation failed",{"ion.operation":"scim.user.create","ion.outcome":"failure",validationIssues:M.issues}),h(400,`Request validation failed: ${M.issues.map((b)=>b.message).join("; ")}`,"invalidValue");let j=M.value;if(!j.userName&&!j.emails?.[0]?.value)return h(400,"userName or email is required","invalidValue");let x=await u(j,{mode:"create"});await n5(C,async()=>{await R.upsert(x),await T(void 0,x)},J9(void 0,x),{oaa:async()=>{await Z9(X,x)},delta:async()=>{await C.iamDelta?.onUserUpsert(x)}});let S=await i(x,Y,H);return H5(S,201,S.meta?.location)},P=async(Y,H,_)=>{let M=await R.get(_);if(!M)return h(404,`User ${_} not found`,"invalidValue");let j=await Y.json(),x=await a5(J.user,j);if(x.issues)return $.error("User replacement validation failed",{"ion.operation":"scim.user.replace","ion.outcome":"failure",validationIssues:x.issues}),h(400,`Request validation failed: ${x.issues.map((y)=>y.message).join("; ")}`,"invalidValue");let S=x.value,b=await u({...S,id:_},{existing:M,mode:"replace"});return b.createdAt=M.createdAt,b.updatedAt=new Date,await n5(C,async()=>{await R.upsert(b),await T(M,b)},J9(M,b),{oaa:async()=>{await Z9(X,b)},delta:async()=>{await a9(C.iamDelta,M,b)}}),H5(await i(b,Y,H))},I=async(Y,H,_)=>{let M=await R.get(_);if(!M)return h(404,`User ${_} not found`,"invalidValue");let x=(await Y.json()).Operations??[],b={...await p(M)};for(let r of x)V(b,r);let y=await a5(J.user,b);if(y.issues)return $.error("User patch validation failed",{"ion.operation":"scim.user.patch","ion.outcome":"failure",validationIssues:y.issues}),h(400,`Request validation failed: ${y.issues.map((r)=>r.message).join("; ")}`,"invalidValue");let U=await u(y.value,{existing:M,mode:"patch"});return U.updatedAt=new Date,await n5(C,async()=>{await R.upsert(U),await T(M,U)},J9(M,U),{oaa:async()=>{await Z9(X,U)},delta:async()=>{await a9(C.iamDelta,M,U)}}),H5(await i(U,Y,H))},N=async(Y)=>{let H=await R.get(Y);if(!H)return h(404,`User ${Y} not found`,"invalidValue");if(K){let _=await K.listBySubject(Y,"user"),M=[];for(let j of _.items)await E1(C,j,M);await W9(C,M)}if(await R.delete(Y),await C.accessIndex?.setSubjectDisabled?.(Y,"user",!1),H.externalId&&C.iamDelta?.isReady())await W1(C,"iam.delta.egress","IAM delta user delete failed after SCIM write; full aggregation will reconcile",()=>C.iamDelta?.onUserDelete(H.externalId)??Promise.resolve(),{id:Y,kind:"user"});else if(C.iamDelta?.isReady())C.log?.warn("IAM delta: deleted User has no externalId; destination delete skipped",{"ion.operation":"iam.delta.delete","ion.outcome":"skipped",id:Y,kind:"user"});if(C.authz.oaa.isReady())await W1(C,"authz.oaa.delete","OAA incremental user delete failed; full sync will reconcile",()=>C.authz.oaa.deleteUser(Y),{id:Y,kind:"user"});return new Response(null,{status:204})};A5={handler:z}}async function p5(R,q){_5();let m=new URL(R.url).pathname,p=y5(q?.usersUrl??v.usersUrl??"/api/iam/Users")??"/api/iam/Users",i=y5(q?.groupsUrl??v.groupsUrl??"/api/iam/Groups")??"/api/iam/Groups",u=await O5(R,q);if(u)return u;let e=(Q)=>m===Q||m.startsWith(`${Q}/`);if(e(p)){if(!a)return h(404,"SCIM Users endpoint is disabled by RemoteConfig");if(!A5)return h(501,"SCIM Users endpoint is enabled by RemoteConfig but no user store capability is wired by the application.");return A5.handler(R,{basePath:p})}if(e(i)){if(!G5)return h(404,"SCIM Groups endpoint is disabled by RemoteConfig");if(!W5)return h(501,"SCIM Groups endpoint is enabled by RemoteConfig but no AccessCatalogStore capability is wired by the application.");return W5.handler(R,{basePath:i})}return h(404,"Resource not found")}return{...v,createUser:j5,getBaseUrl:k5,groups_outbound:x5,groups_inbound:W5,users_inbound:A5,handler:p5,delta:n}}function O9(J,$){let Z=new TextEncoder().encode(J),X=typeof $==="string"?new TextEncoder().encode($):$,K=new Uint8Array(Z.length+1+X.length);return K.set(Z,0),K[Z.length]=46,K.set(X,Z.length+1),K}function k4(J){let $=J.replace(/-/g,"+").replace(/_/g,"/"),Z=$.length%4===0?"":"=".repeat(4-$.length%4),X=atob($+Z),K=new Uint8Array(X.length);for(let W=0;W<X.length;W++)K[W]=X.charCodeAt(W);return K}function f4(J){let $="";for(let Z of J)$+=String.fromCharCode(Z);return btoa($).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function s9(J){let $=JSON.parse(J);if(!$||typeof $!=="object"||!Array.isArray($.keys))throw Error("Invalid JWKS: expected { keys: [...] }");return $}function h4(J){return JSON.stringify(J)}async function g4(J){return crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:J.x},{name:"Ed25519"},!0,["verify"])}async function m4(J){return crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:J.x,d:J.d},{name:"Ed25519"},!0,["sign"])}async function p4(J){let Z=(typeof J.jwks==="string"?s9(J.jwks):J.jwks).keys.find((X)=>X.kid===J.kid&&X.kty==="OKP"&&X.crv==="Ed25519");if(!Z?.x)return!1;try{let X=await g4(Z),K=O9(J.requestId,J.rawBody),W=k4(J.signatureB64Url);return crypto.subtle.verify({name:"Ed25519"},X,W,K)}catch{return!1}}async function u4(J){let $=await m4(J.privateKeyJwk),Z=O9(J.requestId,J.rawBody),X=await crypto.subtle.sign({name:"Ed25519"},$,Z);return f4(new Uint8Array(X))}async function l4(J){let $=await crypto.subtle.generateKey({name:"Ed25519"},!0,["sign","verify"]),Z=await crypto.subtle.exportKey("jwk",$.privateKey),K=(await crypto.subtle.exportKey("jwk",$.publicKey)).x,W=Z.d;if(!K||!W)throw Error("Failed to export Ed25519 key material (missing x/d)");return{privateJwk:{kty:"OKP",crv:"Ed25519",x:K,d:W,kid:J,alg:"EdDSA",use:"sig"},publicJwks:{keys:[{kty:"OKP",crv:"Ed25519",x:K,kid:J,alg:"EdDSA",use:"sig"}]}}}var F1={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 T1(J,$){if(typeof J!=="number"||!Number.isFinite(J))return $.default;let Z=Math.floor(J);if(Z<$.min)return $.min;if(Z>$.max)return $.max;return Z}function e9(J){return{ttlMs:T1(J?.ttlSeconds,F1.jwksTtlSeconds)*1000,maxEntries:T1(J?.maxEntries,F1.jwksMaxEntries)}}function J2(J){let $=J?.read;return{read:{enabled:$?.enabled===!0,ttlMs:T1($?.ttlSeconds,F1.sessionReadTtlSeconds)*1000,maxEntries:T1($?.maxEntries,F1.sessionReadMaxEntries)}}}function c4(J){return{jwks:e9(J?.jwks),session:J2(J?.session)}}function d4(J){let $={};if(!J)return $;let Z=J.split(";");for(let X of Z){let K=X.trim();if(!K)continue;let W=K.indexOf("=");if(W===-1)continue;$[K.slice(0,W).trim()]=K.slice(W+1).trim()}return $}function $2(J){if(!J.expiresAt)return!1;let $=J.expiresAt instanceof Date?J.expiresAt:new Date(J.expiresAt);return!Number.isNaN($.getTime())&&Date.now()>$.getTime()}function n4(J){if(!J||typeof J!=="object"||Array.isArray(J))return;let{access_token:$,id_token:Z,refresh_token:X,tokens:K,...W}=J;return W}function D5(J,$){let Z=J[$];return typeof Z==="string"?Z:""}function a4(J,$){let Z=J.exp;if(typeof Z==="number")return new Date(Z*1000);if(typeof Z==="string"&&Z.trim()){let X=Number(Z);if(!Number.isNaN(X))return new Date(X*1000)}if($ instanceof Date)return $;if($){let X=new Date($);if(!Number.isNaN(X.getTime()))return X}return new Date}function i4(J){let $=J.claims;if(!$?.sub||typeof $.sub!=="string")return;let Z=a4($,J.expiresAt);if(J.authType==="sso")return{id:$.sub,userName:D5($,"preferred_username"),name:D5($,"name"),email:D5($,"email"),avatar:D5($,"picture")||void 0,sso:{profile:$,tenant:{id:D5($,"idp")||D5($,"iss"),name:D5($,"iss")},tokenType:"Bearer",expires:Z}};return{id:$.sub,userName:D5($,"preferred_username"),name:D5($,"name"),email:D5($,"email"),avatar:D5($,"picture")||void 0,userType:"customer",ciam:{profile:$,scope:"openid profile email",tokenType:"Bearer",expires:Z}}}function t4(J){if(J.authType!=="sso"&&J.authType!=="ciam")return;if($2(J))return;return{sid:J.sid,authType:J.authType,tenantId:typeof J.tenantId==="string"?J.tenantId:void 0,sub:J.sub,expiresAt:J.expiresAt,createdAt:J.createdAt,claims:n4(J.claims)}}function o4(J,$){if(!J.endsWith(".session"))return!1;if(!$||$.length===0)return!0;return $.some((Z)=>J===`${Z}.session`)}function r4(J){if(J===void 0)return;let $=(Array.isArray(J)?J:[J]).map((Z)=>Z.trim()).filter((Z)=>Z.length>0);return $.length>0?$:void 0}async function Z2(J,$,Z){return(await X2(J,$,Z)).map(t4).filter((K)=>Boolean(K))}async function X2(J,$,Z){let X=d4(J.headers.get("cookie")),K=r4(Z?.cookiesPrefix),W=[],L=new Set;for(let[G,D]of Object.entries(X)){if(!o4(G,K)||!D)continue;if(L.has(D))continue;L.add(D);let F=await $.get(D);if(!F)continue;if(F.authType!=="sso"&&F.authType!=="ciam")continue;if($2(F))continue;W.push(F)}return W}async function s4(J,$,Z){return(await Z2(J,$,Z)).map(i4).filter((K)=>Boolean(K))}var e4="@ionite/core",JJ=d5(z1(e4));async function $J(J,$){let Z=await T5({idToken:J,jwksUri:$.jwksUri,issuer:$.issuer,audience:$.audience}),X=await JJ.validate(Z);if(X.issues)throw Error(`ID token claims validation failed: ${X.issues.map((L)=>L.message).join("; ")}`);let K=X.value;if(K===void 0)throw Error("ID token claims missing");return Q2(K)}function $5(J){return Date.now()-J}function j9(J){if(J instanceof Error)return{"error.name":J.name,"error.message":J.message};return{"error.name":typeof J,"error.message":String(J)}}function S1(J,$){if(!J)return{};try{let Z=new URL(J);return{[`${$}.origin`]:Z.origin,[`${$}.path`]:Z.pathname}}catch{return{[`${$}.path`]:J.startsWith("/")?J:`/${J}`}}}function x1(J,$=5){if(!Array.isArray(J))return[String(J)];return J.slice(0,$).map((Z)=>{if(!Z||typeof Z!=="object")return String(Z);let X=Z,K=Array.isArray(X.path)?X.path.join("."):String(X.path??""),W=typeof X.message==="string"?X.message:String(X.message??"validation failed");return K?`${K}: ${W}`:W})}function ZJ(J){if(!J||typeof J!=="object")return{};let $=J;return{oidc_error:typeof $.error==="string"?$.error:void 0,oidc_error_description:typeof $.error_description==="string"?$.error_description:void 0,oidc_error_uri:typeof $.error_uri==="string"?$.error_uri:void 0}}function XJ(J,$={}){let Z=typeof J==="string"?J:J?.headers.get("cookie")??void 0;if(!Z)return[];let K=`${$.cookiePrefix??"ion.sso"}.`,W=new Set;for(let L of Object.keys(KJ(Z))){if(!L.startsWith(K))continue;let G=L.slice(K.length),D=G.lastIndexOf(".");if(D<=0)continue;let F=G.slice(0,D).trim();if(F)W.add(F)}return Array.from(W)}function QJ(J,$,Z,X,K){if(!Z&&!X)return;let W=new WeakMap,L=new Map,G={...Z,...X},D=!!(G.authority&&G.tokenUrl&&G.authorizationUrl&&G.clientId&&G.redirectUri&&G.scope),F={...G,authority:D?c(G.authority,"Missing 'authority' from SSO Config"):G.authority,tokenUrl:D?c(G.tokenUrl,"Missing 'tokenUrl' from SSO Config"):G.tokenUrl,authorizationUrl:D?c(G.authorizationUrl,"Missing 'authorizationUrl' from SSO Config"):G.authorizationUrl,clientId:D?c(G.clientId,"Missing 'clientId' from SSO Config"):G.clientId,redirectUri:D?c(G.redirectUri,"Missing 'redirectUri' from SSO Config"):G.redirectUri,scope:D?c(G.scope,"Missing 'scope' from SSO Config"):G.scope,responseType:G.responseType??"code",cookiesSecure:G.cookiesSecure!==void 0?G.cookiesSecure:!0,cookiesSameSite:G.cookiesSameSite!==void 0?G.cookiesSameSite:"Strict",cookiesPrefix:G.cookiesPrefix??(G.clientId?`ion.sso.${G.clientId}`:"ion.sso"),cookiesPath:G.cookiesPath??"/"},f=Math.min(600,Math.max(0,Math.floor(Number(F.rotationGraceSeconds??60))||0))*1000,n=Math.floor(Number(F.sessionWindowSeconds??86400)),d=Number.isFinite(n)&&n>=1?n:86400;function o(){let Q=[];if(!F.authority)Q.push("authority");if(!F.tokenUrl)Q.push("tokenUrl");if(!F.authorizationUrl)Q.push("authorizationUrl");if(!F.clientId)Q.push("clientId");if(!F.redirectUri)Q.push("redirectUri");if(!F.scope)Q.push("scope");if(Q.length>0)throw Error(`Missing OIDC configuration fields: ${Q.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 Z5(Q){if(!F)throw Error("ionite SSO Manager not initialized");let B=W.get(Q);if(B)return B;let V=C(Q);return W.set(Q,V),V}async function C(Q){try{let{tokens:B,session:V,refreshedUser:z}=await R(Q);if(!B)return{status:"unauthenticated"};if(z)return{status:"authenticated",value:z};if(V?.claims)return{status:"authenticated",value:I5(V.claims,B,j5(V.expiresAt))};return{status:"unauthenticated"}}catch(B){if(K2(B))return{status:"unauthenticated"};return $.error("Error parsing user from cookies",{"ion.operation":"cookie.parse","ion.outcome":"degraded"},B),{status:"degraded",error:B instanceof Error?B:void 0}}}async function X5(Q){let B=await Z5(Q);return B.status==="authenticated"?B.value:void 0}async function v(Q){if(!F)throw Error("ionite SSO Manager not initialized");o();let B=c(F.redirectUri,"Missing 'redirectUri' from SSO Config"),V=c(F.authorizationUrl,"Missing 'authorizationUrl' from SSO Config"),z=c(F.clientId,"Missing 'clientId' from SSO Config"),O=c(F.scope,"Missing 'scope' from SSO Config"),w=F.cookiesSecure?Q.url.replace(/^http:\/\//,"https://"):Q.url,T=V5(),E=V5(64),P=V5(),I=B;try{new URL(I)}catch{if(w)try{let M=new URL(w),j=I.startsWith("//")?I.slice(1):I.startsWith("/")?I:`/${I}`;I=new URL(j,M.origin).toString()}catch{try{let M=new URL(V),j=I.startsWith("//")?I.slice(1):I.startsWith("/")?I:`/${I}`;I=new URL(j,M.origin).toString()}catch{throw Error(`Invalid redirectUri: "${B}". It must be a valid absolute URL.`)}}}let N=new URL(V);N.searchParams.append("client_id",z),N.searchParams.append("redirect_uri",I),N.searchParams.append("response_type","code"),N.searchParams.append("scope",O),N.searchParams.append("state",T),N.searchParams.append("nonce",P);let Y=await Z1(E);N.searchParams.append("code_challenge",Y),N.searchParams.append("code_challenge_method","S256");let H=await F.beforeLogin?.({request:Q}),_=H===void 0?{state:T,codeVerifier:E,nonce:P}:{state:T,codeVerifier:E,nonce:P,context:H};return new Response("Redirecting to SSO Provider",{status:302,headers:{Location:N.toString(),"Set-Cookie":m(u(T),_,F.loginStateTtl??600,"Lax")}})}async function a(Q){if(!F)throw Error("ionite SSO Manager not initialized");let B;try{B=await X5(Q)}catch{B=void 0}let V=await F.beforeLogout?.({request:Q,user:B}),z=i("session",Q),O;try{O=await R(Q);let Y=O.tokens?.refresh_token??i("refresh",Q);if(Y)await h5(Y)}catch(Y){$.warn("Failed to revoke token",{"ion.operation":"token.revoke","ion.outcome":"degraded"},Y)}if(F.sessionStore)try{let Y=O?.sid??z;if(Y)await F.sessionStore.delete(Y)}catch(Y){$.warn("Failed to delete session",{"ion.operation":"session.delete","ion.outcome":"degraded"},Y)}let w=[["Set-Cookie",p("session")]],T=await F.afterLogout?.({request:Q,context:V}),E=S5(T,"/",Q.url);if(E.response){let Y=new Headers(E.response.headers);for(let[,H]of w)Y.append("Set-Cookie",H);return new Response(E.response.body,{status:E.response.status,statusText:E.response.statusText,headers:Y})}let P=E.location??"/",I=Q.headers.get("accept");if(I?.includes("application/json")||I?.includes("text/javascript"))return new Response(JSON.stringify({success:!0,message:"Logged out",redirect:P}),{status:200,headers:[["Content-Type","application/json"],...w]});return new Response("Logged out",{status:302,headers:[["Location",P],...w]})}async function G5(Q){if(!F)throw Error("ionite SSO Manager not initialized");if(!F.sessionStore)throw Error("Back-Channel Logout requires sessionStore configuration");try{if(!Q.headers.get("content-type")?.includes("application/x-www-form-urlencoded"))return new Response("Invalid Content-Type, expected application/x-www-form-urlencoded",{status:400});let V=await Q.text(),O=new URLSearchParams(V).get("logout_token");if(!O)return new Response("Missing logout_token parameter",{status:400});let w=c(F.authority,"Missing 'authority' from SSO Config. OIDC configuration is required to verify logout tokens."),T=c(F.clientId,"Missing 'clientId' from SSO Config. OIDC configuration is required to verify logout tokens."),E=F.jwksUri||`${w}/protocol/openid-connect/certs`,P=await n1({logoutToken:O,jwksUri:E,issuer:w,audience:T,log:$}),I=typeof P.sid==="string"?P.sid:void 0;if(!I)return $.warn("Back-Channel Logout: logout_token missing sid claim",{"ion.operation":"backchannel_logout","ion.outcome":"failure"}),new Response("Invalid logout_token: missing sid claim",{status:400});return await F.sessionStore.delete(I),$.info("Back-Channel Logout: successfully deleted session",{"ion.module":"sso",sid:I}),new Response("OK",{status:200})}catch(B){return $.error("Error during back-channel logout",{"ion.operation":"backchannel_logout","ion.outcome":"failure"},B),new Response("Internal Server Error",{status:500})}}async function U5(Q){if(!F)throw Error("ionite SSO Manager not initialized");let B=Date.now(),V=new URL(Q.url),z=new URLSearchParams(V.search);$.debug("SSO callback received",{"ion.event":"ion.sso.callback.received","ion.module":"sso","ion.operation":"sign_in.callback","http.method":Q.method,"url.path":V.pathname,hasCode:z.has("code"),hasState:z.has("state"),hasError:z.has("error"),...S1(z.get("iss")??void 0,"oidc.issuer")});let O=Object.fromEntries(z.entries()),w=await J.callbackParams.validate(O);if(w.issues)return $.warn("SSO callback parameter validation failed",{"ion.event":"ion.sso.callback.validation_failed","ion.operation":"sign_in.callback","ion.outcome":"failure","validation.issues":x1(w.issues)}),Y2(w.issues,"OIDC callback parameters validation failed");let{code:T,state:E}=w.value,P;try{let I=c(E,'OIDC "state" was not present in the callback parameters'),N=i(u(I),Q,!0),{codeVerifier:Y,state:H,nonce:_,context:M}=N??{};P=M,$.debug("SSO callback state cookie read",{"ion.event":"ion.sso.callback.state_cookie_read","ion.module":"sso","ion.operation":"sign_in.callback",hasStateCookie:Boolean(N),hasCodeVerifier:Boolean(Y),hasStateVerifier:Boolean(H),hasNonce:Boolean(_),hasContext:M!==void 0});let j=c(Y,'OIDC "codeVerifier" was not present in cookies, ensure that the SSO login was initiated correctly');c(H,'OIDC "stateVerifier" was not present in cookies, ensure that the SSO login was initiated correctly');let x=c(_,'OIDC "nonce" was not present in cookies, ensure that the SSO login was initiated correctly'),S=c(T,'OIDC "code" was not present in the callback parameters');if(E!==H)throw $.warn("SSO callback state verification failed",{"ion.event":"ion.sso.callback.state_verification_failed","ion.operation":"sign_in.callback","ion.outcome":"failure"}),Error('SSO State Verifier failed, the "state" request parameter does not equal the "state" in the SSO cookie');$.debug("SSO callback state verified",{"ion.event":"ion.sso.callback.state_verified","ion.module":"sso","ion.operation":"sign_in.callback"});let b=F.cookiesSecure?Q.url.replace(/^http:\/\//,"https://"):Q.url,y=await k5(S,j,b),{tokenExpiresAt:U,sessionExpiresAt:r}=_5(y);y.expires=U.toISOString();let Q5=Date.now();$.debug("SSO ID token parsing started",{"ion.event":"ion.sso.id_token.parse_started","ion.module":"sso","ion.operation":"id_token.parse"});let g=await P5(y,x,r);$.debug("SSO ID token parsing completed",{"ion.event":"ion.sso.id_token.parse_completed","ion.module":"sso","ion.operation":"id_token.parse","duration.ms":$5(Q5),"user.id":g.id});let l,L5;{let Y5=O5("SSO requires sessionStore configuration for opaque session cookies."),l5=typeof g.sso.profile.sid==="string"?g.sso.profile.sid:void 0,r5=l5||V5(32),F5=g.id;if($.debug("SSO session creation evaluated",{"ion.event":"ion.sso.session.create_evaluated","ion.module":"sso","ion.operation":"session.create",hasSid:Boolean(r5),hasIdpSid:Boolean(l5),hasSub:Boolean(F5),"user.id":F5}),!F5)throw Error("Session creation failed: missing sub in ID token claims");let b1=Date.now(),V1={sid:r5,sub:F5,idpSid:l5,authType:"sso",tenantId:F.tenantId,tokens:y,claims:g.sso.profile,expiresAt:r,createdAt:new Date};await x5(Y5,V1),L5=V1,l=["Set-Cookie",m("session",r5,r)],$.info("SSO session created",{"ion.event":"ion.sso.session.created","ion.operation":"session.create","ion.outcome":"success","duration.ms":$5(b1),"user.id":F5})}if(F.userStore)try{let Y5=g.id;if(Y5){let l5=new Date,r5=Date.now();$.debug("SSO user store lookup started",{"ion.event":"ion.sso.user.lookup_started","ion.module":"sso","ion.operation":"user.lookup","user.id":Y5});let F5=await F.userStore.get(Y5);if($.debug("SSO user store lookup completed",{"ion.event":"ion.sso.user.lookup_completed","ion.module":"sso","ion.operation":"user.lookup","duration.ms":$5(r5),"user.id":Y5,found:Boolean(F5)}),F5||F.enableJitUserProvisioning){let b1=Date.now(),V1={...F5??{},...g,id:Y5,tenantId:F5?.tenantId,createdAt:F5?.createdAt??l5,updatedAt:l5};await F.userStore.upsert(V1),$.info("SSO user stored",{"ion.event":"ion.sso.user.stored","ion.operation":"user.store","ion.outcome":"success","duration.ms":$5(b1),"user.id":Y5,existing:Boolean(F5),jitProvisioning:Boolean(F.enableJitUserProvisioning)})}else $.warn("JIT user provisioning disabled: user not found in store and will not be created",{"ion.event":"ion.sso.user.skipped","ion.operation":"user.store","ion.outcome":"skipped","user.id":Y5})}else $.warn("User storage skipped: missing sub in ID token claims",{"ion.event":"ion.sso.user.skipped","ion.operation":"user.store","ion.outcome":"skipped"})}catch(Y5){$.warn("Failed to store user",{"ion.event":"ion.sso.user.store_failed","ion.operation":"user.store","ion.outcome":"degraded",...j9(Y5)})}$.info("SSO sign-in succeeded",{"ion.event":"ion.sso.sign_in.succeeded","ion.operation":"sign_in.callback","ion.outcome":"success","duration.ms":$5(B),"user.id":g.id});let t=[["Set-Cookie",p(u(I))],...l?[l]:[]],u5=await F.afterLogin?.({ok:!0,request:Q,user:g,session:L5,context:P}),o5=S5(u5,"/",Q.url);if(o5.response)return R5(o5.response,t.map(([,Y5])=>Y5));return new Response("Authentication successful, redirecting",{status:302,headers:[["Location",o5.location],...t]})}catch(I){$.error("Error during sign-in callback",{"ion.event":"ion.sso.sign_in.callback_failed","ion.operation":"sign_in.callback","ion.outcome":"failure","duration.ms":$5(B),...j9(I)});let N=E?[["Set-Cookie",p(u(E))]]:[],Y=await F.afterLogin?.({ok:!1,request:Q,error:I,context:P}),H=S5(Y,"/",Q.url);if(H.response)return R5(H.response,N.map(([,_])=>_));return new Response("Authentication failed, redirecting",{status:302,headers:[["Location",H.location],...N]})}}function _5(Q){let B=Date.now(),V=Number(Q.expires_in??3600)||3600,z=new Date(B+V*1000),O;if(Q.refresh_expires_in!=null&&Number.isFinite(Number(Q.refresh_expires_in)))O=Number(Q.refresh_expires_in);else if(Q.refresh_token)O=d;else O=V;return{tokenExpiresAt:z,sessionExpiresAt:new Date(B+O*1000)}}async function P5(Q,B,V){if(!F)throw Error("ionite SSO Manager not initialized");let z=Date.now(),O=await m5(Q.id_token,B);return $.debug("SSO user parsed from ID token",{"ion.event":"ion.sso.user.parse_completed","ion.module":"sso","ion.operation":"id_token.parse","duration.ms":$5(z),"user.id":O.sub,hasEmail:Boolean(O.email),hasName:Boolean(O.name)}),I5(O,Q,V)}function I5(Q,B,V){let z=V??_5(B).sessionExpiresAt,O=Q.ecid!==void 0&&Q.ecid!==null?w1(Q.ecid):void 0;return{id:Q.sub,userName:Q.preferred_username||"",name:Q.name||"",email:Q.email||"",emails:[{value:Q.email||"",primary:!0}],...O?{ecid:O}:{},avatar:Q.picture,sso:{profile:{...Q},tenant:{id:Q.idp||Q.iss||"",name:Q.iss||""},scope:B.scope,tokenType:B.token_type,sessionState:B.session_state,expires:z}}}async function C5(Q){if(!F.userStore)return Q;let B=await F.userStore.lookup(Q);if(!B)return Q;return{...Q,...B,id:Q.id,sso:Q.sso}}async function k5(Q,B,V){if(!F)throw Error("ionite SSO Manager not initialized");o();let z=c(F.tokenUrl,"Missing 'tokenUrl' from SSO Config"),O=c(F.redirectUri,"Missing 'redirectUri' from SSO Config"),w=c(F.clientId,"Missing 'clientId' from SSO Config"),T=O;try{new URL(T)}catch{if(V)try{let P=new URL(V),I=T.startsWith("//")?T.slice(1):T.startsWith("/")?T:`/${T}`;T=new URL(I,P.origin).toString()}catch{try{let P=new URL(z),I=T.startsWith("//")?T.slice(1):T.startsWith("/")?T:`/${T}`;T=new URL(I,P.origin).toString()}catch{throw Error(`Invalid redirectUri: "${O}". It must be a valid absolute URL.`)}}}let E=new URLSearchParams;if(E.append("grant_type","authorization_code"),E.append("code",Q),E.append("redirect_uri",T),E.append("client_id",w),F.clientSecret)E.append("client_secret",F.clientSecret);E.append("code_verifier",B);try{let P=Date.now();$.debug("SSO token exchange started",{"ion.event":"ion.sso.token.exchange_started","ion.module":"sso","ion.operation":"token.exchange",...S1(z,"oidc.token_url"),...S1(T,"oidc.redirect_uri"),hasClientSecret:Boolean(F.clientSecret)});let I=await fetch(z,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:E.toString()});$.debug("SSO token exchange response received",{"ion.event":"ion.sso.token.response_received","ion.module":"sso","ion.operation":"token.exchange","http.status_code":I.status,"duration.ms":$5(P)}),$.debug("SSO token exchange response body read started",{"ion.event":"ion.sso.token.response_body_read_started","ion.module":"sso","ion.operation":"token.exchange"});let N=await I.json();if($.debug("SSO token exchange response body read completed",{"ion.event":"ion.sso.token.response_body_read_completed","ion.module":"sso","ion.operation":"token.exchange","duration.ms":$5(P)}),!I.ok){$.error("Token exchange error",{"ion.event":"ion.sso.token.exchange_failed","ion.operation":"token.exchange","ion.outcome":"failure","http.status_code":I.status,"duration.ms":$5(P),...ZJ(N)});let H=N;throw Error(`Token exchange failed: ${H.error||I.statusText} - ${H.error_description||""}`.trim())}let Y=await J.tokenResponse.validate(N);if(Y.issues)throw $.error("Token response validation failed",{"ion.event":"ion.sso.token.response_validation_failed","ion.operation":"token.exchange","ion.outcome":"failure","duration.ms":$5(P),"validation.issues":x1(Y.issues)}),Error(`Token response validation failed: ${Y.issues}`);return $.debug("SSO token exchange completed",{"ion.event":"ion.sso.token.exchange_completed","ion.module":"sso","ion.operation":"token.exchange","ion.outcome":"success","duration.ms":$5(P),tokenType:Y.value.token_type,hasAccessToken:Boolean(Y.value.access_token),hasIdToken:Boolean(Y.value.id_token),hasRefreshToken:Boolean(Y.value.refresh_token),expiresIn:Y.value.expires_in}),Y.value}catch(P){throw $.error("Error during token exchange",{"ion.event":"ion.sso.token.exchange_failed","ion.operation":"token.exchange","ion.outcome":"failure",...j9(P)}),P}}async function f5(Q){return m1(async()=>{if(!F)throw Error("ionite SSO Manager not initialized");o();let B=c(F.tokenUrl,"Missing 'tokenUrl' from SSO Config"),V=c(F.clientId,"Missing 'clientId' from SSO Config"),z=new URLSearchParams;if(z.append("grant_type","refresh_token"),z.append("refresh_token",Q),z.append("client_id",V),F.clientSecret)z.append("client_secret",F.clientSecret);let O=await fetch(B,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:z.toString()}),w=await O.json();if(!O.ok){$.error("Token refresh error",{"ion.operation":"token.refresh","ion.outcome":"failure",response:w});let E=w;throw Error(`Token refresh failed: ${E.error||O.statusText} - ${E.error_description||""}`.trim())}let T=await J.tokenResponse.validate(w);if(T.issues)throw $.error("Token refresh response validation failed",{"ion.event":"ion.sso.token.refresh_validation_failed","ion.operation":"token.refresh","ion.outcome":"failure","validation.issues":x1(T.issues)}),Error(`Token refresh response validation failed: ${T.issues}`);return T.value},void 0,void 0,void 0,$)}async function h5(Q){try{if(!F)throw Error("ionite SSO Manager not initialized");if(!F.revocationEndpoint)return;let B=c(F.clientId,"Missing 'clientId' from SSO Config"),V=new URLSearchParams;if(V.append("token",Q),V.append("token_type_hint","refresh_token"),V.append("client_id",B),F.clientSecret)V.append("client_secret",F.clientSecret);let z=await fetch(F.revocationEndpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:V.toString()});if(!z.ok)$.warn("Token revocation failed",{"ion.operation":"token.revoke","ion.outcome":"degraded",status:z.status,statusText:z.statusText});else $.info("Token revoked successfully",{"ion.module":"sso"})}catch(B){$.warn("Error revoking token",{"ion.operation":"token.revoke","ion.outcome":"degraded"},B)}}async function g5(){if(!F)throw Error("ionite SSO Manager not initialized");let Q=F.authority;if(!F.jwksUri&&!Q)throw Error("Missing 'jwksUri' or 'authority' from SSO Config. OIDC configuration is required for this operation.");let B=F.jwksUri||`${Q}/protocol/openid-connect/certs`;return e5(B,$)}async function m5(Q,B){let V=Date.now(),z=c(F.authority,"Missing 'authority' from SSO Config. OIDC configuration is required to verify ID tokens."),O=c(F.clientId,"Missing 'clientId' from SSO Config. OIDC configuration is required to verify ID tokens."),w=F.jwksUri||`${z}/protocol/openid-connect/certs`;$.debug("SSO ID token verification started",{"ion.event":"ion.sso.id_token.verify_started","ion.module":"sso","ion.operation":"id_token.verify",...S1(w,"oidc.jwks_uri")});let T;try{T=await T5({idToken:Q,jwksUri:w,issuer:z,audience:O,expectedNonce:B,log:$})}catch(P){throw $.error("SSO ID token verification failed",{"ion.event":"ion.sso.id_token.verify_failed","ion.module":"sso","ion.operation":"id_token.verify","ion.outcome":"failure","duration.ms":$5(V)},P),P}$.debug("SSO ID token signature verified",{"ion.event":"ion.sso.id_token.signature_verified","ion.module":"sso","ion.operation":"id_token.verify","duration.ms":$5(V)});let E=await J.idTokenClaims.validate(T);if(E.issues)throw $.error("ID token claims validation failed",{"ion.event":"ion.sso.id_token.validation_failed","ion.operation":"id_token.validate","ion.outcome":"failure","duration.ms":$5(V),"validation.issues":x1(E.issues)}),Error(`ID token claims validation failed: ${E.issues}`);return $.debug("SSO ID token claims validated",{"ion.event":"ion.sso.id_token.claims_validated","ion.module":"sso","ion.operation":"id_token.validate","ion.outcome":"success","duration.ms":$5(V),"user.id":E.value.sub,hasIssuer:Boolean(E.value.iss),hasAudience:Boolean(E.value.aud)}),E.value}function O5(Q="SSO sessionStore is required for opaque session cookies."){if(!F.sessionStore)throw Error(Q);return F.sessionStore}async function x5(Q,B){try{await Q.create(B)}catch(V){if(!await Q.get(B.sid))throw V;await Q.update(B.sid,B)}}function j5(Q){if(!Q)return;if(Q instanceof Date)return Q;let B=new Date(Q);return Number.isNaN(B.getTime())?void 0:B}function W5(Q){let B=Q.tokens;if(!B?.access_token||!B.id_token||!B.token_type)return;return B}async function A5(Q,B=!1){let V=O5(),z=i("session",Q);if(!z)return{tokens:void 0,refreshHeaders:[]};let O=await V.get(z);if(O&&F.tenantId&&O.tenantId&&O.tenantId!==F.tenantId)return{tokens:void 0,refreshHeaders:[["Set-Cookie",p("session")]],sid:z};if(O?.authType!=="sso")return{tokens:void 0,refreshHeaders:[["Set-Cookie",p("session")]],sid:z};let w=W5(O);if(!w)return{tokens:void 0,refreshHeaders:[["Set-Cookie",p("session")]],sid:z};let T=j5(O.expiresAt);if(T?Date.now()>T.getTime():!1)return await V.delete(z),{tokens:void 0,sid:z,refreshHeaders:[["Set-Cookie",p("session")]]};let P=j5(w.expires),I=P?Date.now()>P.getTime():!0;if((B||I)&&w.refresh_token)return p5(z,O,w);return{tokens:w,sid:z,session:O,refreshHeaders:[]}}function p5(Q,B,V){let z=L.get(Q);if(z)return z;let O=O5(),w=(async()=>{let T=await f5(V.refresh_token),{tokenExpiresAt:E,sessionExpiresAt:P}=_5(T);T.expires=E.toISOString();let I=await P5(T,void 0,P),N=I.sso.profile,Y=V5(32),H={...B,sid:Y,tokens:T,claims:N,expiresAt:P,createdAt:new Date};await x5(O,H);try{if(f<=0)await O.delete(Q);else{let{refresh_token:_,...M}=V;await O.update(Q,{tokens:M,expiresAt:new Date(Date.now()+f)})}}catch(_){$.warn("Failed to retire rotated SSO session record",{"ion.operation":"session.rotate","ion.outcome":"degraded"},_)}return{tokens:T,sid:Y,session:H,refreshedUser:I,refreshHeaders:[["Set-Cookie",m("session",Y,P)]]}})();return L.set(Q,w),w.finally(()=>{L.delete(Q)})}async function R(Q,B=!1){return A5(Q,B)}async function q(Q){let{tokens:B}=await R(Q);if(!B)return;return B.access_token}function m(Q,B,V,z=F.cookiesSameSite??"Strict"){if(!F)throw Error("ionite SSO Manager not initialized");if(Q=`${F.cookiesPrefix}.${Q}`,typeof B!=="string")B=btoa(JSON.stringify(B));let O;if(V instanceof Date)O=`Expires=${V.toUTCString()}`;else if(typeof V==="number")O=`Max-Age=${V}`;else throw Error("Invalid expires type",V);if(B.length>4000)throw Error(`Error setting cookie: ${Q}. Cookie length is: ${B.length}`);return`${Q}=${B}; ${O}; Path=${F.cookiesPath}; HttpOnly;${F.cookiesSecure?" Secure;":""} SameSite=${z};`}function p(Q){if(!F)throw Error("ionite SSO Manager not initialized");return`${F.cookiesPrefix}.${Q}=; Max-Age=0; Path=${F.cookiesPath}; HttpOnly;${F.cookiesSecure?" Secure;":""} SameSite=${F.cookiesSameSite};`}function i(Q,B,V=!1){if(!F)throw Error("ionite SSO Manager not initialized");let z=B.headers.get("cookie");if(!z)return null;let O=`${F.cookiesPrefix}.${Q}`,w=z.split(";").find((I)=>I.trim().startsWith(`${O}=`));if(!w)return null;let T=w.indexOf("="),E=w.slice(T+1).trim();if(!V)return E;let P=atob(E);return JSON.parse(P)}function u(Q){return`state_${Q}`}async function e(Q,B){if(!F)throw Error("ionite SSO Manager not initialized");let{loginUrl:V,userUrl:z,tokenUrl:O,refreshUrl:w,logoutUrl:T,logoutBackChannelUrl:E,jwksUrl:P,redirectUri:I}={...F,...B},N=new URL(Q.url).pathname;if(I){let Y;try{Y=new URL(I).pathname}catch{try{let H=new URL(Q.url),_=I.startsWith("//")?I.slice(1):I;Y=new URL(_,H.origin).pathname}catch{Y=I.startsWith("/")?I:`/${I}`}}if(Y===N)return U5(Q)}if(V===N)return v(Q);if(z===N)try{let{tokens:Y,session:H,refreshedUser:_,refreshHeaders:M}=await R(Q);if(!Y)return new Response("User not logged in",{status:401,headers:M});let j=_??(H?.claims?I5(H.claims,Y,j5(H.expiresAt)):void 0);if(!j)return new Response("User not logged in",{status:401,headers:M});let x=await C5(j);return new Response(JSON.stringify(x),{headers:[["Content-Type","application/json"],...M]})}catch(Y){if(K2(Y))return new Response("User not logged in",{status:401});return $.error("Error resolving SSO user",{"ion.operation":"sso.user","ion.outcome":"degraded"},Y),new Response(JSON.stringify({error:"auth_unavailable"}),{status:503,headers:{"Content-Type":"application/json"}})}if(O===N){let{tokens:Y,refreshHeaders:H}=await R(Q);if(!Y)return new Response("User not logged in",{status:401,headers:H});return new Response(JSON.stringify({token:Y.access_token,expires:Y.expires}),{headers:[["Content-Type","application/json"],...H]})}if(w===N){let{tokens:Y,refreshHeaders:H}=await R(Q,!0);if(!Y)return new Response("User not logged in",{status:401});return new Response("Refresh Complete",{status:200,headers:H})}if(T===N)return a(Q);if(E===N)return G5(Q);if(P===N){let Y=await g5();return new Response(JSON.stringify(Y),{headers:[["Content-Type","application/json"]]})}return new Response("Not Found",{status:404})}return{...F,getUser:X5,resolveUser:Z5,getJwt:q,initiateLogin:v,logout:a,logoutBackChannel:G5,callbackHandler:U5,handler:e}}function KJ(J){let $={},Z=J.split(";");for(let X of Z){let K=X.trim();if(!K)continue;let W=K.indexOf("=");if(W===-1)continue;let L=K.slice(0,W).trim(),G=K.slice(W+1).trim();$[L]=G}return $}function K2(J){if(!(J 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(($)=>J.message.includes($))}function B2(J){return J=J??"SSO Unavailable",new Response(JSON.stringify({error:J}),{status:503,statusText:J,headers:{"Content-Type":"application/json"}})}var R1="Ionite instance is required. Create one with ionite(source, config) and pass it to this function.";async function YJ(J,$){return c($,R1),$.sso?.getUser(J)}async function BJ(J,$){return c($,R1),await $.sso?.resolveUser(J)??{status:"unauthenticated"}}async function GJ(J,$){c($,R1);let Z=$.sso;if(!Z)return B2();return Z.initiateLogin(J)}async function WJ(J,$){c($,R1);let Z=$.sso;if(!Z)return B2();return Z.callbackHandler(J)}export{R5 as withSetCookies,$J as verifyUser,n1 as verifyLogoutToken,p4 as verifyLfvSignature,T5 as verifyIdToken,h4 as stringifyLfvJwks,QJ as sso,u4 as signLfvPayload,T2 as setJwksRetry,I2 as setJwksClock,h2 as setDiscoveryClock,VJ as sendTenantWebhook,o1 as sameOriginRedirectRules,BJ as resolveUser,J2 as resolveSessionCacheConfig,r1 as resolveRedirect,U1 as resolveProviderBranding,e9 as resolveJwksCacheConfig,b2 as resolveJwkForKid,e2 as resolveCustomer,D1 as resolveCiamProvider,i2 as resolveCapturedRedirect,c4 as resolveCacheConfig,S5 as resolveAfterRedirect,z9 as reconcileSubjectAccess,Z1 as pkceChallengeFromVerifier,s9 as parseLfvJwks,C1 as orderedEnabledProviders,$1 as normalizeOidcIssuer,XJ as listSsoClientIdsFromCookies,m9 as isRedirectAllowed,GJ as initiateLogin,C4 as iam,A2 as hasScope,z2 as hasRole,N2 as hasPermission,_2 as hasGroup,E2 as hasAnyScope,O2 as hasAny,w2 as hasAllScope,j2 as hasAll,M2 as has,u1 as getVerificationKeyForKid,YJ as getUser,y2 as getPublicKeyFromJwks,v2 as getPublicKeyForKid,q1 as getProviderPreset,e5 as getJwks,s4 as getDiscoveredSessionUsers,s2 as getCustomer,p1 as getCachedVerificationKey,l4 as generateLfvEd25519KeyPair,t1 as generateAppleClientSecret,i1 as fetchUserInfo,N9 as expandRoot,d1 as exchangeAuthorizationCode,s1 as entitlementToScimGroup,Z2 as discoverSessions,X2 as discoverSessionRecords,a1 as discoverOidcEndpoints,n2 as defaultRedirectPolicies,P2 as configureJwksCache,LJ as collectReferencedDefinitions,R2 as clearJwksCache,g2 as clearDiscoveryCache,r2 as ciam,a2 as captureRedirect,WJ as callback,O9 as buildLfvSigningInput,c1 as buildAuthorizationUrl,f9 as blockDangerousUrls,e1 as baseUserToScimUser,U9 as assertTrustedIdTokenClaims,g9 as allowSameOrigin,h9 as allowRelativePaths,c2 as allowOrigins,d2 as allowHosts,FJ as InMemoryTenantStore,M9 as CatalogAdjacencyCache,I9 as CIAM_PROVIDER_PRESETS,F1 as CACHE_BOUNDS};
|
|
1
|
+
import{$ as i5,E as S1,F as i9,G as t9,H as j1,I as a5,J as i,K as N2,O as w1,S as D2,U as I9,V as I1,Y as EJ,Z as AJ,_ as I5,a as x9,aa as t5,d as X2,da as K2,ea as Y2,f as p,g as V9,n as O9,o as j9,q as _9,r as Q2,s as E9,t as N5,u as V1,v as A9,w as P9,x as w9,y as _J}from"./shared/core-ys2a23v0.js";var O2="Ionite instance is required. Create one with ionite(source, config) and pass it to this function.",R9=["user","customer","workload"],j2={user:async(J,$)=>$.sso?.getUser(J),customer:async(J,$)=>$.ciam?.getCustomer(J),workload:async(J,$)=>{let Z=await $.workload?.getWorkloadIdentity?.(J);if(!Z)return;let X=Z.clientId??Z.workloadId??Z.claims.sub;return X?{...Z,id:X}:void 0}};function _2(J){if(J==="any")return R9;let $=Array.isArray(J)?J:[J];return R9.filter((Z)=>$.includes(Z))}function E2(J){let $=J.headers.get("cookie");if(!$)return[];return $.split(";").map((Z)=>Z.slice(0,Z.indexOf("=")===-1?Z.length:Z.indexOf("=")).trim()).filter(Boolean)}function A2(J,$){let Z=J.headers.get("authorization")?.toLowerCase().startsWith("bearer ")??!1,X=E2(J),K=new Set;for(let G of X){if(G.startsWith("ion.sso"))K.add("user");if(G.startsWith("ion.ciam"))K.add("customer")}let B=X.length>0&&!K.has("user")&&!K.has("customer");return $.filter((G)=>{if(G==="workload")return Z;if(X.length===0)return!1;return K.has(G)||B})}function X5(J){return typeof J==="string"?J:J.id}function y9(J){let{subject:$,subjectType:Z}=J,X;if(Z==="user")X=$.sso?.scope;else if(Z==="customer")X=$.ciam?.scope;else if(Z==="workload")X=$.scope;return new Set((X??"").split(/\s+/).filter(Boolean))}function k1(J,$,Z){let X=y9(J),K=$.filter((G)=>X.has(G));return{allow:Z==="any"?K.length>0:$.length>0&&K.length===$.length,metadata:{reason:"scope",wantedScopes:$,matchedScopes:K}}}function n5(J,$){return(Z)=>{if(J.length===0)return;let X=y9(Z),K=J.filter((G)=>X.has(G));return($==="any"?K.length>0:K.length===J.length)?K:void 0}}function M1(J,$,Z){return(X)=>{if($.length===0||X.subjectType!=="workload")return;let K=x9(J.config?.authz,X.subject);if(!K)return;let B=$.filter((W)=>K.has(W));return(Z==="any"?B.length>0:B.length===$.length)?B:void 0}}function P2(J,$){if(J.subjectType==="workload"){let Z=J.subject.scopesAsEntitlements;if(typeof Z==="boolean")return Z}return $.config?.authz?.scopesAsEntitlements===!0}function C1(J,$,Z,X,K){return{allow:Z==="ok",subject:$?.subject,subjectType:$?.subjectType,reason:Z,decision:X,response(){if(Z==="ok")return new Response(null,{status:204});if(Z==="unauthenticated")return J.log.warn("authz.denied",{reason:Z,...K()}),Response.json({error:"Unauthorized"},{status:401});if(Z==="not_configured")return J.log.warn("authz.denied",{reason:Z,subject:$?.subject?.id,subjectType:$?.subjectType,...K()}),Response.json({error:"not_configured"},{status:503});return J.log.warn("authz.denied",{reason:Z,subject:$?.subject?.id,subjectType:$?.subjectType,...K()}),Response.json({error:"Forbidden"},{status:403})}}}function w2(J,$,Z){return new Promise((X)=>{let K=[],B=J.length,G=!1,W=()=>{if(B-=1,B===0&&!G)G=!0,X({outcomes:K})};for(let H of J)$(H).then((F)=>{if(K.push({principal:H,decision:F}),!G&&F.allow){G=!0,X({matched:{principal:H,decision:F},outcomes:K});return}W()},(F)=>{Z?.(H,F),K.push({principal:H,decision:{allow:!1,metadata:{reason:"error"}}}),W()})})}async function x5(J,$,Z,X,K,B,G){i($,O2);let W=A2(J,_2(Z)),F=(await Promise.all(W.map(async(T)=>{let c=await j2[T](J,$);return c?.id?{subject:c,subjectType:T,subjectId:c.id}:void 0}))).filter((T)=>T!==void 0);if(F.length===0)return C1($,void 0,"unauthenticated",void 0,K);let g=async(T)=>{let c=$.authz.accessIndex;if(!c?.isSubjectDisabled)return!1;return c.isSubjectDisabled(T.subjectId,T.subjectType)},u=async(T)=>{if(G){let c=G(T);if(c&&c.length>0){if(await g(T))return{allow:!1,metadata:{reason:"subject_disabled"}};return{allow:!0,metadata:{reason:"trusted-client",matchedPermissions:c}}}}if(B&&P2(T,$)){let c=B(T);if(c&&c.length>0){if(await g(T))return{allow:!1,metadata:{reason:"subject_disabled"}};return{allow:!0,metadata:{reason:"scope",matchedScopes:c}}}}return X(T)},{matched:n,outcomes:e}=await w2(F,u,(T,c)=>{$.log.warn("authz.check_error",{"ion.operation":"authz.check","ion.outcome":"error",subject:T.subjectId,subjectType:T.subjectType,error:c instanceof Error?c.message:String(c),...K()})});if(n){if(n.decision.metadata?.reason==="scope")$.log.info("authz.scope_honor",{"ion.operation":"authz.scope_honor","ion.outcome":"allow",subject:n.principal.subjectId,subjectType:n.principal.subjectType,matchedScopes:n.decision.metadata.matchedScopes,...K()});return C1($,n.principal,"ok",n.decision,K)}let $5=e.length>0&&e.every((T)=>{let c=T.decision.metadata?.reason;return c==="access_index_not_configured"||c==="error"}),b=e[0],r=$5?"not_configured":"forbidden";return C1($,b?.principal,r,b?.decision,K)}async function I2(J,$,Z,X,K,B="any"){return x5(J,$,B,(G)=>$.authz.has(G.subjectId,Z,X,K,G.subjectType),()=>({targetType:Z,target:X5(X),resource:K?X5(K):void 0}),K?void 0:n5([X5(X)],"any"),Z==="permission"&&!K?M1($,[X5(X)],"any"):void 0)}async function T2(J,$,Z,X,K="any"){return x5(J,$,K,(B)=>$.authz.hasPermission(B.subjectId,Z,X,B.subjectType),()=>({targetType:"permission",target:X5(Z),resource:X?X5(X):void 0}),X?void 0:n5([X5(Z)],"any"),X?void 0:M1($,[X5(Z)],"any"))}async function S2(J,$,Z,X,K="any"){return x5(J,$,K,(B)=>$.authz.hasRole(B.subjectId,Z,X,B.subjectType),()=>({targetType:"role",target:X5(Z),resource:X?X5(X):void 0}),X?void 0:n5([X5(Z)],"any"))}async function R2(J,$,Z,X,K="any"){return x5(J,$,K,(B)=>$.authz.hasGroup(B.subjectId,Z,X,B.subjectType),()=>({targetType:"group",target:X5(Z),resource:X?X5(X):void 0}),X?void 0:n5([X5(Z)],"any"))}async function x2(J,$,Z,X="any"){let K=Z.filter((G)=>!G.resource).map((G)=>X5(G.target)),B=Z.filter((G)=>!G.resource&&G.targetType==="permission").map((G)=>X5(G.target));return x5(J,$,X,(G)=>$.authz.hasAny(G.subjectId,Z,G.subjectType),()=>({targets:Z.map((G)=>`${G.targetType}:${X5(G.target)}`)}),K.length>0?n5(K,"any"):void 0,B.length>0?M1($,B,"any"):void 0)}async function y2(J,$,Z,X="any"){let K=Z.length>0&&Z.every((W)=>!W.resource),B=Z.length>0&&Z.every((W)=>!W.resource&&W.targetType==="permission"),G=Z.map((W)=>X5(W.target));return x5(J,$,X,(W)=>$.authz.hasAll(W.subjectId,Z,W.subjectType),()=>({targets:Z.map((W)=>`${W.targetType}:${X5(W.target)}`)}),K?n5(G,"all"):void 0,B?M1($,G,"all"):void 0)}async function b2(J,$,Z,X="any"){return x5(J,$,X,(K)=>Promise.resolve(k1(K,[Z],"any")),()=>({scope:Z}))}async function v2(J,$,Z,X="any"){return x5(J,$,X,(K)=>Promise.resolve(k1(K,Z,"any")),()=>({scopes:Z}))}async function q2(J,$,Z,X="any"){return x5(J,$,X,(K)=>Promise.resolve(k1(K,Z,"all")),()=>({scopes:Z}))}function Y5(J){return typeof J==="string"&&J.length>0?J:void 0}function b9(J){let $=Y5(J.email);return{sub:String(J.sub??""),email:$,name:Y5(J.name),userName:Y5(J.preferred_username)??$,avatar:Y5(J.picture)}}var v9={oidc:{flow:"id_token",scope:"openid profile email",branding:{displayName:"Single sign-on"},mapClaims:b9},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:b9},microsoft:{flow:"id_token",authorizationUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/authorize",tokenUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/token",jwksUri:"https://login.microsoftonline.com/common/discovery/v2.0/keys",scope:"openid email profile",branding:{displayName:"Microsoft",colors:{light:"#ffffff",dark:"#2f2f2f",secondary:"#0067b8"},url:"https://login.microsoftonline.com"},mapClaims:(J)=>{let $=Y5(J.email)??Y5(J.preferred_username);return{sub:String(J.sub??J.oid??""),email:$,name:Y5(J.name),userName:Y5(J.preferred_username)??$,avatar:Y5(J.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:(J)=>{let $=Y5(J.email);return{sub:String(J.sub??""),email:$,name:Y5(J.name),userName:$}}},github:{flow:"userinfo",authorizationUrl:"https://github.com/login/oauth/authorize",tokenUrl:"https://github.com/login/oauth/access_token",userInfoUrl:"https://api.github.com/user",scope:"read:user user:email",branding:{displayName:"GitHub",colors:{light:"#24292f",dark:"#ffffff"},url:"https://github.com"},mapClaims:(J)=>({sub:String(J.id??J.node_id??""),email:Y5(J.email),name:Y5(J.name)??Y5(J.login),userName:Y5(J.login),avatar:Y5(J.avatar_url)})}};function f1(J){if(J==="magic-link")return;return v9[J]}function N1(J,$){if($.type==="magic-link")return;let Z=f1($.type);if(!Z)return;return{name:J,type:$.type,flow:Z.flow,authorizationUrl:$.authorizationUrl??Z.authorizationUrl,tokenUrl:$.tokenUrl??Z.tokenUrl,jwksUri:$.jwksUri??Z.jwksUri,userInfoUrl:$.userInfoUrl??Z.userInfoUrl,scope:$.scope??Z.scope,clientId:$.clientId,clientSecret:$.clientSecret,extraAuthParams:Z.extraAuthParams,branding:{...Z.branding,...$.branding},mapClaims:Z.mapClaims,config:$}}function h1(J){return{...f1(J.type)?.branding??{displayName:J.type},...J.branding}}function m1(J){if(!J)return[];return Object.entries(J).filter(([,$])=>$.enabled!==!1).map(([$,Z],X)=>({name:$,config:Z,index:X})).sort(($,Z)=>{let X=$.config.order??Number.MAX_SAFE_INTEGER,K=Z.config.order??Number.MAX_SAFE_INTEGER;if(X!==K)return X-K;return $.index-Z.index}).map(({name:$,config:Z})=>({name:$,config:Z}))}var U9=600000,p1=256,D5=new Map;function U2(J){if(typeof J?.ttlMs==="number"&&Number.isFinite(J.ttlMs))U9=Math.min(Math.max(J.ttlMs,60000),86400000);if(typeof J?.maxEntries==="number"&&Number.isFinite(J.maxEntries)){p1=Math.max(1,Math.floor(J.maxEntries));while(D5.size>p1){let $=D5.keys().next().value;if($===void 0)break;D5.delete($)}}}function q9(J,$){D5.delete(J),D5.set(J,$);while(D5.size>p1){let Z=D5.keys().next().value;if(Z===void 0)break;D5.delete(Z)}}var $1=new Map,u1=()=>Date.now();function C2(J){u1=J??(()=>Date.now())}var l1={};function k2(J){l1=J??{}}function f2(J){if(!J)return;if(/\bno-store\b/i.test(J))return 60000;let $=/max-age\s*=\s*(\d+)/i.exec(J);if(!$)return;let Z=Number($[1]);return Number.isFinite(Z)?Z*1000:void 0}function h2(J){let Z=f2(J)??U9;return Math.min(Math.max(Z,60000),86400000)}async function c1(J,$=3,Z=1000,X=30000,K){let B=Error("Placeholder Error");for(let G=0;G<=$;G++)try{return await J()}catch(W){if(B=W instanceof Error?W:Error(String(W)),W instanceof Error&&W.message.includes("400"))throw W;if(G===$)throw B;let H=Math.min(Z*2**G,X),F=Math.random()*0.1*H;await new Promise((g)=>setTimeout(g,H+F)),K?.warn(`Retry attempt ${G+1} after ${H+F}ms delay`)}throw B}async function Z1(J,$,Z){let X=D5.get(J);if(!Z?.forceRefresh&&X&&X.expiresAt>u1())return q9(J,X),X.jwks;let K=$1.get(J);if(K)return K;let B=(async()=>{try{return await c1(async()=>{let G=await fetch(J);if(!G.ok)throw Error("Failed to fetch JWKS");let W=await G.json(),H=h2(G.headers.get("cache-control"));return q9(J,{jwks:W,expiresAt:u1()+H,importedKeys:new Map}),W},l1.maxRetries,l1.baseDelayMs,void 0,$)}catch(G){let W=D5.get(J);if(W)return $?.warn("JWKS refresh failed; serving last-known-good keys",{"ion.operation":"jwks.refresh","ion.outcome":"degraded"}),W.jwks;throw G}finally{$1.delete(J)}})();return $1.set(J,B),B}function m2(J){if(J){D5.delete(J),$1.delete(J);return}D5.clear(),$1.clear()}async function g2(J,$,Z){return(await C9(J,$,Z)).jwk}async function C9(J,$,Z){if(!$?.trim())throw Error("JWT header missing kid");await Z1(J,Z);let X=D5.get(J),K=X?.jwks.keys.find((B)=>B.kid===$);if(!K)await Z1(J,Z,{forceRefresh:!0}),X=D5.get(J),K=X?.jwks.keys.find((B)=>B.kid===$);if(!X||!K)throw Error("Public key not found");return{jwk:K,entry:X}}async function d1(J,$,Z,X,K){let{jwk:B,entry:G}=await C9(J,$,K),W=`${$}\x00${Z}`,H=G.importedKeys.get(W);if(H)return H;let F=X(B);return F.catch(()=>{if(G.importedKeys.get(W)===F)G.importedKeys.delete(W)}),G.importedKeys.set(W,F),F}async function p2(J,$){let Z=J.keys.find((X)=>X.kid===$);if(!Z)throw Error("Public key not found");return k9(Z)}function k9(J){return crypto.subtle.importKey("jwk",{kty:J.kty,n:J.n,e:J.e},{name:"RSASSA-PKCS1-v1_5",hash:"SHA-256"},!1,["verify"])}async function u2(J,$,Z){return d1(J,$,"rs256",k9,Z)}var g1={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 n1(J,$,Z,X){if(typeof Z!=="string"||!(Z in g1))throw Error(`Unsupported JWT alg "${String(Z)}" (allowed: ${Object.keys(g1).join(", ")})`);let K=g1[Z];return{key:await d1(J,$,`oidc:${Z}`,(G)=>{if(G.kty!==K.kty)throw Error(`JWK type "${G.kty}" does not match token alg "${Z}"`);if(K.kty==="EC"){let W=G;if(W.crv!==K.crv)throw Error(`JWK curve "${String(W.crv)}" does not match token alg "${Z}"`);return crypto.subtle.importKey("jwk",{kty:"EC",crv:W.crv,x:W.x,y:W.y},K.importParams,!1,["verify"])}return crypto.subtle.importKey("jwk",{kty:G.kty,n:G.n,e:G.e},K.importParams,!1,["verify"])},X),algorithm:K.verifyParams}}function O5(J=32){let $=new Uint8Array(J);return crypto.getRandomValues($),Array.from($,(Z)=>Z.toString(16).padStart(2,"0")).join("").substring(0,J)}function z1(J){let $="";return J.forEach((Z)=>{$+=String.fromCharCode(Z)}),btoa($).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function m9(J){let $=J.replace(/-/g,"+").replace(/_/g,"/"),Z=$.padEnd($.length+(4-$.length%4)%4,"="),X=atob(Z),K=new Uint8Array(X.length);for(let B=0;B<X.length;B++)K[B]=X.charCodeAt(B);return K}function f9(J){let $=new TextDecoder().decode(m9(J));return JSON.parse($)}async function K1(J){let $=new TextEncoder().encode(J),Z=await crypto.subtle.digest("SHA-256",$);return z1(new Uint8Array(Z))}function i1(J){let $=new URL(J.authorizationUrl);if($.searchParams.set("client_id",J.clientId),$.searchParams.set("redirect_uri",J.redirectUri),$.searchParams.set("response_type","code"),$.searchParams.set("scope",J.scope),$.searchParams.set("state",J.state),J.codeChallenge)$.searchParams.set("code_challenge",J.codeChallenge),$.searchParams.set("code_challenge_method","S256");if(J.nonce)$.searchParams.set("nonce",J.nonce);for(let[Z,X]of Object.entries(J.extraParams??{}))$.searchParams.set(Z,X);return $.toString()}async function t1(J){let $=new URLSearchParams;if($.append("grant_type","authorization_code"),$.append("code",J.code),$.append("redirect_uri",J.redirectUri),$.append("client_id",J.clientId),J.clientSecret)$.append("client_secret",J.clientSecret);if(J.codeVerifier)$.append("code_verifier",J.codeVerifier);let Z=await fetch(J.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:$.toString()}),X=await Z.json();if(!Z.ok){let K=X;throw J.log?.error("OIDC authorization-code exchange failed",{"ion.operation":"token.exchange","ion.outcome":"failure","http.status_code":Z.status,oidc_error:K.error}),Error(`Token exchange failed: ${K.error||Z.statusText} - ${K.error_description||""}`.trim())}if(typeof X.access_token!=="string")throw Error("Token exchange response missing access_token");return X}var g9=60;function Q1(J){return J.trim().replace(/\/$/,"")}function p9(J){let{claims:$,audience:Z}=J,X=Q1(J.issuer),K=J.nowSec??Math.floor(Date.now()/1000),B=J.clockSkewSec??g9,G=$.iss;if(typeof G!=="string"||Q1(G)!==X)throw Error("ID token issuer mismatch");let W=$.aud,H=Array.isArray(W)?W.includes(Z):typeof W==="string"&&W===Z,F=typeof $.azp==="string"&&$.azp===Z;if(!H&&!F)throw Error("ID token audience mismatch");if(typeof $.exp!=="number")throw Error("ID token missing exp");if($.exp<K-B)throw Error("ID token expired");if(J.expectedNonce!==void 0){if($.nonce!==J.expectedNonce)throw Error("ID token nonce mismatch")}}async function u9(J,$,Z){let X=J.split(".");if(X.length!==3)throw Error("Invalid JWT");let K=f9(X[0]),B=f9(X[1]),G=m9(X[2]),{key:W,algorithm:H}=await n1($,K.kid,K.alg,Z),F=new TextEncoder().encode(`${X[0]}.${X[1]}`);if(!await crypto.subtle.verify(H,W,G,F))throw Error("Invalid JWT signature");return{header:K,payload:B}}async function U5(J){let{payload:$}=await u9(J.idToken,J.jwksUri,J.log);return p9({claims:$,issuer:J.issuer,audience:J.audience,clockSkewSec:J.clockSkewSec,expectedNonce:J.expectedNonce}),$}var l2="http://schemas.openid.net/event/backchannel-logout";async function o1(J){let{payload:$}=await u9(J.logoutToken,J.jwksUri,J.log),Z=Q1(J.issuer),X=$.iss;if(typeof X!=="string"||Q1(X)!==Z)throw Error("Logout token issuer mismatch");let K=$.aud,B=Array.isArray(K)?K.includes(J.audience):typeof K==="string"&&K===J.audience,G=typeof $.azp==="string"&&$.azp===J.audience;if(!B&&!G)throw Error("Logout token audience mismatch");if($.nonce!=null)throw Error("Logout token must not contain a nonce");let W=$.events;if(!(typeof W==="object"&&W!==null&&!Array.isArray(W)&&Object.hasOwn(W,l2)))throw Error("Logout token missing back-channel logout event");let F=typeof $.sid==="string"&&$.sid.length>0,g=typeof $.sub==="string"&&$.sub.length>0;if(!F&&!g)throw Error("Logout token missing sid and sub");if(typeof $.exp==="number"){let u=Math.floor(Date.now()/1000),n=J.clockSkewSec??g9;if($.exp<u-n)throw Error("Logout token expired")}return $}var c2=3600000,d2=60000,n2=86400000,a2=256,y5=new Map,X1=new Map;function h9(J,$){y5.delete(J),y5.set(J,$);while(y5.size>a2){let Z=y5.keys().next().value;if(Z===void 0)break;y5.delete(Z)}}var a1=()=>Date.now();function i2(J){a1=J??(()=>Date.now())}function t2(J){if(J){y5.delete(J),X1.delete(J);return}y5.clear(),X1.clear()}function o2(J){let $=J?/max-age\s*=\s*(\d+)/i.exec(J):null,Z=$?Number($[1]):Number.NaN,X=Number.isFinite(Z)?Z*1000:c2;return Math.min(Math.max(X,d2),n2)}async function r1(J){let $=y5.get(J);if($&&$.expiresAt>a1())return h9(J,$),$.endpoints;let Z=X1.get(J);if(Z)return Z;let X=(async()=>{try{let K=J.replace(/\/$/,""),B=await fetch(`${K}/.well-known/openid-configuration`,{headers:{Accept:"application/json"}});if(!B.ok)throw Error(`OIDC discovery failed for ${J} with status ${B.status}`);let G=await B.json(),W={authorizationUrl:typeof G.authorization_endpoint==="string"?G.authorization_endpoint:void 0,tokenUrl:typeof G.token_endpoint==="string"?G.token_endpoint:void 0,jwksUri:typeof G.jwks_uri==="string"?G.jwks_uri:void 0,userInfoUrl:typeof G.userinfo_endpoint==="string"?G.userinfo_endpoint:void 0};return h9(J,{endpoints:W,expiresAt:a1()+o2(B.headers.get("cache-control"))}),W}catch(K){let B=y5.get(J);if(B)return B.endpoints;throw K}finally{X1.delete(J)}})();return X1.set(J,X),X}async function s1(J,$){let Z=await fetch(J,{headers:{Authorization:`Bearer ${$}`,Accept:"application/json","User-Agent":"ionite-ciam"}});if(!Z.ok)throw Error(`UserInfo request failed with status ${Z.status}`);return await Z.json()}function r2(J){let $=J.replace(/-----BEGIN [^-]+-----/g,"").replace(/-----END [^-]+-----/g,"").replace(/\s+/g,""),Z=atob($),X=new Uint8Array(Z.length);for(let K=0;K<Z.length;K++)X[K]=Z.charCodeAt(K);return X}async function e1(J){let $=Math.floor(Date.now()/1000),Z={alg:"ES256",kid:J.keyId,typ:"JWT"},X={iss:J.teamId,iat:$,exp:$+(J.expiresInSeconds??3600),aud:"https://appleid.apple.com",sub:J.clientId},K=z1(new TextEncoder().encode(JSON.stringify(Z))),B=z1(new TextEncoder().encode(JSON.stringify(X))),G=`${K}.${B}`,W=await crypto.subtle.importKey("pkcs8",r2(J.privateKey),{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),H=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},W,new TextEncoder().encode(G));return`${G}.${z1(new Uint8Array(H))}`}function s2(J){for(let $=0;$<J.length;$++){let Z=J.charCodeAt($);if(Z<=31||Z===127)return!0}return!1}function e2(J,$){let Z=null;try{Z=new URL(J,$)}catch{Z=null}let X="";try{X=new URL($).origin}catch{X=""}return{candidate:J,url:Z,requestOrigin:X}}function l9(J,$,Z){let X=e2(J,Z),K=!1;for(let B of $){let G=B(X);if(G==="deny")return!1;if(G==="allow")K=!0}return K}function c9(){return({candidate:J,url:$})=>{if(s2(J))return"deny";if(J.includes("\\"))return"deny";if(J.startsWith("//"))return"deny";if(!$)return"deny";if($.protocol!=="http:"&&$.protocol!=="https:")return"deny";if($.username||$.password)return"deny";return"abstain"}}function d9(){return({candidate:J})=>J.startsWith("/")&&!J.startsWith("//")&&!J.startsWith("/\\")?"allow":"abstain"}function n9(){return({url:J,requestOrigin:$})=>J&&$&&J.origin===$?"allow":"abstain"}function J4(...J){let $=new Set(J.map((Z)=>{try{return new URL(Z).origin}catch{return Z}}));return({url:Z})=>Z&&$.has(Z.origin)?"allow":"abstain"}function $4(...J){let $=J.map((Z)=>Z.toLowerCase());return({url:Z})=>{if(!Z)return"abstain";let X=Z.hostname.toLowerCase();for(let K of $)if(K.startsWith(".")){if(X===K.slice(1)||X.endsWith(K))return"allow"}else if(X===K)return"allow";return"abstain"}}function J9(){return[c9(),d9(),n9()]}function a9(J,$,Z){if(!J)return!1;return l9(J,$,Z)}function $9(J,$){if(!J)return $.fallback;return l9(J,$.rules,$.requestUrl)?J:$.fallback}var Z4={rules:J9(),fallback:"/"};function X4(J,$,Z="redirect"){let X=new URL(J.url).searchParams.get(Z)??void 0;return a9(X,$.rules,J.url)?{redirect:X}:void 0}function Q4(J,$){let Z=J.context;return $9(Z?.redirect,{rules:$.rules,fallback:$.fallback,requestUrl:J.request.url})}function C5(J,$,Z){if(J instanceof Response)return{response:J};if(typeof J==="string")return{location:$9(J,{rules:J9(),fallback:$,requestUrl:Z})};return{location:$}}function g5(J,$){if($.length===0)return J;let Z=new Headers(J.headers);for(let X of $)Z.append("Set-Cookie",X);return new Response(J.body,{status:J.status,statusText:J.statusText,headers:Z})}var O1="ciam",K4="id_token",Y4="access_token";function B4(J,$,Z,X,K,B){if(!Z&&!X)return;let G=new WeakMap,W={...Z,...X},H={...W,magicLinkTtl:W.magicLinkTtl??3600,sessionTtl:W.sessionTtl??86400,cookiesSecure:W.cookiesSecure!==void 0?W.cookiesSecure:!0,cookiesSameSite:W.cookiesSameSite!==void 0?W.cookiesSameSite:"Strict",cookiesPrefix:W.cookiesPrefix??(W.ciamId?`ion.ciam.${W.ciamId}`:"ion.ciam"),cookiesPath:W.cookiesPath??"/"};function F(){if(!H.sessionStore)throw Error("Missing CIAM configuration field: sessionStore. CIAM sessionStore is required for server-side session tracking and first-party logout.");return H.sessionStore}function g(){F()}let u=J.callbackParams??a5(i9("ionite.ciam")),n=J.idTokenClaims??a5(j1("ionite.ciam")),e=J.tokenResponse??a5(t9("ionite.ciam"));function $5(Q=32){let Y=new Uint8Array(Q);return crypto.getRandomValues(Y),Array.from(Y,(L)=>L.toString(16).padStart(2,"0")).join("").substring(0,Q)}function b(Q,Y,L,D=H.cookiesSameSite??"Strict"){if(!H)throw Error("ionite CIAM Manager not initialized");if(Q=`${H.cookiesPrefix}.${Q}`,typeof Y!=="string")Y=btoa(JSON.stringify(Y));let z;if(L instanceof Date)z=`Expires=${L.toUTCString()}`;else if(typeof L==="number")z=`Max-Age=${L}`;else throw Error("Invalid expires type",L);if(Y.length>4000)throw Error(`Error setting cookie: ${Q}. Cookie length is: ${Y.length}`);return`${Q}=${Y}; ${z}; Path=${H.cookiesPath}; HttpOnly;${H.cookiesSecure?" Secure;":""} SameSite=${D};`}function r(Q){if(!H)throw Error("ionite CIAM Manager not initialized");return`${H.cookiesPrefix}.${Q}=; Max-Age=0; Path=${H.cookiesPath}; HttpOnly;${H.cookiesSecure?" Secure;":""} SameSite=${H.cookiesSameSite};`}function T(Q,Y,L=!1){if(!H)throw Error("ionite CIAM Manager not initialized");let D=Y.headers.get("cookie");if(!D)return null;let z=`${H.cookiesPrefix}.${Q}`,E=D.split(";").find((w)=>w.trim().startsWith(`${z}=`));if(!E)return null;let A=E.indexOf("="),N=E.substring(A+1).trim();if(!L)return N;try{let w=atob(N);return JSON.parse(w)}catch(w){return $.error("[CIAM] Failed to parse cookie",{"ion.operation":"cookie.parse","ion.outcome":"failure",cookieName:z},w),null}}function c(Q){return`cstate_${Q}`}async function s(Q,Y,L,D){let z=await H.afterLogin?.({...Y,request:Q,context:L}),E=C5(z,"/",Q.url);if(E.response)return g5(E.response,D.map(([,A])=>A));return new Response(Y.ok?"Authentication successful, redirecting":"Authentication failed, redirecting",{status:302,headers:[["Location",E.location],...D]})}function F5(Q,Y){return["Set-Cookie",b("session",Q,Y)]}function G5(Q){if(!Q)return;if(Q instanceof Date)return Q;let Y=new Date(Q);return Number.isNaN(Y.getTime())?void 0:Y}async function M5(Q){let Y=T("session",Q);if(!Y)return;let L=await F().get(Y);if(L&&H.tenantId&&L.tenantId&&L.tenantId!==H.tenantId)return;if(L?.authType!=="ciam")return;let D=G5(L.expiresAt);if(D&&Date.now()>D.getTime()){await F().delete(Y);return}return L}async function K5(Q){if(!H)throw Error("ionite CIAM Manager not initialized");g();let Y=G.get(Q);if(Y)return Y;let L=_5(Q);return G.set(Q,L),L}async function _5(Q){try{let Y=await M5(Q);if(!Y?.claims?.sub)return{status:"unauthenticated"};return{status:"authenticated",value:E5(Y.claims)}}catch(Y){return $.error("CIAM session resolution failed",{"ion.operation":"ciam.session","ion.outcome":"degraded"},Y),{status:"degraded",error:Y instanceof Error?Y:void 0}}}async function c5(Q){let Y=await K5(Q);return Y.status==="authenticated"?Y.value:void 0}async function f5(Q){if(!H)throw Error("ionite CIAM Manager not initialized");g();let Y;try{Y=await c5(Q)}catch{Y=void 0}let L=await H.beforeLogout?.({request:Q,user:Y});try{let S=T("session",Q);if(S)await F().delete(S)}catch(S){$.warn("Failed to delete CIAM session",{"ion.operation":"session.delete","ion.outcome":"degraded"},S)}let D=[["Set-Cookie",r("session")]],z=await H.afterLogout?.({request:Q,context:L}),E=C5(z,"/",Q.url);if(E.response)return g5(E.response,D.map(([,S])=>S));let A=E.location??"/",N=Q.headers.get("accept");if(N?.includes("application/json")||N?.includes("text/javascript"))return new Response(JSON.stringify({success:!0,message:"Logged out",redirect:A}),{status:200,headers:[["Content-Type","application/json"],...D]});return new Response("Logged out",{status:302,headers:[["Location",A],...D]})}function d5(Q){return Q.id||Q.email||`ciam-${Q.userName}`}function e5(Q,Y,L){return{sub:d5(Q),iss:O1,aud:O1,typ:K4,exp:Math.floor(L.getTime()/1000),iat:Math.floor(Date.now()/1000),email:Q.email,name:Q.name,preferred_username:Q.userName,picture:Q.avatar,sid:Y}}function J1(Q,Y,L){return{sub:Q,iss:O1,aud:O1,typ:Y4,exp:Math.floor(L.getTime()/1000),iat:Math.floor(Date.now()/1000),sid:Y,scope:"openid profile email"}}function E5(Q){let Y=Q.exp?new Date(Q.exp*1000):new Date;return{id:Q.sub,userName:Q.preferred_username??"",name:Q.name??"",email:Q.email??"",avatar:Q.picture,userType:"customer",ciam:{profile:Q,scope:"openid profile email",tokenType:"Bearer",expires:Y}}}async function h5(Q){if(!H)throw Error("ionite CIAM Manager not initialized");if(!K)return new Response(JSON.stringify({error:"Workload authentication required"}),{status:401,headers:{"Content-Type":"application/json"}});if(!await K.getWorkloadIdentity(Q))return new Response(JSON.stringify({error:"Unauthorized: Valid workload token required"}),{status:401,headers:{"Content-Type":"application/json"}});let L,D;try{if(!Q.headers.get("content-type")?.includes("application/json"))return new Response(JSON.stringify({error:"Content-Type must be application/json"}),{status:400,headers:{"Content-Type":"application/json"}});let d=await Q.text(),M=JSON.parse(d);D=typeof M?.redirect==="string"&&M.redirect.length>0?M.redirect:void 0;let V={userName:M.userName,name:M.name,email:M.email,avatar:M.avatar},O=await J.customer.validate(V);if(O.issues)return new Response(JSON.stringify({error:"Missing required fields: userName, name, email"}),{status:400,headers:{"Content-Type":"application/json"}});L=O.value}catch(f){return new Response(JSON.stringify({error:"Invalid JSON in request body"}),{status:400,headers:{"Content-Type":"application/json"}})}let E=new URL(Q.url).searchParams.get("ttl"),A=E?parseInt(E,10):H.magicLinkTtl??3600;if(Number.isNaN(A)||A<=0)return new Response(JSON.stringify({error:"Invalid TTL parameter"}),{status:400,headers:{"Content-Type":"application/json"}});let N=$5(32),w=new Date(Date.now()+A*1000);if(!H.magicLinkStore)return new Response(JSON.stringify({error:"Magic link store not configured"}),{status:501,headers:{"Content-Type":"application/json"}});try{await H.magicLinkStore.create(N,L,w)}catch(f){return $.error("Error creating magic link",{"ion.operation":"magic_link.create","ion.outcome":"failure"},f),new Response(JSON.stringify({error:"Failed to create magic link"}),{status:500,headers:{"Content-Type":"application/json"}})}let S=new URL(Q.url),q=H.magicLinkLoginUrl||"/magic-link/login",I=new URL(q,S.origin);if(I.searchParams.set("token",N),D)I.searchParams.set("redirect",D);return new Response(JSON.stringify({magicLink:I.toString(),expiresAt:w.toISOString()}),{status:200,headers:{"Content-Type":"application/json"}})}async function v5(Q){if(!H)throw Error("ionite CIAM Manager not initialized");g();let L=new URL(Q.url).searchParams.get("token");if(!L)return s(Q,{ok:!1,error:Error("Missing magic-link token")},void 0,[]);if(!H.magicLinkStore)return s(Q,{ok:!1,error:Error("Magic link store not configured")},void 0,[]);let D=await H.magicLinkStore.getAndDelete(L);if(!D)return s(Q,{ok:!1,error:Error("Magic link invalid, expired, or already used")},void 0,[]);let z=new Date(Date.now()+(H.sessionTtl??86400)*1000),E=$5(32),A=d5(D.customer),N=e5(D.customer,E,z),w=J1(A,E,z),S=E5(N),q;try{let f={sid:E,sub:A,authType:"ciam",tenantId:H.tenantId,expiresAt:z,claims:N,accessClaims:w,createdAt:new Date};await F().create(f),q=f}catch(f){throw $.warn("Failed to create session",{"ion.operation":"session.create","ion.outcome":"degraded"},f),f}if(H.customerStore)try{let f=S.id;if(f){let d=new Date,M=await H.customerStore.get(f);if(M||H.enableJitUserProvisioning){let V={...M??{},...S,id:f,tenantId:M?.tenantId,createdAt:M?.createdAt??d,updatedAt:d,userType:M?.userType??"customer"};await H.customerStore.upsert(V)}}}catch(f){$.warn("Failed to store customer",{"ion.operation":"customer.store","ion.outcome":"degraded"},f)}let I=[F5(E,z)];return s(Q,{ok:!0,user:S,session:q},void 0,I)}function A5(Q,Y=200,L=[]){return new Response(JSON.stringify(Q),{status:Y,headers:[["Content-Type","application/json"],...L]})}function m5(Q,Y){try{return new URL(Q).toString()}catch{let L=new URL(Y).origin,D=H.cookiesSecure?L.replace(/^http:\/\//,"https://"):L;return new URL(Q,D).toString()}}function R5(){let Q=H.customerLoginUrl||"/auth/customer/login",Y=Q.includes("?")?"&":"?";return m1(H.providers).map(({name:L,config:D})=>{let z=h1(D);return{name:L,type:D.type,displayName:z.displayName,loginUrl:`${Q}${Y}provider=${encodeURIComponent(L)}`,iconUrl:z.iconUrl,colors:z.colors,url:z.url}})}async function V5(Q){if(!Q)return{};let{authorizationUrl:Y,tokenUrl:L,jwksUri:D,userInfoUrl:z}=Q,E=Q.config.authority;if(E&&(!Y||!L||Q.flow==="id_token"&&!D))try{let N=await r1(E);Y=Y??N.authorizationUrl,L=L??N.tokenUrl,D=D??N.jwksUri,z=z??N.userInfoUrl}catch(N){$.error("CIAM provider OIDC discovery failed",{"ion.operation":"ciam.oidc.discovery","ion.outcome":"failure"},N)}return{authorizationUrl:Y,tokenUrl:L,jwksUri:D,userInfoUrl:z}}async function q5(Q){if(Q.type==="apple"){let{teamId:Y,keyId:L,privateKey:D,clientId:z}=Q.config;if(Y&&L&&D&&z)return e1({teamId:Y,keyId:L,privateKey:D,clientId:z})}return Q.clientSecret}async function P5(Q){F();let L=new URL(Q.url).searchParams.get("provider");if(!L)return A5({error:"Missing required query parameter: provider"},400);let D=H.providers?.[L];if(!D||D.enabled===!1||D.type==="magic-link")return A5({error:`Unknown or disabled CIAM provider: ${L}`},404);let z=N1(L,D);if(!z?.clientId)return A5({error:`CIAM provider ${L} is not fully configured`},500);let E=await V5(z);if(!E.authorizationUrl)return A5({error:`CIAM provider ${L} is missing an authorization endpoint`},500);let A=H.customerCallbackUrl||"/auth/customer/callback",N=m5(A,Q.url),w=O5(),S=O5(64),q=O5(),I=z.flow==="id_token",f=I?await K1(S):void 0,d=await H.beforeLogin?.({request:Q}),M=i1({authorizationUrl:E.authorizationUrl,clientId:z.clientId,redirectUri:N,scope:z.scope,state:w,codeChallenge:f,nonce:q,extraParams:z.extraAuthParams}),V={provider:L,state:w,codeVerifier:I?S:void 0,nonce:q,redirectUri:N,...d===void 0?{}:{context:d}};return new Response("Redirecting to CIAM provider",{status:302,headers:[["Location",M],["Set-Cookie",b(c(w),V,H.loginStateTtl??600,"Lax")]]})}async function z5(Q){if(Q.method==="POST"){if((Q.headers.get("content-type")??"").includes("application/x-www-form-urlencoded")){let L=await Q.text();return Object.fromEntries(new URLSearchParams(L).entries())}}return Object.fromEntries(new URL(Q.url).searchParams.entries())}async function y(Q,Y){let L=Q.mapClaims(Y);if(!L.sub)return{ok:!1};let D=`${Q.name}:${L.sub}`,z={id:D,userName:L.userName||L.email||D,name:L.name||"",email:L.email||"",avatar:L.avatar,userType:"customer"},E=D;if(H.customerStore){let I=await H.customerStore.lookup(z)??await H.customerStore.get(D);if(E=I?.id??D,!I&&!H.enableJitUserProvisioning)return $.warn("CIAM JIT customer provisioning disabled: unknown customer rejected",{"ion.operation":"customer.store","ion.outcome":"skipped"}),{ok:!1};let f=new Date,d={...I??{},...z,id:E,tenantId:I?.tenantId,createdAt:I?.createdAt??f,updatedAt:f,userType:I?.userType??"customer"};await H.customerStore.upsert(d)}let A=new Date(Date.now()+(H.sessionTtl??86400)*1000),N=O5(32),w={sub:E,iss:Q.name,aud:Q.clientId,exp:Math.floor(A.getTime()/1000),iat:Math.floor(Date.now()/1000),email:L.email,name:L.name,preferred_username:L.userName??L.email,picture:L.avatar,sid:N},S={sid:N,sub:E,authType:"ciam",tenantId:H.tenantId,expiresAt:A,claims:w,accessClaims:{sub:E,sid:N,scope:Q.scope},createdAt:new Date},q=F();try{await q.create(S)}catch(I){if(!await q.get(N))throw I;await q.update(N,S)}return{ok:!0,claims:w,sid:N,expires:A}}async function U(Q){F();let Y,L,D=(z)=>{let E=Y?[["Set-Cookie",r(Y)]]:[];return s(Q,{ok:!1,error:z},L,E)};try{let z=await z5(Q),E=await u.validate(z);if(E.issues||!E.value)return D(Error("Invalid CIAM callback parameters"));let{code:A,state:N}=E.value;if(!N)return D(Error("Missing CIAM callback state"));Y=c(N);let w=T(Y,Q,!0);if(L=w?.context,!w?.provider||!w.state||w.state!==N)return $.warn("CIAM callback state verification failed",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),D(Error("CIAM callback state verification failed"));let S=H.providers?.[w.provider];if(!S)return D(Error("Unknown CIAM provider"));let q=N1(w.provider,S);if(!q?.clientId)return D(Error("CIAM provider not configured"));let I=await V5(q);if(!I.tokenUrl)return D(Error("CIAM provider missing token endpoint"));let f=await q5(q),d=await t1({tokenUrl:I.tokenUrl,clientId:q.clientId,clientSecret:f,redirectUri:w.redirectUri||m5(H.customerCallbackUrl||"/auth/customer/callback",Q.url),code:A,codeVerifier:q.flow==="id_token"?w.codeVerifier:void 0,log:$}),M;if(q.flow==="id_token"){let _=q.config.authority;if(!d.id_token||!I.jwksUri||!_)return D(Error("CIAM id_token flow misconfigured"));if(!w.nonce)return D(Error("CIAM callback state cookie missing nonce"));if((await e.validate(d)).issues)return $.warn("CIAM token response validation failed",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),D(Error("CIAM token response validation failed"));M=await U5({idToken:d.id_token,jwksUri:I.jwksUri,issuer:_,audience:q.clientId,expectedNonce:w.nonce,log:$});let v=await n.validate(M);if(!v.issues)M=v.value}else{if(!I.userInfoUrl)return D(Error("CIAM provider missing userinfo endpoint"));M=await s1(I.userInfoUrl,d.access_token);let _=q.config.authority;if(d.id_token&&I.jwksUri&&_){let R=await U5({idToken:d.id_token,jwksUri:I.jwksUri,issuer:_,audience:q.clientId,expectedNonce:w.nonce||void 0,log:$}),v=typeof R.sub==="string"?R.sub:"";if(v){if(typeof M.sub==="string"&&M.sub.length>0&&M.sub!==v)return $.warn("CIAM UserInfo sub does not match verified id_token sub",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),D(Error("CIAM UserInfo sub mismatch"));M.sub=v}}if(typeof M.sub!=="string"||M.sub.length===0)return $.warn("CIAM UserInfo response missing sub",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"}),D(Error("CIAM UserInfo response missing sub"))}let V=await y(q,M);if(!V.ok)return D(Error("Failed to persist CIAM customer"));let O=E5(V.claims);$.info("CIAM third-party sign-in succeeded",{"ion.operation":"ciam.oidc.callback","ion.outcome":"success",provider:q.name});let P=[["Set-Cookie",r(Y)],F5(V.sid,V.expires)];return s(Q,{ok:!0,user:O,session:void 0},L,P)}catch(z){return $.error("Error during CIAM third-party sign-in callback",{"ion.operation":"ciam.oidc.callback","ion.outcome":"failure"},z),D(z)}}async function h(Q){if(!H)throw Error("ionite CIAM Manager not initialized");g();let Y=H.magicLinkUrl||"/magic-link",L=H.magicLinkLoginUrl||"/magic-link/login",D=H.logoutUrl||"/auth/customer/logout",z=H.customerLoginUrl||"/auth/customer/login",E=H.customerCallbackUrl||"/auth/customer/callback",A=H.customerProvidersUrl||"/auth/customer/providers",N=new URL(Q.url).pathname,w=(V)=>{if(!V)return;try{return new URL(V).pathname}catch{return V.startsWith("/")?V:`/${V}`}};if(w(Y)===N&&Q.method==="POST")return h5(Q);if(w(L)===N&&Q.method==="GET")return v5(Q);if(w(D)===N&&Q.method==="GET")return f5(Q);if(w(A)===N&&Q.method==="GET")return A5({providers:R5()});if(w(z)===N&&Q.method==="GET")return P5(Q);if(w(E)===N&&(Q.method==="GET"||Q.method==="POST"))return U(Q);return new Response("Not Found",{status:404})}return{...H,getCustomer:c5,resolveCustomer:K5,logout:f5,handler:h,listCustomerProviders:R5}}async function G4(J,$){return i($,"Ionite instance is required. Create one with ionite(source, config) and pass it to this function."),$.ciam?.getCustomer(J)}async function W4(J,$){return i($,"Ionite instance is required. Create one with ionite(source, config) and pass it to this function."),await $.ciam?.resolveCustomer(J)??{status:"unauthenticated"}}var L4="urn:ietf:params:scim:schemas:core:2.0:User",o9="urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",F4="urn:ietf:params:scim:schemas:core:2.0:Group";function Z9(J,$,Z){let K=($==="group"?J.resources:void 0)?.map((B)=>typeof B==="string"?B:B.id).filter(Boolean);return{schemas:[F4,p],id:J.id,externalId:J.providerId,displayName:J.displayName??J.name,members:Z,[p]:{type:$,requestable:J.requestable,providerId:J.providerId,requestUrl:J.requestUrl,source:J.source,deprecated:J.deprecated,description:J.description,resources:K&&K.length>0?K:void 0,assignableSubjectTypes:J.assignableSubjectTypes,recommendedSubjectTypes:J.recommendedSubjectTypes}}}function V4(J){if(J.scimName)return J.scimName;if(!J.name)return;let[$,...Z]=J.name.split(" ");return{givenName:$,familyName:Z.join(" ")||void 0}}function H4(J){let $={};if(J.ecid!==void 0)$.ecid=J.ecid;if(J.accountClass!==void 0)$.accountClass=J.accountClass;return $.ecid!==void 0||$.accountClass!==void 0?$:void 0}function D4(J){return Object.keys(J.scimSchemaExtensions??{}).filter(($)=>$.startsWith("urn:")&&J.scimSchemaExtensions?.[$]!==void 0)}function X9(J){let $=J.userName||J.email||J.id||"",Z=J.emails??(J.email?[{value:J.email,primary:!0}]:[]),X=new Set([L4]);if(J.scimEnterprise!==void 0)X.add(o9);let K=H4(J);if(K!==void 0)X.add(I5);for(let G of D4(J))X.add(G);let B={};if(J.scimEnterprise!==void 0)B[o9]=J.scimEnterprise;if(K!==void 0)B[I5]=K;for(let[G,W]of Object.entries(J.scimSchemaExtensions??{}))if(G.startsWith("urn:")&&G!==I5&&W!==void 0)B[G]=W;return{schemas:Array.from(X),id:J.id,externalId:J.externalId,userName:$,displayName:J.displayName??J.name??$,name:V4(J),nickName:J.nickName,profileUrl:J.avatar,title:J.title,userType:J.userType,preferredLanguage:J.preferredLanguage,locale:J.locale,timezone:J.timezone,active:J.active??!0,emails:Z,phoneNumbers:J.phoneNumbers,ims:J.ims,photos:J.photos,addresses:J.addresses,groups:J.groups,entitlements:J.entitlements,roles:J.roles,x509Certificates:J.x509Certificates,meta:{resourceType:"User",created:(J.createdAt??J.updatedAt??new Date).toISOString(),lastModified:(J.updatedAt??J.createdAt??new Date).toISOString()},...B}}function Q9(J){return{schemas:[i5],id:J.id,externalId:J.externalId,userName:J.clientId??J.id,displayName:J.displayName??J.clientId??J.id,description:J.description,active:J.active??!0,providerId:J.providerId,requestUrl:J.requestUrl,meta:{resourceType:"Workload",created:(J.createdAt??J.updatedAt??new Date).toISOString(),lastModified:(J.updatedAt??J.createdAt??new Date).toISOString()}}}function K9(J){return{schemas:[t5],id:J.id,externalId:J.externalId??J.id,userName:J.userName??J.email??J.id,displayName:J.displayName??J.name??J.userName??J.id,active:J.active??!0,emails:J.emails??(J.email?[{value:J.email,primary:!0}]:void 0),providerId:J.providerId,requestUrl:J.requestUrl,meta:{resourceType:"Customer",created:(J.createdAt??J.updatedAt??new Date).toISOString(),lastModified:(J.updatedAt??J.createdAt??new Date).toISOString()}}}function Y9(J){return{enabled:J?.enabled!==!1,assignment:J?.assignment??"app",delta:J?.delta}}var G1="application/scim+json",M4="urn:ietf:params:scim:api:messages:2.0:ListResponse",H9="urn:ietf:params:scim:api:messages:2.0:Error",D9="urn:ietf:params:scim:schemas:core:2.0:User",W1="urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",M9="urn:ietf:params:scim:schemas:core:2.0:Group",N4="urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig",_1="urn:ietf:params:scim:schemas:core:2.0:ResourceType",p5="urn:ietf:params:scim:schemas:core:2.0:Schema",z4="00000000000000000000000000000000";function O4(J){let $={timestamp:new Date().toISOString()};if(J)$.actor=J;try{let K=globalThis[Symbol.for("opentelemetry.js.api.1")]?.trace?.getActiveSpan?.()?.spanContext?.(),B=K?.traceId;if(B&&B!==z4){if($.traceId=B,K?.spanId)$.spanId=K.spanId}}catch{}return $}class L1 extends Error{constructor(J){super(J);this.name="SubjectTypeNotAssignableError",Object.setPrototypeOf(this,L1.prototype)}}async function B2(J,$,Z,X){let K=Z.subjectType;if(!V9.includes(K))throw new L1(`Cannot grant ${Z.targetType} "${N5(Z.target)}" to a "${K}" principal: only [${V9.join(", ")}] principals are assignable on this platform.`);let B=E9($,J);if(!B&&!X)return;let G=N5(Z.target),W;if(X)W=await X.getNode(Z.targetType,G);else if(B)W=await(Z.targetType==="group"?B.groups:Z.targetType==="role"?B.roles:B.permissions).get(G);if(!W)return;let H=W.assignableSubjectTypes;if(!H||H.length===0||!H.includes(K))throw new L1(`Cannot grant ${Z.targetType} "${G}" to a "${K}" principal: this entitlement restricts assignment to [${(H??[]).join(", ")||"none"}].`)}async function j4(J,$){let Z=O9(J.codeCatalog,N5($.target));if(!Z)return;if(Z.kind!==$.targetType)throw Error(`Cannot grant ${$.targetType} "${Z.entity.id}": code declares that id as ${Z.kind}.`);if(!J.catalogStore)throw Error(`Cannot grant code entitlement "${Z.entity.id}": no AccessCatalogStore is wired for materialization.`);await _9(Z.kind,Z.entity,j9(J.catalogStore,Z.kind))}async function _4(J,$,Z,X){await j4(J,$),await B2(J.catalogStore,J.codeCatalog,$,X);let K={...$,status:$.status??"active",provenance:$.provenance??O4()};if(K.id=V1(K),await J.accessStore?.grant(K),J.accessIndex&&(J.catalogStore||J.codeCatalog)){let B=await P9(K,{catalog:J.catalogStore,code:J.codeCatalog,resources:J.resources,cache:X});await J.accessIndex.materialize(K.id,B)}return Z?.push({op:"add",change:K}),K}async function T1(J,$,Z){let X=$.id??V1($);await J.accessStore?.revoke($),await J.accessIndex?.removeByRoot(X),Z?.push({op:"delete",change:{...$,id:X}})}async function N9(J,$){let Z=await E4(J,$),X=await P4(J,$);return{oaa:Z,delta:X}}async function E4(J,$){if($.length===0||!J.authz.oaa.isReady())return{status:"skipped"};return F1(J,"authz.oaa.push","OAA incremental access push failed after SCIM mutation; full sync will reconcile",()=>J.authz.oaa.pushAccessChanges($),{count:$.length})}async function F1(J,$,Z,X,K){try{return await X(),{status:"ok"}}catch(B){return J.log?.warn(Z,{"ion.operation":$,"ion.outcome":"degraded",...K,error:S5(B)}),{status:"degraded",reason:S5(B)}}}var A4=6;async function P4(J,$){let Z=J.iamDelta;if(!Z?.isReady()||$.length===0)return{status:"skipped"};let X=new Map;for(let H of $){let F=`${H.change.subjectType}:${N5(H.change.subject)}\x00${H.change.targetType}:${N5(H.change.target)}`;X.set(F,H)}let K=[...X.values()],B=K.map(({op:H,change:F})=>()=>H==="add"?Z.onGrant(F):Z.onRevoke(F)),W=(await w4(B,A4)).filter((H)=>H.status==="rejected");if(W.length>0)return J.log?.warn("IAM delta egress degraded after SCIM mutation; IAM server reconcile/aggregation will recover",{"ion.operation":"iam.delta.egress","ion.outcome":"degraded",failed:W.length,total:K.length,error:S5(W[0]?.reason)}),{status:"degraded",reason:S5(W[0]?.reason)};return{status:"ok"}}async function w4(J,$){let Z=Array(J.length),X=0,K=async()=>{while(!0){let G=X++;if(G>=J.length)return;let W=J[G];if(!W)continue;try{Z[G]={status:"fulfilled",value:await W()}}catch(H){Z[G]={status:"rejected",reason:H}}}},B=Array.from({length:Math.min($,J.length)},K);return await Promise.all(B),Z}class R1 extends Error{constructor(J){super(J);this.name="DerivedRevokeError",Object.setPrototypeOf(this,R1.prototype)}}class s5 extends Error{summary;clientError;constructor(J,$,Z=!1){super(J);this.name="ScimMutationError",this.summary=$,this.clientError=Z,Object.setPrototypeOf(this,s5.prototype)}}function C(J,$,Z){return new Response(JSON.stringify({schemas:[H9],status:String(J),scimType:Z,detail:$}),{status:J,headers:{"Content-Type":G1}})}function b5(J,$){let Z=$?.totalResults??J.length,X=$?.startIndex??1,K=$?.itemsPerPage??J.length;return new Response(JSON.stringify({schemas:[M4],totalResults:Z,startIndex:X,itemsPerPage:K,Resources:J}),{status:200,headers:{"Content-Type":G1}})}function L5(J,$=200,Z){let X=new Headers({"Content-Type":G1});if(Z)X.set("Location",Z);return new Response(JSON.stringify(J),{status:$,headers:X})}function r9(J){return C(J.clientError?409:500,`${J.message}; authz mutation summary: ${JSON.stringify(J.summary)}`,J.clientError?"mutability":"invalidValue")}function B1(J){return V1(J)}function B9(J,$){return P1(s9(J),s9($))}function s9(J){let $=new Map;if(!J?.id)return $;for(let Z of J.groups??[]){let X={subject:J.id,subjectType:"user",targetType:"group",target:Z.value,metadata:Z.display||Z.type?{display:Z.display,type:Z.type}:void 0};$.set(B1(X),X)}for(let Z of J.roles??[]){let X={subject:J.id,subjectType:"user",targetType:"role",target:Z.value,metadata:Z.display||Z.type?{display:Z.display,type:Z.type,primary:Z.primary}:void 0};$.set(B1(X),X)}for(let Z of J.entitlements??[]){let X={subject:J.id,subjectType:"user",targetType:"permission",target:Z.value,metadata:Z.display||Z.type?{display:Z.display,type:Z.type,primary:Z.primary}:void 0};$.set(B1(X),X)}return $}class x1 extends Error{constructor(J){super(J);this.name="AmbiguousMemberSubjectTypeError",Object.setPrototypeOf(this,x1.prototype)}}function I4(J,$,Z){if(J.type==="Group")return;if(J.type==="Workload")return"workload";if(J.type==="User")return"user";if(J.type==="Customer")return"customer";let X=$??[];if(X.length===1)return X[0];throw new x1(`SCIM Group member "${J.value}" of entitlement "${Z}" 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 E1(J,$,Z,X,K){let B=new Map,G=X&&X.length>0?X:void 0;for(let W of J??[]){let H=I4(W,K,Z);if(!H)continue;let F={subject:W.value,subjectType:H,targetType:$,target:Z,resources:G,metadata:W.display||W.type?{display:W.display,type:W.type}:void 0};B.set(B1(F),F)}return B}function G9(J){let $=J[p]?.resources;return $&&$.length>0?$:void 0}function T4(J,$){let Z=(K,B)=>[...K??[]].sort().join(",")===[...B??[]].sort().join(","),X=J[p];if(X?.type!==void 0&&X.type!==$.kind)return!0;if(X?.requestable!==void 0&&X.requestable!==$.entity.requestable)return!0;if(X?.resources!==void 0&&!Z(X.resources,z9($.entity)))return!0;if(X?.assignableSubjectTypes!==void 0&&!Z(X.assignableSubjectTypes,$.entity.assignableSubjectTypes))return!0;if(X?.recommendedSubjectTypes!==void 0&&!Z(X.recommendedSubjectTypes,$.entity.recommendedSubjectTypes))return!0;return!1}function S4(J,$){let Z=(B,G)=>[...B??[]].sort().join(",")===[...G??[]].sort().join(","),X=J[p],K=$[p];if(X?.type!==void 0&&X.type!==K?.type)return!0;if(X?.requestable!==void 0&&X.requestable!==K?.requestable)return!0;if(X?.resources!==void 0&&!Z(X.resources,K?.resources))return!0;if(X?.assignableSubjectTypes!==void 0&&!Z(X.assignableSubjectTypes,K?.assignableSubjectTypes))return!0;if(X?.recommendedSubjectTypes!==void 0&&!Z(X.recommendedSubjectTypes,K?.recommendedSubjectTypes))return!0;return!1}function R4(J){let $=new Map;for(let Z of J)$.set(B1(Z),Z);return $}async function u5(J,$,Z,X,K,B){let G=[],W=new Set,H=(g,u)=>`${u}\x00${g}`,F=B?B.get(`${Z}:${X}`)??[]:$?(await $.listByTarget(Z,X)).items:[];for(let g of F){let u=N5(g.subject),n=g.metadata,e=g.subjectType==="workload"?"Workload":g.subjectType==="customer"?"Customer":n?.type??"User",$5=H(u,e);if(W.has($5))continue;W.add($5),G.push({value:u,...n?.display?{display:n.display}:{},type:e})}for(let g of K??[]){if(g.targetType!==Z||N5(g.target)!==X)continue;let u=N5(g.subject),n=H(u,"Workload");if(W.has(n))continue;W.add(n),G.push({value:u,type:"Workload"})}if(Z==="group"){let g=await J.groups.get(X);for(let u of g?.groups??[]){let n=N5(u),e=H(n,"Group");if(!n||W.has(e))continue;W.add(e),G.push({value:n,type:"Group"})}}return G.length>0?G:void 0}function P1(J,$){let Z=[];for(let[X,K]of $)if(!J.has(X))Z.push({action:"grant",change:K});for(let[X,K]of J)if(!$.has(X))Z.push({action:"revoke",change:K});return Z}async function W9(J,$){if(J.oaa.isReady())await J.oaa.pushUser($)}async function e9(J,$,Z){if($?.externalId&&$.externalId!==Z.externalId)await J?.onUserDelete($.externalId);await J?.onUserUpsert(Z)}async function o5(J,$,Z,X){let K={metadataApplied:!1,access:[]},B={status:"skipped"},G=[],W=new A9(J.catalogStore,J.resources,J.codeCatalog);try{try{await $(),K.metadataApplied=!0}catch(H){for(let F of Z)K.access.push({change:F.change,status:"rolled_back"});throw K.metadataApplied=!1,new s5(`SCIM metadata write failed: ${S5(H)}`,K,!1)}if(X?.oaa)await F1(J,"authz.oaa.metadata","OAA metadata projection failed after SCIM write; full sync will reconcile",X.oaa);if(X?.delta&&J.iamDelta?.isReady())B=await F1(J,"iam.delta.egress","IAM delta metadata projection failed after SCIM write; full aggregation will reconcile",X.delta);for(let H=0;H<Z.length;H++){let F=Z[H];try{if(F.action==="grant")await _4(J,F.change,G,W);else await q4(J,F.change,G);K.access.push({change:F.change,status:"applied"})}catch(g){K.access.push({change:F.change,status:"failed",error:g});for(let n=H+1;n<Z.length;n++)K.access.push({change:Z[n].change,status:"rolled_back"});let u=g instanceof R1||g instanceof L1;if(!u)await b4(J,F.change,W);throw new s5(u?S5(g):`SCIM access mutation failed: ${S5(g)}`,K,u)}}return K}finally{await y4(J),K.egress=await N9(J,G),K.egress.delta=x4(B,K.egress.delta),v4(J,K)}}function x4(J,$){if(J.status==="degraded")return J;if($.status==="degraded")return $;return J.status==="ok"||$.status==="ok"?{status:"ok"}:{status:"skipped"}}function S5(J){return J instanceof Error?J.message:String(J)}async function y4(J){try{await J.settleAuthz?.()}catch{}}async function b4(J,$,Z){if(!J.accessIndex||!J.catalogStore&&!J.codeCatalog||!J.accessStore)return;let X=N5($.subject);if(!X)return;let K=$.subjectType;try{await w9(X,K,{accessStore:J.accessStore,accessIndex:J.accessIndex,catalogStore:J.catalogStore,code:J.codeCatalog,resources:J.resources},Z)}catch(B){J.log?.warn("Per-subject reconcile after failed SCIM access mutation failed",{"ion.operation":"authz.reconcile.subject.repair","ion.outcome":"degraded",subject:X,subjectType:K,error:S5(B)})}}function v4(J,$){if(!J.onAccessMutation)return;try{J.onAccessMutation($)}catch{}}async function q4(J,$,Z){if(J.accessStore){let X=$.id??V1($);if(!await J.accessStore.get(X)){if((J.accessIndex?await J.accessIndex.has($.subject,$.targetType,$.target,$.resources?.[0],$.subjectType):{allow:!1}).allow)throw new R1(`Cannot revoke ${$.targetType} "${N5($.target)}" for "${N5($.subject)}": it is not a directly granted root (it is derived from group/role membership). Remove the granting group/role instead.`);await T1(J,$,Z);return}}await T1(J,$,Z)}function r5(J){let $=J[p]?.type??"group";if($==="group"||$==="role"||$==="permission")return $;throw Error(`Unsupported ionite SCIM Group authz type "${String($)}"`)}async function L9(J,$,Z){if(!J.oaa.isReady())return;if(Z==="role"){await J.oaa.pushRole($);return}if(Z==="permission"){await J.oaa.pushPermission($);return}await J.oaa.pushGroup($)}function z9(J){let $=J.resources;if(!$||$.length===0)return;let Z=$.map((X)=>typeof X==="string"?X:X.id).filter(Boolean);return Z.length>0?Z:void 0}function l5(J,$,Z){return Z9(J,$,Z)}function U4(J,$){let Z=J[p],X={id:$,name:J.displayName,displayName:J.displayName,description:Z?.description??J.displayName,requestable:Z?.requestable,providerId:Z?.providerId??J.externalId,requestUrl:Z?.requestUrl,assignableSubjectTypes:["user"]};if(Z?.resources!==void 0)X.resources=Z.resources;return X}function C4(J){if(!J)return;let $=J.trim().match(/^requestable\s+eq\s+(true|false)$/i);if(!$)return;return{requestable:$[1]?.toLowerCase()==="true"}}function J2(J){if(!J)return;let $=J.trim().match(/^externalId\s+eq\s+"([^"]*)"$/i);return $?$[1]:void 0}function k4(J){if(!J)return;let $=J.trim(),Z=$.match(/^userName\s+eq\s+"([^"]*)"$/i);if(Z)return{userName:Z[1]};let X=$.match(/^externalId\s+eq\s+"([^"]*)"$/i);if(X)return{externalId:X[1]};let K=$.match(/^meta\.lastModified\s+gt\s+"([^"]*)"$/i);if(K)return{updatedAfter:K[1]};return}function f4(J,$,Z){let X=new Set(["id","schemas"]),K={...J};if($){let B=new Set($.split(",").map((G)=>G.trim()).filter(Boolean));for(let G of Object.keys(K))if(!X.has(G)&&!B.has(G))delete K[G]}if(Z){for(let B of Z.split(",").map((G)=>G.trim()).filter(Boolean))if(!X.has(B))delete K[B]}return K}function $2(J,$){let Z=(B,G,W)=>{let H=J.toScim(B),F=B.id;return{...H,id:F,meta:{...H.meta??{},resourceType:J.resourceType,location:F?Q5(G,`${W}/${encodeURIComponent(F)}`):void 0}}},X=(B,G)=>{let W=G.op.toLowerCase();if(!G.path){if(W!=="remove"&&G.value&&typeof G.value==="object"&&!Array.isArray(G.value))Object.assign(B,G.value);return}if(W==="remove"){delete B[G.path];return}B[G.path]=G.value};return{handler:async(B,G)=>{if(!await $.validateAuth(B))return C(401,"Authorization required");let W=new URL(B.url),H=G?.basePath??`/${J.resourceType}s`,F=W.pathname;if(F.startsWith(H))F=F.substring(H.length);let g=F.match(/^\/([^/]+)$/),u=g?.[1]?decodeURIComponent(g[1]):void 0,n=W.searchParams.get("attributes"),e=W.searchParams.get("excludedAttributes"),$5=(b)=>f4(b,n,e);try{if(u){if(B.method==="GET"){let b=await J.store.get(u);if(!b)return C(404,`${J.resourceType} not found`);return L5($5(Z(b,B,H)))}if(B.method==="PUT"||B.method==="PATCH"){let b=await J.store.get(u);if(!b)return C(404,`${J.resourceType} not found`);let r=await B.json(),T=r;if(B.method==="PATCH"){let G5=r.Operations;if(!Array.isArray(G5))return C(400,"PATCH requires Operations","invalidSyntax");let M5=J.toScim(b);for(let K5 of G5)X(M5,K5);T=M5}let c=await k5(J.validator,T);if(c.issues)return C(400,c.issues.map((G5)=>G5.message).join("; "),"invalidValue");let s=await J.store.upsert({...J.fromScim(c.value,b),id:b.id??u});if(b.active!==s.active)await $.accessIndex?.setSubjectDisabled?.(s.id,J.subjectType,s.active===!1);let F5=s.id?Q5(B,`${H}/${encodeURIComponent(s.id)}`):void 0;return L5($5(Z(s,B,H)),200,F5)}if(B.method==="DELETE"){if(!await J.store.get(u))return C(404,`${J.resourceType} not found`);if($.accessStore){let r=await $.accessStore.listBySubject(u,J.subjectType);for(let T of r.items)await $.accessStore.revoke(T)}return await J.store.delete(u),await $.accessIndex?.setSubjectDisabled?.(u,J.subjectType,!1),new Response(null,{status:204})}return C(405,"Method not allowed")}if(B.method==="GET"){let b=parseInt(W.searchParams.get("startIndex")??"",10),r=parseInt(W.searchParams.get("count")??"",10),T=b!=null&&!Number.isNaN(b)?Math.max(0,b-1):0,c=r!=null&&!Number.isNaN(r)?r:void 0,s=k4(W.searchParams.get("filter"));if(s?.externalId!==void 0){let M5=J.store.getByExternalId?await J.store.getByExternalId(s.externalId):await J.store.lookup({externalId:s.externalId}),K5=M5?[$5(Z(M5,B,H))]:[];return b5(K5,{totalResults:K5.length,startIndex:1,itemsPerPage:K5.length})}let F5=await J.store.list({start:T,limit:c,filter:s}),G5=F5.items.map((M5)=>$5(Z(M5,B,H)));return b5(G5,{totalResults:F5.total,startIndex:T+1,itemsPerPage:F5.count})}if(B.method==="POST"){let b=await B.json(),r=await k5(J.validator,b);if(r.issues)return C(400,r.issues.map((s)=>s.message).join("; "),"invalidValue");let T=await J.store.upsert(J.fromScim(r.value));if(T.active===!1)await $.accessIndex?.setSubjectDisabled?.(T.id,J.subjectType,!0);let c=T.id?Q5(B,`${H}/${encodeURIComponent(T.id)}`):void 0;return L5($5(Z(T,B,H)),201,c)}return C(405,"Method not allowed")}catch(b){if(I1(b))return C(409,b.message,"uniqueness");return C(500,b instanceof Error?b.message:"Internal error")}}}}async function h4(J,$,Z,X){let K=[],B=[["group",J.groups],["role",J.roles],["permission",J.permissions]];for(let[W,H]of B)for await(let F of X2((g,u)=>H.list({start:g,limit:u,filter:{requestable:!0}})))if(F.providerId===Z)K.push({entity:F,type:W});if(K.length>1)throw new I9(`Ambiguous providerId "${Z}": ${K.length} entitlements share it (${K.map((W)=>`${W.type}:${W.entity.id}`).join(", ")})`,"unique_violation","providerId");let G=K[0];if(G?.entity.requestable!==!0)return;return l5(G.entity,G.type,await u5(J,$,G.type,G.entity.id,X))}async function m4(J,$,Z,X){let K=Math.max(0,Z.start),B=Z.limit!=null?K+Z.limit:void 0,G={start:0,limit:B,filter:Z.filter},[W,H,F]=await Promise.all([J.groups.list(G),J.roles.list(G),J.permissions.list(G)]),g=[...W.items.map((b)=>({entity:b,type:"group"})),...H.items.map((b)=>({entity:b,type:"role"})),...F.items.map((b)=>({entity:b,type:"permission"}))],u=W.total+H.total+F.total,n=g.slice(K,B),e=$?.listByTargets?await $.listByTargets(n.map(({entity:b,type:r})=>({targetType:r,target:b.id}))):void 0,$5=await Promise.all(n.map(async({entity:b,type:r})=>l5(b,r,await u5(J,$,r,b.id,X,e))));return{resources:$5,total:u,count:$5.length}}async function Y1(J,$,Z,X){let[K,B,G]=await Promise.all([J.groups.get(Z),J.roles.get(Z),J.permissions.get(Z)]);if(K)return l5(K,"group",await u5(J,$,"group",Z,X));if(B)return l5(B,"role",await u5(J,$,"role",Z,X));if(G)return l5(G,"permission",await u5(J,$,"permission",Z,X));return}async function F9(J,$,Z){let X=r5($),K=X==="role"?await J.roles.get(Z):X==="permission"?await J.permissions.get(Z):await J.groups.get(Z),B=U4($,Z),G=K?.assignableSubjectTypes&&K.assignableSubjectTypes.length>0?K.assignableSubjectTypes:["user"],W={...K??{},...B,source:K?.source??"scim",assignableSubjectTypes:G},H=X==="role"?J.roles.set(W):X==="permission"?J.permissions.set(W):J.groups.set(W);return await H.ready(),H}async function g4(J,$){await Promise.all([J.groups.delete($),J.roles.delete($),J.permissions.delete($)])}function A1(){return crypto.randomUUID()}function k5(J,$){let Z=J;if(typeof Z.validate==="function")return Z.validate($);return Promise.resolve(J["~standard"].validate($))}function p4(J){if(!J)return;try{return new URL(J).pathname}catch{return J.startsWith("/")?J:`/${J}`}}function T5(J){let $=p4(J);return $?w1($):void 0}function Z2(...J){for(let $ of J){let Z=T5($);if(!Z)continue;for(let X of["/Users","/Groups","/Workloads","/Customers"])if(Z.endsWith(X))return Z.slice(0,-X.length)}return}function Q5(J,$){return new URL($,J.url).toString()}function j(J,$,Z,X){let{multiValued:K=!1,...B}=X??{};return{name:J,type:$,description:Z,multiValued:K,...B}}function u4(J,$){return{schemas:[N4],documentationUri:$?.documentationUri,patch:{supported:!0},bulk:{supported:!1},filter:{supported:!0,maxResults:1000},changePassword:{supported:!1},sort:{supported:!1},etag:{supported:!1},authenticationSchemes:[{type:"oauthbearertoken",name:"OAuth Bearer Token",description:"Use an ionite workload bearer token for IAM discovery and provisioning requests.",primary:!0}],meta:{resourceType:"ServiceProviderConfig",location:Q5(J.request,`${J.basePath}/ServiceProviderConfig`)}}}function l4(J){let $=[];if(J.supportsUsers)$.push({schemas:[_1],id:"User",name:"User",description:"User Account",endpoint:J.usersUrl,schema:D9,schemaExtensions:[{schema:W1,required:!1},{schema:I5,required:!1}],meta:{resourceType:"ResourceType",location:Q5(J.request,`${J.basePath}/ResourceTypes/User`)}});if(J.supportsGroups)$.push({schemas:[_1],id:"Group",name:"Group",description:"Group",endpoint:J.groupsUrl,schema:M9,schemaExtensions:[{schema:p,required:!1}],meta:{resourceType:"ResourceType",location:Q5(J.request,`${J.basePath}/ResourceTypes/Group`)}});if(J.supportsWorkloads)$.push({schemas:[_1],id:"Workload",name:"Workload",description:"Workload (machine) principal",endpoint:J.workloadsUrl,schema:i5,meta:{resourceType:"ResourceType",location:Q5(J.request,`${J.basePath}/ResourceTypes/Workload`)}});if(J.supportsCustomers)$.push({schemas:[_1],id:"Customer",name:"Customer",description:"Customer (CIAM) principal",endpoint:J.customersUrl,schema:t5,meta:{resourceType:"ResourceType",location:Q5(J.request,`${J.basePath}/ResourceTypes/Customer`)}});return $}function c4(J){let $=[];if(J.supportsUsers)$.push({schemas:[p5],id:D9,name:"User",description:"User Account",meta:{resourceType:"Schema",location:Q5(J.request,`${J.basePath}/Schemas/${encodeURIComponent(D9)}`)},attributes:[j("id","string","Unique identifier for the User.",{multiValued:!1,required:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),j("externalId","string","External identifier from the provisioning client.",{multiValued:!1,required:!1,mutability:"readWrite",returned:"default",uniqueness:"none"}),j("userName","string","Unique identifier typically used for login.",{multiValued:!1,required:!0,caseExact:!1,mutability:"readWrite",returned:"default",uniqueness:"server"}),j("name","complex","The components of the user name.",{multiValued:!1,required:!1,mutability:"readWrite",returned:"default",subAttributes:[j("formatted","string","The full name, including titles and suffixes.",{multiValued:!1}),j("familyName","string","The family name of the User.",{multiValued:!1}),j("givenName","string","The given name of the User.",{multiValued:!1}),j("middleName","string","The middle name(s) of the User.",{multiValued:!1}),j("honorificPrefix","string","The honorific prefix(es) of the User.",{multiValued:!1}),j("honorificSuffix","string","The honorific suffix(es) of the User.",{multiValued:!1})]}),j("displayName","string","The name of the User, suitable for display.",{multiValued:!1}),j("nickName","string","The casual way to address the user.",{multiValued:!1}),j("profileUrl","reference","A URL pointing to the User profile.",{multiValued:!1,referenceTypes:["external"]}),j("title","string","The user title, such as Vice President.",{multiValued:!1}),j("userType","string","The relationship between the organization and the User.",{multiValued:!1}),j("preferredLanguage","string","Preferred written or spoken language.",{multiValued:!1}),j("locale","string","Default location for localizing values.",{multiValued:!1}),j("timezone","string","The User time zone.",{multiValued:!1}),j("active","boolean","The User administrative status.",{multiValued:!1}),j("emails","complex","Email addresses for the User.",{multiValued:!0,subAttributes:[j("value","string","Email address value.",{multiValued:!1,required:!0}),j("display","string","Display label for the email.",{multiValued:!1}),j("type","string","Email type such as work or home.",{multiValued:!1}),j("primary","boolean","Primary email indicator.",{multiValued:!1})]}),j("phoneNumbers","complex","Phone numbers for the User.",{multiValued:!0,subAttributes:[j("value","string","Phone number value.",{multiValued:!1,required:!0}),j("display","string","Display label for the phone number.",{multiValued:!1}),j("type","string","Phone number type.",{multiValued:!1}),j("primary","boolean","Primary phone number indicator.",{multiValued:!1})]}),j("photos","complex","Photo URLs for the User.",{multiValued:!0,subAttributes:[j("value","reference","Photo URL.",{multiValued:!1,required:!0,referenceTypes:["external"]}),j("display","string","Display label for the photo.",{multiValued:!1}),j("type","string","Photo type.",{multiValued:!1}),j("primary","boolean","Primary photo indicator.",{multiValued:!1})]}),j("addresses","complex","Physical mailing addresses for the User.",{multiValued:!0,subAttributes:[j("formatted","string","Formatted mailing address.",{multiValued:!1}),j("streetAddress","string","Full street address component.",{multiValued:!1}),j("locality","string","City or locality.",{multiValued:!1}),j("region","string","State or region.",{multiValued:!1}),j("postalCode","string","Postal code.",{multiValued:!1}),j("country","string","Country.",{multiValued:!1}),j("type","string","Address type.",{multiValued:!1}),j("primary","boolean","Primary address indicator.",{multiValued:!1})]}),j("groups","complex","Groups to which the User belongs.",{multiValued:!0,mutability:"readOnly",subAttributes:[j("value","string","Group identifier.",{multiValued:!1,required:!0}),j("$ref","reference","Reference to the Group resource.",{multiValued:!1,referenceTypes:["Group"]}),j("display","string","Display name of the group.",{multiValued:!1}),j("type","string","Relationship type.",{multiValued:!1})]}),j("entitlements","complex","Entitlements for the User.",{multiValued:!0,subAttributes:[j("value","string","Entitlement value.",{multiValued:!1,required:!0}),j("display","string","Display value.",{multiValued:!1}),j("type","string","Entitlement type.",{multiValued:!1}),j("primary","boolean","Primary entitlement indicator.",{multiValued:!1})]}),j("roles","complex","Roles for the User.",{multiValued:!0,subAttributes:[j("value","string","Role value.",{multiValued:!1,required:!0}),j("display","string","Display value.",{multiValued:!1}),j("type","string","Role type.",{multiValued:!1}),j("primary","boolean","Primary role indicator.",{multiValued:!1})]}),j("x509Certificates","complex","Certificates issued to the User.",{multiValued:!0,subAttributes:[j("value","string","Certificate value.",{multiValued:!1,required:!0}),j("display","string","Display value.",{multiValued:!1}),j("type","string","Certificate type.",{multiValued:!1}),j("primary","boolean","Primary certificate indicator.",{multiValued:!1})]})]}),$.push({schemas:[p5],id:W1,name:"EnterpriseUser",description:"Enterprise User extension",meta:{resourceType:"Schema",location:Q5(J.request,`${J.basePath}/Schemas/${encodeURIComponent(W1)}`)},attributes:[j("employeeNumber","string","Numeric or alphanumeric identifier assigned to a person.",{multiValued:!1}),j("costCenter","string","Name of a cost center.",{multiValued:!1}),j("organization","string","Name of an organization.",{multiValued:!1}),j("division","string","Name of a division.",{multiValued:!1}),j("department","string","Name of a department.",{multiValued:!1}),j("manager","complex","The User manager.",{multiValued:!1,subAttributes:[j("value","string","Identifier of the manager User resource.",{multiValued:!1}),j("$ref","reference","Reference to the manager User resource.",{multiValued:!1,referenceTypes:["User"]}),j("displayName","string","Display name of the manager.",{multiValued:!1})]})]}),$.push({schemas:[p5],id:I5,name:"IoniteUser",description:"ionite User extension carrying the Enterprise Controlled ID (ECID) identity correlator and the account purpose (accountClass). See https://ionite.com/docs/llms-ecid.txt.",meta:{resourceType:"Schema",location:Q5(J.request,`${J.basePath}/Schemas/${encodeURIComponent(I5)}`)},attributes:[j("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}),j("accountClass","string","Account purpose (distinct from userType persona). Open value set: 'daily', 'privileged', 'break_glass', 'service'.",{multiValued:!1})]});if(J.supportsGroups)$.push({schemas:[p5],id:p,name:"IoniteAuthzGroup",description:"ionite authorization metadata for SCIM Group resources.",meta:{resourceType:"Schema",location:Q5(J.request,`${J.basePath}/Schemas/${encodeURIComponent(p)}`)},attributes:[j("type","string","Authorization entity kind: group, role, or permission.",{multiValued:!1,required:!1}),j("requestable","boolean","Whether this catalog entry is exposed as assignable access to IAM tooling. Only true entries are served.",{multiValued:!1,required:!1}),j("providerId","string","IAM service-provider id captured when this entitlement is materialized at the destination.",{multiValued:!1,required:!1,mutability:"readWrite"}),j("requestUrl","reference","IAM-owned deep link where a principal can request this entitlement.",{multiValued:!1,required:!1,mutability:"readWrite",referenceTypes:["external"]}),j("source","string","Provenance of the catalog row.",{multiValued:!1,required:!1,mutability:"readOnly",canonicalValues:["code","app","scim"]}),j("deprecated","boolean","Whether this retired entitlement may be deleted.",{multiValued:!1,required:!1,mutability:"readOnly"}),j("description","string","Human-readable authorization entity description.",{multiValued:!1,required:!1}),j("resources","string","Resource ids this entitlement is scoped to.",{multiValued:!0,required:!1}),j("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"]}),j("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"]})]});if(J.supportsGroups)$.push({schemas:[p5],id:M9,name:"Group",description:"Group",meta:{resourceType:"Schema",location:Q5(J.request,`${J.basePath}/Schemas/${encodeURIComponent(M9)}`)},attributes:[j("id","string","Unique identifier for the Group.",{multiValued:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),j("externalId","string","External identifier from the provisioning client.",{multiValued:!1,uniqueness:"none"}),j("displayName","string","Human-readable name for the Group.",{multiValued:!1,required:!0,uniqueness:"none"}),j("members","complex","Members of the Group.",{multiValued:!0,subAttributes:[j("value","string","Identifier of the member resource.",{multiValued:!1,required:!0}),j("$ref","reference","Reference to the member resource.",{multiValued:!1,referenceTypes:["User","Group","Workload","Customer"]}),j("display","string","Display name of the member.",{multiValued:!1}),j("type","string","Member type.",{multiValued:!1})]})]});if(J.supportsWorkloads)$.push({schemas:[p5],id:i5,name:"Workload",description:"Workload (machine) principal",meta:{resourceType:"Schema",location:Q5(J.request,`${J.basePath}/Schemas/${encodeURIComponent(i5)}`)},attributes:[j("id","string","Unique identifier for the Workload.",{multiValued:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),j("externalId","string","External identifier from the provisioning client.",{multiValued:!1}),j("userName","string","Login identifier, typically the OAuth clientId.",{multiValued:!1}),j("displayName","string","Human-readable name for the Workload.",{multiValued:!1}),j("description","string","Free-form description of the Workload.",{multiValued:!1}),j("active","boolean","Administrative status of the Workload.",{multiValued:!1})]});if(J.supportsCustomers)$.push({schemas:[p5],id:t5,name:"Customer",description:"Customer (CIAM) principal",meta:{resourceType:"Schema",location:Q5(J.request,`${J.basePath}/Schemas/${encodeURIComponent(t5)}`)},attributes:[j("id","string","Unique identifier for the Customer.",{multiValued:!1,mutability:"readOnly",returned:"always",uniqueness:"global"}),j("externalId","string","External identifier from the provisioning client.",{multiValued:!1}),j("userName","string","Unique identifier typically used for login.",{multiValued:!1}),j("displayName","string","Human-readable name for the Customer.",{multiValued:!1}),j("active","boolean","Administrative status of the Customer.",{multiValued:!1}),j("emails","complex","Email addresses for the Customer.",{multiValued:!0,subAttributes:[j("value","string","Email address.",{multiValued:!1,required:!0}),j("primary","boolean","Whether this is the primary email.",{multiValued:!1})]})]});return $}function d4(J,$,Z,X,K,B,G,W,H,F,g,u,n,e,$5){let b={authz:X,settleAuthz:$5,accessStore:K,accessIndex:B,catalogStore:G,codeCatalog:W,resources:H,log:$,iamDelta:u,onAccessMutation:n};if(!F&&!g)return;let T={...F,...g},c=T.users?.enabled!==!1,s=T.groups?.enabled!==!1,F5=T.workloads?.enabled!==!1,G5=T.customers?.enabled!==!1;if(Boolean(T.url||T.userStore||G||W)&&!Z)$.error("IAM requires workload identity for SCIM push/pull operations",{"ion.operation":"workload.require","ion.outcome":"failure"});function K5(){if(!Z)throw $.error("IAM requires workload identity for SCIM push/pull operations",{"ion.operation":"workload.require","ion.outcome":"failure"}),Error("IAM requires workload identity for SCIM push/pull operations");return Z}async function _5(y){let U=K5(),h=y.headers.get("Authorization");if(!h?.startsWith("Bearer "))return!1;try{let Q=h.substring(7);return(await U.validateToken(Q)).valid}catch{return!1}}async function c5(){let y=K5(),U=typeof y.getServerToken==="function"?await y.getServerToken():await y.getToken();return new Headers({"Content-Type":G1,Accept:G1,Authorization:`Bearer ${U}`})}async function f5(y,U,h,Q){if(!T.url)throw Error("IAM URL not configured for outgoing requests");let Y=`${T.url}${U}`;try{let L=await c5(),D=await fetch(Y,{method:y,headers:L,body:h?JSON.stringify(h):void 0}),z=await D.json();if(!D.ok)return{success:!1,error:z,status:D.status};let E=await Q["~standard"].validate(z);if(E.issues)return $.error("SCIM response validation failed",{"ion.operation":"scim.response.validate","ion.outcome":"failure",validationIssues:E.issues}),{success:!1,error:{schemas:[H9],status:"400",scimType:"invalidValue",detail:`Response validation failed: ${E.issues.map((A)=>A.message).join("; ")}`},status:400};return{success:!0,data:E.value,status:D.status}}catch(L){return{success:!1,error:{schemas:[H9],status:"500",detail:L instanceof Error?L.message:"Unknown error occurred"},status:500}}}function d5(){return T.url}function e5(y,U){let h=T5(U?.usersUrl??T.usersUrl??"/api/iam/Users")??"/api/iam/Users",Q=T5(U?.groupsUrl??T.groupsUrl??"/api/iam/Groups")??"/api/iam/Groups",Y=T5(U?.workloadsUrl??T.workloadsUrl??"/api/iam/Workloads")??"/api/iam/Workloads",L=T5(U?.customersUrl??T.customersUrl??"/api/iam/Customers")??"/api/iam/Customers",D=T5(U?.discovery?.basePath??T.discovery?.basePath)??Z2(h,Q,Y,L);if(!D)return;return{request:y,basePath:D,usersUrl:h,groupsUrl:Q,workloadsUrl:Y,customersUrl:L,supportsUsers:c&&Boolean(T.userStore),supportsGroups:s&&Boolean(G||W),supportsWorkloads:F5&&Boolean(T.workloadIdentityStore),supportsCustomers:G5&&Boolean(T.customerStore)}}async function J1(y){let U=u4(y,T.discovery);return await T.discovery?.buildServiceProviderConfig?.(y,U)??U}async function E5(y){let U=l4(y);return await T.discovery?.buildResourceTypes?.(y,U)??U}async function h5(y){let U=c4(y);return await T.discovery?.buildSchemas?.(y,U)??U}async function v5(y,U){let h=e5(y,U);if(!h)return;let Q=w1(new URL(y.url).pathname),{basePath:Y}=h;if(Q!==Y&&!Q.startsWith(`${Y}/`))return;let L=w1(Q.slice(Y.length)||"/");if(!(L==="/ServiceProviderConfig"||L==="/ResourceTypes"||L.startsWith("/ResourceTypes/")||L==="/Schemas"||L.startsWith("/Schemas/")))return;if(y.method!=="GET")return C(405,"Method not allowed");if(!await _5(y))return C(401,"Authorization required");if(L==="/ServiceProviderConfig")return L5(await J1(h));if(L==="/ResourceTypes")return b5(await E5(h));if(L.startsWith("/ResourceTypes/")){let E=decodeURIComponent(L.slice(15)),A=(await E5(h)).find((N)=>N.id===E||N.name===E);return A?L5(A):C(404,"Resource not found")}if(L==="/Schemas")return b5(await h5(h));if(L.startsWith("/Schemas/")){let E=decodeURIComponent(L.slice(9)),A=(await h5(h)).find((N)=>N.id===E);return A?L5(A):C(404,"Resource not found")}return}let A5,m5;if(T.url)m5=async(U,h)=>{let Q={...U,schemas:U.schemas??["urn:ietf:params:scim:schemas:core:2.0:User","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"]};return f5("POST","/Users",Q,J.user)},A5={createGroup:async(U,h)=>{let Q={schemas:["urn:ietf:params:scim:schemas:core:2.0:Group"],displayName:U,externalId:h?.id,members:h?.members};return f5("POST","/Groups",Q,J.group)}};let R5;if(G||W){let y=E9(W,G),U=(M,V,O)=>{let P=M[p]??{},_=r5(M),R=M.id,v=R?Q5(V,`${O}/${encodeURIComponent(R)}`):void 0,x={id:R??M.externalId??M.displayName,name:M.displayName,displayName:M.displayName,description:P.description??M.displayName,requestable:P.requestable,providerId:P.providerId??M.externalId,requestUrl:P.requestUrl,source:P.source,deprecated:P.deprecated,assignableSubjectTypes:P.assignableSubjectTypes,recommendedSubjectTypes:P.recommendedSubjectTypes},m=P.requestUrl??T.entitlementRequestUrl?.(x,_,{request:V});return{...M,meta:{...M.meta,resourceType:"Group",location:v},[p]:{...P,requestUrl:m}}},h=(M)=>O9(W,M),Q=async(M,V)=>{if(!G){if(V)throw Error(`Cannot persist access for code entitlement "${M.entity.id}": no AccessCatalogStore is wired.`);return M.entity}try{return await _9(M.kind,M.entity,j9(G,M.kind))}catch(O){if(V)throw O;return $.warn("Code entitlement discovery materialization failed; serving the code template",{"ion.operation":"iam.catalog.materialize","ion.outcome":"degraded",entitlementId:M.entity.id,entitlementType:M.kind,error:S5(O)}),M.entity}},Y=async(M)=>{if(!G)return;try{await Q2(W,G,M)}catch(V){$.warn("Retired code entitlement deprecation failed; serving the last durable row",{"ion.operation":"iam.catalog.deprecate","ion.outcome":"degraded",entitlementId:M,error:S5(V)})}},L=(M,V)=>C(403,`Entitlement "${M}" is declared in application code; its structural definition cannot be ${V} through SCIM. IAM may change presentation and receipts, while code continues to own structure.`,"mutability"),D=(M)=>M.path==="members"||Boolean(M.path?.startsWith("members[")),z=(M)=>D(M)||M.path==="displayName"||M.path===`${p}.description`||M.path===`${p}.providerId`||M.path===`${p}.requestUrl`,E=(M)=>M?.[p]?.requestable===!0,A=(M)=>C(404,`Requestable Group ${M} not found`,"invalidValue"),N=async(M,V)=>{if(!await _5(M))return C(401,"Authorization required");let P=new URL(M.url),_=V?.basePath??"/Groups",R=P.pathname;if(R.startsWith(_))R=R.substring(_.length);let x=R.match(/^\/([^/]+)$/)?.[1],m=M.method;try{if(x)switch(m){case"GET":return await S(M,_,x);case"PUT":return await I(M,_,x);case"PATCH":return await f(M,_,x);case"DELETE":return await d(x);default:return C(405,"Method not allowed")}else if(R===""||R==="/")switch(m){case"GET":return await w(M,_);case"POST":return await q(M,_);default:return C(405,"Method not allowed")}return C(404,"Resource not found")}catch(k){if(k instanceof s5)return r9(k);if(k instanceof x1)return C(400,k.message,"invalidValue");if(I1(k))return C(409,k.message,"uniqueness");return $.error("Groups inbound handler error",{"ion.operation":"scim.groups.handler","ion.outcome":"failure"},k),C(500,k instanceof Error?k.message:"Internal server error")}},w=async(M,V)=>{let O=new URL(M.url),P=O.searchParams.get("startIndex"),_=O.searchParams.get("count"),R=P!=null?parseInt(P,10):void 0,v=_!=null?parseInt(_,10):void 0,x=R!=null&&!Number.isNaN(R)?Math.max(0,R-1):0,m=v!=null&&!Number.isNaN(v)?v:void 0,k=O.searchParams.get("filter"),l=J2(k);if(l!==void 0){await Y();let a=await h4(y,K,l,e),J5=a?[U(a,M,V)]:[];return b5(J5,{totalResults:J5.length,startIndex:1,itemsPerPage:J5.length})}if(C4(k)?.requestable===!1)return b5([],{totalResults:0,startIndex:1,itemsPerPage:0});let W5={requestable:!0};if(W)await Promise.all([...W.groups.list().filter((a)=>a.requestable===!0).map((a)=>({entity:a,kind:"group"})),...W.roles.list().filter((a)=>a.requestable===!0).map((a)=>({entity:a,kind:"role"})),...W.permissions.list().filter((a)=>a.requestable===!0).map((a)=>({entity:a,kind:"permission"}))].map((a)=>Q(a,!1)));await Y();let o=await m4(y,K,{start:x,limit:m,filter:W5},e);return b5(o.resources.map((a)=>U(a,M,V)),{totalResults:o.total,startIndex:x+1,itemsPerPage:o.count})},S=async(M,V,O)=>{let P=h(O);if(P&&P.entity.requestable!==!0)return A(O);if(P)await Q(P,!1);await Y(O);let _=await Y1(y,K,O,e);if(!E(_))return A(O);return L5(U(_,M,V))},q=async(M,V)=>{let O=await M.json(),P=await k5(J.group,O);if(P.issues)return $.error("Group creation validation failed",{"ion.operation":"scim.group.create","ion.outcome":"failure",validationIssues:P.issues}),C(400,`Request validation failed: ${P.issues.map((o)=>o.message).join("; ")}`,"invalidValue");let _=P.value;if(!_.displayName)return C(400,"displayName is required","invalidValue");if(_[p]?.requestable===!1)return C(400,"SCIM may create only requestable entitlements; non-requestable definitions are App-owned.","invalidValue");if(_[p]={..._[p],requestable:!0},!G)return C(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 v=r5(_),x=A1();if(h(x))throw new I9(`id "${x}" is reserved by the code catalog`,"unique_violation","id");let m=G9(_),k=P1(new Map,E1(_.members,v,x,m,_[p]?.assignableSubjectTypes)),l;await o5(b,async()=>{l=await F9(y,_,x)},k,{oaa:()=>L9(X,l,v)});let Z5=await u5(y,K,v,x),W5=U(l5(l,v,Z5),M,V);return L5(W5,201,W5.meta?.location)},I=async(M,V,O)=>{let P=await M.json(),_=await k5(J.group,P);if(_.issues)return $.error("Group replacement validation failed",{"ion.operation":"scim.group.replace","ion.outcome":"failure",validationIssues:_.issues}),C(400,`Request validation failed: ${_.issues.map((J5)=>J5.message).join("; ")}`,"invalidValue");let R=_.value,v=r5(R),x=h(O);if(x&&x.entity.requestable!==!0)return A(O);if(x){if(await Q(x,!0),T4(R,x))return L(O,"replaced")}let m=await Y1(y,K,O);if(!E(m))return A(O);if(!x&&m[p]?.source==="code"&&S4(R,m))return L(O,"replaced");let k=x?.kind??v,l=x?z9(x.entity):G9(R),Z5=K?(await K.listByTarget(k,O)).items:[],W5=P1(R4(Z5),E1(R.members,k,O,l,x?.entity.assignableSubjectTypes??m[p]?.assignableSubjectTypes??R[p]?.assignableSubjectTypes)),o;await o5(b,async()=>{o=await F9(y,R,O)},W5,{oaa:()=>L9(X,o,k)});let a=await u5(y,K,k,O);return L5(U(l5(o,k,a),M,V))},f=async(M,V,O)=>{let P=h(O);if(P&&P.entity.requestable!==!0)return A(O);if(P)await Q(P,!0);let _=await Y1(y,K,O);if(!E(_))return A(O);let R=await M.json();if((P!==void 0||_[p]?.source==="code")&&(R.Operations??[]).some((t)=>!z(t)))return L(O,"patched");let x={..._};for(let t of R.Operations??[])if(t.op==="replace"&&t.path&&t.value!==void 0){if(t.path==="displayName")x.displayName=t.value;else if(t.path===`${p}.requestable`)x[p]={...x[p],requestable:Boolean(t.value)};else if(t.path===`${p}.description`)x[p]={...x[p],description:String(t.value)};else if(t.path===`${p}.providerId`)x[p]={...x[p],providerId:String(t.value)};else if(t.path===`${p}.requestUrl`)x[p]={...x[p],requestUrl:String(t.value)}}else if(t.op==="add"&&t.path==="members"&&t.value!==void 0){let w5=t.value;x.members=[...x.members??[],...w5]}else if(t.op==="remove"&&t.path?.startsWith("members[")){let w5=t.path.match(/members\[value eq "([^"]+)"\]/);if(w5)x.members=(x.members??[]).filter((H5)=>H5.value!==w5[1])}let m=await k5(J.group,x);if(m.issues)return $.error("Group patch validation failed",{"ion.operation":"scim.group.patch","ion.outcome":"failure",validationIssues:m.issues}),C(400,`Request validation failed: ${m.issues.map((t)=>t.message).join("; ")}`,"invalidValue");let k=P?.kind??r5(x),l=P?z9(P.entity):G9(x),Z5=P?.entity.assignableSubjectTypes??_[p]?.assignableSubjectTypes??x[p]?.assignableSubjectTypes,W5=P1(E1(_.members,k,O,l,Z5),E1(x.members,k,O,l,Z5)),o,a=!P||(R.Operations??[]).some((t)=>!D(t));await o5(b,async()=>{if(a)o=await F9(y,x,O)},W5,a?{oaa:()=>L9(X,o,k)}:void 0);let J5=await Y1(y,K,O);return L5(U(J5,M,V))},d=async(M)=>{let V=h(M);if(V&&V.entity.requestable!==!0)return A(M);if(V)await Q(V,!0);let O=await Y1(y,K,M);if(!E(O))return A(M);let P=O[p];if((V||P?.source==="code")&&P?.deprecated!==!0)return C(403,`Code-owned entitlement "${M}" can be deleted only after it is marked deprecated.`,"mutability");let _=r5(O);if(K){let R=await K.listByTarget(_,M),v=[];for(let x of R.items)await T1(b,x,v);await N9(b,v)}return await g4(y,M),new Response(null,{status:204})};R5={handler:N}}let V5,q5,P5;if(T.userStore){let{userStore:y,inboundUsers:U}=T,h=(V)=>V?.find((O)=>O.primary)?.value||V?.[0]?.value,Q=async(V)=>{if(U?.mapBaseUserToScim)return await U.mapBaseUserToScim(V);return X9(V)},Y=async(V,O,P)=>{let _=await Q(V),R=_.id??V.id;return{..._,id:R,meta:{..._.meta,resourceType:"User",location:R?Q5(O,`${P}/${encodeURIComponent(R)}`):void 0}}},L=async(V,O)=>{if(U?.mapValidatedScimToBaseUser)return await U.mapValidatedScimToBaseUser(V,O);let P=new Date,_=h(V.emails),R=V.name?.formatted||[V.name?.givenName,V.name?.middleName,V.name?.familyName].filter(Boolean).join(" ").trim()||V.displayName,v=V.id||O.existing?.id||A1(),x=V.userName||_||O.existing?.userName||v,m=R||V.displayName||O.existing?.name||x,k=Object.fromEntries(Object.entries(V).filter(([a,J5])=>a.startsWith("urn:")&&a!==W1&&a!==I5&&J5!==void 0)),l=V[I5],Z5=l?.ecid!==void 0&&l.ecid!==null?S1(l.ecid):O.existing?.ecid,W5=l?.accountClass??O.existing?.accountClass,o=O.existing?.sso;return{...O.existing??{},id:v,userName:x,name:m,email:_||O.existing?.email||x,avatar:V.profileUrl,sso:{...o??{},profile:{...o?.profile??{},sub:v,iss:o?.profile.iss??"iam-provisioned",aud:o?.profile.aud??"iam-provisioned",exp:o?.profile.exp??Math.floor(Date.now()/1000)+3600,iat:o?.profile.iat??Math.floor(Date.now()/1000),email:_||O.existing?.email||x,email_verified:!0,name:m,preferred_username:x},tenant:o?.tenant??{id:"iam-provisioned",name:"IAM Provisioned"},scope:o?.scope??"openid profile email",tokenType:o?.tokenType??"Bearer",expires:o?.expires??new Date(Date.now()+3600000)},externalId:V.externalId,ecid:Z5,accountClass:W5,displayName:V.displayName,scimName:V.name,emails:V.emails,nickName:V.nickName,title:V.title,preferredLanguage:V.preferredLanguage,locale:V.locale,timezone:V.timezone,active:V.active,phoneNumbers:V.phoneNumbers,ims:V.ims,photos:V.photos,addresses:V.addresses,groups:V.groups,entitlements:V.entitlements,roles:V.roles,x509Certificates:V.x509Certificates,scimEnterprise:V[W1],scimSchemaExtensions:Object.keys(k).length>0?k:void 0,createdAt:O.existing?.createdAt??(V.meta?.created?new Date(V.meta.created):P),updatedAt:V.meta?.lastModified?new Date(V.meta.lastModified):P,userType:V.userType}},D=(V,O,P)=>{V[O]=P},z=(V,O,P)=>{let _=V[O];if(Array.isArray(_)){V[O]=[..._,...Array.isArray(P)?P:[P]];return}if(_&&typeof _==="object"&&!Array.isArray(_)&&P&&typeof P==="object"&&!Array.isArray(P)){V[O]={..._,...P};return}V[O]=P},E=(V,O,P)=>{let _=O.match(/^(urn:.*:(?:User|Group))(?::(.+))?$/),R=_?[_[1],..._[2]?.split(":")??[]]:O.split("."),v=V;for(let m of R.slice(0,-1)){let k=v[m];if(k===void 0){if(!P)return null;v[m]={}}else if(k===null||typeof k!=="object"||Array.isArray(k)){if(!P)return null;v[m]={}}v=v[m]}let x=R.at(-1);if(!x)return null;return{parent:v,key:x}},A=(V,O)=>{let P=O.op.toLowerCase();if(!O.path){if(P!=="remove"&&O.value&&typeof O.value==="object"&&!Array.isArray(O.value))Object.assign(V,O.value);return}let _=O.path.match(/^([A-Za-z0-9]+)\[value eq "([^"]+)"\]$/);if(_&&P==="remove"){let[,v,x]=_,m=V[v];if(Array.isArray(m))V[v]=m.filter((k)=>!(k&&typeof k==="object"&&("value"in k)&&k.value===x));return}let R=E(V,O.path,P!=="remove");if(!R)return;if(P==="remove"){delete R.parent[R.key];return}if(P==="add"){z(R.parent,R.key,O.value);return}D(R.parent,R.key,O.value)},N=async(V,O)=>{if(!await _5(V))return C(401,"Authorization required");let _=new URL(V.url),R=O?.basePath??"/Users",v=_.pathname;if(v.startsWith(R))v=v.substring(R.length);let m=v.match(/^\/([^/]+)$/)?.[1],k=V.method;try{if(m)switch(k){case"GET":return await S(V,R,m);case"PUT":return await f(V,R,m);case"PATCH":return await d(V,R,m);case"DELETE":return await M(m);default:return C(405,"Method not allowed")}else if(v===""||v==="/")switch(k){case"GET":return await w(V,R);case"POST":return await I(V,R);default:return C(405,"Method not allowed")}return C(404,"Resource not found")}catch(l){if(l instanceof s5)return r9(l);if(I1(l))return C(409,l.message,"uniqueness");return $.error("Users inbound handler error",{"ion.operation":"scim.users.handler","ion.outcome":"failure"},l),C(500,l instanceof Error?l.message:"Internal server error")}},w=async(V,O)=>{let P=new URL(V.url),_=P.searchParams.get("startIndex"),R=P.searchParams.get("count"),v=_!=null?parseInt(_,10):void 0,x=R!=null?parseInt(R,10):void 0,m=v!=null&&!Number.isNaN(v)?Math.max(0,v-1):0,k=x!=null&&!Number.isNaN(x)?x:void 0,l=J2(P.searchParams.get("filter"));if(l!==void 0){let o=await y.lookup({externalId:l}),a=o?[await Y(o,V,O)]:[];return b5(a,{totalResults:a.length,startIndex:1,itemsPerPage:a.length})}let Z5=await y.list({start:m,limit:k}),W5=await Promise.all(Z5.items.map((o)=>Y(o,V,O)));return b5(W5,{totalResults:Z5.total,startIndex:m+1,itemsPerPage:Z5.count})},S=async(V,O,P)=>{let _=await y.get(P);if(!_)return C(404,`User ${P} not found`,"invalidValue");return L5(await Y(_,V,O))},q=async(V,O)=>{let P=b.accessIndex;if(!P?.setSubjectDisabled||!O.id)return;let _=V?V.active??!0:!0,R=O.active??!0;if(V&&_===R)return;if(!V&&R)return;await P.setSubjectDisabled(O.id,"user",!R)},I=async(V,O)=>{let P=await V.json(),_=await k5(J.user,P);if(_.issues)return $.error("User creation validation failed",{"ion.operation":"scim.user.create","ion.outcome":"failure",validationIssues:_.issues}),C(400,`Request validation failed: ${_.issues.map((m)=>m.message).join("; ")}`,"invalidValue");let R=_.value;if(!R.userName&&!R.emails?.[0]?.value)return C(400,"userName or email is required","invalidValue");let v=await L(R,{mode:"create"});await o5(b,async()=>{await y.upsert(v),await q(void 0,v)},B9(void 0,v),{oaa:async()=>{await W9(X,v)},delta:async()=>{await b.iamDelta?.onUserUpsert(v)}});let x=await Y(v,V,O);return L5(x,201,x.meta?.location)},f=async(V,O,P)=>{let _=await y.get(P);if(!_)return C(404,`User ${P} not found`,"invalidValue");let R=await V.json(),v=await k5(J.user,R);if(v.issues)return $.error("User replacement validation failed",{"ion.operation":"scim.user.replace","ion.outcome":"failure",validationIssues:v.issues}),C(400,`Request validation failed: ${v.issues.map((k)=>k.message).join("; ")}`,"invalidValue");let x=v.value,m=await L({...x,id:P},{existing:_,mode:"replace"});return m.createdAt=_.createdAt,m.updatedAt=new Date,await o5(b,async()=>{await y.upsert(m),await q(_,m)},B9(_,m),{oaa:async()=>{await W9(X,m)},delta:async()=>{await e9(b.iamDelta,_,m)}}),L5(await Y(m,V,O))},d=async(V,O,P)=>{let _=await y.get(P);if(!_)return C(404,`User ${P} not found`,"invalidValue");let v=(await V.json()).Operations??[],m={...await Q(_)};for(let Z5 of v)A(m,Z5);let k=await k5(J.user,m);if(k.issues)return $.error("User patch validation failed",{"ion.operation":"scim.user.patch","ion.outcome":"failure",validationIssues:k.issues}),C(400,`Request validation failed: ${k.issues.map((Z5)=>Z5.message).join("; ")}`,"invalidValue");let l=await L(k.value,{existing:_,mode:"patch"});return l.updatedAt=new Date,await o5(b,async()=>{await y.upsert(l),await q(_,l)},B9(_,l),{oaa:async()=>{await W9(X,l)},delta:async()=>{await e9(b.iamDelta,_,l)}}),L5(await Y(l,V,O))},M=async(V)=>{let O=await y.get(V);if(!O)return C(404,`User ${V} not found`,"invalidValue");if(K){let P=await K.listBySubject(V,"user"),_=[];for(let R of P.items)await T1(b,R,_);await N9(b,_)}if(await y.delete(V),await b.accessIndex?.setSubjectDisabled?.(V,"user",!1),O.externalId&&b.iamDelta?.isReady())await F1(b,"iam.delta.egress","IAM delta user delete failed after SCIM write; full aggregation will reconcile",()=>b.iamDelta?.onUserDelete(O.externalId)??Promise.resolve(),{id:V,kind:"user"});else if(b.iamDelta?.isReady())b.log?.warn("IAM delta: deleted User has no externalId; destination delete skipped",{"ion.operation":"iam.delta.delete","ion.outcome":"skipped",id:V,kind:"user"});if(b.authz.oaa.isReady())await F1(b,"authz.oaa.delete","OAA incremental user delete failed; full sync will reconcile",()=>b.authz.oaa.deleteUser(V),{id:V,kind:"user"});return new Response(null,{status:204})};V5={handler:N}}if(T.workloadIdentityStore){let y=T.workloadIdentityStore;q5=$2({resourceType:"Workload",subjectType:"workload",store:y,validator:J.workload??K2,toScim:(U)=>Q9(U),fromScim:(U,h)=>{let Q=U,Y=Q.id?.trim()||h?.id||A1();return{...h??{},id:Y,externalId:Q.externalId??h?.externalId,clientId:Q.userName??h?.clientId??Y,displayName:Q.displayName??h?.displayName,description:Q.description??h?.description,active:Q.active??h?.active??!0,providerId:h?.providerId,requestUrl:h?.requestUrl}}},{validateAuth:_5,accessStore:K,accessIndex:B})}if(T.customerStore){let y=T.customerStore;P5=$2({resourceType:"Customer",subjectType:"customer",store:y,validator:J.customer??Y2,toScim:(U)=>K9(U),fromScim:(U,h)=>{let Q=U,Y=Q.id?.trim()||h?.id||A1(),L=Q.emails?.find((D)=>D.primary)?.value??Q.emails?.[0]?.value;return{...h??{},id:Y,externalId:Q.externalId??h?.externalId??Y,userName:Q.userName??h?.userName??Y,name:Q.displayName??h?.name??Q.userName??Y,email:L??h?.email??"",displayName:Q.displayName??h?.displayName,emails:Q.emails??h?.emails,active:Q.active??h?.active??!0,providerId:h?.providerId,requestUrl:h?.requestUrl}}},{validateAuth:_5,accessStore:K,accessIndex:B})}async function z5(y,U){K5();let h=new URL(y.url).pathname,Q=T5(U?.usersUrl??T.usersUrl??"/api/iam/Users")??"/api/iam/Users",Y=T5(U?.groupsUrl??T.groupsUrl??"/api/iam/Groups")??"/api/iam/Groups",L=T5(U?.workloadsUrl??T.workloadsUrl??"/api/iam/Workloads")??"/api/iam/Workloads",D=T5(U?.customersUrl??T.customersUrl??"/api/iam/Customers")??"/api/iam/Customers",z=`${Z2(Q,Y,L,D)??"/api/iam"}/AccessRequests`,E=await v5(y,U);if(E)return E;let A=(N)=>h===N||h.startsWith(`${N}/`);if(A(Q)){if(!c)return C(404,"SCIM Users endpoint is disabled by RemoteConfig");if(!V5)return C(501,"SCIM Users endpoint is enabled by RemoteConfig but no user store capability is wired by the application.");return V5.handler(y,{basePath:Q})}if(A(Y)){if(!s)return C(404,"SCIM Groups endpoint is disabled by RemoteConfig");if(!R5)return C(501,"SCIM Groups endpoint is enabled by RemoteConfig but no AccessCatalogStore capability is wired by the application.");return R5.handler(y,{basePath:Y})}if(A(L)){if(!F5)return C(404,"SCIM Workloads endpoint is disabled by RemoteConfig");if(!q5)return C(501,"SCIM Workloads endpoint is enabled by RemoteConfig but no workload identity store capability is wired by the application.");return q5.handler(y,{basePath:L})}if(A(D)){if(!G5)return C(404,"SCIM Customers endpoint is disabled by RemoteConfig");if(!P5)return C(501,"SCIM Customers endpoint is enabled by RemoteConfig but no customer store capability is wired by the application.");return P5.handler(y,{basePath:D})}if(A(z)){if(!T.accessRequests)return C(404,"AccessRequests endpoint is not configured");if(y.method!=="POST")return C(405,"Method not allowed");if(!await _5(y))return C(401,"Authorization required");let N;try{N=await y.json()}catch{return C(400,"Request body must be valid JSON","invalidSyntax")}if(typeof N.subject!=="string"||!N.subject||typeof N.target!=="string"||!N.target||N.subjectType!=="user"&&N.subjectType!=="workload"&&N.subjectType!=="customer"||N.targetType!=="group"&&N.targetType!=="role"&&N.targetType!=="permission")return C(400,"subject, subjectType, targetType, and target are required","invalidValue");let w=await T.accessRequests.create({subject:N.subject,subjectType:N.subjectType,targetType:N.targetType,target:N.target,justification:typeof N.justification==="string"?N.justification:void 0});return L5(w,201,w.trackingUrl)}return C(404,"Resource not found")}return{...T,users:Y9(T.users),workloads:Y9(T.workloads),customers:Y9(T.customers),groups:{enabled:s},createUser:m5,getBaseUrl:d5,groups_outbound:A5,groups_inbound:R5,users_inbound:V5,workloads_inbound:q5,customers_inbound:P5,handler:z5,delta:u}}function T9(J,$){let Z=new TextEncoder().encode(J),X=typeof $==="string"?new TextEncoder().encode($):$,K=new Uint8Array(Z.length+1+X.length);return K.set(Z,0),K[Z.length]=46,K.set(X,Z.length+1),K}function n4(J){let $=J.replace(/-/g,"+").replace(/_/g,"/"),Z=$.length%4===0?"":"=".repeat(4-$.length%4),X=atob($+Z),K=new Uint8Array(X.length);for(let B=0;B<X.length;B++)K[B]=X.charCodeAt(B);return K}function a4(J){let $="";for(let Z of J)$+=String.fromCharCode(Z);return btoa($).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function G2(J){let $=JSON.parse(J);if(!$||typeof $!=="object"||!Array.isArray($.keys))throw Error("Invalid JWKS: expected { keys: [...] }");return $}function i4(J){return JSON.stringify(J)}async function t4(J){return crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:J.x},{name:"Ed25519"},!0,["verify"])}async function o4(J){return crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:J.x,d:J.d},{name:"Ed25519"},!0,["sign"])}async function r4(J){let Z=(typeof J.jwks==="string"?G2(J.jwks):J.jwks).keys.find((X)=>X.kid===J.kid&&X.kty==="OKP"&&X.crv==="Ed25519");if(!Z?.x)return!1;try{let X=await t4(Z),K=T9(J.requestId,J.rawBody),B=n4(J.signatureB64Url);return crypto.subtle.verify({name:"Ed25519"},X,B,K)}catch{return!1}}async function s4(J){let $=await o4(J.privateKeyJwk),Z=T9(J.requestId,J.rawBody),X=await crypto.subtle.sign({name:"Ed25519"},$,Z);return a4(new Uint8Array(X))}async function e4(J){let $=await crypto.subtle.generateKey({name:"Ed25519"},!0,["sign","verify"]),Z=await crypto.subtle.exportKey("jwk",$.privateKey),K=(await crypto.subtle.exportKey("jwk",$.publicKey)).x,B=Z.d;if(!K||!B)throw Error("Failed to export Ed25519 key material (missing x/d)");return{privateJwk:{kty:"OKP",crv:"Ed25519",x:K,d:B,kid:J,alg:"EdDSA",use:"sig"},publicJwks:{keys:[{kty:"OKP",crv:"Ed25519",x:K,kid:J,alg:"EdDSA",use:"sig"}]}}}var H1={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 y1(J,$){if(typeof J!=="number"||!Number.isFinite(J))return $.default;let Z=Math.floor(J);if(Z<$.min)return $.min;if(Z>$.max)return $.max;return Z}function W2(J){return{ttlMs:y1(J?.ttlSeconds,H1.jwksTtlSeconds)*1000,maxEntries:y1(J?.maxEntries,H1.jwksMaxEntries)}}function L2(J){let $=J?.read;return{read:{enabled:$?.enabled===!0,ttlMs:y1($?.ttlSeconds,H1.sessionReadTtlSeconds)*1000,maxEntries:y1($?.maxEntries,H1.sessionReadMaxEntries)}}}function JJ(J){return{jwks:W2(J?.jwks),session:L2(J?.session)}}function $J(J){let $={};if(!J)return $;let Z=J.split(";");for(let X of Z){let K=X.trim();if(!K)continue;let B=K.indexOf("=");if(B===-1)continue;$[K.slice(0,B).trim()]=K.slice(B+1).trim()}return $}function F2(J){if(!J.expiresAt)return!1;let $=J.expiresAt instanceof Date?J.expiresAt:new Date(J.expiresAt);return!Number.isNaN($.getTime())&&Date.now()>$.getTime()}function ZJ(J){if(!J||typeof J!=="object"||Array.isArray(J))return;let{access_token:$,id_token:Z,refresh_token:X,tokens:K,...B}=J;return B}function j5(J,$){let Z=J[$];return typeof Z==="string"?Z:""}function XJ(J,$){let Z=J.exp;if(typeof Z==="number")return new Date(Z*1000);if(typeof Z==="string"&&Z.trim()){let X=Number(Z);if(!Number.isNaN(X))return new Date(X*1000)}if($ instanceof Date)return $;if($){let X=new Date($);if(!Number.isNaN(X.getTime()))return X}return new Date}function QJ(J){let $=J.claims;if(!$?.sub||typeof $.sub!=="string")return;let Z=XJ($,J.expiresAt);if(J.authType==="sso")return{id:$.sub,userName:j5($,"preferred_username"),name:j5($,"name"),email:j5($,"email"),avatar:j5($,"picture")||void 0,sso:{profile:$,tenant:{id:j5($,"idp")||j5($,"iss"),name:j5($,"iss")},tokenType:"Bearer",expires:Z}};return{id:$.sub,userName:j5($,"preferred_username"),name:j5($,"name"),email:j5($,"email"),avatar:j5($,"picture")||void 0,userType:"customer",ciam:{profile:$,scope:"openid profile email",tokenType:"Bearer",expires:Z}}}function KJ(J){if(J.authType!=="sso"&&J.authType!=="ciam")return;if(F2(J))return;return{sid:J.sid,authType:J.authType,tenantId:typeof J.tenantId==="string"?J.tenantId:void 0,sub:J.sub,expiresAt:J.expiresAt,createdAt:J.createdAt,claims:ZJ(J.claims)}}function YJ(J,$){if(!J.endsWith(".session"))return!1;if(!$||$.length===0)return!0;return $.some((Z)=>J===`${Z}.session`)}function BJ(J){if(J===void 0)return;let $=(Array.isArray(J)?J:[J]).map((Z)=>Z.trim()).filter((Z)=>Z.length>0);return $.length>0?$:void 0}async function V2(J,$,Z){return(await H2(J,$,Z)).map(KJ).filter((K)=>Boolean(K))}async function H2(J,$,Z){let X=$J(J.headers.get("cookie")),K=BJ(Z?.cookiesPrefix),B=[],G=new Set;for(let[W,H]of Object.entries(X)){if(!YJ(W,K)||!H)continue;if(G.has(H))continue;G.add(H);let F=await $.get(H);if(!F)continue;if(F.authType!=="sso"&&F.authType!=="ciam")continue;if(F2(F))continue;B.push(F)}return B}async function GJ(J,$,Z){return(await V2(J,$,Z)).map(QJ).filter((K)=>Boolean(K))}var WJ="@ionite/core",LJ=a5(j1(WJ));async function FJ(J,$){let Z=await U5({idToken:J,jwksUri:$.jwksUri,issuer:$.issuer,audience:$.audience}),X=await LJ.validate(Z);if(X.issues)throw Error(`ID token claims validation failed: ${X.issues.map((G)=>G.message).join("; ")}`);let K=X.value;if(K===void 0)throw Error("ID token claims missing");return D2(K)}function B5(J){return Date.now()-J}function S9(J){if(J instanceof Error)return{"error.name":J.name,"error.message":J.message};return{"error.name":typeof J,"error.message":String(J)}}function b1(J,$){if(!J)return{};try{let Z=new URL(J);return{[`${$}.origin`]:Z.origin,[`${$}.path`]:Z.pathname}}catch{return{[`${$}.path`]:J.startsWith("/")?J:`/${J}`}}}function v1(J,$=5){if(!Array.isArray(J))return[String(J)];return J.slice(0,$).map((Z)=>{if(!Z||typeof Z!=="object")return String(Z);let X=Z,K=Array.isArray(X.path)?X.path.join("."):String(X.path??""),B=typeof X.message==="string"?X.message:String(X.message??"validation failed");return K?`${K}: ${B}`:B})}function VJ(J){if(!J||typeof J!=="object")return{};let $=J;return{oidc_error:typeof $.error==="string"?$.error:void 0,oidc_error_description:typeof $.error_description==="string"?$.error_description:void 0,oidc_error_uri:typeof $.error_uri==="string"?$.error_uri:void 0}}function HJ(J,$={}){let Z=typeof J==="string"?J:J?.headers.get("cookie")??void 0;if(!Z)return[];let K=`${$.cookiePrefix??"ion.sso"}.`,B=new Set;for(let G of Object.keys(MJ(Z))){if(!G.startsWith(K))continue;let W=G.slice(K.length),H=W.lastIndexOf(".");if(H<=0)continue;let F=W.slice(0,H).trim();if(F)B.add(F)}return Array.from(B)}function DJ(J,$,Z,X,K){if(!Z&&!X)return;let B=new WeakMap,G=new Map,W={...Z,...X},H=!!(W.authority&&W.tokenUrl&&W.authorizationUrl&&W.clientId&&W.redirectUri&&W.scope),F={...W,authority:H?i(W.authority,"Missing 'authority' from SSO Config"):W.authority,tokenUrl:H?i(W.tokenUrl,"Missing 'tokenUrl' from SSO Config"):W.tokenUrl,authorizationUrl:H?i(W.authorizationUrl,"Missing 'authorizationUrl' from SSO Config"):W.authorizationUrl,clientId:H?i(W.clientId,"Missing 'clientId' from SSO Config"):W.clientId,redirectUri:H?i(W.redirectUri,"Missing 'redirectUri' from SSO Config"):W.redirectUri,scope:H?i(W.scope,"Missing 'scope' from SSO Config"):W.scope,responseType:W.responseType??"code",cookiesSecure:W.cookiesSecure!==void 0?W.cookiesSecure:!0,cookiesSameSite:W.cookiesSameSite!==void 0?W.cookiesSameSite:"Strict",cookiesPrefix:W.cookiesPrefix??(W.clientId?`ion.sso.${W.clientId}`:"ion.sso"),cookiesPath:W.cookiesPath??"/"},g=Math.min(600,Math.max(0,Math.floor(Number(F.rotationGraceSeconds??60))||0))*1000,u=Math.floor(Number(F.sessionWindowSeconds??86400)),n=Number.isFinite(u)&&u>=1?u:86400;function e(){let Q=[];if(!F.authority)Q.push("authority");if(!F.tokenUrl)Q.push("tokenUrl");if(!F.authorizationUrl)Q.push("authorizationUrl");if(!F.clientId)Q.push("clientId");if(!F.redirectUri)Q.push("redirectUri");if(!F.scope)Q.push("scope");if(Q.length>0)throw Error(`Missing OIDC configuration fields: ${Q.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 $5(Q){if(!F)throw Error("ionite SSO Manager not initialized");let Y=B.get(Q);if(Y)return Y;let L=b(Q);return B.set(Q,L),L}async function b(Q){try{let{tokens:Y,session:L,refreshedUser:D}=await V5(Q);if(!Y)return{status:"unauthenticated"};if(D)return{status:"authenticated",value:D};if(L?.claims)return{status:"authenticated",value:K5(L.claims,Y,v5(L.expiresAt))};return{status:"unauthenticated"}}catch(Y){if(M2(Y))return{status:"unauthenticated"};return $.error("Error parsing user from cookies",{"ion.operation":"cookie.parse","ion.outcome":"degraded"},Y),{status:"degraded",error:Y instanceof Error?Y:void 0}}}async function r(Q){let Y=await $5(Q);return Y.status==="authenticated"?Y.value:void 0}async function T(Q){if(!F)throw Error("ionite SSO Manager not initialized");e();let Y=i(F.redirectUri,"Missing 'redirectUri' from SSO Config"),L=i(F.authorizationUrl,"Missing 'authorizationUrl' from SSO Config"),D=i(F.clientId,"Missing 'clientId' from SSO Config"),z=i(F.scope,"Missing 'scope' from SSO Config"),E=F.cookiesSecure?Q.url.replace(/^http:\/\//,"https://"):Q.url,A=O5(),N=O5(64),w=O5(),S=Y;try{new URL(S)}catch{if(E)try{let M=new URL(E),V=S.startsWith("//")?S.slice(1):S.startsWith("/")?S:`/${S}`;S=new URL(V,M.origin).toString()}catch{try{let M=new URL(L),V=S.startsWith("//")?S.slice(1):S.startsWith("/")?S:`/${S}`;S=new URL(V,M.origin).toString()}catch{throw Error(`Invalid redirectUri: "${Y}". It must be a valid absolute URL.`)}}}let q=new URL(L);q.searchParams.append("client_id",D),q.searchParams.append("redirect_uri",S),q.searchParams.append("response_type","code"),q.searchParams.append("scope",z),q.searchParams.append("state",A),q.searchParams.append("nonce",w);let I=await K1(N);q.searchParams.append("code_challenge",I),q.searchParams.append("code_challenge_method","S256");let f=await F.beforeLogin?.({request:Q}),d=f===void 0?{state:A,codeVerifier:N,nonce:w}:{state:A,codeVerifier:N,nonce:w,context:f};return new Response("Redirecting to SSO Provider",{status:302,headers:{Location:q.toString(),"Set-Cookie":P5(U(A),d,F.loginStateTtl??600,"Lax")}})}async function c(Q){if(!F)throw Error("ionite SSO Manager not initialized");let Y;try{Y=await r(Q)}catch{Y=void 0}let L=await F.beforeLogout?.({request:Q,user:Y}),D=y("session",Q),z;try{z=await V5(Q);let I=z.tokens?.refresh_token??y("refresh",Q);if(I)await d5(I)}catch(I){$.warn("Failed to revoke token",{"ion.operation":"token.revoke","ion.outcome":"degraded"},I)}if(F.sessionStore)try{let I=z?.sid??D;if(I)await F.sessionStore.delete(I)}catch(I){$.warn("Failed to delete session",{"ion.operation":"session.delete","ion.outcome":"degraded"},I)}let E=[["Set-Cookie",z5("session")]],A=await F.afterLogout?.({request:Q,context:L}),N=C5(A,"/",Q.url);if(N.response){let I=new Headers(N.response.headers);for(let[,f]of E)I.append("Set-Cookie",f);return new Response(N.response.body,{status:N.response.status,statusText:N.response.statusText,headers:I})}let w=N.location??"/",S=Q.headers.get("accept");if(S?.includes("application/json")||S?.includes("text/javascript"))return new Response(JSON.stringify({success:!0,message:"Logged out",redirect:w}),{status:200,headers:[["Content-Type","application/json"],...E]});return new Response("Logged out",{status:302,headers:[["Location",w],...E]})}async function s(Q){if(!F)throw Error("ionite SSO Manager not initialized");if(!F.sessionStore)throw Error("Back-Channel Logout requires sessionStore configuration");try{if(!Q.headers.get("content-type")?.includes("application/x-www-form-urlencoded"))return new Response("Invalid Content-Type, expected application/x-www-form-urlencoded",{status:400});let L=await Q.text(),z=new URLSearchParams(L).get("logout_token");if(!z)return new Response("Missing logout_token parameter",{status:400});let E=i(F.authority,"Missing 'authority' from SSO Config. OIDC configuration is required to verify logout tokens."),A=i(F.clientId,"Missing 'clientId' from SSO Config. OIDC configuration is required to verify logout tokens."),N=F.jwksUri||`${E}/protocol/openid-connect/certs`,w=await o1({logoutToken:z,jwksUri:N,issuer:E,audience:A,log:$}),S=typeof w.sid==="string"?w.sid:void 0;if(!S)return $.warn("Back-Channel Logout: logout_token missing sid claim",{"ion.operation":"backchannel_logout","ion.outcome":"failure"}),new Response("Invalid logout_token: missing sid claim",{status:400});return await F.sessionStore.delete(S),$.info("Back-Channel Logout: successfully deleted session",{"ion.module":"sso",sid:S}),new Response("OK",{status:200})}catch(Y){return $.error("Error during back-channel logout",{"ion.operation":"backchannel_logout","ion.outcome":"failure"},Y),new Response("Internal Server Error",{status:500})}}async function F5(Q){if(!F)throw Error("ionite SSO Manager not initialized");let Y=Date.now(),L=new URL(Q.url),D=new URLSearchParams(L.search);$.debug("SSO callback received",{"ion.event":"ion.sso.callback.received","ion.module":"sso","ion.operation":"sign_in.callback","http.method":Q.method,"url.path":L.pathname,hasCode:D.has("code"),hasState:D.has("state"),hasError:D.has("error"),...b1(D.get("iss")??void 0,"oidc.issuer")});let z=Object.fromEntries(D.entries()),E=await J.callbackParams.validate(z);if(E.issues)return $.warn("SSO callback parameter validation failed",{"ion.event":"ion.sso.callback.validation_failed","ion.operation":"sign_in.callback","ion.outcome":"failure","validation.issues":v1(E.issues)}),N2(E.issues,"OIDC callback parameters validation failed");let{code:A,state:N}=E.value,w;try{let S=i(N,'OIDC "state" was not present in the callback parameters'),q=y(U(S),Q,!0),{codeVerifier:I,state:f,nonce:d,context:M}=q??{};w=M,$.debug("SSO callback state cookie read",{"ion.event":"ion.sso.callback.state_cookie_read","ion.module":"sso","ion.operation":"sign_in.callback",hasStateCookie:Boolean(q),hasCodeVerifier:Boolean(I),hasStateVerifier:Boolean(f),hasNonce:Boolean(d),hasContext:M!==void 0});let V=i(I,'OIDC "codeVerifier" was not present in cookies, ensure that the SSO login was initiated correctly');i(f,'OIDC "stateVerifier" was not present in cookies, ensure that the SSO login was initiated correctly');let O=i(d,'OIDC "nonce" was not present in cookies, ensure that the SSO login was initiated correctly'),P=i(A,'OIDC "code" was not present in the callback parameters');if(N!==f)throw $.warn("SSO callback state verification failed",{"ion.event":"ion.sso.callback.state_verification_failed","ion.operation":"sign_in.callback","ion.outcome":"failure"}),Error('SSO State Verifier failed, the "state" request parameter does not equal the "state" in the SSO cookie');$.debug("SSO callback state verified",{"ion.event":"ion.sso.callback.state_verified","ion.module":"sso","ion.operation":"sign_in.callback"});let _=F.cookiesSecure?Q.url.replace(/^http:\/\//,"https://"):Q.url,R=await c5(P,V,_),{tokenExpiresAt:v,sessionExpiresAt:x}=G5(R);R.expires=v.toISOString();let m=Date.now();$.debug("SSO ID token parsing started",{"ion.event":"ion.sso.id_token.parse_started","ion.module":"sso","ion.operation":"id_token.parse"});let k=await M5(R,O,x);$.debug("SSO ID token parsing completed",{"ion.event":"ion.sso.id_token.parse_completed","ion.module":"sso","ion.operation":"id_token.parse","duration.ms":B5(m),"user.id":k.id});let l,Z5;{let J5=E5("SSO requires sessionStore configuration for opaque session cookies."),t=typeof k.sso.profile.sid==="string"?k.sso.profile.sid:void 0,w5=t||O5(32),H5=k.id;if($.debug("SSO session creation evaluated",{"ion.event":"ion.sso.session.create_evaluated","ion.module":"sso","ion.operation":"session.create",hasSid:Boolean(w5),hasIdpSid:Boolean(t),hasSub:Boolean(H5),"user.id":H5}),!H5)throw Error("Session creation failed: missing sub in ID token claims");let U1=Date.now(),D1={sid:w5,sub:H5,idpSid:t,authType:"sso",tenantId:F.tenantId,tokens:R,claims:k.sso.profile,expiresAt:x,createdAt:new Date};await h5(J5,D1),Z5=D1,l=["Set-Cookie",P5("session",w5,x)],$.info("SSO session created",{"ion.event":"ion.sso.session.created","ion.operation":"session.create","ion.outcome":"success","duration.ms":B5(U1),"user.id":H5})}if(F.userStore)try{let J5=k.id;if(J5){let t=new Date,w5=Date.now();$.debug("SSO user store lookup started",{"ion.event":"ion.sso.user.lookup_started","ion.module":"sso","ion.operation":"user.lookup","user.id":J5});let H5=await F.userStore.get(J5);if($.debug("SSO user store lookup completed",{"ion.event":"ion.sso.user.lookup_completed","ion.module":"sso","ion.operation":"user.lookup","duration.ms":B5(w5),"user.id":J5,found:Boolean(H5)}),H5||F.enableJitUserProvisioning){let U1=Date.now(),D1={...H5??{},...k,id:J5,tenantId:H5?.tenantId,createdAt:H5?.createdAt??t,updatedAt:t};await F.userStore.upsert(D1),$.info("SSO user stored",{"ion.event":"ion.sso.user.stored","ion.operation":"user.store","ion.outcome":"success","duration.ms":B5(U1),"user.id":J5,existing:Boolean(H5),jitProvisioning:Boolean(F.enableJitUserProvisioning)})}else $.warn("JIT user provisioning disabled: user not found in store and will not be created",{"ion.event":"ion.sso.user.skipped","ion.operation":"user.store","ion.outcome":"skipped","user.id":J5})}else $.warn("User storage skipped: missing sub in ID token claims",{"ion.event":"ion.sso.user.skipped","ion.operation":"user.store","ion.outcome":"skipped"})}catch(J5){$.warn("Failed to store user",{"ion.event":"ion.sso.user.store_failed","ion.operation":"user.store","ion.outcome":"degraded",...S9(J5)})}$.info("SSO sign-in succeeded",{"ion.event":"ion.sso.sign_in.succeeded","ion.operation":"sign_in.callback","ion.outcome":"success","duration.ms":B5(Y),"user.id":k.id});let W5=[["Set-Cookie",z5(U(S))],...l?[l]:[]],o=await F.afterLogin?.({ok:!0,request:Q,user:k,session:Z5,context:w}),a=C5(o,"/",Q.url);if(a.response)return g5(a.response,W5.map(([,J5])=>J5));return new Response("Authentication successful, redirecting",{status:302,headers:[["Location",a.location],...W5]})}catch(S){$.error("Error during sign-in callback",{"ion.event":"ion.sso.sign_in.callback_failed","ion.operation":"sign_in.callback","ion.outcome":"failure","duration.ms":B5(Y),...S9(S)});let q=N?[["Set-Cookie",z5(U(N))]]:[],I=await F.afterLogin?.({ok:!1,request:Q,error:S,context:w}),f=C5(I,"/",Q.url);if(f.response)return g5(f.response,q.map(([,d])=>d));return new Response("Authentication failed, redirecting",{status:302,headers:[["Location",f.location],...q]})}}function G5(Q){let Y=Date.now(),L=Number(Q.expires_in??3600)||3600,D=new Date(Y+L*1000),z;if(Q.refresh_expires_in!=null&&Number.isFinite(Number(Q.refresh_expires_in)))z=Number(Q.refresh_expires_in);else if(Q.refresh_token)z=n;else z=L;return{tokenExpiresAt:D,sessionExpiresAt:new Date(Y+z*1000)}}async function M5(Q,Y,L){if(!F)throw Error("ionite SSO Manager not initialized");let D=Date.now(),z=await J1(Q.id_token,Y);return $.debug("SSO user parsed from ID token",{"ion.event":"ion.sso.user.parse_completed","ion.module":"sso","ion.operation":"id_token.parse","duration.ms":B5(D),"user.id":z.sub,hasEmail:Boolean(z.email),hasName:Boolean(z.name)}),K5(z,Q,L)}function K5(Q,Y,L){let D=L??G5(Y).sessionExpiresAt,z=Q.ecid!==void 0&&Q.ecid!==null?S1(Q.ecid):void 0;return{id:Q.sub,userName:Q.preferred_username||"",name:Q.name||"",email:Q.email||"",emails:[{value:Q.email||"",primary:!0}],...z?{ecid:z}:{},avatar:Q.picture,sso:{profile:{...Q},tenant:{id:Q.idp||Q.iss||"",name:Q.iss||""},scope:Y.scope,tokenType:Y.token_type,sessionState:Y.session_state,expires:D}}}async function _5(Q){if(!F.userStore)return Q;let Y=await F.userStore.lookup(Q);if(!Y)return Q;return{...Q,...Y,id:Q.id,sso:Q.sso}}async function c5(Q,Y,L){if(!F)throw Error("ionite SSO Manager not initialized");e();let D=i(F.tokenUrl,"Missing 'tokenUrl' from SSO Config"),z=i(F.redirectUri,"Missing 'redirectUri' from SSO Config"),E=i(F.clientId,"Missing 'clientId' from SSO Config"),A=z;try{new URL(A)}catch{if(L)try{let w=new URL(L),S=A.startsWith("//")?A.slice(1):A.startsWith("/")?A:`/${A}`;A=new URL(S,w.origin).toString()}catch{try{let w=new URL(D),S=A.startsWith("//")?A.slice(1):A.startsWith("/")?A:`/${A}`;A=new URL(S,w.origin).toString()}catch{throw Error(`Invalid redirectUri: "${z}". It must be a valid absolute URL.`)}}}let N=new URLSearchParams;if(N.append("grant_type","authorization_code"),N.append("code",Q),N.append("redirect_uri",A),N.append("client_id",E),F.clientSecret)N.append("client_secret",F.clientSecret);N.append("code_verifier",Y);try{let w=Date.now();$.debug("SSO token exchange started",{"ion.event":"ion.sso.token.exchange_started","ion.module":"sso","ion.operation":"token.exchange",...b1(D,"oidc.token_url"),...b1(A,"oidc.redirect_uri"),hasClientSecret:Boolean(F.clientSecret)});let S=await fetch(D,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:N.toString()});$.debug("SSO token exchange response received",{"ion.event":"ion.sso.token.response_received","ion.module":"sso","ion.operation":"token.exchange","http.status_code":S.status,"duration.ms":B5(w)}),$.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 q=await S.json();if($.debug("SSO token exchange response body read completed",{"ion.event":"ion.sso.token.response_body_read_completed","ion.module":"sso","ion.operation":"token.exchange","duration.ms":B5(w)}),!S.ok){$.error("Token exchange error",{"ion.event":"ion.sso.token.exchange_failed","ion.operation":"token.exchange","ion.outcome":"failure","http.status_code":S.status,"duration.ms":B5(w),...VJ(q)});let f=q;throw Error(`Token exchange failed: ${f.error||S.statusText} - ${f.error_description||""}`.trim())}let I=await J.tokenResponse.validate(q);if(I.issues)throw $.error("Token response validation failed",{"ion.event":"ion.sso.token.response_validation_failed","ion.operation":"token.exchange","ion.outcome":"failure","duration.ms":B5(w),"validation.issues":v1(I.issues)}),Error(`Token response validation failed: ${I.issues}`);return $.debug("SSO token exchange completed",{"ion.event":"ion.sso.token.exchange_completed","ion.module":"sso","ion.operation":"token.exchange","ion.outcome":"success","duration.ms":B5(w),tokenType:I.value.token_type,hasAccessToken:Boolean(I.value.access_token),hasIdToken:Boolean(I.value.id_token),hasRefreshToken:Boolean(I.value.refresh_token),expiresIn:I.value.expires_in}),I.value}catch(w){throw $.error("Error during token exchange",{"ion.event":"ion.sso.token.exchange_failed","ion.operation":"token.exchange","ion.outcome":"failure",...S9(w)}),w}}async function f5(Q){return c1(async()=>{if(!F)throw Error("ionite SSO Manager not initialized");e();let Y=i(F.tokenUrl,"Missing 'tokenUrl' from SSO Config"),L=i(F.clientId,"Missing 'clientId' from SSO Config"),D=new URLSearchParams;if(D.append("grant_type","refresh_token"),D.append("refresh_token",Q),D.append("client_id",L),F.clientSecret)D.append("client_secret",F.clientSecret);let z=await fetch(Y,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:D.toString()}),E=await z.json();if(!z.ok){$.error("Token refresh error",{"ion.operation":"token.refresh","ion.outcome":"failure",response:E});let N=E;throw Error(`Token refresh failed: ${N.error||z.statusText} - ${N.error_description||""}`.trim())}let A=await J.tokenResponse.validate(E);if(A.issues)throw $.error("Token refresh response validation failed",{"ion.event":"ion.sso.token.refresh_validation_failed","ion.operation":"token.refresh","ion.outcome":"failure","validation.issues":v1(A.issues)}),Error(`Token refresh response validation failed: ${A.issues}`);return A.value},void 0,void 0,void 0,$)}async function d5(Q){try{if(!F)throw Error("ionite SSO Manager not initialized");if(!F.revocationEndpoint)return;let Y=i(F.clientId,"Missing 'clientId' from SSO Config"),L=new URLSearchParams;if(L.append("token",Q),L.append("token_type_hint","refresh_token"),L.append("client_id",Y),F.clientSecret)L.append("client_secret",F.clientSecret);let D=await fetch(F.revocationEndpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:L.toString()});if(!D.ok)$.warn("Token revocation failed",{"ion.operation":"token.revoke","ion.outcome":"degraded",status:D.status,statusText:D.statusText});else $.info("Token revoked successfully",{"ion.module":"sso"})}catch(Y){$.warn("Error revoking token",{"ion.operation":"token.revoke","ion.outcome":"degraded"},Y)}}async function e5(){if(!F)throw Error("ionite SSO Manager not initialized");let Q=F.authority;if(!F.jwksUri&&!Q)throw Error("Missing 'jwksUri' or 'authority' from SSO Config. OIDC configuration is required for this operation.");let Y=F.jwksUri||`${Q}/protocol/openid-connect/certs`;return Z1(Y,$)}async function J1(Q,Y){let L=Date.now(),D=i(F.authority,"Missing 'authority' from SSO Config. OIDC configuration is required to verify ID tokens."),z=i(F.clientId,"Missing 'clientId' from SSO Config. OIDC configuration is required to verify ID tokens."),E=F.jwksUri||`${D}/protocol/openid-connect/certs`;$.debug("SSO ID token verification started",{"ion.event":"ion.sso.id_token.verify_started","ion.module":"sso","ion.operation":"id_token.verify",...b1(E,"oidc.jwks_uri")});let A;try{A=await U5({idToken:Q,jwksUri:E,issuer:D,audience:z,expectedNonce:Y,log:$})}catch(w){throw $.error("SSO ID token verification failed",{"ion.event":"ion.sso.id_token.verify_failed","ion.module":"sso","ion.operation":"id_token.verify","ion.outcome":"failure","duration.ms":B5(L)},w),w}$.debug("SSO ID token signature verified",{"ion.event":"ion.sso.id_token.signature_verified","ion.module":"sso","ion.operation":"id_token.verify","duration.ms":B5(L)});let N=await J.idTokenClaims.validate(A);if(N.issues)throw $.error("ID token claims validation failed",{"ion.event":"ion.sso.id_token.validation_failed","ion.operation":"id_token.validate","ion.outcome":"failure","duration.ms":B5(L),"validation.issues":v1(N.issues)}),Error(`ID token claims validation failed: ${N.issues}`);return $.debug("SSO ID token claims validated",{"ion.event":"ion.sso.id_token.claims_validated","ion.module":"sso","ion.operation":"id_token.validate","ion.outcome":"success","duration.ms":B5(L),"user.id":N.value.sub,hasIssuer:Boolean(N.value.iss),hasAudience:Boolean(N.value.aud)}),N.value}function E5(Q="SSO sessionStore is required for opaque session cookies."){if(!F.sessionStore)throw Error(Q);return F.sessionStore}async function h5(Q,Y){try{await Q.create(Y)}catch(L){if(!await Q.get(Y.sid))throw L;await Q.update(Y.sid,Y)}}function v5(Q){if(!Q)return;if(Q instanceof Date)return Q;let Y=new Date(Q);return Number.isNaN(Y.getTime())?void 0:Y}function A5(Q){let Y=Q.tokens;if(!Y?.access_token||!Y.id_token||!Y.token_type)return;return Y}async function m5(Q,Y=!1){let L=E5(),D=y("session",Q);if(!D)return{tokens:void 0,refreshHeaders:[]};let z=await L.get(D);if(z&&F.tenantId&&z.tenantId&&z.tenantId!==F.tenantId)return{tokens:void 0,refreshHeaders:[["Set-Cookie",z5("session")]],sid:D};if(z?.authType!=="sso")return{tokens:void 0,refreshHeaders:[["Set-Cookie",z5("session")]],sid:D};let E=A5(z);if(!E)return{tokens:void 0,refreshHeaders:[["Set-Cookie",z5("session")]],sid:D};let A=v5(z.expiresAt);if(A?Date.now()>A.getTime():!1)return await L.delete(D),{tokens:void 0,sid:D,refreshHeaders:[["Set-Cookie",z5("session")]]};let w=v5(E.expires),S=w?Date.now()>w.getTime():!0;if((Y||S)&&E.refresh_token)return R5(D,z,E);return{tokens:E,sid:D,session:z,refreshHeaders:[]}}function R5(Q,Y,L){let D=G.get(Q);if(D)return D;let z=E5(),E=(async()=>{let A=await f5(L.refresh_token),{tokenExpiresAt:N,sessionExpiresAt:w}=G5(A);A.expires=N.toISOString();let S=await M5(A,void 0,w),q=S.sso.profile,I=O5(32),f={...Y,sid:I,tokens:A,claims:q,expiresAt:w,createdAt:new Date};await h5(z,f);try{if(g<=0)await z.delete(Q);else{let{refresh_token:d,...M}=L;await z.update(Q,{tokens:M,expiresAt:new Date(Date.now()+g)})}}catch(d){$.warn("Failed to retire rotated SSO session record",{"ion.operation":"session.rotate","ion.outcome":"degraded"},d)}return{tokens:A,sid:I,session:f,refreshedUser:S,refreshHeaders:[["Set-Cookie",P5("session",I,w)]]}})();return G.set(Q,E),E.finally(()=>{G.delete(Q)})}async function V5(Q,Y=!1){return m5(Q,Y)}async function q5(Q){let{tokens:Y}=await V5(Q);if(!Y)return;return Y.access_token}function P5(Q,Y,L,D=F.cookiesSameSite??"Strict"){if(!F)throw Error("ionite SSO Manager not initialized");if(Q=`${F.cookiesPrefix}.${Q}`,typeof Y!=="string")Y=btoa(JSON.stringify(Y));let z;if(L instanceof Date)z=`Expires=${L.toUTCString()}`;else if(typeof L==="number")z=`Max-Age=${L}`;else throw Error("Invalid expires type",L);if(Y.length>4000)throw Error(`Error setting cookie: ${Q}. Cookie length is: ${Y.length}`);return`${Q}=${Y}; ${z}; Path=${F.cookiesPath}; HttpOnly;${F.cookiesSecure?" Secure;":""} SameSite=${D};`}function z5(Q){if(!F)throw Error("ionite SSO Manager not initialized");return`${F.cookiesPrefix}.${Q}=; Max-Age=0; Path=${F.cookiesPath}; HttpOnly;${F.cookiesSecure?" Secure;":""} SameSite=${F.cookiesSameSite};`}function y(Q,Y,L=!1){if(!F)throw Error("ionite SSO Manager not initialized");let D=Y.headers.get("cookie");if(!D)return null;let z=`${F.cookiesPrefix}.${Q}`,E=D.split(";").find((S)=>S.trim().startsWith(`${z}=`));if(!E)return null;let A=E.indexOf("="),N=E.slice(A+1).trim();if(!L)return N;let w=atob(N);return JSON.parse(w)}function U(Q){return`state_${Q}`}async function h(Q,Y){if(!F)throw Error("ionite SSO Manager not initialized");let{loginUrl:L,userUrl:D,tokenUrl:z,refreshUrl:E,logoutUrl:A,logoutBackChannelUrl:N,jwksUrl:w,redirectUri:S}={...F,...Y},q=new URL(Q.url).pathname;if(S){let I;try{I=new URL(S).pathname}catch{try{let f=new URL(Q.url),d=S.startsWith("//")?S.slice(1):S;I=new URL(d,f.origin).pathname}catch{I=S.startsWith("/")?S:`/${S}`}}if(I===q)return F5(Q)}if(L===q)return T(Q);if(D===q)try{let{tokens:I,session:f,refreshedUser:d,refreshHeaders:M}=await V5(Q);if(!I)return new Response("User not logged in",{status:401,headers:M});let V=d??(f?.claims?K5(f.claims,I,v5(f.expiresAt)):void 0);if(!V)return new Response("User not logged in",{status:401,headers:M});let O=await _5(V);return new Response(JSON.stringify(O),{headers:[["Content-Type","application/json"],...M]})}catch(I){if(M2(I))return new Response("User not logged in",{status:401});return $.error("Error resolving SSO user",{"ion.operation":"sso.user","ion.outcome":"degraded"},I),new Response(JSON.stringify({error:"auth_unavailable"}),{status:503,headers:{"Content-Type":"application/json"}})}if(z===q){let{tokens:I,refreshHeaders:f}=await V5(Q);if(!I)return new Response("User not logged in",{status:401,headers:f});return new Response(JSON.stringify({token:I.access_token,expires:I.expires}),{headers:[["Content-Type","application/json"],...f]})}if(E===q){let{tokens:I,refreshHeaders:f}=await V5(Q,!0);if(!I)return new Response("User not logged in",{status:401});return new Response("Refresh Complete",{status:200,headers:f})}if(A===q)return c(Q);if(N===q)return s(Q);if(w===q){let I=await e5();return new Response(JSON.stringify(I),{headers:[["Content-Type","application/json"]]})}return new Response("Not Found",{status:404})}return{...F,getUser:r,resolveUser:$5,getJwt:q5,initiateLogin:T,logout:c,logoutBackChannel:s,callbackHandler:F5,handler:h}}function MJ(J){let $={},Z=J.split(";");for(let X of Z){let K=X.trim();if(!K)continue;let B=K.indexOf("=");if(B===-1)continue;let G=K.slice(0,B).trim(),W=K.slice(B+1).trim();$[G]=W}return $}function M2(J){if(!(J 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(($)=>J.message.includes($))}function z2(J){return J=J??"SSO Unavailable",new Response(JSON.stringify({error:J}),{status:503,statusText:J,headers:{"Content-Type":"application/json"}})}var q1="Ionite instance is required. Create one with ionite(source, config) and pass it to this function.";async function NJ(J,$){return i($,q1),$.sso?.getUser(J)}async function zJ(J,$){return i($,q1),await $.sso?.resolveUser(J)??{status:"unauthenticated"}}async function OJ(J,$){i($,q1);let Z=$.sso;if(!Z)return z2();return Z.initiateLogin(J)}async function jJ(J,$){i($,q1);let Z=$.sso;if(!Z)return z2();return Z.callbackHandler(J)}export{g5 as withSetCookies,FJ as verifyUser,o1 as verifyLogoutToken,r4 as verifyLfvSignature,U5 as verifyIdToken,i4 as stringifyLfvJwks,DJ as sso,s4 as signLfvPayload,k2 as setJwksRetry,C2 as setJwksClock,i2 as setDiscoveryClock,AJ as sendTenantWebhook,J9 as sameOriginRedirectRules,zJ as resolveUser,L2 as resolveSessionCacheConfig,$9 as resolveRedirect,h1 as resolveProviderBranding,W2 as resolveJwksCacheConfig,g2 as resolveJwkForKid,W4 as resolveCustomer,N1 as resolveCiamProvider,Q4 as resolveCapturedRedirect,JJ as resolveCacheConfig,C5 as resolveAfterRedirect,w9 as reconcileSubjectAccess,K1 as pkceChallengeFromVerifier,G2 as parseLfvJwks,m1 as orderedEnabledProviders,Q1 as normalizeOidcIssuer,HJ as listSsoClientIdsFromCookies,a9 as isRedirectAllowed,OJ as initiateLogin,d4 as iam,b2 as hasScope,S2 as hasRole,T2 as hasPermission,R2 as hasGroup,v2 as hasAnyScope,x2 as hasAny,q2 as hasAllScope,y2 as hasAll,I2 as has,n1 as getVerificationKeyForKid,NJ as getUser,p2 as getPublicKeyFromJwks,u2 as getPublicKeyForKid,f1 as getProviderPreset,Z1 as getJwks,GJ as getDiscoveredSessionUsers,G4 as getCustomer,d1 as getCachedVerificationKey,e4 as generateLfvEd25519KeyPair,e1 as generateAppleClientSecret,s1 as fetchUserInfo,P9 as expandRoot,t1 as exchangeAuthorizationCode,Z9 as entitlementToScimGroup,V2 as discoverSessions,H2 as discoverSessionRecords,r1 as discoverOidcEndpoints,Z4 as defaultRedirectPolicies,U2 as configureJwksCache,_J as collectReferencedDefinitions,m2 as clearJwksCache,t2 as clearDiscoveryCache,B4 as ciam,X4 as captureRedirect,jJ as callback,T9 as buildLfvSigningInput,i1 as buildAuthorizationUrl,c9 as blockDangerousUrls,Q9 as baseWorkloadToScim,X9 as baseUserToScimUser,K9 as baseCustomerToScim,p9 as assertTrustedIdTokenClaims,B2 as assertSubjectTypeAssignable,n9 as allowSameOrigin,d9 as allowRelativePaths,J4 as allowOrigins,$4 as allowHosts,EJ as InMemoryTenantStore,A9 as CatalogAdjacencyCache,v9 as CIAM_PROVIDER_PRESETS,H1 as CACHE_BOUNDS};
|